add CCDeque.{*_opt}

Functions added:
CCDeque.peek_front_opt
CCDeque.peek_back_opt
CCDeque.take_back_opt
CCDeque.take_front_opt
This commit is contained in:
Fardale 2019-10-23 13:51:51 +02:00 committed by Simon Cruanes
parent 035aac9a72
commit a33963c335
2 changed files with 49 additions and 18 deletions

View file

@ -106,11 +106,15 @@ let push_back d x =
n.next <- elt;
d.cur.prev <- elt
let peek_front d = match d.cur.cell with
| Zero -> raise Empty
| One x -> x
| Two (x,_) -> x
| Three (x,_,_) -> x
let peek_front_opt d = match d.cur.cell with
| Zero -> None
| One x -> Some x
| Two (x,_) -> Some x
| Three (x,_,_) -> Some x
let peek_front d = match peek_front_opt d with
| None -> raise Empty
| Some x -> x
(*$T
of_list [1;2;3] |> peek_front = 1
@ -130,14 +134,17 @@ let peek_front d = match d.cur.cell with
OUnit.assert_equal ~printer 10 (peek_back d);
*)
let peek_back d =
if is_empty d then raise Empty
let peek_back_opt d =
if is_empty d then None
else match d.cur.prev.cell with
| Zero -> assert false
| One x -> x
| Two (_,x) -> x
| Three (_,_,x) -> x
| One x -> Some x
| Two (_,x) -> Some x
| Three (_,_,x) -> Some x
let peek_back d = match peek_back_opt d with
| None -> raise Empty
| Some x -> x
(*$T
of_list [1;2;3] |> peek_back = 3
try (ignore (of_list [] |> peek_back); false) with Empty -> true
@ -167,22 +174,26 @@ let remove_node_ n =
n.prev.next <- next;
next.prev <- n.prev
let take_back d =
if is_empty d then raise Empty
let take_back_opt d =
if is_empty d then None
else if Stdlib.(==) d.cur d.cur.prev
then (
(* only one cell *)
decr_size_ d;
take_back_node_ d.cur
Some (take_back_node_ d.cur)
) else (
let n = d.cur.prev in
let x = take_back_node_ n in
decr_size_ d;
(* remove previous node *)
if is_zero_ n then remove_node_ n;
x
Some x
)
let take_back d = match take_back_opt d with
| None -> raise Empty
| Some x -> x
(*$T
let q = of_list [1] in take_back q = 1 && to_list q = []
let q = of_list [1;2] in take_back q = 2 && to_list q = [1]
@ -200,13 +211,13 @@ let take_front_node_ n = match n.cell with
let q = of_list [1;2;3] in take_front q = 1 && to_list q = [2;3]
*)
let take_front d =
if is_empty d then raise Empty
let take_front_opt d =
if is_empty d then None
else if Stdlib.(==) d.cur.prev d.cur
then (
(* only one cell *)
decr_size_ d;
take_front_node_ d.cur
Some (take_front_node_ d.cur)
) else (
decr_size_ d;
let x = take_front_node_ d.cur in
@ -215,9 +226,13 @@ let take_front d =
d.cur.next.prev <- d.cur.prev;
d.cur <- d.cur.next;
);
x
Some x
)
let take_front d = match take_front_opt d with
| None -> raise Empty
| Some x -> x
let iter f d =
let rec iter f ~first n =
begin match n.cell with

View file

@ -45,18 +45,34 @@ val peek_front : 'a t -> 'a
(** First value.
@raise Empty if empty. *)
val peek_front_opt : 'a t -> 'a option
(** First value.
@since NEXT_RELEASE *)
val peek_back : 'a t -> 'a
(** Last value.
@raise Empty if empty. *)
val peek_back_opt : 'a t -> 'a option
(** Last value.
@since NEXT_RELEASE *)
val take_back : 'a t -> 'a
(** Take last value.
@raise Empty if empty. *)
val take_back_opt : 'a t -> 'a option
(** Take last value.
@since NEXT_RELEASE *)
val take_front : 'a t -> 'a
(** Take first value.
@raise Empty if empty. *)
val take_front_opt : 'a t -> 'a option
(** Take first value.
@since NEXT_RELEASE *)
val append_front : into:'a t -> 'a t -> unit
(** [append_front ~into q] adds all elements of [q] at the front
of [into].