mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -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,
|
||||
ActionMan, BV, QCheck, BencodeOnDisk, Show, TTree,
|
||||
HGraph, Automaton, Conv, Levenshtein, Bidir, Iteratee,
|
||||
Ty, Tell, BencodeStream, RatTerm, Cause, KMP
|
||||
Ty, Tell, BencodeStream, RatTerm, Cause, KMP, CircList
|
||||
BuildDepends: unix
|
||||
|
||||
Library "containers_thread"
|
||||
|
|
|
|||
3
_tags
3
_tags
|
|
@ -1,5 +1,5 @@
|
|||
# OASIS_START
|
||||
# DO NOT EDIT (digest: 13877dc814f0b2dee886bafc27842dfc)
|
||||
# DO NOT EDIT (digest: e6a4388a1190cdbd6a00960fb2e08d7f)
|
||||
# Ignore VCS directories, you can use the same kind of rule outside
|
||||
# OASIS_START/STOP if you want to exclude directories that contains
|
||||
# useless stuff for the build process
|
||||
|
|
@ -63,6 +63,7 @@
|
|||
"ratTerm.cmx": for-pack(Containers)
|
||||
"cause.cmx": for-pack(Containers)
|
||||
"KMP.cmx": for-pack(Containers)
|
||||
"circList.cmx": for-pack(Containers)
|
||||
# Library containers_thread
|
||||
"threads/containers_thread.cmxs": use_containers_thread
|
||||
<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
|
||||
# DO NOT EDIT (digest: 404fe51c40218ed7bf430446cec5efde)
|
||||
# DO NOT EDIT (digest: 157f88a0bbe94188791880b268b7df2a)
|
||||
Cache
|
||||
Deque
|
||||
Gen
|
||||
|
|
@ -48,4 +48,5 @@ BencodeStream
|
|||
RatTerm
|
||||
Cause
|
||||
KMP
|
||||
CircList
|
||||
# OASIS_STOP
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# OASIS_START
|
||||
# DO NOT EDIT (digest: 404fe51c40218ed7bf430446cec5efde)
|
||||
# DO NOT EDIT (digest: 157f88a0bbe94188791880b268b7df2a)
|
||||
Cache
|
||||
Deque
|
||||
Gen
|
||||
|
|
@ -48,4 +48,5 @@ BencodeStream
|
|||
RatTerm
|
||||
Cause
|
||||
KMP
|
||||
CircList
|
||||
# OASIS_STOP
|
||||
|
|
|
|||
9
setup.ml
9
setup.ml
|
|
@ -1,7 +1,7 @@
|
|||
(* setup.ml generated for the first time by OASIS v0.3.0 *)
|
||||
|
||||
(* OASIS_START *)
|
||||
(* DO NOT EDIT (digest: b545212f57a5e5b473eeea4866484af0) *)
|
||||
(* DO NOT EDIT (digest: 6abff81b4f6ff21a732c0e62491fa464) *)
|
||||
(*
|
||||
Regenerated by OASIS v0.4.4
|
||||
Visit http://oasis.forge.ocamlcore.org for more information and
|
||||
|
|
@ -7006,7 +7006,8 @@ let setup_t =
|
|||
"BencodeStream";
|
||||
"RatTerm";
|
||||
"Cause";
|
||||
"KMP"
|
||||
"KMP";
|
||||
"CircList"
|
||||
];
|
||||
lib_pack = true;
|
||||
lib_internal_modules = [];
|
||||
|
|
@ -7393,7 +7394,7 @@ let setup_t =
|
|||
};
|
||||
oasis_fn = Some "_oasis";
|
||||
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_setup_args = [];
|
||||
setup_update = false
|
||||
|
|
@ -7401,6 +7402,6 @@ let setup_t =
|
|||
|
||||
let setup () = BaseSetup.setup setup_t;;
|
||||
|
||||
# 7405 "setup.ml"
|
||||
# 7406 "setup.ml"
|
||||
(* OASIS_STOP *)
|
||||
let () = setup ();;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue