mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
add CCImmutArray into containers.data
This commit is contained in:
parent
d4549786c5
commit
574b4ac62e
5 changed files with 218 additions and 1 deletions
|
|
@ -165,6 +165,7 @@ Documentation http://cedeela.fr/~simon/software/containers[here].
|
||||||
- `CCWBTree`, a weight-balanced tree, implementing a map interface
|
- `CCWBTree`, a weight-balanced tree, implementing a map interface
|
||||||
- `CCRAL`, a random-access list structure, with `O(1)` cons/hd/tl and `O(ln(n))`
|
- `CCRAL`, a random-access list structure, with `O(1)` cons/hd/tl and `O(ln(n))`
|
||||||
access to elements by their index.
|
access to elements by their index.
|
||||||
|
- `CCImmutArray`, immutable interface to arrays
|
||||||
|
|
||||||
=== Containers.io
|
=== Containers.io
|
||||||
|
|
||||||
|
|
|
||||||
3
_oasis
3
_oasis
|
|
@ -77,7 +77,8 @@ Library "containers_data"
|
||||||
CCPersistentHashtbl, CCDeque, CCFQueue, CCBV, CCMixtbl,
|
CCPersistentHashtbl, CCDeque, CCFQueue, CCBV, CCMixtbl,
|
||||||
CCMixmap, CCRingBuffer, CCIntMap, CCPersistentArray,
|
CCMixmap, CCRingBuffer, CCIntMap, CCPersistentArray,
|
||||||
CCMixset, CCHashconsedSet, CCGraph, CCHashSet, CCBitField,
|
CCMixset, CCHashconsedSet, CCGraph, CCHashSet, CCBitField,
|
||||||
CCHashTrie, CCBloom, CCWBTree, CCRAL, CCAllocCache
|
CCHashTrie, CCBloom, CCWBTree, CCRAL, CCAllocCache,
|
||||||
|
CCImmutArray
|
||||||
BuildDepends: bytes
|
BuildDepends: bytes
|
||||||
# BuildDepends: bytes, bisect_ppx
|
# BuildDepends: bytes, bisect_ppx
|
||||||
FindlibParent: containers
|
FindlibParent: containers
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ CCFQueue
|
||||||
CCFlatHashtbl
|
CCFlatHashtbl
|
||||||
CCHashSet
|
CCHashSet
|
||||||
CCHashTrie
|
CCHashTrie
|
||||||
|
CCImmutArray
|
||||||
CCIntMap
|
CCIntMap
|
||||||
CCMixmap
|
CCMixmap
|
||||||
CCMixset
|
CCMixset
|
||||||
|
|
|
||||||
129
src/data/CCImmutArray.ml
Normal file
129
src/data/CCImmutArray.ml
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
|
||||||
|
(* This file is free software, part of containers. See file "license" for more details. *)
|
||||||
|
|
||||||
|
(** {1 Immutable Arrays} *)
|
||||||
|
|
||||||
|
(* TODO: tests *)
|
||||||
|
(* TODO: transient API? for batch modifications *)
|
||||||
|
|
||||||
|
type 'a t = 'a array
|
||||||
|
|
||||||
|
let empty = [| |]
|
||||||
|
|
||||||
|
let length = Array.length
|
||||||
|
|
||||||
|
let singleton x = [| x |]
|
||||||
|
|
||||||
|
let doubleton x y = [| x; y |]
|
||||||
|
|
||||||
|
let make n x = Array.make n x
|
||||||
|
|
||||||
|
let init n f = Array.init n f
|
||||||
|
|
||||||
|
let get = Array.get
|
||||||
|
|
||||||
|
let set a n x =
|
||||||
|
let a' = Array.copy a in
|
||||||
|
a'.(n) <- x;
|
||||||
|
a'
|
||||||
|
|
||||||
|
let map = Array.map
|
||||||
|
|
||||||
|
let mapi = Array.mapi
|
||||||
|
|
||||||
|
let append a b =
|
||||||
|
let na = length a in
|
||||||
|
Array.init (na + length b)
|
||||||
|
(fun i -> if i < na then a.(i) else b.(i-na))
|
||||||
|
|
||||||
|
let iter = Array.iter
|
||||||
|
|
||||||
|
let iteri = Array.iteri
|
||||||
|
|
||||||
|
let fold = Array.fold_left
|
||||||
|
|
||||||
|
let foldi f acc a =
|
||||||
|
let n = ref 0 in
|
||||||
|
Array.fold_left
|
||||||
|
(fun acc x ->
|
||||||
|
let acc = f acc !n x in
|
||||||
|
incr n;
|
||||||
|
acc)
|
||||||
|
acc a
|
||||||
|
|
||||||
|
exception ExitNow
|
||||||
|
|
||||||
|
let for_all p a =
|
||||||
|
try
|
||||||
|
Array.iter (fun x -> if not (p x) then raise ExitNow) a;
|
||||||
|
true
|
||||||
|
with ExitNow -> false
|
||||||
|
|
||||||
|
let exists p a =
|
||||||
|
try
|
||||||
|
Array.iter (fun x -> if p x then raise ExitNow) a;
|
||||||
|
false
|
||||||
|
with ExitNow -> true
|
||||||
|
|
||||||
|
(** {2 Conversions} *)
|
||||||
|
|
||||||
|
type 'a sequence = ('a -> unit) -> unit
|
||||||
|
type 'a gen = unit -> 'a option
|
||||||
|
|
||||||
|
let of_list = Array.of_list
|
||||||
|
|
||||||
|
let to_list = Array.to_list
|
||||||
|
|
||||||
|
let of_array_unsafe a = a (* careful with that axe, Eugene *)
|
||||||
|
|
||||||
|
let to_seq a k = iter k a
|
||||||
|
|
||||||
|
let of_seq s =
|
||||||
|
let l = ref [] in
|
||||||
|
s (fun x -> l := x :: !l);
|
||||||
|
Array.of_list (List.rev !l)
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(list int) (fun l -> \
|
||||||
|
let g = Sequence.of_list l in \
|
||||||
|
of_seq g |> to_seq |> Sequence.to_list = l)
|
||||||
|
*)
|
||||||
|
|
||||||
|
let rec gen_to_list_ acc g = match g() with
|
||||||
|
| None -> List.rev acc
|
||||||
|
| Some x -> gen_to_list_ (x::acc) g
|
||||||
|
|
||||||
|
let of_gen g =
|
||||||
|
let l = gen_to_list_ [] g in
|
||||||
|
Array.of_list l
|
||||||
|
|
||||||
|
let to_gen a =
|
||||||
|
let i = ref 0 in
|
||||||
|
fun () ->
|
||||||
|
if !i < Array.length a then (
|
||||||
|
let x = a.(!i) in
|
||||||
|
incr i;
|
||||||
|
Some x
|
||||||
|
) else None
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(list int) (fun l -> \
|
||||||
|
let g = Gen.of_list l in \
|
||||||
|
of_gen g |> to_gen |> Gen.to_list = l)
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** {2 IO} *)
|
||||||
|
|
||||||
|
type 'a printer = Format.formatter -> 'a -> unit
|
||||||
|
|
||||||
|
let print ?(start="[|") ?(stop="|]") ?(sep=";") pp_item out a =
|
||||||
|
Format.pp_print_string out start;
|
||||||
|
for k = 0 to Array.length a - 1 do
|
||||||
|
if k > 0 then (
|
||||||
|
Format.pp_print_string out sep;
|
||||||
|
Format.pp_print_cut out ()
|
||||||
|
);
|
||||||
|
pp_item out a.(k)
|
||||||
|
done;
|
||||||
|
Format.pp_print_string out stop;
|
||||||
|
()
|
||||||
85
src/data/CCImmutArray.mli
Normal file
85
src/data/CCImmutArray.mli
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
|
||||||
|
(* This file is free software, part of containers. See file "license" for more details. *)
|
||||||
|
|
||||||
|
(** {1 Immutable Arrays}
|
||||||
|
|
||||||
|
Purely functional use of arrays. Update is costly, but reads are very fast.
|
||||||
|
Sadly, it is not possible to make this type covariant without using black
|
||||||
|
magic.
|
||||||
|
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
type 'a t
|
||||||
|
(** Array of values of type 'a. The underlying type really is
|
||||||
|
an array, but it will never be modified.
|
||||||
|
|
||||||
|
It should be covariant but OCaml will not accept it. *)
|
||||||
|
|
||||||
|
val empty : 'a t
|
||||||
|
|
||||||
|
val length : _ t -> int
|
||||||
|
|
||||||
|
val singleton : 'a -> 'a t
|
||||||
|
|
||||||
|
val doubleton : 'a -> 'a -> 'a t
|
||||||
|
|
||||||
|
val make : int -> 'a -> 'a t
|
||||||
|
(** [make n x] makes an array of [n] times [x] *)
|
||||||
|
|
||||||
|
val init : int -> (int -> 'a) -> 'a t
|
||||||
|
(** [init n f] makes the array [[| f 0; f 1; ... ; f (n-1) |]].
|
||||||
|
@raise Invalid_argument if [n < 0] *)
|
||||||
|
|
||||||
|
val get : 'a t -> int -> 'a
|
||||||
|
(** Access the element *)
|
||||||
|
|
||||||
|
val set : 'a t -> int -> 'a -> 'a t
|
||||||
|
(** Copy the array and modify its copy *)
|
||||||
|
|
||||||
|
val map : ('a -> 'b) -> 'a t -> 'b t
|
||||||
|
|
||||||
|
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
|
||||||
|
|
||||||
|
val append : 'a t -> 'a t -> 'a t
|
||||||
|
|
||||||
|
val iter : ('a -> unit) -> 'a t -> unit
|
||||||
|
|
||||||
|
val iteri : (int -> 'a -> unit) -> 'a t -> unit
|
||||||
|
|
||||||
|
val foldi : ('a -> int -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
|
|
||||||
|
val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
|
||||||
|
|
||||||
|
val for_all : ('a -> bool) -> 'a t -> bool
|
||||||
|
|
||||||
|
val exists : ('a -> bool) -> 'a t -> bool
|
||||||
|
|
||||||
|
(** {2 Conversions} *)
|
||||||
|
|
||||||
|
type 'a sequence = ('a -> unit) -> unit
|
||||||
|
type 'a gen = unit -> 'a option
|
||||||
|
|
||||||
|
val of_list : 'a list -> 'a t
|
||||||
|
|
||||||
|
val to_list : 'a t -> 'a list
|
||||||
|
|
||||||
|
val of_array_unsafe : 'a array -> 'a t
|
||||||
|
(** Take ownership of the given array. Careful, the array must {b NOT}
|
||||||
|
be modified afterwards! *)
|
||||||
|
|
||||||
|
val to_seq : 'a t -> 'a sequence
|
||||||
|
|
||||||
|
val of_seq : 'a sequence -> 'a t
|
||||||
|
|
||||||
|
val of_gen : 'a gen -> 'a t
|
||||||
|
|
||||||
|
val to_gen : 'a t -> 'a gen
|
||||||
|
|
||||||
|
(** {2 IO} *)
|
||||||
|
|
||||||
|
type 'a printer = Format.formatter -> 'a -> unit
|
||||||
|
|
||||||
|
val print :
|
||||||
|
?start:string -> ?stop:string -> ?sep:string ->
|
||||||
|
'a printer -> 'a t printer
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue