mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
add CCDeque.{fold,append_{front,back},{of,to}_{gen,list}} and others
This commit is contained in:
parent
1baf4c80ea
commit
d204e1946f
2 changed files with 154 additions and 0 deletions
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue