add CCDeque.{fold,append_{front,back},{of,to}_{gen,list}} and others

This commit is contained in:
Simon Cruanes 2015-08-31 16:13:28 +02:00
parent 1baf4c80ea
commit d204e1946f
2 changed files with 154 additions and 0 deletions

View file

@ -113,6 +113,29 @@ let iter f d =
in
iter first
(*$T
let n = ref 0 in iter (fun _ -> incr n) (of_list [1;2;3]); !n = 3
*)
let append_front ~into q = iter (push_front into) q
let append_back ~into q = iter (push_back into) q
let fold f acc d =
match !d with
| None -> acc
| Some first ->
let rec aux acc elt =
let acc = f acc elt.content in
if elt.next != first then aux acc elt.next else acc
in
aux acc first
(*$T
fold (+) 0 (of_list [1;2;3]) = 6
fold (fun acc x -> x::acc) [] (of_list [1;2;3]) = [3;2;1]
*)
let length (d : _ t) =
match !d with
| None -> 0
@ -122,6 +145,19 @@ let length (d : _ t) =
!r
type 'a sequence = ('a -> unit) -> unit
type 'a gen = unit -> 'a option
let add_seq_back q seq = seq (fun x -> push_back q x)
let add_seq_front q seq = seq (fun x -> push_front q x)
(*$R
let q = of_list [4;5] in
add_seq_front q Sequence.(of_list [3;2;1]);
assert_equal [1;2;3;4;5] (to_list q);
add_seq_back q Sequence.(of_list [6;7]);
assert_equal [1;2;3;4;5;6;7] (to_list q);
*)
let of_seq ?(deque=create ()) seq =
seq (fun x -> push_back deque x);
@ -129,12 +165,72 @@ let of_seq ?(deque=create ()) seq =
let to_seq d k = iter k d
let of_list l =
let q = create() in
List.iter (push_back q) l;
q
let to_rev_list q = fold (fun l x -> x::l) [] q
let to_list q = List.rev (to_rev_list q)
let gen_empty_ () = None
let rec gen_iter_ f g = match g() with
| None -> ()
| Some x -> f x; gen_iter_ f g
let of_gen g =
let q = create () in
gen_iter_ (fun x -> push_back q x) g;
q
let to_gen q = match !q with
| None -> gen_empty_
| Some q ->
let cur = ref q in
let first = ref true in
fun () ->
let x = (!cur).content in
if !cur == q && not !first then None
else (
first := false;
cur := (!cur).next;
Some x
)
(*$T
of_list [1;2;3] |> to_gen |> of_gen |> to_list = [1;2;3]
*)
(*$Q
Q.(list int) (fun l -> \
of_list l |> to_gen |> of_gen |> to_list = l)
*)
(* naive implem of copy, for now *)
let copy d =
let d' = create () in
iter (fun x -> push_back d' x) d;
d'
let equal ?(eq=(=)) a b =
let rec aux eq a b = match a() , b() with
| None, None -> true
| None, Some _
| Some _, None -> false
| Some x, Some y -> eq x y && aux eq a b
in aux eq (to_gen a) (to_gen b)
let compare ?(cmp=Pervasives.compare) a b =
let rec aux cmp a b = match a() , b() with
| None, None -> 0
| None, Some _ -> -1
| Some _, None -> 1
| Some x, Some y ->
let c = cmp x y in
if c=0 then aux cmp a b else c
in aux cmp (to_gen a) (to_gen b)
type 'a printer = Format.formatter -> 'a -> unit
let print pp_x out d =

View file

@ -36,6 +36,17 @@ val create : unit -> 'a t
val is_empty : 'a t -> bool
(** Is the deque empty? *)
val equal : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool
(** [equal a b] checks whether [a] and [b] contain the same sequence of
elements.
@param eq comparison function for elements
@since NEXT_RELEASE *)
val compare : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int
(** [equal a b] compares lexicographically [a] and [b]
@param cmp comparison function for elements
@since NEXT_RELEASE *)
val length : 'a t -> int
(** Number of elements (linear) *)
@ -57,18 +68,65 @@ val take_back : 'a t -> 'a
val take_front : 'a t -> 'a
(** Take first value, or raise Empty *)
val append_front : into:'a t -> 'a t -> unit
(** [append_front ~into q] adds all elements of [q] at the front
of [into]
@since NEXT_RELEASE *)
val append_back : into:'a t -> 'a t -> unit
(** [append_back ~into q] adds all elements of [q] at the back of [into]
@since NEXT_RELEASE *)
val iter : ('a -> unit) -> 'a t -> unit
(** Iterate on elements *)
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** Fold on elements
@since NEXT_RELEASE *)
(** {2 Conversions} *)
type 'a gen = unit -> 'a option
type 'a sequence = ('a -> unit) -> unit
val of_seq : ?deque:'a t -> 'a sequence -> 'a t
val to_seq : 'a t -> 'a sequence
val of_gen : 'a gen -> 'a t
(** [of_gen g] makes a deque containing the elements of [g]
@since NEXT_RELEASE *)
val to_gen : 'a t -> 'a gen
(** Iterates on elements of the deque
@since NEXT_RELEASE *)
val add_seq_front : 'a t -> 'a sequence -> unit
(** [add_seq_front q seq] adds elements of [seq] into the front of [q],
in reverse order
@since NEXT_RELEASE *)
val add_seq_back : 'a t -> 'a sequence -> unit
(** [add_seq_back q seq] adds elements of [seq] into the back of [q],
in order
@since NEXT_RELEASE *)
val copy : 'a t -> 'a t
(** Fresh copy *)
val of_list : 'a list -> 'a t
(** Conversion from list, in order
@since NEXT_RELEASE *)
val to_list : 'a t -> 'a list
(** List of elements, in order
{b warning: not tailrec}
@since NEXT_RELEASE *)
val to_rev_list : 'a t -> 'a list
(** Efficient conversion to list, in reverse order
@since NEXT_RELEASE *)
type 'a printer = Format.formatter -> 'a -> unit
val print : 'a printer -> 'a t printer