mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 03:05:29 -05:00
Compare commits
10 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a525d4902c | ||
|
|
99fa66f1db | ||
|
|
21107dc7e7 | ||
|
|
cd2d47f268 | ||
|
|
f9c6c077c6 | ||
|
|
fc69ce4c91 | ||
|
|
d1af13a9dd | ||
|
|
f0f5396cc2 | ||
|
|
399e95b50f | ||
|
|
92d0022079 |
11 changed files with 88 additions and 78 deletions
14
.github/workflows/gh-pages.yml
vendored
14
.github/workflows/gh-pages.yml
vendored
|
|
@ -3,7 +3,7 @@ name: github pages
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- master # Set a branch name to trigger deployment
|
||||
- main # Set a branch name to trigger deployment
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
|
@ -11,16 +11,10 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@main
|
||||
|
||||
- name: Cache opam
|
||||
id: cache-opam
|
||||
uses: actions/cache@v2
|
||||
- uses: ocaml/setup-ocaml@v3
|
||||
with:
|
||||
path: ~/.opam
|
||||
key: opam-ubuntu-latest-4.12.0
|
||||
|
||||
- uses: avsm/setup-ocaml@v1
|
||||
with:
|
||||
ocaml-version: '4.12.0'
|
||||
ocaml-compiler: '4.14.x'
|
||||
allow-prerelease-opam: true
|
||||
|
||||
- name: Pin
|
||||
run: opam pin -n .
|
||||
|
|
|
|||
10
.github/workflows/main.yml
vendored
10
.github/workflows/main.yml
vendored
|
|
@ -2,10 +2,8 @@ name: build
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
run:
|
||||
name: Build
|
||||
|
|
@ -18,13 +16,15 @@ jobs:
|
|||
#- macos-latest
|
||||
ocaml-compiler:
|
||||
- 4.08.x
|
||||
- 4.12.x
|
||||
- 4.14.x
|
||||
# TODO: - 5.1.x # https://github.com/ocaml/setup-ocaml/issues/733
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ocaml/setup-ocaml@v2
|
||||
- uses: ocaml/setup-ocaml@v3
|
||||
with:
|
||||
ocaml-compiler: ${{ matrix.ocaml-compiler }}
|
||||
allow-prerelease-opam: true
|
||||
- run: opam pin -n .
|
||||
- run: opam depext -yt iter
|
||||
- run: opam install -t . --deps-only
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
version = 0.24.1
|
||||
version = 0.26.2
|
||||
profile=conventional
|
||||
margin=80
|
||||
if-then-else=k-r
|
||||
|
|
|
|||
|
|
@ -1,4 +1,10 @@
|
|||
|
||||
# 1.9
|
||||
|
||||
|
||||
- Switch exceptions used for control flow from global to local
|
||||
- Update Iter.ml to use mutable fields instead of refs (#44)
|
||||
|
||||
# 1.8
|
||||
|
||||
- add `Iter.map_while`
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
(names bench_persistent_read bench_persistent benchs)
|
||||
(libraries iter benchmark)
|
||||
(optional)
|
||||
(flags :standard -w +a-4-42-44-48-50-58-32-60-70@8 -safe-string -color always)
|
||||
(flags :standard -w +a-4-42-44-48-50-58-32-60-70@8 -safe-string -color
|
||||
always)
|
||||
(ocamlopt_flags :standard -O3 -color always -unbox-closures
|
||||
-unbox-closures-factor 20))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
(executable
|
||||
(name test_sexpr)
|
||||
(libraries iter)
|
||||
(flags :standard -w +a-4-42-44-48-50-58-32-60-70@8 -safe-string -color always)
|
||||
(flags :standard -w +a-4-42-44-48-50-58-32-60-70@8 -safe-string -color
|
||||
always)
|
||||
(ocamlopt_flags :standard -O3 -color always -unbox-closures
|
||||
-unbox-closures-factor 20))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
opam-version: "2.0"
|
||||
name: "iter"
|
||||
version: "1.8"
|
||||
version: "1.9"
|
||||
authors: ["Simon Cruanes" "Gabriel Radanne"]
|
||||
maintainer: "simon.cruanes.2007@m4x.org"
|
||||
license: "BSD-2-clause"
|
||||
|
|
|
|||
116
src/Iter.ml
116
src/Iter.ml
|
|
@ -189,63 +189,75 @@ let keep_error seq k =
|
|||
|
||||
(** Mutable unrolled list to serve as intermediate storage *)
|
||||
module MList = struct
|
||||
type 'a node = Nil | Cons of 'a array * int ref * 'a node ref
|
||||
type 'a node =
|
||||
| Nil
|
||||
| Cons of { a: 'a array; mutable n: int; mutable tl: 'a node }
|
||||
|
||||
(* build and call callback on every element *)
|
||||
let of_iter_with seq k =
|
||||
let start = ref Nil in
|
||||
let chunk_size = ref 8 in
|
||||
(* fill the list. prev: tail-reference from previous node *)
|
||||
let prev, cur = ref start, ref Nil in
|
||||
let acc = ref Nil in
|
||||
let cur = ref Nil in
|
||||
let tail = ref Nil in
|
||||
|
||||
let[@inline] replace_tail () =
|
||||
match !acc with
|
||||
| Nil -> acc := !cur
|
||||
| _ ->
|
||||
(match !tail with
|
||||
| Nil -> ()
|
||||
| Cons r -> r.tl <- !cur)
|
||||
in
|
||||
|
||||
seq (fun x ->
|
||||
k x;
|
||||
(* callback *)
|
||||
match !cur with
|
||||
| Nil ->
|
||||
let n = !chunk_size in
|
||||
if n < 4096 then chunk_size := 2 * !chunk_size;
|
||||
cur := Cons (Array.make n x, ref 1, ref Nil)
|
||||
| Cons (a, n, next) ->
|
||||
assert (!n < Array.length a);
|
||||
a.(!n) <- x;
|
||||
incr n;
|
||||
if !n = Array.length a then (
|
||||
!prev := !cur;
|
||||
prev := next;
|
||||
if n < 4096 then chunk_size := 2 * n;
|
||||
cur := Cons { a = Array.make n x; n = 1; tl = Nil }
|
||||
| Cons r ->
|
||||
assert (r.n < Array.length r.a);
|
||||
r.a.(r.n) <- x;
|
||||
r.n <- succ r.n;
|
||||
if r.n = Array.length r.a then (
|
||||
replace_tail ();
|
||||
tail := !cur;
|
||||
cur := Nil
|
||||
));
|
||||
!prev := !cur;
|
||||
!start
|
||||
replace_tail ();
|
||||
!acc
|
||||
|
||||
let of_iter seq = of_iter_with seq (fun _ -> ())
|
||||
|
||||
let rec iter f l =
|
||||
match l with
|
||||
| Nil -> ()
|
||||
| Cons (a, n, tl) ->
|
||||
for i = 0 to !n - 1 do
|
||||
| Cons { a; n; tl } ->
|
||||
for i = 0 to n - 1 do
|
||||
f a.(i)
|
||||
done;
|
||||
iter f !tl
|
||||
iter f tl
|
||||
|
||||
let iteri f l =
|
||||
let rec iteri i f l =
|
||||
match l with
|
||||
| Nil -> ()
|
||||
| Cons (a, n, tl) ->
|
||||
for j = 0 to !n - 1 do
|
||||
| Cons { a; n; tl } ->
|
||||
for j = 0 to n - 1 do
|
||||
f (i + j) a.(j)
|
||||
done;
|
||||
iteri (i + !n) f !tl
|
||||
iteri (i + n) f tl
|
||||
in
|
||||
iteri 0 f l
|
||||
|
||||
let rec iter_rev f l =
|
||||
match l with
|
||||
| Nil -> ()
|
||||
| Cons (a, n, tl) ->
|
||||
iter_rev f !tl;
|
||||
for i = !n - 1 downto 0 do
|
||||
| Cons { a; n; tl } ->
|
||||
iter_rev f tl;
|
||||
for i = n - 1 downto 0 do
|
||||
f a.(i)
|
||||
done
|
||||
|
||||
|
|
@ -253,7 +265,7 @@ module MList = struct
|
|||
let rec len acc l =
|
||||
match l with
|
||||
| Nil -> acc
|
||||
| Cons (_, n, tl) -> len (acc + !n) !tl
|
||||
| Cons { n; tl; _ } -> len (acc + n) tl
|
||||
in
|
||||
len 0 l
|
||||
|
||||
|
|
@ -261,8 +273,8 @@ module MList = struct
|
|||
let rec get l i =
|
||||
match l with
|
||||
| Nil -> raise (Invalid_argument "MList.get")
|
||||
| Cons (a, n, _) when i < !n -> a.(i)
|
||||
| Cons (_, n, tl) -> get !tl (i - !n)
|
||||
| Cons { a; n; _ } when i < n -> a.(i)
|
||||
| Cons { n; tl; _ } -> get tl (i - n)
|
||||
|
||||
let to_iter l k = iter k l
|
||||
|
||||
|
|
@ -273,11 +285,11 @@ module MList = struct
|
|||
let rec get_next _ =
|
||||
match !cur with
|
||||
| Nil -> None
|
||||
| Cons (_, n, tl) when !i = !n ->
|
||||
cur := !tl;
|
||||
| Cons { n; tl; _ } when !i = n ->
|
||||
cur := tl;
|
||||
i := 0;
|
||||
get_next arg
|
||||
| Cons (a, _, _) ->
|
||||
| Cons { a; _ } ->
|
||||
let x = a.(!i) in
|
||||
incr i;
|
||||
Some x
|
||||
|
|
@ -290,8 +302,8 @@ module MList = struct
|
|||
let rec make (l, i) () =
|
||||
match l with
|
||||
| Nil -> Seq.Nil
|
||||
| Cons (_, n, tl) when i = !n -> make (!tl, 0) ()
|
||||
| Cons (a, _, _) -> Seq.Cons (a.(i), make (l, i + 1))
|
||||
| Cons { n; tl; _ } when i = n -> make (tl, 0) ()
|
||||
| Cons { a; _ } -> Seq.Cons (a.(i), make (l, i + 1))
|
||||
in
|
||||
make (l, 0)
|
||||
end
|
||||
|
|
@ -318,9 +330,8 @@ let sort ?(cmp = Stdlib.compare) seq =
|
|||
let l = List.fast_sort cmp l in
|
||||
fun k -> List.iter k l
|
||||
|
||||
exception Exit_sorted
|
||||
|
||||
let sorted ?(cmp = Stdlib.compare) seq =
|
||||
let exception Exit_sorted in
|
||||
let prev = ref None in
|
||||
try
|
||||
seq (fun x ->
|
||||
|
|
@ -544,9 +555,8 @@ let diff (type a) ?(eq = ( = )) ?(hash = Hashtbl.hash) c1 c2 =
|
|||
c2 (fun x -> Tbl.replace tbl x ());
|
||||
fun yield -> c1 (fun x -> if not (Tbl.mem tbl x) then yield x)
|
||||
|
||||
exception Subset_exit
|
||||
|
||||
let subset (type a) ?(eq = ( = )) ?(hash = Hashtbl.hash) c1 c2 =
|
||||
let exception Subset_exit in
|
||||
let module Tbl = Hashtbl.Make (struct
|
||||
type t = a
|
||||
|
||||
|
|
@ -618,9 +628,8 @@ let sumf seq : float =
|
|||
sum := t);
|
||||
!sum
|
||||
|
||||
exception ExitHead
|
||||
|
||||
let head seq =
|
||||
let exception ExitHead in
|
||||
let r = ref None in
|
||||
try
|
||||
seq (fun x ->
|
||||
|
|
@ -634,9 +643,8 @@ let head_exn seq =
|
|||
| None -> invalid_arg "Iter.head_exn"
|
||||
| Some x -> x
|
||||
|
||||
exception ExitTake
|
||||
|
||||
let take n seq k =
|
||||
let exception ExitTake in
|
||||
let count = ref 0 in
|
||||
try
|
||||
seq (fun x ->
|
||||
|
|
@ -645,9 +653,8 @@ let take n seq k =
|
|||
k x)
|
||||
with ExitTake -> ()
|
||||
|
||||
exception ExitTakeWhile
|
||||
|
||||
let take_while p seq k =
|
||||
let exception ExitTakeWhile in
|
||||
try
|
||||
seq (fun x ->
|
||||
if p x then
|
||||
|
|
@ -656,19 +663,20 @@ let take_while p seq k =
|
|||
raise_notrace ExitTakeWhile)
|
||||
with ExitTakeWhile -> ()
|
||||
|
||||
exception ExitFoldWhile
|
||||
|
||||
let map_while f seq k =
|
||||
let exception ExitMapWhile in
|
||||
let consume x =
|
||||
match f x with
|
||||
| `Yield y -> k y
|
||||
| `Return y -> k y; raise_notrace ExitMapWhile
|
||||
| `Return y ->
|
||||
k y;
|
||||
raise_notrace ExitMapWhile
|
||||
| `Stop -> raise_notrace ExitMapWhile
|
||||
in
|
||||
try seq consume with ExitMapWhile -> ()
|
||||
|
||||
let fold_while f s seq =
|
||||
let exception ExitFoldWhile in
|
||||
let state = ref s in
|
||||
let consume x =
|
||||
let acc, cont = f !state x in
|
||||
|
|
@ -707,18 +715,16 @@ let rev seq =
|
|||
let l = MList.of_iter seq in
|
||||
fun k -> MList.iter_rev k l
|
||||
|
||||
exception ExitForall
|
||||
|
||||
let for_all p seq =
|
||||
let exception ExitForall in
|
||||
try
|
||||
seq (fun x -> if not (p x) then raise_notrace ExitForall);
|
||||
true
|
||||
with ExitForall -> false
|
||||
|
||||
exception ExitExists
|
||||
|
||||
(** Exists there some element satisfying the predicate? *)
|
||||
let exists p seq =
|
||||
let exception ExitExists in
|
||||
try
|
||||
seq (fun x -> if p x then raise_notrace ExitExists);
|
||||
false
|
||||
|
|
@ -726,9 +732,8 @@ let exists p seq =
|
|||
|
||||
let mem ?(eq = ( = )) x seq = exists (eq x) seq
|
||||
|
||||
exception ExitFind
|
||||
|
||||
let find_map f seq =
|
||||
let exception ExitFind in
|
||||
let r = ref None in
|
||||
(try
|
||||
seq (fun x ->
|
||||
|
|
@ -743,6 +748,7 @@ let find_map f seq =
|
|||
let find = find_map
|
||||
|
||||
let find_mapi f seq =
|
||||
let exception ExitFind in
|
||||
let i = ref 0 in
|
||||
let r = ref None in
|
||||
(try
|
||||
|
|
@ -776,9 +782,8 @@ let[@inline] length seq =
|
|||
seq (fun _ -> incr r);
|
||||
!r
|
||||
|
||||
exception ExitIsEmpty
|
||||
|
||||
let is_empty seq =
|
||||
let exception ExitIsEmpty in
|
||||
try
|
||||
seq (fun _ -> raise_notrace ExitIsEmpty);
|
||||
true
|
||||
|
|
@ -1026,9 +1031,14 @@ module Map = struct
|
|||
let of_iter_ seq = fold (fun m (k, v) -> M.add k v m) M.empty seq
|
||||
let keys m = from_iter (fun k -> M.iter (fun x _ -> k x) m)
|
||||
let values m = from_iter (fun k -> M.iter (fun _ y -> k y) m)
|
||||
|
||||
[@@@ocaml.warning "-32"]
|
||||
|
||||
let of_list l = of_iter_ (of_list l)
|
||||
let to_list x = to_list (to_iter_ x)
|
||||
|
||||
[@@@ocaml.warning "+32"]
|
||||
|
||||
include M
|
||||
|
||||
let to_iter = to_iter_
|
||||
|
|
|
|||
|
|
@ -22,4 +22,4 @@ let mmap filename yield =
|
|||
with e ->
|
||||
Unix.close fd;
|
||||
raise e
|
||||
[@@ocaml.warning "-3"]
|
||||
[@@ocaml.warning "-3"]
|
||||
|
|
|
|||
3
src/dune
3
src/dune
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
(library
|
||||
(name iter)
|
||||
(public_name iter)
|
||||
(wrapped false)
|
||||
(modules Iter IterLabels)
|
||||
(flags :standard -w +a -warn-error -a+8 -nolabels))
|
||||
(flags :standard -w +a-4 -warn-error -a+8 -nolabels))
|
||||
|
||||
(env
|
||||
(_
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
(tests
|
||||
(names t_iter)
|
||||
(libraries iter qcheck-core qcheck-core.runner ounit2))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue