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

View file

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