mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
remove slice APIs in string and array
This commit is contained in:
parent
a767e4618d
commit
d923795e1a
20 changed files with 123 additions and 1333 deletions
|
|
@ -1,442 +0,0 @@
|
||||||
|
|
||||||
(* This file is free software, part of containers. See file "license" for more details. *)
|
|
||||||
|
|
||||||
(** {1 Array Slice} *)
|
|
||||||
|
|
||||||
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
|
|
||||||
type 'a equal = 'a -> 'a -> bool
|
|
||||||
type 'a ord = 'a -> 'a -> int
|
|
||||||
type 'a random_gen = Random.State.t -> 'a
|
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
|
||||||
|
|
||||||
(*$inject
|
|
||||||
let (--) = CCArray.(--)
|
|
||||||
*)
|
|
||||||
|
|
||||||
type 'a t = {
|
|
||||||
arr : 'a array;
|
|
||||||
i : int; (** Start index (included) *)
|
|
||||||
j : int; (** Stop index (excluded) *)
|
|
||||||
}
|
|
||||||
|
|
||||||
let empty = {
|
|
||||||
arr = [||];
|
|
||||||
i = 0;
|
|
||||||
j = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
let make arr i ~len =
|
|
||||||
if i<0||i+len > Array.length arr then invalid_arg "CCArray_slice.make";
|
|
||||||
{ arr; i; j=i+len; }
|
|
||||||
|
|
||||||
let of_slice (arr,i,len) = make arr i ~len
|
|
||||||
|
|
||||||
let to_slice a = a.arr, a.i, a.j-a.i
|
|
||||||
|
|
||||||
let full arr = { arr; i=0; j=Array.length arr; }
|
|
||||||
|
|
||||||
let underlying a = a.arr
|
|
||||||
|
|
||||||
let length a = a.j - a.i
|
|
||||||
|
|
||||||
let copy a = Array.sub a.arr a.i (length a)
|
|
||||||
|
|
||||||
let sub a i len = make a.arr (a.i + i) ~len
|
|
||||||
(*$=
|
|
||||||
[ 3;4 ] \
|
|
||||||
(let a = make (0--10) 2 5 in sub a 1 2 |> to_list)
|
|
||||||
[ ] \
|
|
||||||
(let a = make (0--10) 2 5 in sub a 1 0 |> to_list)
|
|
||||||
[ 5 ] \
|
|
||||||
(let a = make (0--10) 1 9 in sub a 4 1 |> to_list)
|
|
||||||
*)
|
|
||||||
|
|
||||||
let rec _foldi f acc a i j =
|
|
||||||
if i = j then acc else _foldi f (f acc i a.(i)) a (i+1) j
|
|
||||||
|
|
||||||
let _reverse_in_place a i ~len =
|
|
||||||
if len=0 then ()
|
|
||||||
else
|
|
||||||
for k = 0 to (len-1)/2 do
|
|
||||||
let t = a.(i+k) in
|
|
||||||
a.(i+k) <- a.(i+len-1-k);
|
|
||||||
a.(i+len-1-k) <- t;
|
|
||||||
done
|
|
||||||
|
|
||||||
let rec _equal eq a1 i1 j1 a2 i2 j2 =
|
|
||||||
if i1 = j1
|
|
||||||
then (assert (i1=j1 && i2=j2); true)
|
|
||||||
else
|
|
||||||
eq a1.(i1) a2.(i2) && _equal eq a1 (i1+1) j1 a2 (i2+1) j2
|
|
||||||
|
|
||||||
let rec _compare cmp a1 i1 j1 a2 i2 j2 =
|
|
||||||
if i1 = j1
|
|
||||||
then if i2=j2 then 0 else -1
|
|
||||||
else if i2=j2
|
|
||||||
then 1
|
|
||||||
else
|
|
||||||
let c = cmp a1.(i1) a2.(i2) in
|
|
||||||
if c = 0
|
|
||||||
then _compare cmp a1 (i1+1) j1 a2 (i2+1) j2
|
|
||||||
else c
|
|
||||||
|
|
||||||
let equal eq a b =
|
|
||||||
length a = length b && _equal eq a.arr a.i a.j b.arr b.i b.j
|
|
||||||
|
|
||||||
let compare_int (a : int) b = Stdlib.compare a b
|
|
||||||
let compare cmp a b =
|
|
||||||
_compare cmp a.arr a.i a.j b.arr b.i b.j
|
|
||||||
|
|
||||||
let fold f acc a =
|
|
||||||
let rec _fold acc i j =
|
|
||||||
if i=j then acc
|
|
||||||
else _fold (f acc a.arr.(i)) (i+1) j
|
|
||||||
in _fold acc a.i a.j
|
|
||||||
|
|
||||||
let to_list a =
|
|
||||||
let l = fold (fun l x -> x::l) [] a in
|
|
||||||
List.rev l
|
|
||||||
|
|
||||||
let foldi f acc a = _foldi f acc a.arr a.i a.j
|
|
||||||
|
|
||||||
let fold_while f acc a =
|
|
||||||
let rec fold_while_i f acc i =
|
|
||||||
if i < Array.length a.arr && i < a.j then
|
|
||||||
let acc, cont = f acc a.arr.(i) in
|
|
||||||
match cont with
|
|
||||||
| `Stop -> acc
|
|
||||||
| `Continue -> fold_while_i f acc (i+1)
|
|
||||||
else acc
|
|
||||||
in fold_while_i f acc a.i
|
|
||||||
|
|
||||||
let get a i =
|
|
||||||
let j = a.i + i in
|
|
||||||
if i<0 || j>=a.j then invalid_arg "CCArray_slice.get";
|
|
||||||
a.arr.(j)
|
|
||||||
|
|
||||||
let get_safe a i =
|
|
||||||
try Some (get a i)
|
|
||||||
with Invalid_argument _ -> None
|
|
||||||
|
|
||||||
(*$inject
|
|
||||||
let sub_a = make [|1;2;3;4;5|] 1 ~len:3
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$=
|
|
||||||
(Some 2) (get_safe sub_a 0)
|
|
||||||
(Some 3) (get_safe sub_a 1)
|
|
||||||
(Some 4) (get_safe sub_a 2)
|
|
||||||
None (get_safe sub_a 4)
|
|
||||||
None (get_safe sub_a max_int)
|
|
||||||
None (get_safe sub_a ~-1)
|
|
||||||
None (get_safe sub_a ~-42)
|
|
||||||
*)
|
|
||||||
|
|
||||||
let set a i x =
|
|
||||||
let j = a.i + i in
|
|
||||||
if i<0 || j>=a.j then invalid_arg "CCArray_slice.set";
|
|
||||||
a.arr.(j) <- x
|
|
||||||
|
|
||||||
let iter f a =
|
|
||||||
for k=a.i to a.j-1 do f a.arr.(k) done
|
|
||||||
|
|
||||||
let iteri f a =
|
|
||||||
for k=0 to length a-1 do f k a.arr.(a.i + k) done
|
|
||||||
|
|
||||||
let blit a i b j len =
|
|
||||||
if i+len>length a || j+len>length b then invalid_arg "CCArray_slice.blit";
|
|
||||||
Array.blit a.arr (a.i+i) b.arr (b.i+j) len
|
|
||||||
|
|
||||||
let rec _find f a i j =
|
|
||||||
if i = j then None
|
|
||||||
else match f i a.(i) with
|
|
||||||
| Some _ as res -> res
|
|
||||||
| None -> _find f a (i+1) j
|
|
||||||
|
|
||||||
let rec _lookup_rec ~cmp k a i j =
|
|
||||||
if i>j then raise Not_found
|
|
||||||
else if i=j
|
|
||||||
then if cmp k a.(i) = 0
|
|
||||||
then i
|
|
||||||
else raise Not_found
|
|
||||||
else
|
|
||||||
let middle = (j+i)/2 in
|
|
||||||
match cmp k a.(middle) with
|
|
||||||
| 0 -> middle
|
|
||||||
| n when n<0 -> _lookup_rec ~cmp k a i (middle-1)
|
|
||||||
| _ -> _lookup_rec ~cmp k a (middle+1) j
|
|
||||||
|
|
||||||
let _lookup_exn ~cmp k a i j =
|
|
||||||
if i>j then raise Not_found;
|
|
||||||
match cmp k a.(i) with
|
|
||||||
| 0 -> i
|
|
||||||
| n when n<0 -> raise Not_found (* too low *)
|
|
||||||
| _ when i=j -> raise Not_found (* too high *)
|
|
||||||
| _ ->
|
|
||||||
match cmp k a.(j) with
|
|
||||||
| 0 -> j
|
|
||||||
| n when n<0 -> _lookup_rec ~cmp k a (i+1) (j-1)
|
|
||||||
| _ -> raise Not_found (* too high *)
|
|
||||||
|
|
||||||
let bsearch_ ~cmp x arr i j =
|
|
||||||
let rec aux i j =
|
|
||||||
if i > j
|
|
||||||
then `Just_after j
|
|
||||||
else
|
|
||||||
let middle = i + (j - i) / 2 in (* avoid overflow *)
|
|
||||||
match cmp x arr.(middle) with
|
|
||||||
| 0 -> `At middle
|
|
||||||
| n when n<0 -> aux i (middle - 1)
|
|
||||||
| _ -> aux (middle + 1) j
|
|
||||||
in
|
|
||||||
if i>=j then `Empty
|
|
||||||
else match cmp arr.(i) x, cmp arr.(j) x with
|
|
||||||
| n, _ when n>0 -> `All_bigger
|
|
||||||
| _, n when n<0 -> `All_lower
|
|
||||||
| _ -> aux i j
|
|
||||||
|
|
||||||
let rec _for_all p a i j =
|
|
||||||
i = j || (p a.(i) && _for_all p a (i+1) j)
|
|
||||||
|
|
||||||
let rec _exists p a i j =
|
|
||||||
i <> j && (p a.(i) || _exists p a (i+1) j)
|
|
||||||
|
|
||||||
let rec _for_all2 p a1 a2 i1 i2 ~len =
|
|
||||||
len=0 || (p a1.(i1) a2.(i2) && _for_all2 p a1 a2 (i1+1) (i2+1) ~len:(len-1))
|
|
||||||
|
|
||||||
let rec _exists2 p a1 a2 i1 i2 ~len =
|
|
||||||
len>0 && (p a1.(i1) a2.(i2) || _exists2 p a1 a2 (i1+1) (i2+1) ~len:(len-1))
|
|
||||||
|
|
||||||
(* shuffle a[i...j[ using the given int random generator
|
|
||||||
See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle *)
|
|
||||||
let _shuffle _rand_int a i j =
|
|
||||||
for k = j-1 downto i+1 do
|
|
||||||
let l = _rand_int (k+1) in
|
|
||||||
let tmp = a.(l) in
|
|
||||||
a.(l) <- a.(k);
|
|
||||||
a.(k) <- tmp;
|
|
||||||
done
|
|
||||||
|
|
||||||
(*$T
|
|
||||||
let st = Random.State.make [||] in let a = 0--10000 in \
|
|
||||||
let b = Array.copy a in CCArray.shuffle_with st a; a <> b
|
|
||||||
*)
|
|
||||||
|
|
||||||
let _sort_indices cmp a i j =
|
|
||||||
let len = j-i in
|
|
||||||
let b = Array.init len (fun k->k) in
|
|
||||||
Array.sort (fun k1 k2 -> cmp a.(k1+i) a.(k2+i)) b;
|
|
||||||
b
|
|
||||||
|
|
||||||
let _sorted cmp a i j =
|
|
||||||
let len = j-i in
|
|
||||||
let b = Array.sub a i len in
|
|
||||||
Array.sort cmp b;
|
|
||||||
b
|
|
||||||
|
|
||||||
let _choose a i j st =
|
|
||||||
if i>=j then raise Not_found;
|
|
||||||
a.(i+Random.State.int st (j-i))
|
|
||||||
|
|
||||||
let _pp ~sep pp_item out a i j =
|
|
||||||
for k = i to j - 1 do
|
|
||||||
if k > i then (Format.pp_print_string out sep; Format.pp_print_cut out ());
|
|
||||||
pp_item out a.(k)
|
|
||||||
done
|
|
||||||
|
|
||||||
let _pp_i ~sep pp_item out a i j =
|
|
||||||
for k = i to j - 1 do
|
|
||||||
if k > i then (Format.pp_print_string out sep; Format.pp_print_cut out ());
|
|
||||||
pp_item k out a.(k)
|
|
||||||
done
|
|
||||||
|
|
||||||
let _to_gen a i j =
|
|
||||||
let k = ref i in
|
|
||||||
fun () ->
|
|
||||||
if !k < j
|
|
||||||
then (
|
|
||||||
let x = a.(!k) in
|
|
||||||
incr k;
|
|
||||||
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)
|
|
||||||
|
|
||||||
let reverse_in_place a = _reverse_in_place a.arr a.i ~len:(length a)
|
|
||||||
|
|
||||||
(*$T
|
|
||||||
let a = 1--6 in let s = make a 2 ~len:3 in \
|
|
||||||
reverse_in_place s; a = [| 1; 2; 5; 4; 3; 6 |]
|
|
||||||
*)
|
|
||||||
|
|
||||||
let sorted cmp a = _sorted cmp a.arr a.i a.j
|
|
||||||
|
|
||||||
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
|
|
||||||
[||] \
|
|
||||||
(let a = 1--6 in let s = make a 2 ~len:0 in \
|
|
||||||
sorted Stdlib.compare s)
|
|
||||||
[|2;3;4|] \
|
|
||||||
(let a = [|6;5;4;3;2;1|] in let s = make a 2 ~len:3 in \
|
|
||||||
sorted Stdlib.compare s)
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$Q
|
|
||||||
Q.(array int) (fun a -> \
|
|
||||||
Array.length a > 10 ==> ( Array.length a > 10 && \
|
|
||||||
let s = make a 5 ~len:5 in \
|
|
||||||
let b = Array.sub a 5 5 in \
|
|
||||||
Array.sort Stdlib.compare b; b = sorted Stdlib.compare s))
|
|
||||||
*)
|
|
||||||
|
|
||||||
let sort_ranking cmp a =
|
|
||||||
let idx = _sort_indices cmp a.arr a.i a.j in
|
|
||||||
let sort_indices cmp a = _sort_indices cmp a 0 (Array.length a) in
|
|
||||||
sort_indices compare_int idx
|
|
||||||
|
|
||||||
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
|
|
||||||
[||] \
|
|
||||||
(let a = 1--6 in let s = make a 2 ~len:0 in \
|
|
||||||
sort_ranking Stdlib.compare s)
|
|
||||||
[|2;1;3;0|] \
|
|
||||||
(let a = [|"d";"c";"b";"e";"a"|] in let s = make a 1 ~len:4 in \
|
|
||||||
sort_ranking Stdlib.compare s)
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$Q
|
|
||||||
Q.(array_of_size Gen.(0--50) printable_string) (fun a -> \
|
|
||||||
Array.length a > 10 ==> ( Array.length a > 10 && \
|
|
||||||
let s = make a 5 ~len:5 in \
|
|
||||||
let b = sort_indices String.compare s in \
|
|
||||||
sorted String.compare s = Array.map (get s) b))
|
|
||||||
*)
|
|
||||||
|
|
||||||
let sort_indices cmp a = _sort_indices cmp a.arr a.i a.j
|
|
||||||
|
|
||||||
(*$= & ~cmp:(=) ~printer:Q.Print.(array int)
|
|
||||||
[||] \
|
|
||||||
(let a = 1--6 in let s = make a 2 ~len:0 in \
|
|
||||||
sort_indices Stdlib.compare s)
|
|
||||||
[|3;1;0;2|] \
|
|
||||||
(let a = [|"d";"c";"b";"e";"a"|] in let s = make a 1 ~len:4 in \
|
|
||||||
sort_indices Stdlib.compare s)
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$Q
|
|
||||||
Q.(array_of_size Gen.(0--60) printable_string) (fun a -> \
|
|
||||||
Array.length a > 10 ==> ( Array.length a > 10 && \
|
|
||||||
let s = make a 5 ~len:5 in \
|
|
||||||
let b = sort_ranking String.compare s in \
|
|
||||||
let a_sorted = sorted String.compare s in \
|
|
||||||
copy s = Array.map (Array.get a_sorted) b))
|
|
||||||
*)
|
|
||||||
|
|
||||||
|
|
||||||
let find f a = _find (fun _ -> f) a.arr a.i a.j
|
|
||||||
|
|
||||||
let findi f a = _find (fun i -> f (i-a.i)) a.arr a.i a.j
|
|
||||||
|
|
||||||
let find_idx p a =
|
|
||||||
_find (fun i x -> if p x then Some (i-a.i,x) else None) a.arr a.i a.j
|
|
||||||
|
|
||||||
(*$=
|
|
||||||
(Some (1,"c")) (find_idx ((=) "c") (make [| "a"; "b"; "c" |] 1 2))
|
|
||||||
*)
|
|
||||||
|
|
||||||
let lookup_exn ~cmp k a =
|
|
||||||
_lookup_exn ~cmp k a.arr a.i (a.j-1) - a.i
|
|
||||||
|
|
||||||
let lookup ~cmp k a =
|
|
||||||
try Some (_lookup_exn ~cmp k a.arr a.i (a.j-1) - a.i)
|
|
||||||
with Not_found -> None
|
|
||||||
|
|
||||||
(*$=
|
|
||||||
(Some 1) (lookup ~cmp:CCString.compare "c" (make [| "a"; "b"; "c" |] 1 2))
|
|
||||||
*)
|
|
||||||
|
|
||||||
let bsearch ~cmp k a =
|
|
||||||
match bsearch_ ~cmp k a.arr a.i (a.j - 1) with
|
|
||||||
| `At m -> `At (m - a.i)
|
|
||||||
| `Just_after m -> `Just_after (m - a.i)
|
|
||||||
| res -> res
|
|
||||||
|
|
||||||
let for_all p a = _for_all p a.arr a.i a.j
|
|
||||||
|
|
||||||
let exists p a = _exists p a.arr a.i a.j
|
|
||||||
|
|
||||||
let for_all2 p a b =
|
|
||||||
length a = length b && _for_all2 p a.arr b.arr a.i b.i ~len:(length a)
|
|
||||||
|
|
||||||
let exists2 p a b =
|
|
||||||
_exists2 p a.arr b.arr a.i b.i ~len:(min (length a) (length b))
|
|
||||||
|
|
||||||
(*$T
|
|
||||||
exists2 (=) (make [| 1;2;3;4 |] 1 ~len:2) (make [| 0;1;3;4 |] 1 ~len:3)
|
|
||||||
*)
|
|
||||||
|
|
||||||
let _iter2 f a b i j ~len =
|
|
||||||
for o = 0 to len-1 do
|
|
||||||
f (Array.get a (i+o)) (Array.get b (j+o))
|
|
||||||
done
|
|
||||||
|
|
||||||
let iter2 f a b =
|
|
||||||
if length a <> length b then invalid_arg "CCArray_slice_iter2";
|
|
||||||
_iter2 f a.arr b.arr a.i b.i ~len:(length a)
|
|
||||||
|
|
||||||
let _fold2 f acc a b i j ~len =
|
|
||||||
let rec aux acc o =
|
|
||||||
if o=len then acc
|
|
||||||
else
|
|
||||||
let acc = f acc (Array.get a (i+o)) (Array.get b (j+o)) in
|
|
||||||
aux acc (o+1)
|
|
||||||
in
|
|
||||||
aux acc 0
|
|
||||||
|
|
||||||
let fold2 f acc a b =
|
|
||||||
if length a <> length b then invalid_arg "CCArray_slice_fold2";
|
|
||||||
_fold2 f acc a.arr b.arr a.i b.i ~len:(length a)
|
|
||||||
|
|
||||||
let shuffle a =
|
|
||||||
_shuffle Random.int a.arr a.i a.j
|
|
||||||
|
|
||||||
let shuffle_with st a =
|
|
||||||
_shuffle (Random.State.int st) a.arr a.i a.j
|
|
||||||
|
|
||||||
let random_choose a st = _choose a.arr a.i a.j st
|
|
||||||
|
|
||||||
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_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
|
|
||||||
|
|
||||||
|
|
||||||
(* test consistency of interfaces *)
|
|
||||||
(*$inject
|
|
||||||
module type L = module type of CCArray_slice
|
|
||||||
module type LL = module type of CCArray_sliceLabels
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$R
|
|
||||||
ignore (module CCArray_sliceLabels : L)
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$R
|
|
||||||
ignore (module CCArray_slice : LL)
|
|
||||||
*)
|
|
||||||
|
|
||||||
|
|
@ -1,286 +0,0 @@
|
||||||
(* AUTOGENERATED FROM CCArray_sliceLabels.mli *)
|
|
||||||
|
|
||||||
|
|
||||||
(* This file is free software, part of containers. See file "license" for more details. *)
|
|
||||||
|
|
||||||
(** {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 2.8 *)
|
|
||||||
|
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
|
||||||
type 'a gen = unit -> 'a option
|
|
||||||
type 'a equal = 'a -> 'a -> bool
|
|
||||||
type 'a ord = 'a -> 'a -> int
|
|
||||||
type 'a random_gen = Random.State.t -> 'a
|
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
|
||||||
|
|
||||||
type 'a t
|
|
||||||
(** The type for an array slice, containing elements of type ['a] *)
|
|
||||||
|
|
||||||
val empty : 'a t
|
|
||||||
(** [empty] is the empty array slice. *)
|
|
||||||
|
|
||||||
val equal : 'a equal -> 'a t equal
|
|
||||||
(** [equal eq as1 as2] is [true] if the lengths of [as1] and [as2] are the same
|
|
||||||
and if the corresponding elements test equal using [eq]. *)
|
|
||||||
|
|
||||||
val compare : 'a ord -> 'a t ord
|
|
||||||
(** [compare cmp as1 as2] compares the two slices [as1] and [as2] using
|
|
||||||
the comparison function [cmp], element by element. *)
|
|
||||||
|
|
||||||
val get : 'a t -> int -> 'a
|
|
||||||
(** [get as n] returns the element number [n] of slice [as].
|
|
||||||
The first element has number 0.
|
|
||||||
The last element has number [length as - 1].
|
|
||||||
You can also write [as.(n)] instead of [get as n].
|
|
||||||
|
|
||||||
Raise [Invalid_argument "index out of bounds"]
|
|
||||||
if [n] is outside the range 0 to [(length as - 1)]. *)
|
|
||||||
|
|
||||||
val get_safe : 'a t -> int -> 'a option
|
|
||||||
(** [get_safe as i] returns [Some as.(i)] if [i] is a valid index.
|
|
||||||
@since 0.18 *)
|
|
||||||
|
|
||||||
val make : 'a array -> int -> len:int -> 'a t
|
|
||||||
(** [make a i ~len] creates a slice from given offset [i] and length [len] of the given array [a].
|
|
||||||
@raise Invalid_argument if the slice isn't valid. *)
|
|
||||||
|
|
||||||
val of_slice : ('a array * int * int) -> 'a t
|
|
||||||
(** [of_slice (a, i, len)] makes a slice from a triple [(a, i, len)] where [a] is the array,
|
|
||||||
[i] the offset in [a], and [len] the number of elements of the slice.
|
|
||||||
@raise Invalid_argument if the slice isn't valid (See {!make}). *)
|
|
||||||
|
|
||||||
val to_slice : 'a t -> ('a array * int * int)
|
|
||||||
(** [to_slice as] converts the slice [as] into a triple [(a, i, len)] where [len] is the length of
|
|
||||||
the sub-array of [a] starting at offset [i]. *)
|
|
||||||
|
|
||||||
val to_list : 'a t -> 'a list
|
|
||||||
(** [to_list as] converts the slice [as] directly to a list.
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val full : 'a array -> 'a t
|
|
||||||
(** [full a] creates a slice that covers the full array [a]. *)
|
|
||||||
|
|
||||||
val underlying : 'a t -> 'a array
|
|
||||||
(** [underlying as] returns the underlying array (shared). Modifying this array will modify
|
|
||||||
the slice [as]. *)
|
|
||||||
|
|
||||||
val copy : 'a t -> 'a array
|
|
||||||
(** [copy as] copies the slice [as] into a new array. *)
|
|
||||||
|
|
||||||
val sub : 'a t -> int -> int -> 'a t
|
|
||||||
(** [sub as i len] builds a new sub-slice that contains the given subrange specified
|
|
||||||
by the index [i] and the length [len]. *)
|
|
||||||
|
|
||||||
val set : 'a t -> int -> 'a -> unit
|
|
||||||
(** [set as n x] modifies the slice [as] in place, replacing
|
|
||||||
element number [n] with [x].
|
|
||||||
You can also write [as.(n) <- x] instead of [set as n x].
|
|
||||||
|
|
||||||
Raise [Invalid_argument "index out of bounds"]
|
|
||||||
if [n] is outside the range 0 to [length as - 1]. *)
|
|
||||||
|
|
||||||
val length : _ t -> int
|
|
||||||
(** [length as] returns the length (number of elements) of the given slice [as]. *)
|
|
||||||
|
|
||||||
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
|
||||||
(** [fold f acc as] computes [f (... (f (f acc as.(0)) as.(1)) ...) as.(length as - 1)]. *)
|
|
||||||
|
|
||||||
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
|
||||||
(** [foldi f acc as] is just like {!fold} but it also passes in the index of each element
|
|
||||||
as the second argument to the folded function [f]. *)
|
|
||||||
|
|
||||||
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
|
|
||||||
(** [fold_while f acc as] folds left on slice [as] until a stop condition via [('a, `Stop)]
|
|
||||||
is indicated by the accumulator.
|
|
||||||
@since 0.8 *)
|
|
||||||
|
|
||||||
val iter : ('a -> unit) -> 'a t -> unit
|
|
||||||
(** [iter f as] applies function [f] in turn to all elements of [as].
|
|
||||||
It is equivalent to [f as.(0); f as.(1); ...; f as.(length as - 1); ()]. *)
|
|
||||||
|
|
||||||
val iteri : (int -> 'a -> unit) -> 'a t -> unit
|
|
||||||
(** [iteri f as] is like {!iter}, but the function [f] is applied with the index of the element
|
|
||||||
as first argument, and the element itself as second argument. *)
|
|
||||||
|
|
||||||
val blit : 'a t -> int -> 'a t -> int -> int -> unit
|
|
||||||
(** [blit as1 o1 as2 o2 len] copies [len] elements
|
|
||||||
from slice [as1], starting at element number [o1], to slice [as2],
|
|
||||||
starting at element number [o2]. It works correctly even if
|
|
||||||
[as1] and [as2] are the same slice, and the source and
|
|
||||||
destination chunks overlap.
|
|
||||||
|
|
||||||
Raise [Invalid_argument "CCArray_slice.blit"] if [o1] and [len] do not
|
|
||||||
designate a valid subarray of [as1], or if [o2] and [len] do not
|
|
||||||
designate a valid subarray of [as2]. *)
|
|
||||||
|
|
||||||
val reverse_in_place : 'a t -> unit
|
|
||||||
(** [reverse_in_place as] reverses the slice [as] in place. *)
|
|
||||||
|
|
||||||
val sorted : ('a -> 'a -> int) -> 'a t -> 'a array
|
|
||||||
(** [sorted cmp as] makes a copy of [as] and sorts it with [cmp].
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val sort_indices : ('a -> 'a -> int) -> 'a t -> int array
|
|
||||||
(** [sort_indices cmp as] returns a new array [b], with the same length as [as],
|
|
||||||
such that [b.(i)] is the index at which the [i]-th element of [sorted cmp as]
|
|
||||||
appears in [as]. [as] is not modified.
|
|
||||||
|
|
||||||
In other words, [map (fun i -> as.(i)) (sort_indices cmp as) = sorted cmp as].
|
|
||||||
[sort_indices] yields the inverse permutation of {!sort_ranking}.
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val sort_ranking : ('a -> 'a -> int) -> 'a t -> int array
|
|
||||||
(** [sort_ranking cmp as] returns a new array [b], with the same length as [as],
|
|
||||||
such that [b.(i)] is the index at which the [i]-th element of [as] appears
|
|
||||||
in [sorted cmp as]. [as] is not modified.
|
|
||||||
|
|
||||||
In other words, [map (fun i -> (sorted cmp as).(i)) (sort_ranking cmp as) = as].
|
|
||||||
[sort_ranking] yields the inverse permutation of {!sort_indices}.
|
|
||||||
|
|
||||||
In the absence of duplicate elements in [as], we also have
|
|
||||||
[lookup_exn as.(i) (sorted as) = (sorted_ranking as).(i)].
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val find : ('a -> 'b option) -> 'a t -> 'b option
|
|
||||||
(** [find f as] returns [Some y] if there is an element [x] such
|
|
||||||
that [f x = Some y]. Otherwise returns [None]. *)
|
|
||||||
|
|
||||||
val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option
|
|
||||||
(** [findi f as] is like {!find}, but the index of the element is also passed
|
|
||||||
to the predicate function [f].
|
|
||||||
@since 0.3.4 *)
|
|
||||||
|
|
||||||
val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option
|
|
||||||
(** [find_idx p as] returns [Some (i,x)] where [x] is the [i]-th element of [as],
|
|
||||||
and [p x] holds. Otherwise returns [None].
|
|
||||||
@since 0.3.4 *)
|
|
||||||
|
|
||||||
val lookup : cmp:('a ord) -> 'a -> 'a t -> int option
|
|
||||||
(** [lookup ~cmp x as] lookups the index [i] of some key [x] in the slice [as], provided [as] is
|
|
||||||
sorted using [cmp].
|
|
||||||
@return [None] if the key [x] is not present, or
|
|
||||||
[Some i] ([i] the index of the key) otherwise. *)
|
|
||||||
|
|
||||||
val lookup_exn : cmp:('a ord) -> 'a -> 'a t -> int
|
|
||||||
(** [lookup_exn ~cmp x as] is like {!lookup}, but
|
|
||||||
@raise Not_found if the key [x] is not present. *)
|
|
||||||
|
|
||||||
val bsearch : cmp:('a -> 'a -> int) -> 'a -> 'a t ->
|
|
||||||
[ `All_lower | `All_bigger | `Just_after of int | `Empty | `At of int ]
|
|
||||||
(** [bsearch ~cmp x as] finds the index of the object [x] in the slice [as],
|
|
||||||
provided [as] is {b sorted} using [cmp]. If the slice is not sorted,
|
|
||||||
the result is not specified (may raise Invalid_argument).
|
|
||||||
|
|
||||||
Complexity: [O(log n)] where n is the length of the slice [as]
|
|
||||||
(dichotomic search).
|
|
||||||
|
|
||||||
@return
|
|
||||||
- [`At i] if [cmp as.(i) x = 0] (for some i).
|
|
||||||
- [`All_lower] if all elements of [as] are lower than [x].
|
|
||||||
- [`All_bigger] if all elements of [as] are bigger than [x].
|
|
||||||
- [`Just_after i] if [as.(i) < x < as.(i+1)].
|
|
||||||
- [`Empty] if the slice [as] is empty.
|
|
||||||
|
|
||||||
@raise Invalid_argument if the slice is found to be unsorted w.r.t [cmp].
|
|
||||||
@since 0.13 *)
|
|
||||||
|
|
||||||
val for_all : ('a -> bool) -> 'a t -> bool
|
|
||||||
(** [for_all p [|as1; ...; asn|]] checks if all elements of the slice
|
|
||||||
satisfy the predicate [p]. That is, it returns
|
|
||||||
[(p as1) && (p as2) && ... && (p asn)]. *)
|
|
||||||
|
|
||||||
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
|
||||||
(** [for_all2 p [|as1; ...; asn|] [|bs1; ...; bsn|]] is [true] if each pair of elements [asi bsi]
|
|
||||||
satisfies the predicate [p].
|
|
||||||
That is, it returns [(p as1 bs1) && (p as2 bs2) && ... && (p asn bsn)].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
Allow different types.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val exists : ('a -> bool) -> 'a t -> bool
|
|
||||||
(** [exists p [|as1; ...; asn|]] is [true] if at least one element of
|
|
||||||
the slice satisfies the predicate [p]. That is, it returns
|
|
||||||
[(p as1) || (p as2) || ... || (p asn)]. *)
|
|
||||||
|
|
||||||
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
|
||||||
(** [exists2 p [|as1; ...; asn|] [|bs1; ...; bsn|]] is [true] if any pair of elements [asi bsi]
|
|
||||||
satisfies the predicate [p].
|
|
||||||
That is, it returns [(p as1 bs1) || (p as2 bs2) || ... || (p asn bsn)].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
Allow different types.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
|
|
||||||
(** [fold2 f acc as bs] fold on two slices [as] and [bs] stepwise.
|
|
||||||
It computes [f (... (f acc as1 bs1)...) asn bsn].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit
|
|
||||||
(** [iter2 f as bs] iterates on the two slices [as] and [bs] stepwise.
|
|
||||||
It is equivalent to [f as0 bs0; ...; f as.(length as - 1) bs.(length bs - 1); ()].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val shuffle : 'a t -> unit
|
|
||||||
(** [shuffle as] randomly shuffles the slice [as], in place. *)
|
|
||||||
|
|
||||||
val shuffle_with : Random.State.t -> 'a t -> unit
|
|
||||||
(** [shuffle_with rs as] randomly shuffles the slice [as] (like {!shuffle}) but a specialized random
|
|
||||||
state [rs] is used to control the random numbers being produced during shuffling (for reproducibility). *)
|
|
||||||
|
|
||||||
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 2.8 *)
|
|
||||||
|
|
||||||
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 2.8
|
|
||||||
*)
|
|
||||||
|
|
||||||
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.
|
|
||||||
@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].
|
|
||||||
@deprecated use {!to_std_seq} *)
|
|
||||||
[@@ocaml.deprecated "use to_std_seq"]
|
|
||||||
|
|
||||||
(** {2 IO} *)
|
|
||||||
|
|
||||||
val pp: ?sep:string -> 'a printer -> 'a t printer
|
|
||||||
(** [pp ~sep pp_item ppf as] formats the slice [as] on [ppf].
|
|
||||||
Each element is formatted with [pp_item] and elements are separated
|
|
||||||
by [sep] (defaults to ", "). *)
|
|
||||||
|
|
||||||
val pp_i: ?sep:string -> (int -> 'a printer) -> 'a t printer
|
|
||||||
(** [pp_i ~sep pp_item ppf as] prints the slice [as] on [ppf].
|
|
||||||
The printing function [pp_item] is giving both index and element.
|
|
||||||
Elements are separated by [sep] (defaults to ", "). *)
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
(* This file is free software, part of containers. See file "license" for more details. *)
|
|
||||||
|
|
||||||
include CCArray_slice
|
|
||||||
|
|
@ -1,283 +0,0 @@
|
||||||
|
|
||||||
(* This file is free software, part of containers. See file "license" for more details. *)
|
|
||||||
|
|
||||||
(** {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 2.8 *)
|
|
||||||
|
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
|
||||||
type 'a gen = unit -> 'a option
|
|
||||||
type 'a equal = 'a -> 'a -> bool
|
|
||||||
type 'a ord = 'a -> 'a -> int
|
|
||||||
type 'a random_gen = Random.State.t -> 'a
|
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
|
||||||
|
|
||||||
type 'a t
|
|
||||||
(** The type for an array slice, containing elements of type ['a] *)
|
|
||||||
|
|
||||||
val empty : 'a t
|
|
||||||
(** [empty] is the empty array slice. *)
|
|
||||||
|
|
||||||
val equal : 'a equal -> 'a t equal
|
|
||||||
(** [equal eq as1 as2] is [true] if the lengths of [as1] and [as2] are the same
|
|
||||||
and if the corresponding elements test equal using [eq]. *)
|
|
||||||
|
|
||||||
val compare : 'a ord -> 'a t ord
|
|
||||||
(** [compare cmp as1 as2] compares the two slices [as1] and [as2] using
|
|
||||||
the comparison function [cmp], element by element. *)
|
|
||||||
|
|
||||||
val get : 'a t -> int -> 'a
|
|
||||||
(** [get as n] returns the element number [n] of slice [as].
|
|
||||||
The first element has number 0.
|
|
||||||
The last element has number [length as - 1].
|
|
||||||
You can also write [as.(n)] instead of [get as n].
|
|
||||||
|
|
||||||
Raise [Invalid_argument "index out of bounds"]
|
|
||||||
if [n] is outside the range 0 to [(length as - 1)]. *)
|
|
||||||
|
|
||||||
val get_safe : 'a t -> int -> 'a option
|
|
||||||
(** [get_safe as i] returns [Some as.(i)] if [i] is a valid index.
|
|
||||||
@since 0.18 *)
|
|
||||||
|
|
||||||
val make : 'a array -> int -> len:(int [@keep_label]) -> 'a t
|
|
||||||
(** [make a i ~len] creates a slice from given offset [i] and length [len] of the given array [a].
|
|
||||||
@raise Invalid_argument if the slice isn't valid. *)
|
|
||||||
|
|
||||||
val of_slice : ('a array * int * int) -> 'a t
|
|
||||||
(** [of_slice (a, i, len)] makes a slice from a triple [(a, i, len)] where [a] is the array,
|
|
||||||
[i] the offset in [a], and [len] the number of elements of the slice.
|
|
||||||
@raise Invalid_argument if the slice isn't valid (See {!make}). *)
|
|
||||||
|
|
||||||
val to_slice : 'a t -> ('a array * int * int)
|
|
||||||
(** [to_slice as] converts the slice [as] into a triple [(a, i, len)] where [len] is the length of
|
|
||||||
the sub-array of [a] starting at offset [i]. *)
|
|
||||||
|
|
||||||
val to_list : 'a t -> 'a list
|
|
||||||
(** [to_list as] converts the slice [as] directly to a list.
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val full : 'a array -> 'a t
|
|
||||||
(** [full a] creates a slice that covers the full array [a]. *)
|
|
||||||
|
|
||||||
val underlying : 'a t -> 'a array
|
|
||||||
(** [underlying as] returns the underlying array (shared). Modifying this array will modify
|
|
||||||
the slice [as]. *)
|
|
||||||
|
|
||||||
val copy : 'a t -> 'a array
|
|
||||||
(** [copy as] copies the slice [as] into a new array. *)
|
|
||||||
|
|
||||||
val sub : 'a t -> int -> int -> 'a t
|
|
||||||
(** [sub as i len] builds a new sub-slice that contains the given subrange specified
|
|
||||||
by the index [i] and the length [len]. *)
|
|
||||||
|
|
||||||
val set : 'a t -> int -> 'a -> unit
|
|
||||||
(** [set as n x] modifies the slice [as] in place, replacing
|
|
||||||
element number [n] with [x].
|
|
||||||
You can also write [as.(n) <- x] instead of [set as n x].
|
|
||||||
|
|
||||||
Raise [Invalid_argument "index out of bounds"]
|
|
||||||
if [n] is outside the range 0 to [length as - 1]. *)
|
|
||||||
|
|
||||||
val length : _ t -> int
|
|
||||||
(** [length as] returns the length (number of elements) of the given slice [as]. *)
|
|
||||||
|
|
||||||
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
|
||||||
(** [fold f acc as] computes [f (... (f (f acc as.(0)) as.(1)) ...) as.(length as - 1)]. *)
|
|
||||||
|
|
||||||
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
|
||||||
(** [foldi f acc as] is just like {!fold} but it also passes in the index of each element
|
|
||||||
as the second argument to the folded function [f]. *)
|
|
||||||
|
|
||||||
val fold_while : ('a -> 'b -> 'a * [`Stop | `Continue]) -> 'a -> 'b t -> 'a
|
|
||||||
(** [fold_while f acc as] folds left on slice [as] until a stop condition via [('a, `Stop)]
|
|
||||||
is indicated by the accumulator.
|
|
||||||
@since 0.8 *)
|
|
||||||
|
|
||||||
val iter : ('a -> unit) -> 'a t -> unit
|
|
||||||
(** [iter f as] applies function [f] in turn to all elements of [as].
|
|
||||||
It is equivalent to [f as.(0); f as.(1); ...; f as.(length as - 1); ()]. *)
|
|
||||||
|
|
||||||
val iteri : (int -> 'a -> unit) -> 'a t -> unit
|
|
||||||
(** [iteri f as] is like {!iter}, but the function [f] is applied with the index of the element
|
|
||||||
as first argument, and the element itself as second argument. *)
|
|
||||||
|
|
||||||
val blit : 'a t -> int -> 'a t -> int -> int -> unit
|
|
||||||
(** [blit as1 o1 as2 o2 len] copies [len] elements
|
|
||||||
from slice [as1], starting at element number [o1], to slice [as2],
|
|
||||||
starting at element number [o2]. It works correctly even if
|
|
||||||
[as1] and [as2] are the same slice, and the source and
|
|
||||||
destination chunks overlap.
|
|
||||||
|
|
||||||
Raise [Invalid_argument "CCArray_slice.blit"] if [o1] and [len] do not
|
|
||||||
designate a valid subarray of [as1], or if [o2] and [len] do not
|
|
||||||
designate a valid subarray of [as2]. *)
|
|
||||||
|
|
||||||
val reverse_in_place : 'a t -> unit
|
|
||||||
(** [reverse_in_place as] reverses the slice [as] in place. *)
|
|
||||||
|
|
||||||
val sorted : ('a -> 'a -> int) -> 'a t -> 'a array
|
|
||||||
(** [sorted cmp as] makes a copy of [as] and sorts it with [cmp].
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val sort_indices : ('a -> 'a -> int) -> 'a t -> int array
|
|
||||||
(** [sort_indices cmp as] returns a new array [b], with the same length as [as],
|
|
||||||
such that [b.(i)] is the index at which the [i]-th element of [sorted cmp as]
|
|
||||||
appears in [as]. [as] is not modified.
|
|
||||||
|
|
||||||
In other words, [map (fun i -> as.(i)) (sort_indices cmp as) = sorted cmp as].
|
|
||||||
[sort_indices] yields the inverse permutation of {!sort_ranking}.
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val sort_ranking : ('a -> 'a -> int) -> 'a t -> int array
|
|
||||||
(** [sort_ranking cmp as] returns a new array [b], with the same length as [as],
|
|
||||||
such that [b.(i)] is the index at which the [i]-th element of [as] appears
|
|
||||||
in [sorted cmp as]. [as] is not modified.
|
|
||||||
|
|
||||||
In other words, [map (fun i -> (sorted cmp as).(i)) (sort_ranking cmp as) = as].
|
|
||||||
[sort_ranking] yields the inverse permutation of {!sort_indices}.
|
|
||||||
|
|
||||||
In the absence of duplicate elements in [as], we also have
|
|
||||||
[lookup_exn as.(i) (sorted as) = (sorted_ranking as).(i)].
|
|
||||||
@since 1.0 *)
|
|
||||||
|
|
||||||
val find : ('a -> 'b option) -> 'a t -> 'b option
|
|
||||||
(** [find f as] returns [Some y] if there is an element [x] such
|
|
||||||
that [f x = Some y]. Otherwise returns [None]. *)
|
|
||||||
|
|
||||||
val findi : (int -> 'a -> 'b option) -> 'a t -> 'b option
|
|
||||||
(** [findi f as] is like {!find}, but the index of the element is also passed
|
|
||||||
to the predicate function [f].
|
|
||||||
@since 0.3.4 *)
|
|
||||||
|
|
||||||
val find_idx : ('a -> bool) -> 'a t -> (int * 'a) option
|
|
||||||
(** [find_idx p as] returns [Some (i,x)] where [x] is the [i]-th element of [as],
|
|
||||||
and [p x] holds. Otherwise returns [None].
|
|
||||||
@since 0.3.4 *)
|
|
||||||
|
|
||||||
val lookup : cmp:(('a ord) [@keep_label]) -> 'a -> 'a t -> int option
|
|
||||||
(** [lookup ~cmp x as] lookups the index [i] of some key [x] in the slice [as], provided [as] is
|
|
||||||
sorted using [cmp].
|
|
||||||
@return [None] if the key [x] is not present, or
|
|
||||||
[Some i] ([i] the index of the key) otherwise. *)
|
|
||||||
|
|
||||||
val lookup_exn : cmp:(('a ord) [@keep_label]) -> 'a -> 'a t -> int
|
|
||||||
(** [lookup_exn ~cmp x as] is like {!lookup}, but
|
|
||||||
@raise Not_found if the key [x] is not present. *)
|
|
||||||
|
|
||||||
val bsearch : cmp:(('a -> 'a -> int) [@keep_label]) -> 'a -> 'a t ->
|
|
||||||
[ `All_lower | `All_bigger | `Just_after of int | `Empty | `At of int ]
|
|
||||||
(** [bsearch ~cmp x as] finds the index of the object [x] in the slice [as],
|
|
||||||
provided [as] is {b sorted} using [cmp]. If the slice is not sorted,
|
|
||||||
the result is not specified (may raise Invalid_argument).
|
|
||||||
|
|
||||||
Complexity: [O(log n)] where n is the length of the slice [as]
|
|
||||||
(dichotomic search).
|
|
||||||
|
|
||||||
@return
|
|
||||||
- [`At i] if [cmp as.(i) x = 0] (for some i).
|
|
||||||
- [`All_lower] if all elements of [as] are lower than [x].
|
|
||||||
- [`All_bigger] if all elements of [as] are bigger than [x].
|
|
||||||
- [`Just_after i] if [as.(i) < x < as.(i+1)].
|
|
||||||
- [`Empty] if the slice [as] is empty.
|
|
||||||
|
|
||||||
@raise Invalid_argument if the slice is found to be unsorted w.r.t [cmp].
|
|
||||||
@since 0.13 *)
|
|
||||||
|
|
||||||
val for_all : ('a -> bool) -> 'a t -> bool
|
|
||||||
(** [for_all p [|as1; ...; asn|]] checks if all elements of the slice
|
|
||||||
satisfy the predicate [p]. That is, it returns
|
|
||||||
[(p as1) && (p as2) && ... && (p asn)]. *)
|
|
||||||
|
|
||||||
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
|
||||||
(** [for_all2 p [|as1; ...; asn|] [|bs1; ...; bsn|]] is [true] if each pair of elements [asi bsi]
|
|
||||||
satisfies the predicate [p].
|
|
||||||
That is, it returns [(p as1 bs1) && (p as2 bs2) && ... && (p asn bsn)].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
Allow different types.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val exists : ('a -> bool) -> 'a t -> bool
|
|
||||||
(** [exists p [|as1; ...; asn|]] is [true] if at least one element of
|
|
||||||
the slice satisfies the predicate [p]. That is, it returns
|
|
||||||
[(p as1) || (p as2) || ... || (p asn)]. *)
|
|
||||||
|
|
||||||
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
|
||||||
(** [exists2 p [|as1; ...; asn|] [|bs1; ...; bsn|]] is [true] if any pair of elements [asi bsi]
|
|
||||||
satisfies the predicate [p].
|
|
||||||
That is, it returns [(p as1 bs1) || (p as2 bs2) || ... || (p asn bsn)].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
Allow different types.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val fold2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc
|
|
||||||
(** [fold2 f acc as bs] fold on two slices [as] and [bs] stepwise.
|
|
||||||
It computes [f (... (f acc as1 bs1)...) asn bsn].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit
|
|
||||||
(** [iter2 f as bs] iterates on the two slices [as] and [bs] stepwise.
|
|
||||||
It is equivalent to [f as0 bs0; ...; f as.(length as - 1) bs.(length bs - 1); ()].
|
|
||||||
|
|
||||||
@raise Invalid_argument if slices have distinct lengths.
|
|
||||||
@since 0.20 *)
|
|
||||||
|
|
||||||
val shuffle : 'a t -> unit
|
|
||||||
(** [shuffle as] randomly shuffles the slice [as], in place. *)
|
|
||||||
|
|
||||||
val shuffle_with : Random.State.t -> 'a t -> unit
|
|
||||||
(** [shuffle_with rs as] randomly shuffles the slice [as] (like {!shuffle}) but a specialized random
|
|
||||||
state [rs] is used to control the random numbers being produced during shuffling (for reproducibility). *)
|
|
||||||
|
|
||||||
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 2.8 *)
|
|
||||||
|
|
||||||
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 2.8
|
|
||||||
*)
|
|
||||||
|
|
||||||
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.
|
|
||||||
@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].
|
|
||||||
@deprecated use {!to_std_seq} *)
|
|
||||||
[@@ocaml.deprecated "use to_std_seq"]
|
|
||||||
|
|
||||||
(** {2 IO} *)
|
|
||||||
|
|
||||||
val pp: ?sep:string -> 'a printer -> 'a t printer
|
|
||||||
(** [pp ~sep pp_item ppf as] formats the slice [as] on [ppf].
|
|
||||||
Each element is formatted with [pp_item] and elements are separated
|
|
||||||
by [sep] (defaults to ", "). *)
|
|
||||||
|
|
||||||
val pp_i: ?sep:string -> (int -> 'a printer) -> 'a t printer
|
|
||||||
(** [pp_i ~sep pp_item ppf as] prints the slice [as] on [ppf].
|
|
||||||
The printing function [pp_item] is giving both index and element.
|
|
||||||
Elements are separated by [sep] (defaults to ", "). *)
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
(** {1 Helpers for Format} *)
|
(** {1 Helpers for Format} *)
|
||||||
|
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
|
|
||||||
include Format
|
include Format
|
||||||
|
|
||||||
|
|
@ -77,6 +77,14 @@ let arrayi ?(sep=return ",@ ") pp fmt a =
|
||||||
done
|
done
|
||||||
|
|
||||||
let seq ?(sep=return ",@ ") pp fmt seq =
|
let seq ?(sep=return ",@ ") pp fmt seq =
|
||||||
|
let first = ref true in
|
||||||
|
CCSeq.iter
|
||||||
|
(fun x ->
|
||||||
|
if !first then first := false else sep fmt ();
|
||||||
|
pp fmt x)
|
||||||
|
seq
|
||||||
|
|
||||||
|
let iter ?(sep=return ",@ ") pp fmt seq =
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
seq
|
seq
|
||||||
(fun x ->
|
(fun x ->
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
@since 0.8 *)
|
@since 0.8 *)
|
||||||
|
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
|
|
||||||
(* include Format, and alias all its types.
|
(* include Format, and alias all its types.
|
||||||
see https://discuss.ocaml.org/t/extend-existing-module/1389/4
|
see https://discuss.ocaml.org/t/extend-existing-module/1389/4
|
||||||
|
|
@ -69,7 +69,8 @@ val string_quoted : string printer
|
||||||
val list : ?sep:unit printer -> 'a printer -> 'a list printer
|
val list : ?sep:unit printer -> 'a printer -> 'a list printer
|
||||||
val array : ?sep:unit printer -> 'a printer -> 'a array printer
|
val array : ?sep:unit printer -> 'a printer -> 'a array printer
|
||||||
val arrayi : ?sep:unit printer -> (int * 'a) printer -> 'a array printer
|
val arrayi : ?sep:unit printer -> (int * 'a) printer -> 'a array printer
|
||||||
val seq : ?sep:unit printer -> 'a printer -> 'a sequence printer
|
val seq : ?sep:unit printer -> 'a printer -> 'a Seq.t printer
|
||||||
|
val iter : ?sep:unit printer -> 'a printer -> 'a iter printer
|
||||||
|
|
||||||
val opt : 'a printer -> 'a option printer
|
val opt : 'a printer -> 'a option printer
|
||||||
(** [opt pp] prints options as follows:
|
(** [opt pp] prints options as follows:
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ type hash = int
|
||||||
|
|
||||||
type 'a t = 'a -> hash
|
type 'a t = 'a -> hash
|
||||||
|
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||||
|
|
||||||
|
|
@ -72,11 +72,16 @@ let list_comm f l =
|
||||||
let a = Array.of_list l in
|
let a = Array.of_list l in
|
||||||
array_comm f a
|
array_comm f a
|
||||||
|
|
||||||
let seq f seq =
|
let iter f seq =
|
||||||
let h = ref 0x43 in
|
let h = ref 0x43 in
|
||||||
seq (fun x -> h := combine f !h x);
|
seq (fun x -> h := combine f !h x);
|
||||||
!h
|
!h
|
||||||
|
|
||||||
|
let seq f seq =
|
||||||
|
let h = ref 0x43 in
|
||||||
|
Seq.iter (fun x -> h := combine f !h x) seq;
|
||||||
|
!h
|
||||||
|
|
||||||
let gen f g =
|
let gen f g =
|
||||||
let rec aux s = match g () with
|
let rec aux s = match g () with
|
||||||
| None -> s
|
| None -> s
|
||||||
|
|
|
||||||
|
|
@ -72,10 +72,11 @@ val combine6 : hash -> hash -> hash -> hash -> hash -> hash -> hash
|
||||||
|
|
||||||
(** {2 Iterators} *)
|
(** {2 Iterators} *)
|
||||||
|
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||||
|
|
||||||
val seq : 'a t -> 'a sequence t
|
val seq : 'a t -> 'a Seq.t t
|
||||||
|
val iter : 'a t -> 'a iter t
|
||||||
val gen : 'a t -> 'a gen t
|
val gen : 'a t -> 'a gen t
|
||||||
val klist : 'a t -> 'a klist t
|
val klist : 'a t -> 'a klist t
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
(** {1 Leftist Heaps} *)
|
(** {1 Leftist Heaps} *)
|
||||||
|
|
||||||
type 'a iter = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
type 'a printer = Format.formatter -> 'a -> unit
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,6 @@
|
||||||
|
|
||||||
Implementation following Okasaki's book. *)
|
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
|
type 'a iter = ('a -> unit) -> unit
|
||||||
(** Fast internal iterator.
|
(** Fast internal iterator.
|
||||||
@since 2.8 *)
|
@since 2.8 *)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
open CCShims_
|
open CCShims_
|
||||||
|
|
||||||
type t = int
|
type t = int
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
|
|
||||||
let equal (a:int) b = Stdlib.(=) a b
|
let equal (a:int) b = Stdlib.(=) a b
|
||||||
|
|
||||||
|
|
@ -80,8 +80,8 @@ module Infix : sig
|
||||||
val (>) : t -> t -> bool
|
val (>) : t -> t -> bool
|
||||||
val (<=) : t -> t -> bool
|
val (<=) : t -> t -> bool
|
||||||
val (>=) : t -> t -> bool
|
val (>=) : t -> t -> bool
|
||||||
val (--) : t -> t -> t sequence
|
val (--) : t -> t -> t iter
|
||||||
val (--^) : t -> t -> t sequence
|
val (--^) : t -> t -> t iter
|
||||||
val (+) : t -> t -> t
|
val (+) : t -> t -> t
|
||||||
val (-) : t -> t -> t
|
val (-) : t -> t -> t
|
||||||
val (~-) : t -> t
|
val (~-) : t -> t
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ val rem : t -> t -> t
|
||||||
|
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
type 'a printer = Format.formatter -> 'a -> unit
|
||||||
type 'a random_gen = Random.State.t -> 'a
|
type 'a random_gen = Random.State.t -> 'a
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
|
|
||||||
val random : int -> t random_gen
|
val random : int -> t random_gen
|
||||||
val random_small : t random_gen
|
val random_small : t random_gen
|
||||||
|
|
@ -77,19 +77,19 @@ val max : t -> t -> t
|
||||||
(** The maximum of two integers.
|
(** The maximum of two integers.
|
||||||
@since 0.17 *)
|
@since 0.17 *)
|
||||||
|
|
||||||
val range_by : step:t -> t -> t -> t sequence
|
val range_by : step:t -> t -> t -> t iter
|
||||||
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
||||||
where the difference between successive elements is [step].
|
where the difference between successive elements is [step].
|
||||||
Use a negative [step] for a decreasing list.
|
Use a negative [step] for a decreasing list.
|
||||||
@raise Invalid_argument if [step=0].
|
@raise Invalid_argument if [step=0].
|
||||||
@since 1.2 *)
|
@since 1.2 *)
|
||||||
|
|
||||||
val range : t -> t -> t sequence
|
val range : t -> t -> t iter
|
||||||
(** [range i j] iterates on integers from [i] to [j] included . It works
|
(** [range i j] iterates on integers from [i] to [j] included . It works
|
||||||
both for decreasing and increasing ranges.
|
both for decreasing and increasing ranges.
|
||||||
@since 1.2 *)
|
@since 1.2 *)
|
||||||
|
|
||||||
val range' : t -> t -> t sequence
|
val range' : t -> t -> t iter
|
||||||
(** Like {!range} but the second bound is excluded.
|
(** Like {!range} but the second bound is excluded.
|
||||||
For instance [range' 0 5 = Iter.of_list [0;1;2;3;4]].
|
For instance [range' 0 5 = Iter.of_list [0;1;2;3;4]].
|
||||||
@since 1.2 *)
|
@since 1.2 *)
|
||||||
|
|
@ -117,11 +117,11 @@ module Infix : sig
|
||||||
val (>=) : t -> t -> bool
|
val (>=) : t -> t -> bool
|
||||||
(** @since 0.17 *)
|
(** @since 0.17 *)
|
||||||
|
|
||||||
val (--) : t -> t -> t sequence
|
val (--) : t -> t -> t iter
|
||||||
(** Alias to {!range}.
|
(** Alias to {!range}.
|
||||||
@since 1.2 *)
|
@since 1.2 *)
|
||||||
|
|
||||||
val (--^) : t -> t -> t sequence
|
val (--^) : t -> t -> t iter
|
||||||
(** Alias to {!range'}.
|
(** Alias to {!range'}.
|
||||||
@since 1.2 *)
|
@since 1.2 *)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
open CCShims_
|
open CCShims_
|
||||||
|
|
||||||
type 'a or_error = ('a, string) result
|
type 'a or_error = ('a, string) result
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
|
|
||||||
module type SEXP = CCSexp_intf.SEXP
|
module type SEXP = CCSexp_intf.SEXP
|
||||||
|
|
@ -118,13 +118,13 @@ module Make(Sexp : SEXP) = struct
|
||||||
pp fmt t;
|
pp fmt t;
|
||||||
Format.pp_print_flush fmt ()
|
Format.pp_print_flush fmt ()
|
||||||
|
|
||||||
let to_file_seq filename seq =
|
let to_file_iter filename seq =
|
||||||
_with_out filename
|
_with_out filename
|
||||||
(fun oc ->
|
(fun oc ->
|
||||||
seq (fun t -> to_chan oc t; output_char oc '\n')
|
seq (fun t -> to_chan oc t; output_char oc '\n')
|
||||||
)
|
)
|
||||||
|
|
||||||
let to_file filename t = to_file_seq filename (fun k -> k t)
|
let to_file filename t = to_file_iter filename (fun k -> k t)
|
||||||
|
|
||||||
(** {2 Parsing} *)
|
(** {2 Parsing} *)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
*)
|
*)
|
||||||
|
|
||||||
type 'a or_error = ('a, string) result
|
type 'a or_error = ('a, string) result
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
|
|
||||||
(** {2 Abstract representation of S-expressions}
|
(** {2 Abstract representation of S-expressions}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
type 'a or_error = ('a, string) result
|
type 'a or_error = ('a, string) result
|
||||||
type 'a sequence = ('a -> unit) -> unit
|
type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
|
|
||||||
(** {2 Abstract representation of S-expressions}
|
(** {2 Abstract representation of S-expressions}
|
||||||
|
|
@ -73,8 +73,8 @@ module type S = sig
|
||||||
|
|
||||||
val to_file : string -> t -> unit
|
val to_file : string -> t -> unit
|
||||||
|
|
||||||
val to_file_seq : string -> t sequence -> unit
|
val to_file_iter : string -> t iter -> unit
|
||||||
(** Print the given sequence of expressions to a file. *)
|
(** Print the given iter of expressions to a file. *)
|
||||||
|
|
||||||
val to_chan : out_channel -> t -> unit
|
val to_chan : out_channel -> t -> unit
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,55 +13,6 @@ type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||||
|
|
||||||
include String
|
include String
|
||||||
|
|
||||||
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. *)
|
|
||||||
|
|
||||||
(*
|
|
||||||
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 2.8 *)
|
|
||||||
|
|
||||||
val to_std_seq : t -> char Seq.t
|
|
||||||
(** [to_std_seq s] returns a [Seq.t] of the bytes in [s].
|
|
||||||
@since 2.8
|
|
||||||
*)
|
|
||||||
|
|
||||||
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 compare_int (a : int) b = Stdlib.compare a b
|
let compare_int (a : int) b = Stdlib.compare a b
|
||||||
let compare = String.compare
|
let compare = String.compare
|
||||||
|
|
||||||
|
|
@ -1109,86 +1060,6 @@ let pp_buf buf s =
|
||||||
let pp fmt s =
|
let pp fmt s =
|
||||||
Format.fprintf fmt "\"%s\"" s
|
Format.fprintf fmt "\"%s\"" s
|
||||||
|
|
||||||
module Sub = struct
|
|
||||||
type t = string * int * int
|
|
||||||
|
|
||||||
let make s i ~len =
|
|
||||||
if i<0||len<0||i+len > String.length s then invalid_arg "CCString.Sub.make";
|
|
||||||
s,i,len
|
|
||||||
|
|
||||||
let full s = s, 0, String.length s
|
|
||||||
|
|
||||||
let copy (s,i,len) = String.sub s i len
|
|
||||||
|
|
||||||
let underlying (s,_,_) = s
|
|
||||||
|
|
||||||
let sub (s,i,len) i' len' =
|
|
||||||
if i+i' + len' > i+len then invalid_arg "CCString.Sub.sub";
|
|
||||||
(s, i+i',len')
|
|
||||||
|
|
||||||
let length (_,_,l) = l
|
|
||||||
|
|
||||||
let get (s,i,l) j =
|
|
||||||
if j<0 || j>= l then invalid_arg "CCString.Sub.get";
|
|
||||||
String.unsafe_get s (i+j)
|
|
||||||
|
|
||||||
let blit (a1,i1,len1) o1 a2 o2 len =
|
|
||||||
if o1+len>len1 then invalid_arg "CCString.Sub.blit";
|
|
||||||
blit a1 (i1+o1) a2 o2 len
|
|
||||||
|
|
||||||
let fold f acc (s,i,len) =
|
|
||||||
let rec fold_rec f acc s i j =
|
|
||||||
if i = j then acc
|
|
||||||
else fold_rec f (f acc s.[i]) s (i+1) j
|
|
||||||
in fold_rec f acc s i (i+len)
|
|
||||||
|
|
||||||
(*$T
|
|
||||||
let s = Sub.make "abcde" 1 3 in \
|
|
||||||
Sub.fold (fun acc x -> x::acc) [] s = ['d'; 'c'; 'b']
|
|
||||||
Sub.make "abcde" 1 3 |> Sub.copy = "bcd"
|
|
||||||
Sub.full "abcde" |> Sub.copy = "abcde"
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$T
|
|
||||||
let sub = Sub.make " abc " 1 ~len:3 in \
|
|
||||||
"\"abc\"" = (CCFormat.to_string Sub.pp sub)
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$= & ~printer:(String.make 1)
|
|
||||||
'b' Sub.(get (make "abc" 1 ~len:2) 0)
|
|
||||||
'c' Sub.(get (make "abc" 1 ~len:2) 1)
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*$QR
|
|
||||||
Q.(printable_string_of_size Gen.(3--10)) (fun s ->
|
|
||||||
let open Iter.Infix in
|
|
||||||
begin
|
|
||||||
(0 -- (length s-2)
|
|
||||||
>|= fun i -> i, Sub.make s i ~len:(length s-i))
|
|
||||||
>>= fun (i,sub) ->
|
|
||||||
(0 -- (Sub.length sub-1) >|= fun j -> i,j,sub)
|
|
||||||
end
|
|
||||||
|> Iter.for_all
|
|
||||||
(fun (i,j,sub) -> Sub.get sub j = s.[i+j]))
|
|
||||||
*)
|
|
||||||
|
|
||||||
let to_gen (s,i,len) = _to_gen s i len
|
|
||||||
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
|
|
||||||
|
|
||||||
let pp_buf buf (s,i,len) =
|
|
||||||
Buffer.add_char buf '"';
|
|
||||||
Buffer.add_substring buf s i len;
|
|
||||||
Buffer.add_char buf '"'
|
|
||||||
|
|
||||||
let pp fmt s =
|
|
||||||
Format.fprintf fmt "\"%s\"" (copy s)
|
|
||||||
end
|
|
||||||
|
|
||||||
(* test consistency of interfaces *)
|
(* test consistency of interfaces *)
|
||||||
(*$inject
|
(*$inject
|
||||||
module type L = module type of CCString
|
module type L = module type of CCString
|
||||||
|
|
|
||||||
|
|
@ -12,61 +12,53 @@ type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||||
|
|
||||||
(** {2 Common Signature} *)
|
|
||||||
|
|
||||||
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. *)
|
|
||||||
|
|
||||||
(*
|
|
||||||
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 2.8 *)
|
|
||||||
|
|
||||||
val to_std_seq : t -> char Seq.t
|
|
||||||
(** [to_std_seq s] returns a [Seq.t] of the bytes in [s].
|
|
||||||
@since 2.8
|
|
||||||
*)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
(** {2 Strings} *)
|
|
||||||
|
|
||||||
include module type of struct include String end
|
include module type of struct include String end
|
||||||
|
|
||||||
|
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. *)
|
||||||
|
|
||||||
|
(*
|
||||||
|
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 2.8 *)
|
||||||
|
|
||||||
|
val to_std_seq : t -> char Seq.t
|
||||||
|
(** [to_std_seq s] returns a [Seq.t] of the bytes in [s].
|
||||||
|
@since 2.8
|
||||||
|
*)
|
||||||
|
|
||||||
|
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. *)
|
||||||
|
|
||||||
val compare : string -> string -> int
|
val compare : string -> string -> int
|
||||||
|
|
||||||
val is_empty : string -> bool
|
val is_empty : string -> bool
|
||||||
|
|
@ -235,8 +227,6 @@ val exists : (char -> bool) -> string -> bool
|
||||||
(** True for some char?
|
(** True for some char?
|
||||||
@since 0.12 *)
|
@since 0.12 *)
|
||||||
|
|
||||||
include S with type t := string
|
|
||||||
|
|
||||||
val drop_while : (char -> bool) -> t -> t
|
val drop_while : (char -> bool) -> t -> t
|
||||||
(** [drop_while f s] discards any characters starting from the left,
|
(** [drop_while f s] discards any characters starting from the left,
|
||||||
up to the first character [c] not satisfying [f c].
|
up to the first character [c] not satisfying [f c].
|
||||||
|
|
@ -419,33 +409,3 @@ val edit_distance : string -> string -> int
|
||||||
(** Edition distance between two strings. This satisfies the classical
|
(** Edition distance between two strings. This satisfies the classical
|
||||||
distance axioms: it is always positive, symmetric, and satisfies
|
distance axioms: it is always positive, symmetric, and satisfies
|
||||||
the formula [distance a b + distance b c >= distance a c]. *)
|
the formula [distance a b + distance b c >= distance a c]. *)
|
||||||
|
|
||||||
(** {2 Slices}
|
|
||||||
|
|
||||||
A contiguous part of a string *)
|
|
||||||
|
|
||||||
module Sub : sig
|
|
||||||
type t = string * int * int
|
|
||||||
(** A string, an offset, and the length of the slice. *)
|
|
||||||
|
|
||||||
val make : string -> int -> len:int -> t
|
|
||||||
|
|
||||||
val full : string -> t
|
|
||||||
(** Full string. *)
|
|
||||||
|
|
||||||
val copy : t -> string
|
|
||||||
(** Make a copy of the substring. *)
|
|
||||||
|
|
||||||
val underlying : t -> string
|
|
||||||
|
|
||||||
val sub : t -> int -> int -> t
|
|
||||||
(** Sub-slice. *)
|
|
||||||
|
|
||||||
val get : t -> int -> char
|
|
||||||
(** [get s i] gets the [i]-th element, or fails.
|
|
||||||
@raise Invalid_argument if the index is not within [0 ... length - 1].
|
|
||||||
@since 1.2 *)
|
|
||||||
|
|
||||||
include S with type t := t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
|
||||||
|
|
@ -10,61 +10,55 @@ type 'a iter = ('a -> unit) -> unit
|
||||||
type 'a gen = unit -> 'a option
|
type 'a gen = unit -> 'a option
|
||||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||||
|
|
||||||
(** {2 Common Signature} *)
|
include module type of struct include StringLabels end
|
||||||
|
|
||||||
module type S = sig
|
val length : t -> int
|
||||||
type t
|
(** Return the length (number of characters) of the given string. *)
|
||||||
|
|
||||||
val length : t -> int
|
val blit : src:t -> src_pos:int -> dst:Bytes.t -> dst_pos:int -> len:int -> unit
|
||||||
(** Return the length (number of characters) of the given string. *)
|
(** Like {!String.blit}.
|
||||||
|
Compatible with the [-safe-string] option.
|
||||||
|
@raise Invalid_argument if indices are not valid. *)
|
||||||
|
|
||||||
val blit : src:t -> src_pos:int -> dst:Bytes.t -> dst_pos:int -> len:int -> unit
|
(*
|
||||||
(** Like {!String.blit}.
|
val blit_immut : t -> int -> t -> int -> int -> string
|
||||||
Compatible with the [-safe-string] option.
|
(** Immutable version of {!blit}, returning a new string.
|
||||||
@raise Invalid_argument if indices are not valid. *)
|
[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 : f:('a -> char -> 'a) -> init:'a -> t -> 'a
|
||||||
val blit_immut : t -> int -> t -> int -> int -> string
|
(** Fold on chars by increasing index.
|
||||||
(** Immutable version of {!blit}, returning a new string.
|
@since 0.7 *)
|
||||||
[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 : f:('a -> char -> 'a) -> init:'a -> t -> 'a
|
(** {2 Conversions} *)
|
||||||
(** 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_gen : t -> char gen
|
val to_iter : t -> char iter
|
||||||
(** Return the [gen] of characters contained in the string. *)
|
(** Return the [iter] of characters contained in the string.
|
||||||
|
@since 2.8 *)
|
||||||
|
|
||||||
val to_iter : t -> char iter
|
val to_std_seq : t -> char Seq.t
|
||||||
(** Return the [iter] of characters contained in the string.
|
(** [to_std_seq s] returns a [Seq.t] of the bytes in [s].
|
||||||
@since 2.8 *)
|
@since 2.8
|
||||||
|
*)
|
||||||
|
|
||||||
val to_std_seq : t -> char Seq.t
|
val to_list : t -> char list
|
||||||
(** [to_std_seq s] returns a [Seq.t] of the bytes in [s].
|
(** Return the list of characters contained in the string. *)
|
||||||
@since 2.8
|
|
||||||
*)
|
|
||||||
|
|
||||||
val to_list : t -> char list
|
val pp_buf : Buffer.t -> t -> unit
|
||||||
(** Return the list of characters contained in the string. *)
|
(** Renamed from [pp] since 2.0. *)
|
||||||
|
|
||||||
val pp_buf : Buffer.t -> t -> unit
|
val pp : Format.formatter -> t -> unit
|
||||||
(** Renamed from [pp] since 2.0. *)
|
(** Print the string within quotes.
|
||||||
|
|
||||||
val pp : Format.formatter -> t -> unit
|
Renamed from [print] since 2.0. *)
|
||||||
(** Print the string within quotes.
|
|
||||||
|
|
||||||
Renamed from [print] since 2.0. *)
|
|
||||||
end
|
|
||||||
|
|
||||||
(** {2 Strings} *)
|
(** {2 Strings} *)
|
||||||
|
|
||||||
include module type of struct include StringLabels end
|
|
||||||
|
|
||||||
val equal : string -> string -> bool
|
val equal : string -> string -> bool
|
||||||
(** Equality function on strings. *)
|
(** Equality function on strings. *)
|
||||||
|
|
||||||
|
|
@ -236,8 +230,6 @@ val exists : f:(char -> bool) -> string -> bool
|
||||||
(** True for some char?
|
(** True for some char?
|
||||||
@since 0.12 *)
|
@since 0.12 *)
|
||||||
|
|
||||||
include S with type t := string
|
|
||||||
|
|
||||||
val drop_while : f:(char -> bool) -> t -> t
|
val drop_while : f:(char -> bool) -> t -> t
|
||||||
(** [drop_while f s] discards any characters starting from the left,
|
(** [drop_while f s] discards any characters starting from the left,
|
||||||
up to the first character [c] not satisfying [f c].
|
up to the first character [c] not satisfying [f c].
|
||||||
|
|
@ -436,33 +428,3 @@ val edit_distance : string -> string -> int
|
||||||
(** Edition distance between two strings. This satisfies the classical
|
(** Edition distance between two strings. This satisfies the classical
|
||||||
distance axioms: it is always positive, symmetric, and satisfies
|
distance axioms: it is always positive, symmetric, and satisfies
|
||||||
the formula [distance a b + distance b c >= distance a c]. *)
|
the formula [distance a b + distance b c >= distance a c]. *)
|
||||||
|
|
||||||
(** {2 Slices}
|
|
||||||
|
|
||||||
A contiguous part of a string *)
|
|
||||||
|
|
||||||
module Sub : sig
|
|
||||||
type t = string * int * int
|
|
||||||
(** A string, an offset, and the length of the slice. *)
|
|
||||||
|
|
||||||
val make : string -> pos:int -> len:(int [@keep_label]) -> t
|
|
||||||
|
|
||||||
val full : string -> t
|
|
||||||
(** Full string. *)
|
|
||||||
|
|
||||||
val copy : t -> string
|
|
||||||
(** Make a copy of the substring. *)
|
|
||||||
|
|
||||||
val underlying : t -> string
|
|
||||||
|
|
||||||
val sub : t -> int -> int -> t
|
|
||||||
(** Sub-slice. *)
|
|
||||||
|
|
||||||
val get : t -> int -> char
|
|
||||||
(** [get s i] gets the [i]-th element, or fails.
|
|
||||||
@raise Invalid_argument if the index is not within [0 ... length - 1].
|
|
||||||
@since 1.2 *)
|
|
||||||
|
|
||||||
include S with type t := t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
(** {1 Drop-In replacement to Stdlib} *)
|
(** {1 Drop-In replacement to Stdlib} *)
|
||||||
|
|
||||||
module Array = CCArray
|
module Array = CCArray
|
||||||
module Array_slice = CCArray_slice
|
|
||||||
module Bool = CCBool
|
module Bool = CCBool
|
||||||
module Char = CCChar
|
module Char = CCChar
|
||||||
module Equal = CCEqual
|
module Equal = CCEqual
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,8 @@
|
||||||
(** {1 Drop-In replacement to Stdlib} *)
|
(** {1 Drop-In replacement to Stdlib} *)
|
||||||
|
|
||||||
module Array = CCArrayLabels
|
module Array = CCArrayLabels
|
||||||
module Array_slice = CCArray_sliceLabels
|
|
||||||
module Bool = CCBool
|
module Bool = CCBool
|
||||||
module Char = Char
|
module Char = CCChar
|
||||||
module Equal = CCEqualLabels
|
module Equal = CCEqualLabels
|
||||||
module Float = CCFloat
|
module Float = CCFloat
|
||||||
module Format = CCFormat
|
module Format = CCFormat
|
||||||
|
|
@ -39,10 +38,16 @@ module Parse = CCParse
|
||||||
module Random = CCRandom
|
module Random = CCRandom
|
||||||
module Ref = CCRef
|
module Ref = CCRef
|
||||||
module Result = CCResult
|
module Result = CCResult
|
||||||
|
module Seq = CCSeq
|
||||||
module Set = CCSet
|
module Set = CCSet
|
||||||
module String = CCStringLabels
|
module String = CCStringLabels
|
||||||
module Vector = CCVector
|
module Vector = CCVector
|
||||||
module Monomorphic = CCMonomorphic
|
module Monomorphic = CCMonomorphic
|
||||||
module Utf8_string = CCUtf8_string
|
module Utf8_string = CCUtf8_string
|
||||||
|
|
||||||
|
module Sexp = CCSexp
|
||||||
|
module Sexp_intf = CCSexp_intf
|
||||||
|
|
||||||
|
module Stdlib = CCShims_.Stdlib
|
||||||
|
|
||||||
include Monomorphic
|
include Monomorphic
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue