diff --git a/README.md b/README.md index b18bc559..edf35ecc 100644 --- a/README.md +++ b/README.md @@ -351,14 +351,14 @@ module IntMap = CCMap.Make(CCInt) let map : string IntMap.t = l2 |> List.map (fun x -> x, string_of_int x) - |> CCList.to_seq - |> IntMap.of_seq;; + |> CCList.to_iter + |> IntMap.of_iter;; val map : string IntMap.t = -# CCList.to_seq ;; (* check the type *) -- : 'a list -> 'a CCList.sequence = -# IntMap.of_seq ;; -- : (int * 'a) CCMap.sequence -> 'a IntMap.t = +# CCList.to_iter;; (* check the type *) +- : 'a list -> 'a CCList.iter = +# IntMap.of_iter ;; +- : (int * 'a) CCMap.iter -> 'a IntMap.t = # (* we can print, too *) Format.printf "@[<2>map =@ @[%a@]@]@." @@ -448,7 +448,7 @@ module IntHeap = CCHeap.Make(struct type t = int let leq = (<=) end);; ``` ```ocaml -# let h = v2 |> CCVector.to_seq |> IntHeap.of_seq ;; +# let h = v2 |> CCVector.to_iter |> IntHeap.of_iter ;; val h : IntHeap.t = # (* We can print the content of h diff --git a/src/core/CCArray.ml b/src/core/CCArray.ml index 86c5ef06..668389e2 100644 --- a/src/core/CCArray.ml +++ b/src/core/CCArray.ml @@ -2,6 +2,7 @@ (** {1 Array utils} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option @@ -559,7 +560,21 @@ let to_string ?(sep=", ") item_to_string a = (to_string string_of_int [|1|]) "1" *) -let to_seq a k = iter k a +let to_std_seq a = + let rec aux i () = + if i>= length a then Seq.Nil + else Seq.Cons (a.(i), aux (i+1)) + in + aux 0 + +(*$= + [] (to_std_seq [||] |> CCList.of_std_seq) + [1;2;3] (to_std_seq [|1;2;3|] |> CCList.of_std_seq) + CCList.(1 -- 1000) (to_std_seq (1--1000) |> CCList.of_std_seq) +*) + +let to_iter a k = iter k a +let to_seq = to_iter let to_gen a = let k = ref 0 in diff --git a/src/core/CCArray.mli b/src/core/CCArray.mli index af710ac7..454e823a 100644 --- a/src/core/CCArray.mli +++ b/src/core/CCArray.mli @@ -1,10 +1,16 @@ -(* AUTOGENERATED FROM CCArrayLabels.mli *) (* This file is free software, part of containers. See file "license" for more details. *) (** {1 Array utils} *) +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option type 'a equal = 'a -> 'a -> bool @@ -251,16 +257,31 @@ val to_string : ?sep:string -> ('a -> string) -> 'a array -> string between elements of [a]. @since 2.7 *) -val to_seq : 'a t -> 'a sequence -(** [to_seq a] returns a [sequence] of the elements of an array [a]. +val to_iter : 'a t -> 'a iter +(** [to_iter a] returns an [iter] of the elements of an array [a]. The input array [a] is shared with the sequence and modification of it will result - in modification of the sequence. *) + in modification of the iterator. + @since NEXT_RELEASE *) + +val to_std_seq : 'a t -> 'a Seq.t +(** [to_std_seq a] returns a [Seq.t] of the elements of an array [a]. + The input array [a] is shared with the sequence and modification of it will result + in modification of the sequence. + @since NEXT_RELEASE +*) + +val to_seq : 'a t -> 'a sequence +(** Same as {!to_iter}. + @deprecated use {!to_iter} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] val to_gen : 'a t -> 'a gen (** [to_gen a] returns a [gen] of the elements of an array [a]. *) val to_klist : 'a t -> 'a klist -(** [to_klist] returns a [klist] of the elements of an array [a]. *) +(** [to_klist] returns a [klist] of the elements of an array [a]. + @deprecated use {!to_std_seq} *) +[@@ocaml.deprecated "use to_std_seq"] (** {2 IO} *) diff --git a/src/core/CCArrayLabels.mli b/src/core/CCArrayLabels.mli index 76684e5b..97c56ec8 100644 --- a/src/core/CCArrayLabels.mli +++ b/src/core/CCArrayLabels.mli @@ -2,7 +2,15 @@ (** {1 Array utils} *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option type 'a equal = 'a -> 'a -> bool @@ -249,16 +257,31 @@ val to_string : ?sep:string -> ('a -> string) -> 'a array -> string between elements of [a]. @since 2.7 *) -val to_seq : 'a t -> 'a sequence -(** [to_seq a] returns a [sequence] of the elements of an array [a]. +val to_iter : 'a t -> 'a iter +(** [to_iter a] returns an [iter] of the elements of an array [a]. The input array [a] is shared with the sequence and modification of it will result - in modification of the sequence. *) + in modification of the iterator. + @since NEXT_RELEASE *) + +val to_std_seq : 'a t -> 'a Seq.t +(** [to_std_seq a] returns a [Seq.t] of the elements of an array [a]. + The input array [a] is shared with the sequence and modification of it will result + in modification of the sequence. + @since NEXT_RELEASE +*) + +val to_seq : 'a t -> 'a sequence +(** Same as {!to_iter}. + @deprecated use {!to_iter} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] val to_gen : 'a t -> 'a gen (** [to_gen a] returns a [gen] of the elements of an array [a]. *) val to_klist : 'a t -> 'a klist -(** [to_klist] returns a [klist] of the elements of an array [a]. *) +(** [to_klist] returns a [klist] of the elements of an array [a]. + @deprecated use {!to_std_seq} *) +[@@ocaml.deprecated "use to_std_seq"] (** {2 IO} *) @@ -298,13 +321,13 @@ val filter_map : f:('a -> 'b option) -> 'a t -> 'b t of all elements [bi] such as [~f ai = Some bi]. When [~f] returns [None], the corresponding element of [a] is discarded. *) -val flat_map : f:('a -> 'b t) -> 'a t -> 'b array -(** [flat_map ~f a] transforms each element of [a] into an array, then flattens. *) - val monoid_product : f:('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t (** All combinaisons of tuples from the two arrays are passed to the function @since NEXT_RELEASE *) +val flat_map : f:('a -> 'b t) -> 'a t -> 'b array +(** [flat_map ~f a] transforms each element of [a] into an array, then flattens. *) + val (>>=) : 'a t -> ('a -> 'b t) -> 'b t (** [a >>= f] is the infix version of {!flat_map}. *) diff --git a/src/core/CCArray_slice.ml b/src/core/CCArray_slice.ml index a9db0cab..53118d85 100644 --- a/src/core/CCArray_slice.ml +++ b/src/core/CCArray_slice.ml @@ -5,6 +5,7 @@ open CCShims_ +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option @@ -264,6 +265,9 @@ let _to_gen a i j = Some x ) else None +let rec _to_std_seq a i j () = + if i=j then Seq.Nil else Seq.Cons (a.(i), _to_std_seq a (i+1) j) + let rec _to_klist a i j () = if i=j then `Nil else `Cons (a.(i), _to_klist a (i+1) j) @@ -413,10 +417,12 @@ let pp ?(sep=", ") pp_item buf a = _pp ~sep pp_item buf a.arr a.i a.j let pp_i ?(sep=", ") pp_item out a = _pp_i ~sep (fun k out x -> pp_item (k-a.i) out x) out a.arr a.i a.j -let to_seq a k = iter k a +let to_iter a k = iter k a +let to_seq = to_iter let to_gen a = _to_gen a.arr a.i a.j +let to_std_seq a = _to_std_seq a.arr a.i a.j let to_klist a = _to_klist a.arr a.i a.j diff --git a/src/core/CCArray_slice.mli b/src/core/CCArray_slice.mli index f79fcb78..aa7beb07 100644 --- a/src/core/CCArray_slice.mli +++ b/src/core/CCArray_slice.mli @@ -5,7 +5,15 @@ (** {1 Array Slice} *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option type 'a equal = 'a -> 'a -> bool @@ -237,16 +245,33 @@ val random_choose : 'a t -> 'a random_gen (** [random_choose as rs] randomly chooses an element of [as]. @raise Not_found if the array/slice is empty. *) +val to_iter : 'a t -> 'a iter +(** [to_iter a] returns an [iter] of the elements of a slice [a]. + The input array [a] is shared with the sequence and modification of it will result + in modification of the iterator. + @since NEXT_RELEASE *) + +val to_std_seq : 'a t -> 'a Seq.t +(** [to_std_seq a] returns a [Seq.t] of the elements of a slice [a]. + The input array [a] is shared with the sequence and modification of it will result + in modification of the sequence. + @since NEXT_RELEASE +*) + val to_seq : 'a t -> 'a sequence (** [to_seq as] returns a [sequence] of the elements of a slice [as]. The input slice [as] is shared with the sequence and modification of it will result - in modification of the sequence. *) + in modification of the sequence. + @deprecated use {!to_iter} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] val to_gen : 'a t -> 'a gen (** [to_gen as] returns a [gen] of the elements of a slice [as]. *) val to_klist : 'a t -> 'a klist -(** [to_klist as] returns a [klist] of the elements of a slice [as]. *) +(** [to_klist as] returns a [klist] of the elements of a slice [as]. + @deprecated use {!to_std_seq} *) +[@@ocaml.deprecated "use to_std_seq"] (** {2 IO} *) diff --git a/src/core/CCArray_sliceLabels.mli b/src/core/CCArray_sliceLabels.mli index 41b59667..8fecce9c 100644 --- a/src/core/CCArray_sliceLabels.mli +++ b/src/core/CCArray_sliceLabels.mli @@ -3,7 +3,14 @@ (** {1 Array Slice} *) +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option type 'a equal = 'a -> 'a -> bool @@ -235,10 +242,25 @@ val random_choose : 'a t -> 'a random_gen (** [random_choose as rs] randomly chooses an element of [as]. @raise Not_found if the array/slice is empty. *) +val to_iter : 'a t -> 'a iter +(** [to_iter a] returns an [iter] of the elements of a slice [a]. + The input array [a] is shared with the sequence and modification of it will result + in modification of the iterator. + @since NEXT_RELEASE *) + +val to_std_seq : 'a t -> 'a Seq.t +(** [to_std_seq a] returns a [Seq.t] of the elements of a slice [a]. + The input array [a] is shared with the sequence and modification of it will result + in modification of the sequence. + @since NEXT_RELEASE +*) + val to_seq : 'a t -> 'a sequence (** [to_seq as] returns a [sequence] of the elements of a slice [as]. The input slice [as] is shared with the sequence and modification of it will result - in modification of the sequence. *) + in modification of the sequence. + @deprecated use {!to_iter} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] val to_gen : 'a t -> 'a gen (** [to_gen as] returns a [gen] of the elements of a slice [as]. *) diff --git a/src/core/CCHashtbl.ml b/src/core/CCHashtbl.ml index 39fa57a3..ba58413f 100644 --- a/src/core/CCHashtbl.ml +++ b/src/core/CCHashtbl.ml @@ -3,6 +3,7 @@ (** {1 Extension to the standard Hashtbl} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a eq = 'a -> 'a -> bool type 'a hash = 'a -> int @@ -59,22 +60,42 @@ module Poly = struct |> List.sort Stdlib.compare = ["1a"; "2b"] *) - let to_seq tbl k = Hashtbl.iter (fun key v -> k (key,v)) tbl + let to_iter tbl k = Hashtbl.iter (fun key v -> k (key,v)) tbl - let add_seq tbl seq = seq (fun (k,v) -> Hashtbl.add tbl k v) + let add_iter tbl i = i (fun (k,v) -> Hashtbl.add tbl k v) - let of_seq seq = + let add_std_seq tbl seq = Seq.iter (fun (k,v) -> Hashtbl.add tbl k v) seq + + let of_iter i = let tbl = Hashtbl.create 32 in - add_seq tbl seq; + add_iter tbl i; tbl - let add_seq_count tbl seq = seq (fun k -> incr tbl k) - - let of_seq_count seq = + let of_std_seq i = let tbl = Hashtbl.create 32 in - add_seq_count tbl seq; + add_std_seq tbl i; tbl + let add_iter_count tbl i = i (fun k -> incr tbl k) + + let add_std_seq_count tbl seq = Seq.iter (fun k -> incr tbl k) seq + + let of_iter_count i = + let tbl = Hashtbl.create 32 in + add_iter_count tbl i; + tbl + + let of_std_seq_count i = + let tbl = Hashtbl.create 32 in + add_std_seq_count tbl i; + tbl + + let to_seq = to_iter + let add_seq = add_iter + let of_seq = of_iter + let add_seq_count = add_iter_count + let of_seq_count = of_iter_count + let to_list tbl = Hashtbl.fold (fun k v l -> (k,v) :: l) @@ -145,23 +166,23 @@ module type S = sig include Hashtbl.S val get : 'a t -> key -> 'a option - (** Safe version of {!Hashtbl.find} *) + (** Safe version of {!Hashtbl.find}. *) val get_or : 'a t -> key -> default:'a -> 'a (** [get_or tbl k ~default] returns the value associated to [k] if present, - and returns [default] otherwise (if [k] doesn't belong in [tbl]) + and returns [default] otherwise (if [k] doesn't belong in [tbl]). @since 0.16 *) val add_list : 'a list t -> key -> 'a -> unit (** [add_list tbl x y] adds [y] to the list [x] is bound to. If [x] is - not bound, it becomes bound to [[y]]. + not bound, it becomes bound to [y]. @since 0.16 *) val incr : ?by:int -> int t -> key -> unit (** [incr ?by tbl x] increments or initializes the counter associated with [x]. If [get tbl x = None], then after update, [get tbl x = Some 1]; otherwise, if [get tbl x = Some n], now [get tbl x = Some (n+1)]. - @param by if specified, the int value is incremented by [by] rather than 1 + @param by if specified, the int value is incremented by [by] rather than 1. @since 0.16 *) val decr : ?by:int -> int t -> key -> unit @@ -170,45 +191,96 @@ module type S = sig This does nothing if the key is not already present in the table. @since 0.16 *) - val keys : 'a t -> key sequence - (** Iterate on keys (similar order as {!Hashtbl.iter}) *) + val keys : 'a t -> key iter + (** Iterate on keys (similar order as {!Hashtbl.iter}). *) - val values : 'a t -> 'a sequence - (** Iterate on values in the table *) + val values : 'a t -> 'a iter + (** Iterate on values in the table. *) val keys_list : _ t -> key list - (** [keys t] is the list of keys in [t]. + (** [keys_list t] is the list of keys in [t]. + If the key is in the Hashtable multiple times, all occurrences will be returned. @since 0.8 *) val values_list : 'a t -> 'a list - (** [values t] is the list of values in [t]. + (** [values_list t] is the list of values in [t]. @since 0.8 *) val map_list : (key -> 'a -> 'b) -> 'a t -> 'b list - (** Map on a hashtable's items, collect into a list *) + (** Map on a hashtable's items, collect into a list. *) + + val to_iter : 'a t -> (key * 'a) iter + (** Iterate on bindings in the table. + @since NEXT_RELEASE *) val to_seq : 'a t -> (key * 'a) sequence - (** Iterate on values in the table *) + (** Iterate on values in the table. + @deprecated use {!to_iter} instead *) + [@@ocaml.deprecated "use to_iter"] - val of_seq : (key * 'a) sequence -> 'a t - (** From the given bindings, added in order *) + val add_iter : 'a t -> (key * 'a) iter -> unit + (** Add the corresponding pairs to the table, using {!Hashtbl.add}. + @since NEXT_RELEASE *) + + val add_std_seq : 'a t -> (key * 'a) Seq.t -> unit + (** Add the corresponding pairs to the table, using {!Hashtbl.add}. + @since NEXT_RELEASE *) val add_seq : 'a t -> (key * 'a) sequence -> unit (** Add the corresponding pairs to the table, using {!Hashtbl.add}. - @since 0.16 *) + @since 0.16 + @deprecated use {!add_iter} or {!add_std_seq} *) + [@@ocaml.deprecated "use add_iter or add_std_seq"] + + val of_iter : (key * 'a) iter -> 'a t + (** From the given bindings, added in order. + @since NEXT_RELEASE *) + + val of_std_seq : (key * 'a) Seq.t -> 'a t + (** From the given bindings, added in order. + @since NEXT_RELEASE *) + + val of_seq : (key * 'a) sequence -> 'a t + (** From the given bindings, added in order. + @deprecated use {!of_iter} or {!of_std_seq} *) + [@@ocaml.deprecated "use of_iter or of_std_seq"] + + val add_iter_count : int t -> key iter -> unit + (** [add_iter_count tbl i] increments the count of each element of [i] + by calling {!incr}. This is useful for counting how many times each + element of [i] occurs. + @since NEXT_RELEASE *) + + val add_std_seq_count : int t -> key Seq.t -> unit + (** [add_seq_count tbl seq] increments the count of each element of [seq] + by calling {!incr}. This is useful for counting how many times each + element of [seq] occurs. + @since NEXT_RELEASE *) val add_seq_count : int t -> key sequence -> unit (** [add_seq_count tbl seq] increments the count of each element of [seq] by calling {!incr}. This is useful for counting how many times each element of [seq] occurs. - @since 0.16 *) + @since 0.16 + @deprecated use {!add_iter_count} or {!add_std_seq_count} *) + [@@ocaml.deprecated "use add_iter_count or add_std_seq_count"] + + val of_iter_count : key iter -> int t + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since NEXT_RELEASE *) + + val of_std_seq_count : key Seq.t -> int t + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since NEXT_RELEASE *) val of_seq_count : key sequence -> int t - (** Like {!add_seq_count}, but allocates a new table and returns it - @since 0.16 *) + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since 0.16 + @deprecated use {!of_iter_count} or {!of_std_seq_count} *) + [@@ocaml.deprecated "use add_iter_count or add_std_seq_count"] val to_list : 'a t -> (key * 'a) list - (** List of bindings (order unspecified) *) + (** List of bindings (order unspecified). *) val of_list : (key * 'a) list -> 'a t (** Build a table from the given list of bindings [k_i -> v_i], @@ -221,7 +293,7 @@ module type S = sig [k] was mapped to [v], or [f k None] otherwise; if the call returns [None] then [k] is removed/stays removed, if the call returns [Some v'] then the binding [k -> v'] is inserted - using {!Hashtbl.replace} + using {!Hashtbl.replace}. @since 0.14 *) val get_or_add : 'a t -> f:(key -> 'a) -> k:key -> 'a @@ -232,9 +304,9 @@ module type S = sig @since 1.0 *) val pp : key printer -> 'a printer -> 'a t printer - (** Printer for table - @since 0.13 - Renamed from [print] @since 2.0 *) + (** Printer for tables. + Renamed from [print] since 2.0. + @since 0.13 *) end (*$inject @@ -318,22 +390,42 @@ module Make(X : Hashtbl.HashedType) add tbl k v; v - let to_seq tbl k = iter (fun key v -> k (key,v)) tbl + let to_iter tbl k = iter (fun key v -> k (key,v)) tbl - let add_seq tbl seq = seq (fun (k,v) -> add tbl k v) + let add_iter tbl i = i (fun (k,v) -> add tbl k v) - let of_seq seq = + let add_std_seq tbl seq = Seq.iter (fun (k,v) -> add tbl k v) seq + + let of_iter i = let tbl = create 32 in - add_seq tbl seq; + add_iter tbl i; tbl - let add_seq_count tbl seq = seq (fun k -> incr tbl k) - - let of_seq_count seq = + let of_std_seq i = let tbl = create 32 in - add_seq_count tbl seq; + add_std_seq tbl i; tbl + let add_iter_count tbl i = i (fun k -> incr tbl k) + + let add_std_seq_count tbl seq = Seq.iter (fun k -> incr tbl k) seq + + let of_iter_count seq = + let tbl = create 32 in + add_iter_count tbl seq; + tbl + + let of_std_seq_count i = + let tbl = create 32 in + add_std_seq_count tbl i; + tbl + + let to_seq = to_iter + let add_seq = add_iter + let of_seq = of_iter + let add_seq_count = add_iter_count + let of_seq_count = of_iter_count + let to_list tbl = fold (fun k v l -> (k,v) :: l) diff --git a/src/core/CCHashtbl.mli b/src/core/CCHashtbl.mli index 3897ff93..5ce3c219 100644 --- a/src/core/CCHashtbl.mli +++ b/src/core/CCHashtbl.mli @@ -5,7 +5,15 @@ @since 0.4 *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a eq = 'a -> 'a -> bool type 'a hash = 'a -> int type 'a printer = Format.formatter -> 'a -> unit @@ -23,10 +31,10 @@ module Poly : sig and returns [default] otherwise (if [k] doesn't belong in [tbl]). @since 0.16 *) - val keys : ('a,'b) Hashtbl.t -> 'a sequence + val keys : ('a,'b) Hashtbl.t -> 'a iter (** Iterate on keys (similar order as {!Hashtbl.iter}). *) - val values : ('a,'b) Hashtbl.t -> 'b sequence + val values : ('a,'b) Hashtbl.t -> 'b iter (** Iterate on values in the table. *) val keys_list : ('a, 'b) Hashtbl.t -> 'a list @@ -54,30 +62,80 @@ module Poly : sig This does nothing if the key is not already present in the table. @since 0.16 *) + val to_iter : ('a,'b) Hashtbl.t -> ('a * 'b) iter + (** Iterate on bindings in the table. + @since NEXT_RELEASE *) + val to_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence - (** Iterate on bindings in the table. *) + (** Iterate on bindings in the table. + @deprecated use {!to_iter} instead *) + [@@ocaml.deprecated "use to_iter"] val add_list : ('a, 'b list) Hashtbl.t -> 'a -> 'b -> unit (** [add_list tbl x y] adds [y] to the list [x] is bound to. If [x] is not bound, it becomes bound to [y]. @since 0.16 *) + val add_iter : ('a,'b) Hashtbl.t -> ('a * 'b) iter -> unit + (** Add the corresponding pairs to the table, using {!Hashtbl.add}. + @since NEXT_RELEASE *) + + val add_std_seq : ('a,'b) Hashtbl.t -> ('a * 'b) Seq.t -> unit + (** Add the corresponding pairs to the table, using {!Hashtbl.add}. + @since NEXT_RELEASE *) + val add_seq : ('a,'b) Hashtbl.t -> ('a * 'b) sequence -> unit (** Add the corresponding pairs to the table, using {!Hashtbl.add}. - @since 0.16 *) + @since 0.16 + @deprecated use {!add_iter} or {!add_std_seq} *) + [@@ocaml.deprecated "use add_iter or add_std_seq"] + + val of_iter : ('a * 'b) iter -> ('a,'b) Hashtbl.t + (** From the given bindings, added in order. + @since NEXT_RELEASE *) + + val of_std_seq : ('a * 'b) Seq.t -> ('a,'b) Hashtbl.t + (** From the given bindings, added in order. + @since NEXT_RELEASE *) val of_seq : ('a * 'b) sequence -> ('a,'b) Hashtbl.t - (** From the given bindings, added in order. *) + (** From the given bindings, added in order. + @deprecated use {!of_iter} or {!of_std_seq} *) + [@@ocaml.deprecated "use of_iter or of_std_seq"] + + val add_iter_count : ('a, int) Hashtbl.t -> 'a iter -> unit + (** [add_iter_count tbl i] increments the count of each element of [i] + by calling {!incr}. This is useful for counting how many times each + element of [i] occurs. + @since NEXT_RELEASE *) + + val add_std_seq_count : ('a, int) Hashtbl.t -> 'a Seq.t -> unit + (** [add_seq_count tbl seq] increments the count of each element of [seq] + by calling {!incr}. This is useful for counting how many times each + element of [seq] occurs. + @since NEXT_RELEASE *) val add_seq_count : ('a, int) Hashtbl.t -> 'a sequence -> unit (** [add_seq_count tbl seq] increments the count of each element of [seq] by calling {!incr}. This is useful for counting how many times each element of [seq] occurs. - @since 0.16 *) + @since 0.16 + @deprecated use {!add_iter_count} or {!add_std_seq_count} *) + [@@ocaml.deprecated "use add_iter_count or add_std_seq_count"] + + val of_iter_count : 'a iter -> ('a, int) Hashtbl.t + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since NEXT_RELEASE *) + + val of_std_seq_count : 'a Seq.t -> ('a, int) Hashtbl.t + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since NEXT_RELEASE *) val of_seq_count : 'a sequence -> ('a, int) Hashtbl.t (** Like {!add_seq_count}, but allocates a new table and returns it. - @since 0.16 *) + @since 0.16 + @deprecated use {!of_iter_count} or {!of_std_seq_count} *) + [@@ocaml.deprecated "use add_iter_count or add_std_seq_count"] val to_list : ('a,'b) Hashtbl.t -> ('a * 'b) list (** List of bindings (order unspecified). *) @@ -142,10 +200,10 @@ module type S = sig This does nothing if the key is not already present in the table. @since 0.16 *) - val keys : 'a t -> key sequence + val keys : 'a t -> key iter (** Iterate on keys (similar order as {!Hashtbl.iter}). *) - val values : 'a t -> 'a sequence + val values : 'a t -> 'a iter (** Iterate on values in the table. *) val keys_list : _ t -> key list @@ -160,25 +218,75 @@ module type S = sig val map_list : (key -> 'a -> 'b) -> 'a t -> 'b list (** Map on a hashtable's items, collect into a list. *) - val to_seq : 'a t -> (key * 'a) sequence - (** Iterate on values in the table. *) + val to_iter : 'a t -> (key * 'a) iter + (** Iterate on bindings in the table. + @since NEXT_RELEASE *) - val of_seq : (key * 'a) sequence -> 'a t - (** From the given bindings, added in order. *) + val to_seq : 'a t -> (key * 'a) sequence + (** Iterate on values in the table. + @deprecated use {!to_iter} instead *) + [@@ocaml.deprecated "use to_iter"] + + val add_iter : 'a t -> (key * 'a) iter -> unit + (** Add the corresponding pairs to the table, using {!Hashtbl.add}. + @since NEXT_RELEASE *) + + val add_std_seq : 'a t -> (key * 'a) Seq.t -> unit + (** Add the corresponding pairs to the table, using {!Hashtbl.add}. + @since NEXT_RELEASE *) val add_seq : 'a t -> (key * 'a) sequence -> unit (** Add the corresponding pairs to the table, using {!Hashtbl.add}. - @since 0.16 *) + @since 0.16 + @deprecated use {!add_iter} or {!add_std_seq} *) + [@@ocaml.deprecated "use add_iter or add_std_seq"] + + val of_iter : (key * 'a) iter -> 'a t + (** From the given bindings, added in order. + @since NEXT_RELEASE *) + + val of_std_seq : (key * 'a) Seq.t -> 'a t + (** From the given bindings, added in order. + @since NEXT_RELEASE *) + + val of_seq : (key * 'a) sequence -> 'a t + (** From the given bindings, added in order. + @deprecated use {!of_iter} or {!of_std_seq} *) + [@@ocaml.deprecated "use of_iter or of_std_seq"] + + val add_iter_count : int t -> key iter -> unit + (** [add_iter_count tbl i] increments the count of each element of [i] + by calling {!incr}. This is useful for counting how many times each + element of [i] occurs. + @since NEXT_RELEASE *) + + val add_std_seq_count : int t -> key Seq.t -> unit + (** [add_seq_count tbl seq] increments the count of each element of [seq] + by calling {!incr}. This is useful for counting how many times each + element of [seq] occurs. + @since NEXT_RELEASE *) val add_seq_count : int t -> key sequence -> unit (** [add_seq_count tbl seq] increments the count of each element of [seq] by calling {!incr}. This is useful for counting how many times each element of [seq] occurs. - @since 0.16 *) + @since 0.16 + @deprecated use {!add_iter_count} or {!add_std_seq_count} *) + [@@ocaml.deprecated "use add_iter_count or add_std_seq_count"] + + val of_iter_count : key iter -> int t + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since NEXT_RELEASE *) + + val of_std_seq_count : key Seq.t -> int t + (** Like {!add_seq_count}, but allocates a new table and returns it. + @since NEXT_RELEASE *) val of_seq_count : key sequence -> int t (** Like {!add_seq_count}, but allocates a new table and returns it. - @since 0.16 *) + @since 0.16 + @deprecated use {!of_iter_count} or {!of_std_seq_count} *) + [@@ocaml.deprecated "use add_iter_count or add_std_seq_count"] val to_list : 'a t -> (key * 'a) list (** List of bindings (order unspecified). *) diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index ebc9f1d8..2cab7086 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -3,6 +3,7 @@ (** {1 Leftist Heaps} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a gen = unit -> 'a option type 'a printer = Format.formatter -> 'a -> unit @@ -130,14 +131,16 @@ module type S = sig val delete_one : (elt -> elt -> bool) -> elt -> t -> t (** Delete one occurrence of a value if it exist in the heap. [delete_one eq x h], use [eq] to find one [x] in [h] and delete it. - If [h] do not contain [x] then it return [h]. *) + If [h] do not contain [x] then it return [h]. + @since 2.0 *) val delete_all : (elt -> elt -> bool) -> elt -> t -> t (** Delete all occurrences of a value in the heap. [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. If [h] do not contain [x] then it return [h]. The difference with {!filter} is that [delete_all] stops as soon as - it enters a subtree whose root is bigger than the element. *) + it enters a subtree whose root is bigger than the element. + @since 2.0 *) val iter : (elt -> unit) -> t -> unit (** Iterate on elements. *) @@ -151,7 +154,7 @@ module type S = sig (** {2 Conversions} The interface of [of_gen], [of_seq], [of_klist] - has changed @since 0.16 (the old signatures + has changed since 0.16 (the old signatures are now [add_seq], [add_gen], [add_klist]). *) val to_list : t -> elt list @@ -167,26 +170,65 @@ module type S = sig @since 0.16 *) val of_list : elt list -> t - (** [of_list l] is [add_list empty l]. *) + (** [of_list l] is [add_list empty l]. Complexity: [O(n log n)]. *) - val add_seq : t -> elt sequence -> t + val add_iter : t -> elt iter -> t (** Like {!add_list}. - @since 0.16 *) + @since NEXT_RELEASE *) + + val add_std_seq : t -> elt Seq.t -> t + (** Like {!add_list}. + @since NEXT_RELEASE *) + + val add_seq : t -> elt sequence -> t (** @since 0.16 *) + (** Like {!add_list}. + @deprecated use {!add_iter} or {!add_std_seq} instead *) + [@@ocaml.deprecated "use add_iter. For the standard Seq, see {!add_std_seq}"] + + val of_iter : elt iter -> t + (** Build a heap from a given [iter]. Complexity: [O(n log n)]. + @since NEXT_RELEASE *) + + val of_std_seq : elt Seq.t -> t + (** Build a heap from a given [Seq.t]. Complexity: [O(n log n)]. + @since NEXT_RELEASE *) val of_seq : elt sequence -> t - (** Build a heap from a given [sequence]. *) + (** Build a heap from a given [sequence]. Complexity: [O(n log n)]. + @deprecated use {!of_iter} or {!of_std_seq} instead *) + [@@ocaml.deprecated "use of_iter. For the standard Seq, see {!of_std_seq}"] + + val to_iter : t -> elt iter + (** Return a [iter] of the elements of the heap. + @since NEXT_RELEASE *) + + val to_std_seq : t -> elt Seq.t + (** Return a [Seq.t] of the elements of the heap. + @since NEXT_RELEASE *) val to_seq : t -> elt sequence - (** Return a [sequence] of the elements of the heap. *) + (** Return a [sequence] of the elements of the heap. + @deprecated use {!to_iter} or {!to_std_seq} instead *) + [@@ocaml.deprecated "use to_iter. For the standard Seq, see {!to_std_seq}"] + + val to_iter_sorted : t -> elt iter + (** Iterate on the elements, in increasing order. + @since NEXT_RELEASE *) + + val to_std_seq_sorted : t -> elt Seq.t + (** Iterate on the elements, in increasing order. + @since NEXT_RELEASE *) val to_seq_sorted : t -> elt sequence (** Iterate on the elements, in increasing order. - @since 1.1 *) + @since 1.1 + @deprecated use {!to_iter_sorted} or {!to_std_seq_sorted} instead *) + [@@ocaml.deprecated "use to_iter_sorted or to_std_seq_sorted"] val add_klist : t -> elt klist -> t (** @since 0.16 *) val of_klist : elt klist -> t - (** Build a heap from a given [klist]. *) + (** Build a heap from a given [klist]. Complexity: [O(n log n)]. *) val to_klist : t -> elt klist (** Return a [klist] of the elements of the heap. *) @@ -194,7 +236,7 @@ module type S = sig val add_gen : t -> elt gen -> t (** @since 0.16 *) val of_gen : elt gen -> t - (** Build a heap from a given [gen]. *) + (** Build a heap from a given [gen]. Complexity: [O(n log n)]. *) val to_gen : t -> elt gen (** Return a [gen] of the elements of the heap. *) @@ -207,8 +249,9 @@ module type S = sig @since 2.7 *) val pp : ?sep:string -> elt printer -> t printer - (** @since 0.16 - Renamed from {!print} @since 2.0 *) + (** Printer. + Renamed from {!print} since 2.0 + @since 0.16 *) end module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct @@ -340,22 +383,46 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct let of_list l = add_list empty l - let add_seq h seq = + let add_iter h i = let h = ref h in - seq (fun x -> h := insert x !h); + i (fun x -> h := insert x !h); !h - let of_seq seq = add_seq empty seq + let add_std_seq h seq = + let h = ref h in + Seq.iter (fun x -> h := insert x !h) seq; + !h - let to_seq h k = iter k h + let of_iter i = add_iter empty i + let of_std_seq seq = add_std_seq empty seq - let to_seq_sorted heap = + let to_iter h k = iter k h + + let to_std_seq h = + (* use an explicit stack [st] *) + let rec aux st () = + match st with + | [] -> Seq.Nil + | E :: st' -> aux st' () + | N(_,x,l,r) :: st' -> Seq.Cons (x, aux (l::r::st')) + in aux [h] + + let to_iter_sorted heap = let rec recurse h k = match take h with | None -> () | Some (h',x) -> k x; recurse h' k in fun k -> recurse heap k + let rec to_std_seq_sorted h () = match take h with + | None -> Seq.Nil + | Some (h', x) -> Seq.Cons (x, to_std_seq_sorted h') + + let add_seq = add_iter + let of_seq = of_iter + let to_seq = to_iter + let to_seq_sorted = to_iter_sorted + let rec add_klist h l = match l() with | `Nil -> h | `Cons (x, l') -> diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index b0bc278e..0caab204 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -5,7 +5,15 @@ Implementation following Okasaki's book. *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a ktree = unit -> [`Nil | `Node of 'a * 'a ktree list] @@ -110,18 +118,58 @@ module type S = sig val of_list : elt list -> t (** [of_list l] is [add_list empty l]. Complexity: [O(n log n)]. *) + val add_iter : t -> elt iter -> t + (** Like {!add_list}. + @since NEXT_RELEASE *) + + val add_std_seq : t -> elt Seq.t -> t + (** Like {!add_list}. + @since NEXT_RELEASE *) + val add_seq : t -> elt sequence -> t (** @since 0.16 *) - (** Like {!add_list}. *) + (** Like {!add_list}. + @deprecated use {!add_iter} or {!add_std_seq} instead *) + [@@ocaml.deprecated "use add_iter. For the standard Seq, see {!add_std_seq}"] + + val of_iter : elt iter -> t + (** Build a heap from a given [iter]. Complexity: [O(n log n)]. + @since NEXT_RELEASE *) + + val of_std_seq : elt Seq.t -> t + (** Build a heap from a given [Seq.t]. Complexity: [O(n log n)]. + @since NEXT_RELEASE *) val of_seq : elt sequence -> t - (** Build a heap from a given [sequence]. Complexity: [O(n log n)]. *) + (** Build a heap from a given [sequence]. Complexity: [O(n log n)]. + @deprecated use {!of_iter} or {!of_std_seq} instead *) + [@@ocaml.deprecated "use of_iter. For the standard Seq, see {!of_std_seq}"] + + val to_iter : t -> elt iter + (** Return a [iter] of the elements of the heap. + @since NEXT_RELEASE *) + + val to_std_seq : t -> elt Seq.t + (** Return a [Seq.t] of the elements of the heap. + @since NEXT_RELEASE *) val to_seq : t -> elt sequence - (** Return a [sequence] of the elements of the heap. *) + (** Return a [sequence] of the elements of the heap. + @deprecated use {!to_iter} or {!to_std_seq} instead *) + [@@ocaml.deprecated "use to_iter. For the standard Seq, see {!to_std_seq}"] + + val to_iter_sorted : t -> elt iter + (** Iterate on the elements, in increasing order. + @since NEXT_RELEASE *) + + val to_std_seq_sorted : t -> elt Seq.t + (** Iterate on the elements, in increasing order. + @since NEXT_RELEASE *) val to_seq_sorted : t -> elt sequence (** Iterate on the elements, in increasing order. - @since 1.1 *) + @since 1.1 + @deprecated use {!to_iter_sorted} or {!to_std_seq_sorted} instead *) + [@@ocaml.deprecated "use to_iter_sorted or to_std_seq_sorted"] val add_klist : t -> elt klist -> t (** @since 0.16 *) diff --git a/src/core/CCList.ml b/src/core/CCList.ml index ea09ddf3..48db53c0 100644 --- a/src/core/CCList.ml +++ b/src/core/CCList.ml @@ -1608,6 +1608,7 @@ end (** {2 Conversions} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] @@ -1651,16 +1652,42 @@ let to_string ?(start="") ?(stop="") ?(sep=", ") item_to_string l = (to_string ~sep:" " string_of_int [1;2;3;4]) "1 2 3 4" *) -let to_seq l k = List.iter k l -let of_seq seq = +let to_iter l k = List.iter k l + +let rec to_std_seq l () = match l with + | [] -> Seq.Nil + | x :: tl -> Seq.Cons (x, to_std_seq tl) + +let of_iter i = let l = ref [] in - seq (fun x -> l := x :: !l); + i (fun x -> l := x :: !l); List.rev !l +let of_std_seq_rev l = + let rec loop acc s = match s() with + | Seq.Nil -> acc + | Seq.Cons (x,tl) -> loop (x::acc) tl + in + loop [] l + +let of_std_seq l = + let rec direct i seq = + if i <= 0 then List.rev (of_std_seq_rev seq) + else ( + match seq() with + | Seq.Nil -> [] + | Seq.Cons (x, tl) -> x :: direct (i-1) tl + ) + in + direct direct_depth_default_ l + (*$Q Q.(list int) (fun l -> of_seq (to_seq l) = l) *) +let to_seq = to_iter +let of_seq = of_iter + let to_gen l = let l = ref l in fun () -> diff --git a/src/core/CCList.mli b/src/core/CCList.mli index 620ca315..64430bb0 100644 --- a/src/core/CCList.mli +++ b/src/core/CCList.mli @@ -1,11 +1,17 @@ -(* AUTOGENERATED FROM CCListLabels.mli *) - (* This file is free software, part of containers. See file "license" for more details. *) (** {1 Complements to list} *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a printer = Format.formatter -> 'a -> unit @@ -691,12 +697,38 @@ val to_string : ?start:string -> ?stop:string -> ?sep:string -> [sep] as a separator between elements of [l]. @since 2.7 *) +val to_iter : 'a t -> 'a iter +(** Return a [iter] of the elements of the list. + @since NEXT_RELEASE *) + +val to_std_seq : 'a t -> 'a Seq.t +(** Return a [Seq.t] of the elements of the list. + @since NEXT_RELEASE *) + val to_seq : 'a t -> 'a sequence -(** Return a [sequence] of the elements of the list. *) +(** Return a [sequence] of the elements of the list. + @deprecated use {!to_iter} or {!to_std_seq} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] + +val of_iter : 'a iter -> 'a t +(** Build a list from a given [iter]. + In the result, elements appear in the same order as they did in the source [iter]. + @since NEXT_RELEASE *) + +val of_std_seq_rev : 'a Seq.t -> 'a t +(** Build a list from a given [Seq.t], in reverse order. + @since NEXT_RELEASE *) + +val of_std_seq : 'a Seq.t -> 'a t +(** Build a list from a given [Seq.t]. + In the result, elements appear in the same order as they did in the source [seq]. + @since NEXT_RELEASE *) val of_seq : 'a sequence -> 'a t (** Build a list from a given [sequence]. - In the result, elements appear in the same order as they did in the source [sequence]. *) + In the result, elements appear in the same order as they did in the source [sequence]. + @deprecated use {!of_iter} or {!of_std_seq} instead *) +[@@ocaml.deprecated "use of_iter or of_std_seq"] val to_gen : 'a t -> 'a gen (** Return a [gen] of the elements of the list. *) diff --git a/src/core/CCListLabels.mli b/src/core/CCListLabels.mli index 2b8df038..bc914720 100644 --- a/src/core/CCListLabels.mli +++ b/src/core/CCListLabels.mli @@ -3,7 +3,15 @@ (** {1 Complements to list} *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a printer = Format.formatter -> 'a -> unit @@ -689,12 +697,38 @@ val to_string : ?start:string -> ?stop:string -> ?sep:string -> [sep] as a separator between elements of [l]. @since 2.7 *) +val to_iter : 'a t -> 'a iter +(** Return a [iter] of the elements of the list. + @since NEXT_RELEASE *) + +val to_std_seq : 'a t -> 'a Seq.t +(** Return a [Seq.t] of the elements of the list. + @since NEXT_RELEASE *) + val to_seq : 'a t -> 'a sequence -(** Return a [sequence] of the elements of the list. *) +(** Return a [sequence] of the elements of the list. + @deprecated use {!to_iter} or {!to_std_seq} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] + +val of_iter : 'a iter -> 'a t +(** Build a list from a given [iter]. + In the result, elements appear in the same order as they did in the source [iter]. + @since NEXT_RELEASE *) + +val of_std_seq_rev : 'a Seq.t -> 'a t +(** Build a list from a given [Seq.t], in reverse order. + @since NEXT_RELEASE *) + +val of_std_seq : 'a Seq.t -> 'a t +(** Build a list from a given [Seq.t]. + In the result, elements appear in the same order as they did in the source [seq]. + @since NEXT_RELEASE *) val of_seq : 'a sequence -> 'a t (** Build a list from a given [sequence]. - In the result, elements appear in the same order as they did in the source [sequence]. *) + In the result, elements appear in the same order as they did in the source [sequence]. + @deprecated use {!of_iter} or {!of_std_seq} instead *) +[@@ocaml.deprecated "use of_iter or of_std_seq"] val to_gen : 'a t -> 'a gen (** Return a [gen] of the elements of the list. *) diff --git a/src/core/CCMap.ml b/src/core/CCMap.ml index 214b00e7..5f68e0b7 100644 --- a/src/core/CCMap.ml +++ b/src/core/CCMap.ml @@ -3,6 +3,7 @@ (** {1 Extensions of Standard Map} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a printer = Format.formatter -> 'a -> unit @@ -12,11 +13,11 @@ module type S = sig include Map.S val get : key -> 'a t -> 'a option - (** Safe version of {!find} *) + (** Safe version of {!find}. *) val get_or : key -> 'a t -> default:'a -> 'a (** [get_or k m ~default] returns the value associated to [k] if present, - and returns [default] otherwise (if [k] doesn't belong in [m]) + and returns [default] otherwise (if [k] doesn't belong in [m]). @since 0.16 *) val update : key -> ('a option -> 'a option) -> 'a t -> 'a t @@ -26,19 +27,19 @@ module type S = sig [add k v' m] is returned. *) val choose_opt : 'a t -> (key * 'a) option - (** Safe version of {!choose} + (** Safe version of {!choose}. @since 1.5 *) val min_binding_opt : 'a t -> (key * 'a) option - (** Safe version of {!min_binding} + (** Safe version of {!min_binding}. @since 1.5 *) val max_binding_opt : 'a t -> (key * 'a) option - (** Safe version of {!max_binding} + (** Safe version of {!max_binding}. @since 1.5 *) val find_opt : key -> 'a t -> 'a option - (** Safe version of {!find} + (** Safe version of {!find}. @since 1.5 *) val find_first : (key -> bool) -> 'a t -> key * 'a @@ -47,7 +48,7 @@ module type S = sig @since 1.5 *) val find_first_opt : (key -> bool) -> 'a t -> (key * 'a) option - (** Safe version of {!find_first} + (** Safe version of {!find_first}. @since 1.5 *) val merge_safe : @@ -58,16 +59,46 @@ module type S = sig val union : (key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t (** Union of both maps, using the function to combine bindings - that belong to both inputs + that belong to both inputs. @since 1.4 *) + val of_iter : (key * 'a) iter -> 'a t + (** Like {!of_list}. + @since NEXT_RELEASE *) + + val add_std_seq : 'a t -> (key * 'a) Seq.t -> 'a t + (** Like {!add_list}. + @since NEXT_RELEASE *) + + val of_std_seq : (key * 'a) Seq.t -> 'a t + (** Like {!of_list}. + @since NEXT_RELEASE *) + + val add_iter : 'a t -> (key * 'a) iter -> 'a t + (** Like {!add_list}. + @since NEXT_RELEASE *) + + val of_iter : (key * 'a) iter -> 'a t + (** Like {!of_list}. + @since NEXT_RELEASE *) + + val to_iter : 'a t -> (key * 'a) iter + (** Like {!to_list}. + @since NEXT_RELEASE *) + val of_seq : (key * 'a) sequence -> 'a t - (** Like {!of_list} *) + (** Like {!of_list}. + @deprecated use {!of_iter} instead. *) + [@@ocaml.deprecated "use of_iter instead"] val add_seq : 'a t -> (key * 'a) sequence -> 'a t - (** @since 0.14 *) + (** @since 0.14 + @deprecated use {!add_iter} instead. *) + [@@ocaml.deprecated "use add_iter instead"] val to_seq : 'a t -> (key * 'a) sequence + (** @deprecated use {!to_iter} instead. *) + [@@ocaml.deprecated "use to_iter instead"] val of_list : (key * 'a) list -> 'a t (** Build a map from the given list of bindings [k_i -> v_i], @@ -78,12 +109,12 @@ module type S = sig val add_list : 'a t -> (key * 'a) list -> 'a t (** @since 0.14 *) - val keys : _ t -> key sequence - (** Iterate on keys only + val keys : _ t -> key iter + (** Iterate on keys only. @since 0.15 *) - val values : 'a t -> 'a sequence - (** Iterate on values only + val values : 'a t -> 'a iter + (** Iterate on values only. @since 0.15 *) val to_list : 'a t -> (key * 'a) list @@ -182,16 +213,27 @@ module Make(O : Map.OrderedType) = struct | Some v1, Some v2 -> f k (`Both (v1,v2))) a b - let add_seq m s = + let add_std_seq m s = + let m = ref m in + Seq.iter (fun (k,v) -> m := add k v !m) s; + !m + + let of_std_seq s = add_std_seq empty s + + let add_iter m s = let m = ref m in s (fun (k,v) -> m := add k v !m); !m - let of_seq s = add_seq empty s + let of_iter s = add_iter empty s - let to_seq m yield = + let to_iter m yield = iter (fun k v -> yield (k,v)) m + let add_seq = add_iter + let of_seq = of_iter + let to_seq = to_iter + let keys m yield = iter (fun k _ -> yield k) m diff --git a/src/core/CCMap.mli b/src/core/CCMap.mli index b241a30c..71158f3d 100644 --- a/src/core/CCMap.mli +++ b/src/core/CCMap.mli @@ -6,7 +6,15 @@ Provide useful functions and iterators on [Map.S] @since 0.5 *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a printer = Format.formatter -> 'a -> unit module type OrderedType = Map.OrderedType @@ -65,13 +73,43 @@ module type S = sig that belong to both inputs. @since 1.4 *) + val of_iter : (key * 'a) iter -> 'a t + (** Like {!of_list}. + @since NEXT_RELEASE *) + + val add_std_seq : 'a t -> (key * 'a) Seq.t -> 'a t + (** Like {!add_list}. + @since NEXT_RELEASE *) + + val of_std_seq : (key * 'a) Seq.t -> 'a t + (** Like {!of_list}. + @since NEXT_RELEASE *) + + val add_iter : 'a t -> (key * 'a) iter -> 'a t + (** Like {!add_list}. + @since NEXT_RELEASE *) + + val of_iter : (key * 'a) iter -> 'a t + (** Like {!of_list}. + @since NEXT_RELEASE *) + + val to_iter : 'a t -> (key * 'a) iter + (** Like {!to_list}. + @since NEXT_RELEASE *) + val of_seq : (key * 'a) sequence -> 'a t - (** Like {!of_list}. *) + (** Like {!of_list}. + @deprecated use {!of_iter} instead. *) + [@@ocaml.deprecated "use of_iter instead"] val add_seq : 'a t -> (key * 'a) sequence -> 'a t - (** @since 0.14 *) + (** @since 0.14 + @deprecated use {!add_iter} instead. *) + [@@ocaml.deprecated "use add_iter instead"] val to_seq : 'a t -> (key * 'a) sequence + (** @deprecated use {!to_iter} instead. *) + [@@ocaml.deprecated "use to_iter instead"] val of_list : (key * 'a) list -> 'a t (** Build a map from the given list of bindings [k_i -> v_i], @@ -82,11 +120,11 @@ module type S = sig val add_list : 'a t -> (key * 'a) list -> 'a t (** @since 0.14 *) - val keys : _ t -> key sequence + val keys : _ t -> key iter (** Iterate on keys only. @since 0.15 *) - val values : 'a t -> 'a sequence + val values : 'a t -> 'a iter (** Iterate on values only. @since 0.15 *) diff --git a/src/core/CCOpt.mli b/src/core/CCOpt.mli index b3e3467d..2231ff5a 100644 --- a/src/core/CCOpt.mli +++ b/src/core/CCOpt.mli @@ -205,6 +205,8 @@ val to_iter : 'a t -> 'a sequence val to_seq : 'a t -> 'a sequence (** Previous name for {!to_iter} - @deprecated use {!to_iter} instead *) + @deprecated use {!to_iter} or {!to_std_seq} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] + val pp : 'a printer -> 'a t printer diff --git a/src/core/CCResult.ml b/src/core/CCResult.ml index 99b2f07e..20ad028a 100644 --- a/src/core/CCResult.ml +++ b/src/core/CCResult.ml @@ -2,6 +2,7 @@ (** {1 Error Monad} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a equal = 'a -> 'a -> bool type 'a ord = 'a -> 'a -> int @@ -323,10 +324,16 @@ let of_opt = function | None -> Error "of_opt" | Some x -> Ok x -let to_seq e k = match e with +let to_std_seq e () = match e with + | Ok x -> Seq.Cons (x, Seq.empty) + | Error _ -> Seq.Nil + +let to_iter e k = match e with | Ok x -> k x | Error _ -> () +let to_seq = to_iter + type ('a, 'b) error = [`Ok of 'a | `Error of 'b] let of_err = function diff --git a/src/core/CCResult.mli b/src/core/CCResult.mli index 320cbec9..61984ac2 100644 --- a/src/core/CCResult.mli +++ b/src/core/CCResult.mli @@ -6,7 +6,15 @@ @since 0.16 *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a equal = 'a -> 'a -> bool type 'a ord = 'a -> 'a -> int type 'a printer = Format.formatter -> 'a -> unit @@ -246,7 +254,15 @@ val to_opt : ('a, _) t -> 'a option val of_opt : 'a option -> ('a, string) t (** Convert an option to a result. *) +val to_iter : ('a, _) t -> 'a iter +(** @since NEXT_RELEASE *) + +val to_std_seq : ('a, _) t -> 'a Seq.t +(** @since NEXT_RELEASE *) + val to_seq : ('a, _) t -> 'a sequence +(** @deprecated use {!to_iter} or {!to_std_seq} *) +[@@ocaml.deprecated "use to_iter or to_std_seq"] type ('a, 'b) error = [`Ok of 'a | `Error of 'b] diff --git a/src/core/CCSet.ml b/src/core/CCSet.ml index 36f21a2e..4bfa7d04 100644 --- a/src/core/CCSet.ml +++ b/src/core/CCSet.ml @@ -3,6 +3,7 @@ (** {1 Wrapper around Set} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a printer = Format.formatter -> 'a -> unit @@ -19,43 +20,62 @@ module type S = sig include Set.S val min_elt_opt : t -> elt option - (** Safe version of {!min_elt} + (** Safe version of {!min_elt}. @since 1.5 *) val max_elt_opt : t -> elt option - (** Safe version of {!max_elt} + (** Safe version of {!max_elt}. @since 1.5 *) val choose_opt : t -> elt option - (** Safe version of {!choose} + (** Safe version of {!choose}. @since 1.5 *) val find_opt : elt -> t -> elt option - (** Safe version of {!find} + (** Safe version of {!find}. @since 1.5 *) val find_first : (elt -> bool) -> t -> elt - (** Find minimum element satisfying predicate + (** Find minimum element satisfying predicate. @since 1.5 *) val find_first_opt : (elt -> bool) -> t -> elt option - (** Safe version of {!find_first} + (** Safe version of {!find_first}. @since 1.5 *) val find_last : (elt -> bool) -> t -> elt - (** Find maximum element satisfying predicate + (** Find maximum element satisfying predicate. @since 1.5 *) val find_last_opt : (elt -> bool) -> t -> elt option - (** Safe version of {!find_last} + (** Safe version of {!find_last}. @since 1.5 *) + val of_iter : elt iter -> t + (** Build a set from the given [iter] of elements. + @since NEXT_RELEASE *) + + val add_iter : t -> elt iter -> t + (** @since NEXT_RELEASE *) + + val to_iter : t -> elt iter + (** [to_iter t] converts the set [t] to a [iter] of the elements. + @since NEXT_RELEASE *) + val of_seq : elt sequence -> t + (** Build a set from the given [sequence] of elements. + @deprecated use {!of_iter} instead. *) + [@@ocaml.deprecated "use of_iter instead"] val add_seq : t -> elt sequence -> t - (** @since 0.14 *) + (** @since 0.14 + @deprecated use {!add_iter} instead. *) + [@@ocaml.deprecated "use add_iter instead"] val to_seq : t -> elt sequence + (** [to_seq t] converts the set [t] to a [sequence] of the elements. + @deprecated use {!to_iter} instead. *) + [@@ocaml.deprecated "use to_iter instead"] val of_list : elt list -> t (** Build a set from the given list of elements, @@ -65,6 +85,7 @@ module type S = sig (** @since 0.14 *) val to_list : t -> elt list + (** [to_list t] converts the set [t] to a list of the elements. *) val to_string : ?start:string -> ?stop:string -> ?sep:string -> @@ -75,6 +96,7 @@ module type S = sig val pp : ?start:string -> ?stop:string -> ?sep:string -> elt printer -> t printer + (** Print the set. *) end module Make(O : Map.OrderedType) = struct @@ -133,14 +155,24 @@ module Make(O : Map.OrderedType) = struct include S - let add_seq set seq = + let add_std_seq set seq = let set = ref set in - seq (fun x -> set := add x !set); + Seq.iter (fun x -> set := add x !set) seq; !set - let of_seq s = add_seq empty s + let of_std_seq s = add_std_seq empty s - let to_seq s yield = iter yield s + let add_iter set i = + let set = ref set in + i (fun x -> set := add x !set); + !set + + let of_iter s = add_iter empty s + let to_iter s yield = iter yield s + + let add_seq = add_iter + let of_seq = of_iter + let to_seq = to_iter let add_list = List.fold_left (fun set x -> add x set) diff --git a/src/core/CCSet.mli b/src/core/CCSet.mli index f31246ef..47e9d8de 100644 --- a/src/core/CCSet.mli +++ b/src/core/CCSet.mli @@ -5,7 +5,15 @@ @since 0.9 *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a printer = Format.formatter -> 'a -> unit module type OrderedType = Set.OrderedType @@ -46,14 +54,31 @@ module type S = sig (** Safe version of {!find_last}. @since 1.5 *) + val of_iter : elt iter -> t + (** Build a set from the given [iter] of elements. + @since NEXT_RELEASE *) + + val add_iter : t -> elt iter -> t + (** @since NEXT_RELEASE *) + + val to_iter : t -> elt iter + (** [to_iter t] converts the set [t] to a [iter] of the elements. + @since NEXT_RELEASE *) + val of_seq : elt sequence -> t - (** Build a set from the given [sequence] of elements. *) + (** Build a set from the given [sequence] of elements. + @deprecated use {!of_iter} instead. *) + [@@ocaml.deprecated "use of_iter instead"] val add_seq : t -> elt sequence -> t - (** @since 0.14 *) + (** @since 0.14 + @deprecated use {!add_iter} instead. *) + [@@ocaml.deprecated "use add_iter instead"] val to_seq : t -> elt sequence - (** [to_seq t] converts the set [t] to a [sequence] of the elements. *) + (** [to_seq t] converts the set [t] to a [sequence] of the elements. + @deprecated use {!to_iter} instead. *) + [@@ocaml.deprecated "use to_iter instead"] val of_list : elt list -> t (** Build a set from the given list of elements, @@ -75,7 +100,6 @@ module type S = sig ?start:string -> ?stop:string -> ?sep:string -> elt printer -> t printer (** Print the set. *) - end module Make(O : Set.OrderedType) : S diff --git a/src/core/CCString.ml b/src/core/CCString.ml index f947184c..ab36d1c4 100644 --- a/src/core/CCString.ml +++ b/src/core/CCString.ml @@ -5,6 +5,7 @@ open CCShims_ +type 'a iter = ('a -> unit) -> unit type 'a gen = unit -> 'a option type 'a sequence = ('a -> unit) -> unit type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] @@ -44,23 +45,59 @@ module type S = sig type t val length : t -> int + (** Return the length (number of characters) of the given string. *) val blit : t -> int -> Bytes.t -> int -> int -> unit (** Like {!String.blit}. Compatible with the [-safe-string] option. - @raise Invalid_argument if indices are not valid *) + @raise Invalid_argument if indices are not valid. *) + + (* + val blit_immut : t -> int -> t -> int -> int -> string + (** Immutable version of {!blit}, returning a new string. + [blit a i b j len] is the same as [b], but in which + the range [j, ..., j+len] is replaced by [a.[i], ..., a.[i + len]]. + @raise Invalid_argument if indices are not valid. *) + *) val fold : ('a -> char -> 'a) -> 'a -> t -> 'a + (** Fold on chars by increasing index. + @since 0.7 *) (** {2 Conversions} *) val to_gen : t -> char gen + (** Return the [gen] of characters contained in the string. *) + + val to_iter : t -> char iter + (** Return the [iter] of characters contained in the string. + @since NEXT_RELEASE *) + + val to_std_seq : t -> char Seq.t + (** [to_std_seq s] returns a [Seq.t] of the bytes in [s]. + @since NEXT_RELEASE + *) + val to_seq : t -> char sequence + (** Return the [sequence] of characters contained in the string. + @deprecated use {!to_iter} instead *) + [@@ocaml.deprecated "use to_iter or to_std_seq"] + val to_klist : t -> char klist + (** Return the [klist] of characters contained in the string. + @deprecated use {!to_std_seq} instead *) + [@@ocaml.deprecated "use to_std_seq"] + val to_list : t -> char list + (** Return the list of characters contained in the string. *) val pp_buf : Buffer.t -> t -> unit + (** Renamed from [pp] since 2.0. *) + val pp : Format.formatter -> t -> unit + (** Print the string within quotes. + + Renamed from [print] since 2.0. *) end let equal (a:string) b = Stdlib.(=) a b @@ -458,6 +495,20 @@ module Split = struct Split.list_cpy ~by:" " "hello world aie" = ["hello"; ""; "world"; "aie"] *) + let _mkseq ~drop ~by s k = + let by = Find.compile by in + let rec make state () = match _split ~by s state with + | None -> Seq.Nil + | Some (state', 0, 0) when drop.first -> make state' () + | Some (_, i, 0) when drop.last && i=length s -> Seq.Nil + | Some (state', i, len) -> + Seq.Cons (k s i len , make state') + in make (SplitAt 0) + + let std_seq ?(drop=default_drop) ~by s = _mkseq ~drop ~by s _tuple3 + + let std_seq_cpy ?(drop=default_drop) ~by s = _mkseq ~drop ~by s String.sub + let _mkklist ~drop ~by s k = let by = Find.compile by in let rec make state () = match _split ~by s state with @@ -472,7 +523,7 @@ module Split = struct let klist_cpy ?(drop=default_drop) ~by s = _mkklist ~drop ~by s String.sub - let _mkseq ~drop ~by s f k = + let _mk_iter ~drop ~by s f k = let by = Find.compile by in let rec aux state = match _split ~by s state with | None -> () @@ -481,8 +532,11 @@ module Split = struct | Some (state', i, len) -> k (f s i len); aux state' in aux (SplitAt 0) - let seq ?(drop=default_drop) ~by s = _mkseq ~drop ~by s _tuple3 - let seq_cpy ?(drop=default_drop) ~by s = _mkseq ~drop ~by s String.sub + let iter ?(drop=default_drop) ~by s = _mk_iter ~drop ~by s _tuple3 + let iter_cpy ?(drop=default_drop) ~by s = _mk_iter ~drop ~by s String.sub + + let seq = iter + let seq_cpy = iter_cpy let left_exn ~by s = let i = find ~sub:by s in @@ -516,7 +570,6 @@ module Split = struct Split.right ~by:"_" "abcde" = None Split.right ~by:"a_" "abcde" = None *) - end let split_on_char c s: _ list = @@ -822,13 +875,28 @@ let of_gen g = | Some c -> Buffer.add_char b c; aux () in aux () -let to_seq s k = String.iter k s +let to_iter s k = String.iter k s -let of_seq seq = - let b= Buffer.create 32 in - seq (Buffer.add_char b); +let to_seq = to_iter + +let rec _to_std_seq s i len () = + if len=0 then Seq.Nil + else Seq.Cons (s.[i], _to_std_seq s (i+1)(len-1)) + +let to_std_seq s = _to_std_seq s 0 (String.length s) + +let of_iter i = + let b = Buffer.create 32 in + i (Buffer.add_char b); Buffer.contents b +let of_std_seq seq = + let b = Buffer.create 32 in + Seq.iter (Buffer.add_char b) seq; + Buffer.contents b + +let of_seq = of_iter + let rec _to_klist s i len () = if len=0 then `Nil else `Cons (s.[i], _to_klist s (i+1)(len-1)) @@ -1149,8 +1217,10 @@ module Sub = struct *) let to_gen (s,i,len) = _to_gen s i len - let to_seq (s,i,len) k = - for i=i to i+len-1 do k s.[i] done + let to_iter (s,i,len) k = for i=i to i+len-1 do k s.[i] done + let to_std_seq (s,i,len) = _to_std_seq s i len + + let to_seq = to_iter let to_klist (s,i,len) = _to_klist s i len let to_list (s,i,len) = _to_list s [] i len diff --git a/src/core/CCString.mli b/src/core/CCString.mli index 74379a0f..9beacbed 100644 --- a/src/core/CCString.mli +++ b/src/core/CCString.mli @@ -5,8 +5,16 @@ (** {1 Basic String Utils} *) -type 'a gen = unit -> 'a option + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + +type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] (** {2 Common Signature} *) @@ -39,11 +47,24 @@ module type S = sig val to_gen : t -> char gen (** Return the [gen] of characters contained in the string. *) + val to_iter : t -> char iter + (** Return the [iter] of characters contained in the string. + @since NEXT_RELEASE *) + + val to_std_seq : t -> char Seq.t + (** [to_std_seq s] returns a [Seq.t] of the bytes in [s]. + @since NEXT_RELEASE + *) + val to_seq : t -> char sequence - (** Return the [sequence] of characters contained in the string. *) + (** Return the [sequence] of characters contained in the string. + @deprecated use {!to_iter} instead *) + [@@ocaml.deprecated "use to_iter or to_std_seq"] val to_klist : t -> char klist - (** Return the [klist] of characters contained in the string. *) + (** Return the [klist] of characters contained in the string. + @deprecated use {!to_std_seq} instead *) + [@@ocaml.deprecated "use to_std_seq"] val to_list : t -> char list (** Return the list of characters contained in the string. *) @@ -94,11 +115,23 @@ val of_char : char -> string val of_gen : char gen -> string (** Convert a [gen] of characters to a string. *) +val of_iter : char iter -> string +(** Convert a [iter] of characters to a string. + @since NEXT_RELEASE *) + +val of_std_seq : char Seq.t -> string +(** Convert a [sequence] of characters to a string. + @since NEXT_RELEASE *) + val of_seq : char sequence -> string -(** Convert a [sequence] of characters to a string. *) +(** Convert a [sequence] of characters to a string. + @deprecated use {!of_iter} instead *) +[@@ocaml.deprecated "use of_iter"] val of_klist : char klist -> string -(** Convert a [klist] of characters to a string. *) +(** Convert a [klist] of characters to a string. + @deprecated use {!of_std_seq} instead *) +[@@ocaml.deprecated "use of_std_seq"] val of_list : char list -> string (** Convert a list of characters to a string. *) @@ -379,9 +412,19 @@ module Split : sig val gen : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) gen + val iter : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) sequence + (** @since NEXT_RELEASE *) + + val std_seq : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) Seq.t + (** @since NEXT_RELEASE *) + val seq : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) sequence + (** deprecated, use {!iter} instead *) + [@@ocaml.deprecated "use iter"] val klist : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) klist + (** deprecated, use {!std_seq} instead *) + [@@ocaml.deprecated "use std_seq"] (** {4 Copying functions} @@ -392,9 +435,19 @@ module Split : sig val gen_cpy : ?drop:drop_if_empty -> by:string -> string -> string gen + val iter_cpy : ?drop:drop_if_empty -> by:string -> string -> string sequence + (** @since NEXT_RELEASE *) + + val std_seq_cpy : ?drop:drop_if_empty -> by:string -> string -> string Seq.t + (** @since NEXT_RELEASE *) + val seq_cpy : ?drop:drop_if_empty -> by:string -> string -> string sequence + (** deprecated, use {!iter_cpy} instead *) + [@@ocaml.deprecated "use iter_cpy"] val klist_cpy : ?drop:drop_if_empty -> by:string -> string -> string klist + (** deprecated, use {!std_seq_cpy} instead *) + [@@ocaml.deprecated "use std_seq_cpy"] val left : by:string -> string -> (string * string) option (** Split on the first occurrence of [by] from the leftmost part of diff --git a/src/core/CCStringLabels.mli b/src/core/CCStringLabels.mli index 87b710d4..041e4780 100644 --- a/src/core/CCStringLabels.mli +++ b/src/core/CCStringLabels.mli @@ -3,8 +3,15 @@ (** {1 Basic String Utils} *) -type 'a gen = unit -> 'a option +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + +type 'a gen = unit -> 'a option type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] (** {2 Common Signature} *) @@ -37,11 +44,24 @@ module type S = sig val to_gen : t -> char gen (** Return the [gen] of characters contained in the string. *) + val to_iter : t -> char iter + (** Return the [iter] of characters contained in the string. + @since NEXT_RELEASE *) + + val to_std_seq : t -> char Seq.t + (** [to_std_seq s] returns a [Seq.t] of the bytes in [s]. + @since NEXT_RELEASE + *) + val to_seq : t -> char sequence - (** Return the [sequence] of characters contained in the string. *) + (** Return the [sequence] of characters contained in the string. + @deprecated use {!to_iter} instead *) + [@@ocaml.deprecated "use to_iter or to_std_seq"] val to_klist : t -> char klist - (** Return the [klist] of characters contained in the string. *) + (** Return the [klist] of characters contained in the string. + @deprecated use {!to_std_seq} instead *) + [@@ocaml.deprecated "use to_std_seq"] val to_list : t -> char list (** Return the list of characters contained in the string. *) @@ -92,11 +112,23 @@ val of_char : char -> string val of_gen : char gen -> string (** Convert a [gen] of characters to a string. *) +val of_iter : char iter -> string +(** Convert a [iter] of characters to a string. + @since NEXT_RELEASE *) + +val of_std_seq : char Seq.t -> string +(** Convert a [sequence] of characters to a string. + @since NEXT_RELEASE *) + val of_seq : char sequence -> string -(** Convert a [sequence] of characters to a string. *) +(** Convert a [sequence] of characters to a string. + @deprecated use {!of_iter} instead *) +[@@ocaml.deprecated "use of_iter"] val of_klist : char klist -> string -(** Convert a [klist] of characters to a string. *) +(** Convert a [klist] of characters to a string. + @deprecated use {!of_std_seq} instead *) +[@@ocaml.deprecated "use of_std_seq"] val of_list : char list -> string (** Convert a list of characters to a string. *) @@ -375,24 +407,44 @@ module Split : sig a string from the slice. @raise Failure if [by = ""]. *) - val gen : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> (string*int*int) gen + val gen : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) gen - val seq : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> (string*int*int) sequence + val iter : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) sequence + (** @since NEXT_RELEASE *) - val klist : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> (string*int*int) klist + val std_seq : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) Seq.t + (** @since NEXT_RELEASE *) + + val seq : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) sequence + (** deprecated, use {!iter} instead *) + [@@ocaml.deprecated "use iter"] + + val klist : ?drop:drop_if_empty -> by:string -> string -> (string*int*int) klist + (** deprecated, use {!std_seq} instead *) + [@@ocaml.deprecated "use std_seq"] (** {4 Copying functions} Those split functions actually copy the substrings, which can be more convenient but less efficient in general. *) - val list_cpy : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> string list + val list_cpy : ?drop:drop_if_empty -> by:string -> string -> string list - val gen_cpy : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> string gen + val gen_cpy : ?drop:drop_if_empty -> by:string -> string -> string gen - val seq_cpy : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> string sequence + val iter_cpy : ?drop:drop_if_empty -> by:string -> string -> string sequence + (** @since NEXT_RELEASE *) - val klist_cpy : ?drop:drop_if_empty -> by:(string [@keep_label]) -> string -> string klist + val std_seq_cpy : ?drop:drop_if_empty -> by:string -> string -> string Seq.t + (** @since NEXT_RELEASE *) + + val seq_cpy : ?drop:drop_if_empty -> by:string -> string -> string sequence + (** deprecated, use {!iter_cpy} instead *) + [@@ocaml.deprecated "use iter_cpy"] + + val klist_cpy : ?drop:drop_if_empty -> by:string -> string -> string klist + (** deprecated, use {!std_seq_cpy} instead *) + [@@ocaml.deprecated "use std_seq_cpy"] val left : by:(string [@keep_label]) -> string -> (string * string) option (** Split on the first occurrence of [by] from the leftmost part of diff --git a/src/core/CCUtf8_string.ml b/src/core/CCUtf8_string.ml index 2fc60809..71a0c422 100644 --- a/src/core/CCUtf8_string.ml +++ b/src/core/CCUtf8_string.ml @@ -9,6 +9,7 @@ open CCShims_ type uchar = Uchar.t type 'a gen = unit -> 'a option +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit let equal (a:string) b = Stdlib.(=) a b @@ -113,7 +114,7 @@ let to_gen ?(idx=0) str : uchar gen = exception Stop -let to_seq ?(idx=0) s : uchar sequence = +let to_iter ?(idx=0) s : uchar iter = fun yield -> let st = Dec.make ~idx s in try @@ -124,7 +125,41 @@ let to_seq ?(idx=0) s : uchar sequence = done with Stop -> () -let iter ?idx f s = to_seq ?idx s f +let to_seq = to_iter + +let to_std_seq ?(idx=0) s : uchar Seq.t = + let rec loop st = + let r = ref None in + fun () -> + match !r with + | Some c -> c + | None -> + let c = next_ st ~yield:(fun x -> Seq.Cons (x, loop st)) + ~stop:(fun () -> Seq.Nil) () + in + r := Some c; + c + in + let st = Dec.make ~idx s in + loop st + +(*$= & ~cmp:(=) ~printer:Q.Print.(list (fun c -> string_of_int@@ Uchar.to_int c)) + (to_list (of_string_exn "aébõ😀")) (to_std_seq (of_string_exn "aébõ😀") |> CCList.of_std_seq) + *) + +(* make sure it's persisted correctly *) +(*$R + let s = (of_string_exn "aébõ😀") in + let seq = to_std_seq s in + let l = to_list s in + let testeq seq = assert_equal ~cmp:(=) l (CCList.of_std_seq seq) in + testeq seq; + testeq seq; + testeq seq; + *) + + +let iter ?idx f s = to_iter ?idx s f let fold ?idx f acc s = let st = Dec.make ?idx s in @@ -181,11 +216,18 @@ let of_gen g : t = in aux () -let of_seq seq : t = +let of_std_seq seq : t = let buf = Buffer.create 32 in - seq (code_to_string buf); + Seq.iter (code_to_string buf) seq; Buffer.contents buf +let of_iter i : t = + let buf = Buffer.create 32 in + i (code_to_string buf); + Buffer.contents buf + +let of_seq = of_iter + let of_list l : t = let buf = Buffer.create 32 in List.iter (code_to_string buf) l; diff --git a/src/core/CCUtf8_string.mli b/src/core/CCUtf8_string.mli index f174bf97..12875459 100644 --- a/src/core/CCUtf8_string.mli +++ b/src/core/CCUtf8_string.mli @@ -18,7 +18,15 @@ type uchar = Uchar.t type 'a gen = unit -> 'a option + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type t = private string (** A UTF8 string *) @@ -41,9 +49,22 @@ val to_gen : ?idx:int -> t -> uchar gen (** Generator of unicode codepoints. @param idx offset where to start the decoding. *) +val to_iter : ?idx:int -> t -> uchar iter +(** Iterator of unicode codepoints. + @param idx offset where to start the decoding. + @since NEXT_RELEASE *) + val to_seq : ?idx:int -> t -> uchar sequence (** Iter of unicode codepoints. - @param idx offset where to start the decoding. *) + @param idx offset where to start the decoding. + @deprecated use {!to_iter} or {!to_std_seq} instead *) +[@@ocaml.deprecated "use to_iter or to_std_seq instead"] + +val to_std_seq : ?idx:int -> t -> uchar Seq.t +(** Iter of unicode codepoints. + @param idx offset where to start the decoding. + @since NEXT_RELEASE +*) val to_list : ?idx:int -> t -> uchar list (** List of unicode codepoints. @@ -69,7 +90,17 @@ val append : t -> t -> t val concat : t -> t list -> t +val of_std_seq : uchar Seq.t -> t +(** Build a string from unicode codepoints + @since NEXT_RELEASE *) + +val of_iter : uchar sequence -> t +(** Build a string from unicode codepoints + @since NEXT_RELEASE *) + val of_seq : uchar sequence -> t +(** @deprecated use {!of_seq} or {!of_std_seq} instead *) +[@@ocaml.deprecated "use of_iter or of_std_seq instead"] val of_gen : uchar gen -> t @@ -87,5 +118,8 @@ val is_valid : string -> bool val unsafe_of_string : string -> t (** Conversion from a string without validating. - Upon iteration, if an invalid substring is met, Malformed will be raised. *) + {b CAUTION} this is unsafe and can break all the other functions + in this module. Use only if you're sure the string is valid UTF8. + Upon iteration, if an invalid substring is met, Malformed will be raised. +*) diff --git a/src/core/CCVector.ml b/src/core/CCVector.ml index 09d03729..df941e27 100644 --- a/src/core/CCVector.ml +++ b/src/core/CCVector.ml @@ -6,6 +6,7 @@ type rw = [`RW] type ro = [`RO] type 'a sequence = ('a -> unit) -> unit +type 'a iter = ('a -> unit) -> unit type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option type 'a equal = 'a -> 'a -> bool @@ -256,8 +257,9 @@ let remove v i = v.size <- v.size - 1; fill_with_junk_ v.vec v.size 1 -let append_seq a seq = - seq (fun x -> push a x) +let append_iter a i = i (fun x -> push a x) + +let append_std_seq a seq = Seq.iter (fun x -> push a x) seq let append_array a b = let len_b = Array.length b in @@ -801,12 +803,21 @@ let flat_map f v = iter (fun x -> iter (push v') (f x)) v; v' -let flat_map_seq f v = +let flat_map_iter f v = let v' = create () in iter (fun x -> let seq = f x in - append_seq v' seq) + append_iter v' seq) + v; + v' + +let flat_map_std_seq f v = + let v' = create () in + iter + (fun x -> + let seq = f x in + append_std_seq v' seq) v; v' @@ -899,22 +910,46 @@ let capacity v = Array.length v.vec let unsafe_get_array v = v.vec -let of_seq ?(init=create ()) seq = - append_seq init seq; +let of_iter ?(init=create ()) seq = + append_iter init seq; + init + +let of_std_seq ?(init=create ()) seq = + append_std_seq init seq; init (*$T of_seq Iter.(1 -- 10) |> to_list = CCList.(1 -- 10) *) -let to_seq v k = iter k v +let to_iter v k = iter k v -let to_seq_rev v k = +let to_iter_rev v k = let n = v.size in for i = n - 1 downto 0 do k (Array.unsafe_get v.vec i) done +let to_std_seq v = + let rec aux i () = + if i>= size v then Seq.Nil + else Seq.Cons (v.vec.(i), aux (i+1)) + in + aux 0 + +let to_std_seq_rev v = + let rec aux i () = + if i<0 || i > size v then Seq.Nil + else Seq.Cons (v.vec.(i), aux (i-1)) + in + aux (size v-1) + +let of_seq = of_iter +let to_seq = to_iter +let to_seq_rev = to_iter_rev +let append_seq = append_iter +let flat_map_seq = flat_map_iter + (*$Q Q.(list int) (fun l -> \ let v= of_list l in v |> to_seq_rev |> Iter.to_rev_list = l) diff --git a/src/core/CCVector.mli b/src/core/CCVector.mli index e02d53fb..715911fd 100644 --- a/src/core/CCVector.mli +++ b/src/core/CCVector.mli @@ -18,7 +18,14 @@ type 'a ro_vector = ('a, ro) t (** Alias for immutable vectors. @since 0.15 *) +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option type 'a equal = 'a -> 'a -> bool @@ -79,6 +86,14 @@ val append : ('a, rw) t -> ('a, _) t -> unit val append_array : ('a, rw) t -> 'a array -> unit (** Like {!append}, with an array. *) +val append_iter : ('a, rw) t -> 'a iter -> unit +(** Append content of iterator. + @since NEXT_RELEASE *) + +val append_std_seq : ('a, rw) t -> 'a Seq.t -> unit +(** Append content of iterator. + @since NEXT_RELEASE *) + val append_seq : ('a, rw) t -> 'a sequence -> unit (** Append content of sequence. *) @@ -198,10 +213,20 @@ val filter_map_in_place : ('a -> 'a option) -> ('a,_) t -> unit val flat_map : ('a -> ('b,_) t) -> ('a,_) t -> ('b, 'mut) t (** Map each element to a sub-vector. *) +val flat_map_iter : ('a -> 'b sequence) -> ('a,_) t -> ('b, 'mut) t +(** Like {!flat_map}, but using {!iter} for intermediate collections. + @since NEXT_RELEASE *) + +val flat_map_std_seq : ('a -> 'b Seq.t) -> ('a,_) t -> ('b, 'mut) t +(** Like {!flat_map}, but using [Seq] for intermediate collections. + @since NEXT_RELEASE *) + val flat_map_seq : ('a -> 'b sequence) -> ('a,_) t -> ('b, 'mut) t (** Like {!flat_map}, but using {!sequence} for intermediate collections. + @deprecated use {!flat_map_iter} or {!flat_map_std_seq} @since 0.14 *) +[@@ocaml.deprecated "use flat_map_iter or flat_map_std_seq"] val flat_map_list : ('a -> 'b list) -> ('a,_) t -> ('b, 'mut) t (** Like {!flat_map}, but using {!list} for @@ -277,14 +302,47 @@ val to_list : ('a,_) t -> 'a list (** Return a list with the elements contained in the vector. *) val of_seq : ?init:('a,rw) t -> 'a sequence -> ('a, rw) t +(** Convert an Iterator to a vector. + @deprecated use of_iter *) +[@@ocaml.deprecated "use of_iter. For the standard Seq, see {!of_std_seq}"] + +val of_std_seq : ?init:('a,rw) t -> 'a Seq.t -> ('a, rw) t +(** Convert an Iterator to a vector. + @deprecated use of_iter *) +[@@ocaml.deprecated "use of_iter. For the standard Seq, see {!of_std_seq}"] + +val to_iter : ('a,_) t -> 'a iter +(** Return a [iter] with the elements contained in the vector. + @since NEXT_RELEASE +*) + +val to_iter_rev : ('a,_) t -> 'a iter +(** [to_iter_rev v] returns the sequence of elements of [v] in reverse order, + that is, the last elements of [v] are iterated on first. + @since NEXT_RELEASE +*) + +val to_std_seq : ('a,_) t -> 'a Seq.t +(** Return an iterator with the elements contained in the vector. + @since NEXT_RELEASE +*) + +val to_std_seq_rev : ('a,_) t -> 'a Seq.t +(** [to_seq v] returns the sequence of elements of [v] in reverse order, + that is, the last elements of [v] are iterated on first. + @since NEXT_RELEASE +*) val to_seq : ('a,_) t -> 'a sequence -(** Return a [sequence] with the elements contained in the vector. *) +(** @deprecated use to_iter *) +[@@ocaml.deprecated "use to_iter. For the standard Seq, see {!to_std_seq}"] val to_seq_rev : ('a, _) t -> 'a sequence (** [to_seq_rev v] returns the sequence of elements of [v] in reverse order, that is, the last elements of [v] are iterated on first. - @since 0.14 *) + @since 0.14 + @deprecated use {!to_iter_rev} *) +[@@ocaml.deprecated "use to_iter_rev. For the standard Seq, see {!to_std_seq_rev}"] val slice : ('a,rw) t -> ('a array * int * int) (** Vector as an array slice. By doing it we expose the internal array, so diff --git a/src/data/CCSimple_queue.ml b/src/data/CCSimple_queue.ml index 01150d33..25ecf393 100644 --- a/src/data/CCSimple_queue.ml +++ b/src/data/CCSimple_queue.ml @@ -3,6 +3,7 @@ (** {1 Functional queues (fifo)} *) +type 'a iter = ('a -> unit) -> unit type 'a sequence = ('a -> unit) -> unit type 'a printer = Format.formatter -> 'a -> unit type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] @@ -107,14 +108,18 @@ let to_list q = fold (fun acc x->x::acc) [] q |> List.rev let add_list q l = List.fold_left snoc q l let of_list l = add_list empty l -let to_seq q = fun k -> iter k q +let to_iter q = fun k -> iter k q -let add_seq q seq = +let add_iter q seq = let q = ref q in seq (fun x -> q := push x !q); !q -let of_seq s = add_seq empty s +let of_iter s = add_iter empty s + +let of_seq = of_iter +let to_seq = to_iter +let add_seq = add_iter (*$Q Q.(list small_int) (fun l -> \ @@ -125,6 +130,19 @@ let of_seq s = add_seq empty s l = (of_list l |> to_seq |> Iter.to_list)) *) +let add_std_seq q l = add_iter q (fun k -> Seq.iter k l) +let of_std_seq l = add_std_seq empty l + +let to_std_seq q = + let rec aux1 l () = match l with + | [] -> aux2 (List.rev q.tl) () + | x :: tl -> Seq.Cons (x, aux1 tl) + and aux2 l () = match l with + | [] -> Seq.Nil + | x :: tl -> Seq.Cons (x, aux2 tl) + in + aux1 q.hd + let rec klist_iter_ k f = match k() with | `Nil -> () | `Cons (x,tl) -> f x; klist_iter_ tl f diff --git a/src/data/CCSimple_queue.mli b/src/data/CCSimple_queue.mli index a49232bb..236bddf7 100644 --- a/src/data/CCSimple_queue.mli +++ b/src/data/CCSimple_queue.mli @@ -6,7 +6,15 @@ (** Simple implementation of functional queues @since 1.3 *) + +(* TODO: remove for 3.0 *) type 'a sequence = ('a -> unit) -> unit +(** @deprecated use ['a iter] instead *) + +type 'a iter = ('a -> unit) -> unit +(** Fast internal iterator. + @since NEXT_RELEASE *) + type 'a printer = Format.formatter -> 'a -> unit type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist] type 'a gen = unit -> 'a option @@ -76,13 +84,31 @@ val to_list : 'a t -> 'a list val add_list : 'a t -> 'a list -> 'a t val of_list : 'a list -> 'a t +val to_iter : 'a t -> 'a iter +val add_iter : 'a t -> 'a iter -> 'a t +val of_iter : 'a iter -> 'a t + val to_seq : 'a t -> 'a sequence +[@@ocaml.deprecated "use to_iter"] + val add_seq : 'a t -> 'a sequence -> 'a t +[@@ocaml.deprecated "use add_iter"] + val of_seq : 'a sequence -> 'a t +[@@ocaml.deprecated "use of_iter"] + +val to_std_seq : 'a t -> 'a Seq.t +val add_std_seq : 'a t -> 'a Seq.t -> 'a t +val of_std_seq : 'a Seq.t -> 'a t val to_klist : 'a t -> 'a klist +[@@ocaml.deprecated "use to_std_seq"] + val add_klist : 'a t -> 'a klist -> 'a t +[@@ocaml.deprecated "use add_std_seq"] + val of_klist : 'a klist -> 'a t +[@@ocaml.deprecated "use of_std_seq"] val of_gen : 'a gen -> 'a t val add_gen : 'a t -> 'a gen -> 'a t