Merge branch 'master' into stable for 0.6

This commit is contained in:
Simon Cruanes 2016-01-08 20:45:39 +01:00
commit 629d538a41
9 changed files with 579 additions and 592 deletions

View file

@ -1,4 +1,4 @@
Copyright (c) 2012, Simon Cruanes
Copyright (c) 2012-2016, Simon Cruanes
All rights reserved.
Redistribution and use in source and binary forms, with or without

8
META
View file

@ -1,6 +1,6 @@
# OASIS_START
# DO NOT EDIT (digest: 2f8e4d7fc3cb814610643e4ca5e33697)
version = "0.5.5"
# DO NOT EDIT (digest: e23210adac78822adc0cf3b47bd47a95)
version = "0.6"
description = "Simple sequence (iterator) datatype and combinators"
requires = "bytes"
archive(byte) = "sequence.cma"
@ -9,7 +9,7 @@ archive(native) = "sequence.cmxa"
archive(native, plugin) = "sequence.cmxs"
exists_if = "sequence.cma"
package "invert" (
version = "0.5.5"
version = "0.6"
description = "Simple sequence (iterator) datatype and combinators"
requires = "sequence delimcc"
archive(byte) = "invert.cma"
@ -20,7 +20,7 @@ package "invert" (
)
package "bigarray" (
version = "0.5.5"
version = "0.6"
description = "Simple sequence (iterator) datatype and combinators"
requires = "sequence bigarray"
archive(byte) = "bigarray.cma"

2
_oasis
View file

@ -1,6 +1,6 @@
OASISFormat: 0.4
Name: sequence
Version: 0.5.5
Version: 0.6
Homepage: https://github.com/c-cube/sequence
Authors: Simon Cruanes
License: BSD-2-clause

6
opam
View file

@ -12,7 +12,11 @@ install: [make "install"]
remove: [
["ocamlfind" "remove" "sequence"]
]
depends: ["ocamlfind" "base-bytes"]
depends: [
"ocamlfind"
"base-bytes"
"ocamlbuild" {build}
]
tags: [ "sequence" "iterator" "iter" "fold" ]
homepage: "https://github.com/c-cube/sequence/"
depopts: ["delimcc" "base-bigarray"]

View file

@ -1,29 +1,7 @@
(*
Copyright (c) 2013, 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:
(* This file is free software, part of sequence. See file "license" for more details. *)
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 Transient iterators, that abstract on a finite sequence of elements.} *)
(** {1 Simple and Efficient Iterators} *)
(** Sequence abstract iterator type *)
type 'a t = ('a -> unit) -> unit
@ -140,12 +118,10 @@ module MList = struct
assert (!n < Array.length a);
a.(!n) <- x;
incr n;
if !n = Array.length a then begin
if !n = Array.length a then (
!prev := !cur;
prev := next;
cur := Nil
end
);
cur := Nil));
!prev := !cur;
!start
@ -238,7 +214,7 @@ let sort ?(cmp=Pervasives.compare) seq =
let l = List.fast_sort cmp l in
fun k -> List.iter k l
let group ?(eq=fun x y -> x = y) seq k =
let group_succ_by ?(eq=fun x y -> x = y) seq k =
let cur = ref [] in
seq (fun x ->
match !cur with
@ -251,17 +227,36 @@ let group ?(eq=fun x y -> x = y) seq k =
(* last list *)
if !cur <> [] then k !cur
let group = group_succ_by
let group_by (type k) ?(hash=Hashtbl.hash) ?(eq=(=)) seq =
let module Tbl = Hashtbl.Make(struct
type t = k
let equal = eq
let hash = hash
end) in
(* compute group table *)
let tbl = Tbl.create 32 in
seq
(fun x ->
let l = try Tbl.find tbl x with Not_found -> [] in
Tbl.replace tbl x (x::l)
);
fun yield ->
Tbl.iter (fun _ l -> yield l) tbl
let uniq ?(eq=fun x y -> x = y) seq k =
let has_prev = ref false
and prev = ref (Obj.magic 0) in (* avoid option type, costly *)
seq (fun x ->
seq
(fun x ->
if !has_prev && eq !prev x
then () (* duplicate *)
else begin
else (
has_prev := true;
prev := x;
k x
end)
))
let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq =
let module S = Set.Make(struct
@ -272,23 +267,17 @@ let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq =
fun k -> S.iter k set
let product outer inner k =
outer (fun x ->
inner (fun y -> k (x,y))
)
outer (fun x -> inner (fun y -> k (x,y)))
let product2 outer inner k =
outer (fun x ->
inner (fun y -> k x y)
)
outer (fun x -> inner (fun y -> k x y))
let join ~join_row s1 s2 k =
s1 (fun a ->
s2 (fun b ->
match join_row a b with
| None -> ()
| Some c -> k c
)
) (* yield the combination of [a] and [b] *)
| Some c -> k c))
let rec unfoldr f b k = match f b with
| None -> ()
@ -303,14 +292,16 @@ let scan f acc seq k =
let max ?(lt=fun x y -> x < y) seq =
let ret = ref None in
seq (fun x -> match !ret with
seq
(fun x -> match !ret with
| None -> ret := Some x
| Some y -> if lt y x then ret := Some x);
!ret
let min ?(lt=fun x y -> x < y) seq =
let ret = ref None in
seq (fun x -> match !ret with
seq
(fun x -> match !ret with
| None -> ret := Some x
| Some y -> if lt x y then ret := Some x);
!ret
@ -333,11 +324,11 @@ exception ExitTake
let take n seq k =
let count = ref 0 in
try
seq (fun x ->
seq
(fun x ->
if !count = n then raise ExitTake;
incr count;
k x;
)
k x)
with ExitTake -> ()
exception ExitTakeWhile
@ -368,7 +359,8 @@ let drop n seq k =
let drop_while p seq k =
let drop = ref true in
seq (fun x ->
seq
(fun x ->
if !drop
then if p x then () else (drop := false; k x)
else k x)
@ -400,11 +392,12 @@ exception ExitFind
let find f seq =
let r = ref None in
begin try
seq (fun x -> match f x with
begin
try
seq
(fun x -> match f x with
| None -> ()
| Some _ as res -> r := res; raise ExitFind
);
| Some _ as res -> r := res; raise ExitFind);
with ExitFind -> ()
end;
!r
@ -475,16 +468,13 @@ let to_array seq =
let n = MList.length l in
if n = 0
then [||]
else begin
else (
let a = Array.make n (MList.get l 0) in
MList.iteri (fun i x -> a.(i) <- x) l;
a
end
)
let of_array a k =
for i = 0 to Array.length a - 1 do
k (Array.unsafe_get a i)
done
let of_array a k = Array.iter k a
let of_array_i a k =
for i = 0 to Array.length a - 1 do
@ -565,8 +555,7 @@ let of_in_channel ic =
while true do
let c = input_char ic in k c
done
with End_of_file -> ()
)
with End_of_file -> ())
let to_buffer seq buf =
seq (fun c -> Buffer.add_char buf c)
@ -578,6 +567,8 @@ let int_range ~start ~stop k =
let int_range_dec ~start ~stop k =
for i = start downto stop do k i done
let bools k = k false; k true
let of_set (type s) (type v) m set =
let module S = (val m : Set.S with type t = s and type elt = v) in
fun k -> S.iter k set
@ -725,10 +716,10 @@ let pp_seq ?(sep=", ") pp_elt formatter seq =
seq
(fun x ->
(if !first then first := false
else begin
else (
Format.pp_print_string formatter sep;
Format.pp_print_cut formatter ();
end);
));
pp_elt formatter x)
let pp_buf ?(sep=", ") pp_elt buf seq =

View file

@ -1,27 +1,5 @@
(*
copyright (c) 2013, 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.
*)
(* This file is free software, part of sequence. See file "license" for more details. *)
(** {1 Simple and Efficient Iterators} *)
@ -168,18 +146,18 @@ val flatten : 'a t t -> 'a t
(** Alias for {!concat} *)
val flatMap : ('a -> 'b t) -> 'a t -> 'b t
(** Monadic bind. Intuitively, it applies the function to every element of the
initial sequence, and calls {!concat}. *)
(** @deprecated use {!flat_map} since NEXT_RELEASE *)
val flat_map : ('a -> 'b t) -> 'a t -> 'b t
(** Alias to {!flatMap} with a more explicit name
(** Monadic bind. Intuitively, it applies the function to every
element of the initial sequence, and calls {!concat}.
@since 0.5 *)
val fmap : ('a -> 'b option) -> 'a t -> 'b t
(** Specialized version of {!flatMap} for options. *)
(** @deprecated use {!filter_map} since NEXT_RELEASE *)
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
(** Alias to {!fmap} with a more explicit name
(** Map and only keep non-[None] elements
@since 0.5 *)
val intersperse : 'a -> 'a t -> 'a t
@ -215,7 +193,19 @@ val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
(** Sort the sequence and remove duplicates. Eager, same as [sort] *)
val group : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
(** Group equal consecutive elements. *)
(** Group equal consecutive elements.
@deprecated use {!group_succ_by} *)
val group_succ_by : ?eq:('a -> 'a -> bool) -> 'a t -> 'a list t
(** Group equal consecutive elements.
Synonym to {!group}.
@since NEXT_RELEASE *)
val group_by : ?hash:('a -> int) -> ?eq:('a -> 'a -> bool) ->
'a t -> 'a list t
(** Group equal elements, disregarding their order of appearance.
The result sequence is traversable as many times as required.
@since NEXT_RELEASE *)
val uniq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t
(** Remove consecutive duplicate elements. Basically this is
@ -422,6 +412,10 @@ val int_range_dec : start:int -> stop:int -> int t
(** Iterator on decreasing integers in [stop...start] by steps -1.
See {!(--^)} for an infix version *)
val bools : bool t
(** Iterates on [true] and [false]
@since NEXT_RELEASE *)
val of_set : (module Set.S with type elt = 'a and type t = 'b) -> 'b -> 'a t
(** Convert the given set to a sequence. The set module must be provided. *)

View file

@ -1,27 +1,6 @@
(*
copyright (c) 2013, 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:
(* This file is free software, part of sequence. See file "license" for more details. *)
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 Simple and Efficient Iterators}
@ -143,16 +122,13 @@ val flatten : 'a t t -> 'a t
(** Alias for {!concat} *)
val flatMap : f:('a -> 'b t) -> 'a t -> 'b t
(** Monadic bind. Intuitively, it applies the function to every element of the
initial sequence, and calls {!concat}.
@deprecated use {!flat_map} *)
(** @deprecated use {!flat_map} *)
val flat_map : f:('a -> 'b t) -> 'a t -> 'b t
(** Alias to {!flatMap} with a more explicit name *)
val fmap : f:('a -> 'b option) -> 'a t -> 'b t
(** Specialized version of {!flatMap} for options.
@deprecated use {!filter_map} *)
(** @deprecated use {!filter_map} *)
val filter_map : f:('a -> 'b option) -> 'a t -> 'b t
(** Alias to {!fmap} with a more explicit name *)

View file

@ -1,7 +1,7 @@
(* setup.ml generated for the first time by OASIS v0.4.4 *)
(* OASIS_START *)
(* DO NOT EDIT (digest: 333f749d9a0c9bcd48d939db40a13c4b) *)
(* DO NOT EDIT (digest: ba3f6d5b3b5e6f77424dfec99217b2f6) *)
(*
Regenerated by OASIS v0.4.5
Visit http://oasis.forge.ocamlcore.org for more information and
@ -6861,7 +6861,7 @@ let setup_t =
alpha_features = [];
beta_features = [];
name = "sequence";
version = "0.5.5";
version = "0.6";
license =
OASISLicense.DEP5License
(OASISLicense.DEP5Unit
@ -7280,7 +7280,7 @@ let setup_t =
};
oasis_fn = Some "_oasis";
oasis_version = "0.4.5";
oasis_digest = Some "\179Sa\175xP\026d\164\216\201\198\001\028\141O";
oasis_digest = Some "\224\020Z\173\146\131E\193\nn\225\205\167u\192\196";
oasis_exec = None;
oasis_setup_args = [];
setup_update = false

View file

@ -124,11 +124,16 @@ let test_sort_uniq () =
|> S.to_list
|> OUnit.assert_equal [1;2;3;4;5;42]
let test_group () =
let test_group_succ () =
[1;2;3;3;2;2;3;4]
|> S.of_list |> S.group ?eq:None |> S.to_list
|> S.of_list |> S.group_succ_by ?eq:None |> S.to_list
|> OUnit.assert_equal [[1];[2];[3;3];[2;2];[3];[4]]
let test_group_by () =
[1;2;3;3;2;2;3;4]
|> S.of_list |> S.group_by ?eq:None ?hash:None |> S.sort ?cmp:None |> S.to_list
|> OUnit.assert_equal [[1];[2;2;2];[3;3;3];[4]]
let test_uniq () =
[1;2;2;3;4;4;4;3;3]
|> S.of_list |> S.uniq ?eq:None |> S.to_list
@ -203,6 +208,19 @@ let test_take () =
OUnit.assert_equal ~printer:pp_ilist [1;2;3;4;5] l;
()
let test_for_all () =
OUnit.assert_bool "true" S.(for_all (fun x -> x < 10) (1--9));
OUnit.assert_bool "false" S.(not (for_all (fun x -> x < 10) (2--11)));
OUnit.assert_bool "true" S.(for_all (fun _ -> false) empty);
OUnit.assert_bool "nested"
S.(
for_all
(fun seq ->
not (for_all (fun x -> x < 8) seq)
) (1 -- 10 >|= fun x -> x--20)
);
()
let test_regression1 () =
let s = S.(take 10 (repeat 1)) in
OUnit.assert_bool "not empty" (not (S.is_empty s));
@ -225,8 +243,9 @@ let suite =
"test_persistent" >:: test_persistent;
"test_big_persistent" >:: test_big_persistent;
"test_sort" >:: test_sort;
"test_sort_uniq" >:: test_sort;
"test_group" >:: test_group;
"test_sort_uniq" >:: test_sort_uniq;
"test_group_succ_by" >:: test_group_succ;
"test_group_by" >:: test_group_by;
"test_uniq" >:: test_uniq;
"test_product" >:: test_product;
"test_join" >:: test_join;
@ -237,5 +256,8 @@ let suite =
"test_hashtbl" >:: test_hashtbl;
"test_int_range" >:: test_int_range;
"test_take" >:: test_take;
"test_fold_while" >:: test_fold_while;
"test_buff" >:: test_buff;
"test_for_all" >:: test_for_all;
"test_regression1" >:: test_regression1;
]