From f9e9c39c3705ea838eecf1fc37d0c999866464b5 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Tue, 12 Jan 2021 11:53:37 -0500 Subject: [PATCH] feat: add iter/seq functions to `CCString` --- src/core/CCString.ml | 56 +++++++++++++++++++++++++++++++++++++ src/core/CCString.mli | 26 ++++++++++++++++- src/core/CCStringLabels.mli | 24 ++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) diff --git a/src/core/CCString.ml b/src/core/CCString.ml index 7665b7b1..aa250b1b 100644 --- a/src/core/CCString.ml +++ b/src/core/CCString.ml @@ -837,6 +837,10 @@ let to_array s = let lines_gen s = Split.gen_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s +let lines_iter s = Split.iter_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s + +let lines_seq s = Split.seq_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s + let lines s = Split.list_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s (*$= & ~printer:Q.Print.(list @@ Printf.sprintf "%S") @@ -847,6 +851,13 @@ let lines s = Split.list_cpy ~drop:{Split.first=false; last=true} ~by:"\n" s [""; "a"] (lines "\na") *) +(*$Q + Q.(printable_string) (fun s -> \ + lines s = (lines_gen s |> Gen.to_list)) + Q.(printable_string) (fun s -> \ + lines s = (lines_iter s |> Iter.to_list)) +*) + let concat_gen_buf ~sep g : Buffer.t = let b = Buffer.create 256 in let rec aux ~first () = match g () with @@ -861,6 +872,41 @@ let concat_gen ~sep g = let buf = concat_gen_buf ~sep g in Buffer.contents buf +let concat_iter_buf ~sep i : Buffer.t = + let buf = Buffer.create 256 in + let first = ref true in + i (fun s -> + if !first then first := false else Buffer.add_string buf sep; + Buffer.add_string buf s); + buf + +let concat_iter ~sep i = + let buf = concat_iter_buf ~sep i in + Buffer.contents buf + +let concat_seq_buf ~sep seq : Buffer.t = + let buf = Buffer.create 256 in + let first = ref true in + Seq.iter + (fun s -> + if !first then first := false else Buffer.add_string buf sep; + Buffer.add_string buf s) + seq; + buf + +let concat_seq ~sep seq = + let buf = concat_seq_buf ~sep seq in + Buffer.contents buf + +(*$Q + Q.(small_list printable_string) (fun l -> \ + concat_iter ~sep:"\n" (Iter.of_list l) = concat "\n" l) + Q.(small_list printable_string) (fun l -> \ + concat_gen ~sep:"\n" (Gen.of_list l) = concat "\n" l) + Q.(small_list printable_string) (fun l -> \ + concat_seq ~sep:"\n" (CCSeq.of_list l) = concat "\n" l) +*) + let unlines l = let len = List.fold_left (fun n s -> n + 1 + String.length s) 0 l in let buf = Bytes.create len in @@ -881,6 +927,16 @@ let unlines_gen g = Buffer.add_char buf '\n'; Buffer.contents buf +let unlines_iter i = + let buf = concat_iter_buf ~sep:"\n" i in + Buffer.add_char buf '\n'; + Buffer.contents buf + +let unlines_seq seq = + let buf = concat_seq_buf ~sep:"\n" seq in + Buffer.add_char buf '\n'; + Buffer.contents buf + (*$= & ~printer:CCFun.id "" (unlines []) "ab\nc\n" (unlines ["ab"; "c"]) diff --git a/src/core/CCString.mli b/src/core/CCString.mli index 773eba89..a26b9eea 100644 --- a/src/core/CCString.mli +++ b/src/core/CCString.mli @@ -182,10 +182,26 @@ val lines_gen : string -> string gen (** [lines_gen s] returns a generator of the lines of [s] (splits along '\n'). @since 0.10 *) +val lines_iter : string -> string iter +(** [lines_iter s] returns an iterator of the lines of [s] (splits along '\n'). + @since NEXT_RELEASE *) + +val lines_seq : string -> string Seq.t +(** [lines_seq s] returns an iterator of the lines of [s] (splits along '\n'). + @since NEXT_RELEASE *) + val concat_gen : sep:string -> string gen -> string (** [concat_gen ~sep g] concatenates all strings of [g], separated with [sep]. @since 0.10 *) +val concat_seq : sep:string -> string Seq.t -> string +(** [concat_seq ~sep s] concatenates all strings of [s], separated with [sep]. + @since NEXT_RELEASE *) + +val concat_iter : sep:string -> string iter -> string +(** [concat_iter ~sep i] concatenates all strings of [i], separated with [sep]. + @since NEXT_RELEASE *) + val unlines : string list -> string (** [unlines l] concatenates all strings of [l], separated with '\n'. @since 0.10 *) @@ -194,6 +210,14 @@ val unlines_gen : string gen -> string (** [unlines_gen g] concatenates all strings of [g], separated with '\n'. @since 0.10 *) +val unlines_iter : string iter -> string +(** [unlines_iter i] concatenates all strings of [i], separated with '\n'. + @since NEXT_RELEASE *) + +val unlines_seq : string Seq.t -> string +(** [unlines_seq s] concatenates all strings of [s], separated with '\n'. + @since NEXT_RELEASE *) + val set : string -> int -> char -> string (** [set s i c] creates a new string which is a copy of [s], except for index [i], which becomes [c]. @@ -358,7 +382,7 @@ 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 iter + val iter_cpy : ?drop:drop_if_empty -> by:string -> string -> string iter (** @since 2.8 *) val seq_cpy : ?drop:drop_if_empty -> by:string -> string -> string Seq.t diff --git a/src/core/CCStringLabels.mli b/src/core/CCStringLabels.mli index 3f788625..4136a1b7 100644 --- a/src/core/CCStringLabels.mli +++ b/src/core/CCStringLabels.mli @@ -192,10 +192,26 @@ val lines_gen : string -> string gen (** [lines_gen s] returns a generator [gen] of the lines of [s] (splits along '\n'). @since 0.10 *) +val lines_iter : string -> string iter +(** [lines_iter s] returns an iterator of the lines of [s] (splits along '\n'). + @since NEXT_RELEASE *) + +val lines_seq : string -> string Seq.t +(** [lines_seq s] returns an iterator of the lines of [s] (splits along '\n'). + @since NEXT_RELEASE *) + +val concat_iter : sep:string -> string iter -> string +(** [concat_iter ~sep i] concatenates all strings of [i], separated with [sep]. + @since NEXT_RELEASE *) + val concat_gen : sep:(string [@keep_label]) -> string gen -> string (** [concat_gen ~sep gen] concatenates all strings of [gen], separated with [sep]. @since 0.10 *) +val concat_seq : sep:string -> string Seq.t -> string +(** [concat_seq ~sep s] concatenates all strings of [s], separated with [sep]. + @since NEXT_RELEASE *) + val unlines : string list -> string (** [unlines ls] concatenates all strings of [ls], separated with '\n'. @since 0.10 *) @@ -204,6 +220,14 @@ val unlines_gen : string gen -> string (** [unlines_gen gen] concatenates all strings of [gen], separated with '\n'. @since 0.10 *) +val unlines_iter : string iter -> string +(** [unlines_iter i] concatenates all strings of [i], separated with '\n'. + @since NEXT_RELEASE *) + +val unlines_seq : string Seq.t -> string +(** [unlines_seq s] concatenates all strings of [s], separated with '\n'. + @since NEXT_RELEASE *) + val set : string -> int -> char -> string (** [set s i c] creates a new string which is a copy of [s], except for index [i], which becomes [c].