mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 19:25:28 -05:00
circular lists
This commit is contained in:
parent
0375c0f721
commit
88f006171f
7 changed files with 207 additions and 8 deletions
2
_oasis
2
_oasis
|
|
@ -41,7 +41,7 @@ Library "containers"
|
||||||
UnionFind, SmallSet, Leftistheap, AbsSet, CSM, MultiMap,
|
UnionFind, SmallSet, Leftistheap, AbsSet, CSM, MultiMap,
|
||||||
ActionMan, BV, QCheck, BencodeOnDisk, Show, TTree,
|
ActionMan, BV, QCheck, BencodeOnDisk, Show, TTree,
|
||||||
HGraph, Automaton, Conv, Levenshtein, Bidir, Iteratee,
|
HGraph, Automaton, Conv, Levenshtein, Bidir, Iteratee,
|
||||||
Ty, Tell, BencodeStream, RatTerm, Cause, KMP
|
Ty, Tell, BencodeStream, RatTerm, Cause, KMP, CircList
|
||||||
BuildDepends: unix
|
BuildDepends: unix
|
||||||
|
|
||||||
Library "containers_thread"
|
Library "containers_thread"
|
||||||
|
|
|
||||||
3
_tags
3
_tags
|
|
@ -1,5 +1,5 @@
|
||||||
# OASIS_START
|
# OASIS_START
|
||||||
# DO NOT EDIT (digest: 13877dc814f0b2dee886bafc27842dfc)
|
# DO NOT EDIT (digest: e6a4388a1190cdbd6a00960fb2e08d7f)
|
||||||
# Ignore VCS directories, you can use the same kind of rule outside
|
# Ignore VCS directories, you can use the same kind of rule outside
|
||||||
# OASIS_START/STOP if you want to exclude directories that contains
|
# OASIS_START/STOP if you want to exclude directories that contains
|
||||||
# useless stuff for the build process
|
# useless stuff for the build process
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
"ratTerm.cmx": for-pack(Containers)
|
"ratTerm.cmx": for-pack(Containers)
|
||||||
"cause.cmx": for-pack(Containers)
|
"cause.cmx": for-pack(Containers)
|
||||||
"KMP.cmx": for-pack(Containers)
|
"KMP.cmx": for-pack(Containers)
|
||||||
|
"circList.cmx": for-pack(Containers)
|
||||||
# Library containers_thread
|
# Library containers_thread
|
||||||
"threads/containers_thread.cmxs": use_containers_thread
|
"threads/containers_thread.cmxs": use_containers_thread
|
||||||
<threads/*.ml{,i}>: package(threads)
|
<threads/*.ml{,i}>: package(threads)
|
||||||
|
|
|
||||||
114
circList.ml
Normal file
114
circList.ml
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
|
||||||
|
(*
|
||||||
|
copyright (c) 2013-2014, simon cruanes
|
||||||
|
all rights reserved.
|
||||||
|
|
||||||
|
redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer. redistributions in binary
|
||||||
|
form must reproduce the above copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other materials provided with
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** {1 Functional Circular List}
|
||||||
|
|
||||||
|
Those are infinite lists that are built from a finite list of
|
||||||
|
elements, and cycles through them. *)
|
||||||
|
|
||||||
|
type 'a t = {
|
||||||
|
front : 'a list;
|
||||||
|
f_len : int;
|
||||||
|
rear : 'a list;
|
||||||
|
r_len : int;
|
||||||
|
}
|
||||||
|
(* invariant: if front=[] then rear=[] *)
|
||||||
|
|
||||||
|
let make f f_len r r_len = match f with
|
||||||
|
| [] ->
|
||||||
|
assert (f_len = 0);
|
||||||
|
{ front=List.rev r; f_len=r_len; rear=[]; r_len=0; }
|
||||||
|
| _::_ -> {front=f; f_len; rear=r; r_len; }
|
||||||
|
|
||||||
|
let singleton x = make [x] 1 [] 0
|
||||||
|
|
||||||
|
let of_list l = make l (List.length l) [] 0
|
||||||
|
|
||||||
|
let length l = l.f_len + l.r_len
|
||||||
|
|
||||||
|
let cons x l = make (x::l.front) (l.f_len+1) l.rear l.r_len
|
||||||
|
|
||||||
|
let snoc l x = make l.front l.f_len (x::l.rear) (l.r_len+1)
|
||||||
|
|
||||||
|
let next l = match l.front with
|
||||||
|
| [] -> assert false
|
||||||
|
| x::l' ->
|
||||||
|
x, make l' (l.f_len-1) l.rear l.r_len
|
||||||
|
|
||||||
|
let rev l = make l.rear l.r_len l.front l.f_len
|
||||||
|
|
||||||
|
let find p l =
|
||||||
|
let rec _find p i l =
|
||||||
|
if i = 0 then None
|
||||||
|
else
|
||||||
|
let x, l' = next l in
|
||||||
|
if p x then Some x else _find p (i-1) l'
|
||||||
|
in
|
||||||
|
_find p (length l) l
|
||||||
|
|
||||||
|
let mem ?(eq=fun x y -> x=y) x l =
|
||||||
|
match find (eq x) l with
|
||||||
|
| None -> false
|
||||||
|
| Some _ -> true
|
||||||
|
|
||||||
|
let exists p l = match find p l with
|
||||||
|
| None -> false
|
||||||
|
| Some _ -> true
|
||||||
|
|
||||||
|
let for_all p l =
|
||||||
|
let rec _check i l =
|
||||||
|
i = 0 ||
|
||||||
|
( let x, l' = next l in
|
||||||
|
p x && _check (i-1) l')
|
||||||
|
in
|
||||||
|
_check (length l) l
|
||||||
|
|
||||||
|
let fold f acc l =
|
||||||
|
let rec _fold acc i l =
|
||||||
|
if i=0 then acc
|
||||||
|
else
|
||||||
|
let x, l' = next l in
|
||||||
|
let acc = f acc x in
|
||||||
|
_fold acc (i-1) l'
|
||||||
|
in
|
||||||
|
_fold acc (length l) l
|
||||||
|
|
||||||
|
type 'a gen = unit -> 'a option
|
||||||
|
type 'a sequence = ('a -> unit) -> unit
|
||||||
|
|
||||||
|
let gen l =
|
||||||
|
let l = ref l in
|
||||||
|
fun () ->
|
||||||
|
let x, l' = next !l in
|
||||||
|
l := l';
|
||||||
|
Some x
|
||||||
|
|
||||||
|
let seq l k =
|
||||||
|
let r' = lazy (List.rev l.rear) in
|
||||||
|
while true do
|
||||||
|
List.iter k l.front;
|
||||||
|
List.iter k (Lazy.force r')
|
||||||
|
done
|
||||||
81
circList.mli
Normal file
81
circList.mli
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
|
||||||
|
(*
|
||||||
|
copyright (c) 2013-2014, simon cruanes
|
||||||
|
all rights reserved.
|
||||||
|
|
||||||
|
redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer. redistributions in binary
|
||||||
|
form must reproduce the above copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other materials provided with
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** {1 Functional Circular List}
|
||||||
|
|
||||||
|
Those are infinite lists that are built from a finite list of
|
||||||
|
elements, and cycles through them.
|
||||||
|
Unless specified otherwise, operations have an amortized cost in O(1). *)
|
||||||
|
|
||||||
|
type +'a t
|
||||||
|
|
||||||
|
val singleton : 'a -> 'a t
|
||||||
|
(** list that cycles on one element *)
|
||||||
|
|
||||||
|
val of_list : 'a list -> 'a t
|
||||||
|
(** build a circular list from a list. Linear in the length
|
||||||
|
of the list *)
|
||||||
|
|
||||||
|
val length : 'a t -> int
|
||||||
|
(** length of the cycle. *)
|
||||||
|
|
||||||
|
val cons : 'a -> 'a t -> 'a t
|
||||||
|
(** [cons x l] adds [x] at the beginning of [l] *)
|
||||||
|
|
||||||
|
val snoc : 'a t -> 'a -> 'a t
|
||||||
|
(** [snoc l x] adds [x] at the end of [l] *)
|
||||||
|
|
||||||
|
val next : 'a t -> 'a * 'a t
|
||||||
|
(** obtain the next element, and the list rotated by one. *)
|
||||||
|
|
||||||
|
val rev : 'a t -> 'a t
|
||||||
|
(** reverse the traversal (goes right-to-left from now). *)
|
||||||
|
|
||||||
|
val find : ('a -> bool) -> 'a t -> 'a option
|
||||||
|
(** [find p l] returns [Some x] where [p x] is [true]
|
||||||
|
and [x] belongs to [l], or [None] if no such
|
||||||
|
element exists *)
|
||||||
|
|
||||||
|
val mem : ?eq:('a -> 'a -> bool) -> 'a -> 'a t -> bool
|
||||||
|
(** does the element belong to the infinite list? *)
|
||||||
|
|
||||||
|
val exists : ('a -> bool) -> 'a t -> bool
|
||||||
|
|
||||||
|
val for_all : ('a -> bool) -> 'a t -> bool
|
||||||
|
|
||||||
|
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
|
||||||
|
(** fold through each element of the list exactly once. *)
|
||||||
|
|
||||||
|
(** {2 Iterators} *)
|
||||||
|
|
||||||
|
type 'a gen = unit -> 'a option
|
||||||
|
type 'a sequence = ('a -> unit) -> unit
|
||||||
|
|
||||||
|
val gen : 'a t -> 'a gen
|
||||||
|
(** Generator on elements of the list *)
|
||||||
|
|
||||||
|
val seq : 'a t -> 'a sequence
|
||||||
|
(** Sequence of elements of the list *)
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# OASIS_START
|
# OASIS_START
|
||||||
# DO NOT EDIT (digest: 404fe51c40218ed7bf430446cec5efde)
|
# DO NOT EDIT (digest: 157f88a0bbe94188791880b268b7df2a)
|
||||||
Cache
|
Cache
|
||||||
Deque
|
Deque
|
||||||
Gen
|
Gen
|
||||||
|
|
@ -48,4 +48,5 @@ BencodeStream
|
||||||
RatTerm
|
RatTerm
|
||||||
Cause
|
Cause
|
||||||
KMP
|
KMP
|
||||||
|
CircList
|
||||||
# OASIS_STOP
|
# OASIS_STOP
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# OASIS_START
|
# OASIS_START
|
||||||
# DO NOT EDIT (digest: 404fe51c40218ed7bf430446cec5efde)
|
# DO NOT EDIT (digest: 157f88a0bbe94188791880b268b7df2a)
|
||||||
Cache
|
Cache
|
||||||
Deque
|
Deque
|
||||||
Gen
|
Gen
|
||||||
|
|
@ -48,4 +48,5 @@ BencodeStream
|
||||||
RatTerm
|
RatTerm
|
||||||
Cause
|
Cause
|
||||||
KMP
|
KMP
|
||||||
|
CircList
|
||||||
# OASIS_STOP
|
# OASIS_STOP
|
||||||
|
|
|
||||||
9
setup.ml
9
setup.ml
|
|
@ -1,7 +1,7 @@
|
||||||
(* setup.ml generated for the first time by OASIS v0.3.0 *)
|
(* setup.ml generated for the first time by OASIS v0.3.0 *)
|
||||||
|
|
||||||
(* OASIS_START *)
|
(* OASIS_START *)
|
||||||
(* DO NOT EDIT (digest: b545212f57a5e5b473eeea4866484af0) *)
|
(* DO NOT EDIT (digest: 6abff81b4f6ff21a732c0e62491fa464) *)
|
||||||
(*
|
(*
|
||||||
Regenerated by OASIS v0.4.4
|
Regenerated by OASIS v0.4.4
|
||||||
Visit http://oasis.forge.ocamlcore.org for more information and
|
Visit http://oasis.forge.ocamlcore.org for more information and
|
||||||
|
|
@ -7006,7 +7006,8 @@ let setup_t =
|
||||||
"BencodeStream";
|
"BencodeStream";
|
||||||
"RatTerm";
|
"RatTerm";
|
||||||
"Cause";
|
"Cause";
|
||||||
"KMP"
|
"KMP";
|
||||||
|
"CircList"
|
||||||
];
|
];
|
||||||
lib_pack = true;
|
lib_pack = true;
|
||||||
lib_internal_modules = [];
|
lib_internal_modules = [];
|
||||||
|
|
@ -7393,7 +7394,7 @@ let setup_t =
|
||||||
};
|
};
|
||||||
oasis_fn = Some "_oasis";
|
oasis_fn = Some "_oasis";
|
||||||
oasis_version = "0.4.4";
|
oasis_version = "0.4.4";
|
||||||
oasis_digest = Some "\228\227\"@\138\216\007\132\190[\139\215a\153B<";
|
oasis_digest = Some "\174j\228\162\204\138v>\191a1\251\130\209\232\003";
|
||||||
oasis_exec = None;
|
oasis_exec = None;
|
||||||
oasis_setup_args = [];
|
oasis_setup_args = [];
|
||||||
setup_update = false
|
setup_update = false
|
||||||
|
|
@ -7401,6 +7402,6 @@ let setup_t =
|
||||||
|
|
||||||
let setup () = BaseSetup.setup setup_t;;
|
let setup () = BaseSetup.setup setup_t;;
|
||||||
|
|
||||||
# 7405 "setup.ml"
|
# 7406 "setup.ml"
|
||||||
(* OASIS_STOP *)
|
(* OASIS_STOP *)
|
||||||
let () = setup ();;
|
let () = setup ();;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue