mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-08 04:05:30 -05:00
Merge branch 'master' into stable for 0.18
This commit is contained in:
commit
ed2b741865
27 changed files with 490 additions and 61 deletions
|
|
@ -1,8 +1,19 @@
|
||||||
= Changelog
|
= Changelog
|
||||||
|
|
||||||
|
== 0.18
|
||||||
|
|
||||||
|
- update implem of `CCVector.equal`
|
||||||
|
- add `CCOpt.get_or` with label, deprecates `get`
|
||||||
|
- add `CCArray.get_safe` (close #70)
|
||||||
|
- add `CCGraph.is_dag`
|
||||||
|
- add aliases to deprecated functions from `String`, add `Fun.opaque_identity`
|
||||||
|
- add `CCLazy_list.take`
|
||||||
|
- add `Lazy_list.filter`
|
||||||
|
- add CCList.range_by
|
||||||
|
|
||||||
== 0.17
|
== 0.17
|
||||||
|
|
||||||
=== potentially breaking
|
=== potentially breaking
|
||||||
|
|
||||||
- change the semantics of `CCString.find_all` (allow overlaps)
|
- change the semantics of `CCString.find_all` (allow overlaps)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ can be removed.
|
||||||
8. `git merge master`
|
8. `git merge master`
|
||||||
9. `oasis setup; make test doc`
|
9. `oasis setup; make test doc`
|
||||||
10. tag, and push both to github
|
10. tag, and push both to github
|
||||||
11. new opam package
|
11. `opam pin https://github.com/c-cube/ocaml-containers#<release>`
|
||||||
|
12. new opam package: `opam publish prepare; opam publish submit`
|
||||||
|
|
||||||
== List Authors
|
== List Authors
|
||||||
|
|
||||||
|
|
|
||||||
10
README.adoc
10
README.adoc
|
|
@ -2,10 +2,11 @@
|
||||||
:toc: macro
|
:toc: macro
|
||||||
:source-highlighter: pygments
|
:source-highlighter: pygments
|
||||||
|
|
||||||
image::media/logo.png[logo]
|
|
||||||
|
|
||||||
What is _containers_? (take a look at the link:TUTORIAL.adoc[tutorial]!
|
What is _containers_? (take a look at the link:TUTORIAL.adoc[tutorial]!
|
||||||
or the http://cedeela.fr/~simon/software/containers[documentation])
|
or the http://cedeela.fr/~simon/software/containers[documentation])
|
||||||
|
In `containers` and `containers.data`, all modules abide by
|
||||||
|
_pay for what you use_: only modules that are used are linked (there are no
|
||||||
|
cross-module dependencies).
|
||||||
|
|
||||||
- A usable, reasonably well-designed library that extends OCaml's standard
|
- A usable, reasonably well-designed library that extends OCaml's standard
|
||||||
library (in 'src/core/', packaged under `containers` in ocamlfind. Modules
|
library (in 'src/core/', packaged under `containers` in ocamlfind. Modules
|
||||||
|
|
@ -42,6 +43,8 @@ image:https://ci.cedeela.fr/buildStatus/icon?job=containers[alt="Build Status",
|
||||||
|
|
||||||
toc::[]
|
toc::[]
|
||||||
|
|
||||||
|
image::media/logo.png[logo]
|
||||||
|
|
||||||
== Change Log
|
== Change Log
|
||||||
|
|
||||||
See link:CHANGELOG.adoc[this file].
|
See link:CHANGELOG.adoc[this file].
|
||||||
|
|
@ -268,3 +271,6 @@ A few guidelines:
|
||||||
|
|
||||||
Powered by image:http://oasis.forge.ocamlcore.org/oasis-badge.png[alt="OASIS", style="border: none;", link="http://oasis.forge.ocamlcore.org/"]
|
Powered by image:http://oasis.forge.ocamlcore.org/oasis-badge.png[alt="OASIS", style="border: none;", link="http://oasis.forge.ocamlcore.org/"]
|
||||||
|
|
||||||
|
== Documentation by version
|
||||||
|
|
||||||
|
- http://c-cube.github.io/ocaml-containers/0.17/[0.17]
|
||||||
|
|
|
||||||
4
_oasis
4
_oasis
|
|
@ -1,6 +1,6 @@
|
||||||
OASISFormat: 0.4
|
OASISFormat: 0.4
|
||||||
Name: containers
|
Name: containers
|
||||||
Version: 0.17
|
Version: 0.18
|
||||||
Homepage: https://github.com/c-cube/ocaml-containers
|
Homepage: https://github.com/c-cube/ocaml-containers
|
||||||
Authors: Simon Cruanes
|
Authors: Simon Cruanes
|
||||||
License: BSD-2-clause
|
License: BSD-2-clause
|
||||||
|
|
@ -40,7 +40,7 @@ Flag "bigarray"
|
||||||
Default: true
|
Default: true
|
||||||
|
|
||||||
Flag "advanced"
|
Flag "advanced"
|
||||||
Description: Build advanced combinators, including CCLinq (requires "sequence")
|
Description: Build advanced combinators (requires "sequence")
|
||||||
Default: true
|
Default: true
|
||||||
|
|
||||||
Library "containers"
|
Library "containers"
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ by ocamlfind).
|
||||||
|
|
||||||
{4 Core Modules (extension of the standard library)}
|
{4 Core Modules (extension of the standard library)}
|
||||||
|
|
||||||
|
{b findlib name}: containers
|
||||||
|
|
||||||
{!modules:
|
{!modules:
|
||||||
CCArray
|
CCArray
|
||||||
CCBool
|
CCBool
|
||||||
|
|
@ -63,6 +65,8 @@ such as:
|
||||||
|
|
||||||
{4 Containers.data}
|
{4 Containers.data}
|
||||||
|
|
||||||
|
{b findlib name}: containers.data
|
||||||
|
|
||||||
Various data structures.
|
Various data structures.
|
||||||
|
|
||||||
{!modules:
|
{!modules:
|
||||||
|
|
@ -123,6 +127,8 @@ CCLazy_list}
|
||||||
|
|
||||||
{4 String}
|
{4 String}
|
||||||
|
|
||||||
|
{b findlib name}: containers.string
|
||||||
|
|
||||||
{!modules:
|
{!modules:
|
||||||
CCApp_parse
|
CCApp_parse
|
||||||
CCKMP
|
CCKMP
|
||||||
|
|
@ -139,6 +145,8 @@ Use bigarrays to hold large strings and map files directly into memory.
|
||||||
|
|
||||||
{4 Advanced}
|
{4 Advanced}
|
||||||
|
|
||||||
|
{b findlib name}: containers.advanced
|
||||||
|
|
||||||
This module is qualified with [Containers_advanced]. It
|
This module is qualified with [Containers_advanced]. It
|
||||||
requires {{:https://github.com/c-cube/sequence} Sequence}.
|
requires {{:https://github.com/c-cube/sequence} Sequence}.
|
||||||
|
|
||||||
|
|
@ -152,7 +160,11 @@ Moved to its own repository.
|
||||||
|
|
||||||
Moved to its own repository
|
Moved to its own repository
|
||||||
|
|
||||||
{4 Others}
|
{4 Thread Helpers}
|
||||||
|
|
||||||
|
{b findlib name}: containers.thread
|
||||||
|
|
||||||
|
Modules related to the use of [Thread].
|
||||||
|
|
||||||
{!modules:
|
{!modules:
|
||||||
CCBlockingQueue
|
CCBlockingQueue
|
||||||
|
|
|
||||||
174
myocamlbuild.ml
174
myocamlbuild.ml
|
|
@ -1,5 +1,5 @@
|
||||||
(* OASIS_START *)
|
(* OASIS_START *)
|
||||||
(* DO NOT EDIT (digest: b119194f5742ac2f3cdceac9a223dda7) *)
|
(* DO NOT EDIT (digest: 9ba607f1a3e839f1c1e8ea449ddfab16) *)
|
||||||
module OASISGettext = struct
|
module OASISGettext = struct
|
||||||
(* # 22 "src/oasis/OASISGettext.ml" *)
|
(* # 22 "src/oasis/OASISGettext.ml" *)
|
||||||
|
|
||||||
|
|
@ -29,6 +29,166 @@ module OASISGettext = struct
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module OASISString = struct
|
||||||
|
(* # 22 "src/oasis/OASISString.ml" *)
|
||||||
|
|
||||||
|
|
||||||
|
(** Various string utilities.
|
||||||
|
|
||||||
|
Mostly inspired by extlib and batteries ExtString and BatString libraries.
|
||||||
|
|
||||||
|
@author Sylvain Le Gall
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
||||||
|
let nsplitf str f =
|
||||||
|
if str = "" then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
let buf = Buffer.create 13 in
|
||||||
|
let lst = ref [] in
|
||||||
|
let push () =
|
||||||
|
lst := Buffer.contents buf :: !lst;
|
||||||
|
Buffer.clear buf
|
||||||
|
in
|
||||||
|
let str_len = String.length str in
|
||||||
|
for i = 0 to str_len - 1 do
|
||||||
|
if f str.[i] then
|
||||||
|
push ()
|
||||||
|
else
|
||||||
|
Buffer.add_char buf str.[i]
|
||||||
|
done;
|
||||||
|
push ();
|
||||||
|
List.rev !lst
|
||||||
|
|
||||||
|
|
||||||
|
(** [nsplit c s] Split the string [s] at char [c]. It doesn't include the
|
||||||
|
separator.
|
||||||
|
*)
|
||||||
|
let nsplit str c =
|
||||||
|
nsplitf str ((=) c)
|
||||||
|
|
||||||
|
|
||||||
|
let find ~what ?(offset=0) str =
|
||||||
|
let what_idx = ref 0 in
|
||||||
|
let str_idx = ref offset in
|
||||||
|
while !str_idx < String.length str &&
|
||||||
|
!what_idx < String.length what do
|
||||||
|
if str.[!str_idx] = what.[!what_idx] then
|
||||||
|
incr what_idx
|
||||||
|
else
|
||||||
|
what_idx := 0;
|
||||||
|
incr str_idx
|
||||||
|
done;
|
||||||
|
if !what_idx <> String.length what then
|
||||||
|
raise Not_found
|
||||||
|
else
|
||||||
|
!str_idx - !what_idx
|
||||||
|
|
||||||
|
|
||||||
|
let sub_start str len =
|
||||||
|
let str_len = String.length str in
|
||||||
|
if len >= str_len then
|
||||||
|
""
|
||||||
|
else
|
||||||
|
String.sub str len (str_len - len)
|
||||||
|
|
||||||
|
|
||||||
|
let sub_end ?(offset=0) str len =
|
||||||
|
let str_len = String.length str in
|
||||||
|
if len >= str_len then
|
||||||
|
""
|
||||||
|
else
|
||||||
|
String.sub str 0 (str_len - len)
|
||||||
|
|
||||||
|
|
||||||
|
let starts_with ~what ?(offset=0) str =
|
||||||
|
let what_idx = ref 0 in
|
||||||
|
let str_idx = ref offset in
|
||||||
|
let ok = ref true in
|
||||||
|
while !ok &&
|
||||||
|
!str_idx < String.length str &&
|
||||||
|
!what_idx < String.length what do
|
||||||
|
if str.[!str_idx] = what.[!what_idx] then
|
||||||
|
incr what_idx
|
||||||
|
else
|
||||||
|
ok := false;
|
||||||
|
incr str_idx
|
||||||
|
done;
|
||||||
|
if !what_idx = String.length what then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
|
||||||
|
|
||||||
|
let strip_starts_with ~what str =
|
||||||
|
if starts_with ~what str then
|
||||||
|
sub_start str (String.length what)
|
||||||
|
else
|
||||||
|
raise Not_found
|
||||||
|
|
||||||
|
|
||||||
|
let ends_with ~what ?(offset=0) str =
|
||||||
|
let what_idx = ref ((String.length what) - 1) in
|
||||||
|
let str_idx = ref ((String.length str) - 1) in
|
||||||
|
let ok = ref true in
|
||||||
|
while !ok &&
|
||||||
|
offset <= !str_idx &&
|
||||||
|
0 <= !what_idx do
|
||||||
|
if str.[!str_idx] = what.[!what_idx] then
|
||||||
|
decr what_idx
|
||||||
|
else
|
||||||
|
ok := false;
|
||||||
|
decr str_idx
|
||||||
|
done;
|
||||||
|
if !what_idx = -1 then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
|
||||||
|
|
||||||
|
let strip_ends_with ~what str =
|
||||||
|
if ends_with ~what str then
|
||||||
|
sub_end str (String.length what)
|
||||||
|
else
|
||||||
|
raise Not_found
|
||||||
|
|
||||||
|
|
||||||
|
let replace_chars f s =
|
||||||
|
let buf = Buffer.create (String.length s) in
|
||||||
|
String.iter (fun c -> Buffer.add_char buf (f c)) s;
|
||||||
|
Buffer.contents buf
|
||||||
|
|
||||||
|
let lowercase_ascii =
|
||||||
|
replace_chars
|
||||||
|
(fun c ->
|
||||||
|
if (c >= 'A' && c <= 'Z') then
|
||||||
|
Char.chr (Char.code c + 32)
|
||||||
|
else
|
||||||
|
c)
|
||||||
|
|
||||||
|
let uncapitalize_ascii s =
|
||||||
|
if s <> "" then
|
||||||
|
(lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
|
||||||
|
else
|
||||||
|
s
|
||||||
|
|
||||||
|
let uppercase_ascii =
|
||||||
|
replace_chars
|
||||||
|
(fun c ->
|
||||||
|
if (c >= 'a' && c <= 'z') then
|
||||||
|
Char.chr (Char.code c - 32)
|
||||||
|
else
|
||||||
|
c)
|
||||||
|
|
||||||
|
let capitalize_ascii s =
|
||||||
|
if s <> "" then
|
||||||
|
(uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
|
||||||
|
else
|
||||||
|
s
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
module OASISExpr = struct
|
module OASISExpr = struct
|
||||||
(* # 22 "src/oasis/OASISExpr.ml" *)
|
(* # 22 "src/oasis/OASISExpr.ml" *)
|
||||||
|
|
||||||
|
|
@ -129,7 +289,7 @@ module OASISExpr = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 132 "myocamlbuild.ml"
|
# 292 "myocamlbuild.ml"
|
||||||
module BaseEnvLight = struct
|
module BaseEnvLight = struct
|
||||||
(* # 22 "src/base/BaseEnvLight.ml" *)
|
(* # 22 "src/base/BaseEnvLight.ml" *)
|
||||||
|
|
||||||
|
|
@ -234,7 +394,7 @@ module BaseEnvLight = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 237 "myocamlbuild.ml"
|
# 397 "myocamlbuild.ml"
|
||||||
module MyOCamlbuildFindlib = struct
|
module MyOCamlbuildFindlib = struct
|
||||||
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
|
(* # 22 "src/plugins/ocamlbuild/MyOCamlbuildFindlib.ml" *)
|
||||||
|
|
||||||
|
|
@ -516,7 +676,7 @@ module MyOCamlbuildBase = struct
|
||||||
| nm, [], intf_modules ->
|
| nm, [], intf_modules ->
|
||||||
ocaml_lib nm;
|
ocaml_lib nm;
|
||||||
let cmis =
|
let cmis =
|
||||||
List.map (fun m -> (String.uncapitalize m) ^ ".cmi")
|
List.map (fun m -> (OASISString.uncapitalize_ascii m) ^ ".cmi")
|
||||||
intf_modules in
|
intf_modules in
|
||||||
dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
|
dep ["ocaml"; "link"; "library"; "file:"^nm^".cma"] cmis
|
||||||
| nm, dir :: tl, intf_modules ->
|
| nm, dir :: tl, intf_modules ->
|
||||||
|
|
@ -529,7 +689,7 @@ module MyOCamlbuildBase = struct
|
||||||
["compile"; "infer_interface"; "doc"])
|
["compile"; "infer_interface"; "doc"])
|
||||||
tl;
|
tl;
|
||||||
let cmis =
|
let cmis =
|
||||||
List.map (fun m -> dir^"/"^(String.uncapitalize m)^".cmi")
|
List.map (fun m -> dir^"/"^(OASISString.uncapitalize_ascii m)^".cmi")
|
||||||
intf_modules in
|
intf_modules in
|
||||||
dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
|
dep ["ocaml"; "link"; "library"; "file:"^dir^"/"^nm^".cma"]
|
||||||
cmis)
|
cmis)
|
||||||
|
|
@ -603,7 +763,7 @@ module MyOCamlbuildBase = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 606 "myocamlbuild.ml"
|
# 766 "myocamlbuild.ml"
|
||||||
open Ocamlbuild_plugin;;
|
open Ocamlbuild_plugin;;
|
||||||
let package_default =
|
let package_default =
|
||||||
{
|
{
|
||||||
|
|
@ -669,7 +829,7 @@ let conf = {MyOCamlbuildFindlib.no_automatic_syntax = false}
|
||||||
|
|
||||||
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
|
let dispatch_default = MyOCamlbuildBase.dispatch_default conf package_default;;
|
||||||
|
|
||||||
# 673 "myocamlbuild.ml"
|
# 833 "myocamlbuild.ml"
|
||||||
(* OASIS_STOP *)
|
(* OASIS_STOP *)
|
||||||
let doc_intro = "doc/intro.txt" ;;
|
let doc_intro = "doc/intro.txt" ;;
|
||||||
|
|
||||||
|
|
|
||||||
1
opam
1
opam
|
|
@ -26,6 +26,7 @@ remove: [
|
||||||
]
|
]
|
||||||
depends: [
|
depends: [
|
||||||
"ocamlfind" {build}
|
"ocamlfind" {build}
|
||||||
|
"oasis" {build}
|
||||||
"base-bytes"
|
"base-bytes"
|
||||||
"result"
|
"result"
|
||||||
"cppo" {build}
|
"cppo" {build}
|
||||||
|
|
|
||||||
76
setup.ml
76
setup.ml
|
|
@ -1,9 +1,9 @@
|
||||||
(* setup.ml generated for the first time by OASIS v0.4.4 *)
|
(* setup.ml generated for the first time by OASIS v0.4.4 *)
|
||||||
|
|
||||||
(* OASIS_START *)
|
(* OASIS_START *)
|
||||||
(* DO NOT EDIT (digest: 93504d34b391fe80e66c77fd2e99f4e0) *)
|
(* DO NOT EDIT (digest: 935c9eb827a9a1a9b4de988f1afb58dd) *)
|
||||||
(*
|
(*
|
||||||
Regenerated by OASIS v0.4.5
|
Regenerated by OASIS v0.4.6
|
||||||
Visit http://oasis.forge.ocamlcore.org for more information and
|
Visit http://oasis.forge.ocamlcore.org for more information and
|
||||||
documentation about functions used in this file.
|
documentation about functions used in this file.
|
||||||
*)
|
*)
|
||||||
|
|
@ -246,6 +246,33 @@ module OASISString = struct
|
||||||
String.iter (fun c -> Buffer.add_char buf (f c)) s;
|
String.iter (fun c -> Buffer.add_char buf (f c)) s;
|
||||||
Buffer.contents buf
|
Buffer.contents buf
|
||||||
|
|
||||||
|
let lowercase_ascii =
|
||||||
|
replace_chars
|
||||||
|
(fun c ->
|
||||||
|
if (c >= 'A' && c <= 'Z') then
|
||||||
|
Char.chr (Char.code c + 32)
|
||||||
|
else
|
||||||
|
c)
|
||||||
|
|
||||||
|
let uncapitalize_ascii s =
|
||||||
|
if s <> "" then
|
||||||
|
(lowercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
|
||||||
|
else
|
||||||
|
s
|
||||||
|
|
||||||
|
let uppercase_ascii =
|
||||||
|
replace_chars
|
||||||
|
(fun c ->
|
||||||
|
if (c >= 'a' && c <= 'z') then
|
||||||
|
Char.chr (Char.code c - 32)
|
||||||
|
else
|
||||||
|
c)
|
||||||
|
|
||||||
|
let capitalize_ascii s =
|
||||||
|
if s <> "" then
|
||||||
|
(uppercase_ascii (String.sub s 0 1)) ^ (String.sub s 1 ((String.length s) - 1))
|
||||||
|
else
|
||||||
|
s
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -315,19 +342,15 @@ module OASISUtils = struct
|
||||||
|
|
||||||
|
|
||||||
let compare_csl s1 s2 =
|
let compare_csl s1 s2 =
|
||||||
String.compare (String.lowercase s1) (String.lowercase s2)
|
String.compare (OASISString.lowercase_ascii s1) (OASISString.lowercase_ascii s2)
|
||||||
|
|
||||||
|
|
||||||
module HashStringCsl =
|
module HashStringCsl =
|
||||||
Hashtbl.Make
|
Hashtbl.Make
|
||||||
(struct
|
(struct
|
||||||
type t = string
|
type t = string
|
||||||
|
let equal s1 s2 = (compare_csl s1 s2) = 0
|
||||||
let equal s1 s2 =
|
let hash s = Hashtbl.hash (OASISString.lowercase_ascii s)
|
||||||
(String.lowercase s1) = (String.lowercase s2)
|
|
||||||
|
|
||||||
let hash s =
|
|
||||||
Hashtbl.hash (String.lowercase s)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
module SetStringCsl =
|
module SetStringCsl =
|
||||||
|
|
@ -365,7 +388,7 @@ module OASISUtils = struct
|
||||||
else
|
else
|
||||||
buf
|
buf
|
||||||
in
|
in
|
||||||
String.lowercase buf
|
OASISString.lowercase_ascii buf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -471,7 +494,7 @@ module PropList = struct
|
||||||
order = Queue.create ();
|
order = Queue.create ();
|
||||||
name_norm =
|
name_norm =
|
||||||
(if case_insensitive then
|
(if case_insensitive then
|
||||||
String.lowercase
|
OASISString.lowercase_ascii
|
||||||
else
|
else
|
||||||
fun s -> s);
|
fun s -> s);
|
||||||
}
|
}
|
||||||
|
|
@ -1822,13 +1845,13 @@ module OASISUnixPath = struct
|
||||||
let capitalize_file f =
|
let capitalize_file f =
|
||||||
let dir = dirname f in
|
let dir = dirname f in
|
||||||
let base = basename f in
|
let base = basename f in
|
||||||
concat dir (String.capitalize base)
|
concat dir (OASISString.capitalize_ascii base)
|
||||||
|
|
||||||
|
|
||||||
let uncapitalize_file f =
|
let uncapitalize_file f =
|
||||||
let dir = dirname f in
|
let dir = dirname f in
|
||||||
let base = basename f in
|
let base = basename f in
|
||||||
concat dir (String.uncapitalize base)
|
concat dir (OASISString.uncapitalize_ascii base)
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -2890,7 +2913,7 @@ module OASISFileUtil = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 2893 "setup.ml"
|
# 2916 "setup.ml"
|
||||||
module BaseEnvLight = struct
|
module BaseEnvLight = struct
|
||||||
(* # 22 "src/base/BaseEnvLight.ml" *)
|
(* # 22 "src/base/BaseEnvLight.ml" *)
|
||||||
|
|
||||||
|
|
@ -2995,7 +3018,7 @@ module BaseEnvLight = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 2998 "setup.ml"
|
# 3021 "setup.ml"
|
||||||
module BaseContext = struct
|
module BaseContext = struct
|
||||||
(* # 22 "src/base/BaseContext.ml" *)
|
(* # 22 "src/base/BaseContext.ml" *)
|
||||||
|
|
||||||
|
|
@ -5406,7 +5429,7 @@ module BaseSetup = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 5409 "setup.ml"
|
# 5432 "setup.ml"
|
||||||
module InternalConfigurePlugin = struct
|
module InternalConfigurePlugin = struct
|
||||||
(* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
|
(* # 22 "src/plugins/internal/InternalConfigurePlugin.ml" *)
|
||||||
|
|
||||||
|
|
@ -5845,8 +5868,8 @@ module InternalInstallPlugin = struct
|
||||||
let make_fnames modul sufx =
|
let make_fnames modul sufx =
|
||||||
List.fold_right
|
List.fold_right
|
||||||
begin fun sufx accu ->
|
begin fun sufx accu ->
|
||||||
(String.capitalize modul ^ sufx) ::
|
(OASISString.capitalize_ascii modul ^ sufx) ::
|
||||||
(String.uncapitalize modul ^ sufx) ::
|
(OASISString.uncapitalize_ascii modul ^ sufx) ::
|
||||||
accu
|
accu
|
||||||
end
|
end
|
||||||
sufx
|
sufx
|
||||||
|
|
@ -6270,7 +6293,7 @@ module InternalInstallPlugin = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 6273 "setup.ml"
|
# 6296 "setup.ml"
|
||||||
module OCamlbuildCommon = struct
|
module OCamlbuildCommon = struct
|
||||||
(* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
|
(* # 22 "src/plugins/ocamlbuild/OCamlbuildCommon.ml" *)
|
||||||
|
|
||||||
|
|
@ -6648,7 +6671,7 @@ module OCamlbuildDocPlugin = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 6651 "setup.ml"
|
# 6674 "setup.ml"
|
||||||
module CustomPlugin = struct
|
module CustomPlugin = struct
|
||||||
(* # 22 "src/plugins/custom/CustomPlugin.ml" *)
|
(* # 22 "src/plugins/custom/CustomPlugin.ml" *)
|
||||||
|
|
||||||
|
|
@ -6796,7 +6819,7 @@ module CustomPlugin = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 6799 "setup.ml"
|
# 6822 "setup.ml"
|
||||||
open OASISTypes;;
|
open OASISTypes;;
|
||||||
|
|
||||||
let setup_t =
|
let setup_t =
|
||||||
|
|
@ -6875,7 +6898,7 @@ let setup_t =
|
||||||
alpha_features = ["ocamlbuild_more_args"];
|
alpha_features = ["ocamlbuild_more_args"];
|
||||||
beta_features = [];
|
beta_features = [];
|
||||||
name = "containers";
|
name = "containers";
|
||||||
version = "0.17";
|
version = "0.18";
|
||||||
license =
|
license =
|
||||||
OASISLicense.DEP5License
|
OASISLicense.DEP5License
|
||||||
(OASISLicense.DEP5Unit
|
(OASISLicense.DEP5Unit
|
||||||
|
|
@ -6987,7 +7010,7 @@ let setup_t =
|
||||||
{
|
{
|
||||||
flag_description =
|
flag_description =
|
||||||
Some
|
Some
|
||||||
"Build advanced combinators, including CCLinq (requires \"sequence\")";
|
"Build advanced combinators (requires \"sequence\")";
|
||||||
flag_default = [(OASISExpr.EBool true, true)]
|
flag_default = [(OASISExpr.EBool true, true)]
|
||||||
});
|
});
|
||||||
Library
|
Library
|
||||||
|
|
@ -7721,8 +7744,9 @@ let setup_t =
|
||||||
plugin_data = []
|
plugin_data = []
|
||||||
};
|
};
|
||||||
oasis_fn = Some "_oasis";
|
oasis_fn = Some "_oasis";
|
||||||
oasis_version = "0.4.5";
|
oasis_version = "0.4.6";
|
||||||
oasis_digest = Some "\168\138o\130\169\030i2!\170\1730n\148\174\208";
|
oasis_digest =
|
||||||
|
Some "\006\139\194\135\189\021\197\018\208\031.\187\212'\016\192";
|
||||||
oasis_exec = None;
|
oasis_exec = None;
|
||||||
oasis_setup_args = [];
|
oasis_setup_args = [];
|
||||||
setup_update = false
|
setup_update = false
|
||||||
|
|
@ -7730,6 +7754,6 @@ let setup_t =
|
||||||
|
|
||||||
let setup () = BaseSetup.setup setup_t;;
|
let setup () = BaseSetup.setup setup_t;;
|
||||||
|
|
||||||
# 7734 "setup.ml"
|
# 7758 "setup.ml"
|
||||||
(* OASIS_STOP *)
|
(* OASIS_STOP *)
|
||||||
let () = setup ();;
|
let () = setup ();;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ Functions and operations are assumed to be referentially transparent, i.e.
|
||||||
they should not rely on external side effects, they should not rely on
|
they should not rely on external side effects, they should not rely on
|
||||||
the order of execution.
|
the order of execution.
|
||||||
|
|
||||||
@deprecated use {{: https://github.com/c-cube/olinq} OLinq} (once released)
|
@deprecated use {{: https://github.com/c-cube/olinq} OLinq}
|
||||||
|
|
||||||
{[
|
{[
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ module type S = sig
|
||||||
|
|
||||||
val get : 'a t -> int -> 'a
|
val get : 'a t -> int -> 'a
|
||||||
|
|
||||||
|
val get_safe : 'a t -> int -> 'a option
|
||||||
|
(** [get_safe a i] returns [Some a.(i)] if [i] is a valid index
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
val set : 'a t -> int -> 'a -> unit
|
val set : 'a t -> int -> 'a -> unit
|
||||||
|
|
||||||
val length : _ t -> int
|
val length : _ t -> int
|
||||||
|
|
@ -291,6 +295,21 @@ let length = Array.length
|
||||||
|
|
||||||
let get = Array.get
|
let get = Array.get
|
||||||
|
|
||||||
|
let get_safe a i =
|
||||||
|
if i>=0 && i<Array.length a
|
||||||
|
then Some (Array.unsafe_get a i)
|
||||||
|
else None
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
(Some 1) (get_safe [|1;2;3|] 0)
|
||||||
|
(Some 2) (get_safe [|1;2;3|] 1)
|
||||||
|
(Some 3) (get_safe [|1;2;3|] 2)
|
||||||
|
None (get_safe [|1;2;3|] 4)
|
||||||
|
None (get_safe [|1;2;3|] max_int)
|
||||||
|
None (get_safe [|1;2;3|] ~-1)
|
||||||
|
None (get_safe [|1;2;3|] ~-42)
|
||||||
|
*)
|
||||||
|
|
||||||
let set = Array.set
|
let set = Array.set
|
||||||
|
|
||||||
let fold = Array.fold_left
|
let fold = Array.fold_left
|
||||||
|
|
@ -568,6 +587,24 @@ module Sub = struct
|
||||||
if i<0 || j>=a.j then invalid_arg "Array.Sub.get";
|
if i<0 || j>=a.j then invalid_arg "Array.Sub.get";
|
||||||
a.arr.(j)
|
a.arr.(j)
|
||||||
|
|
||||||
|
let get_safe a i =
|
||||||
|
try Some (get a i)
|
||||||
|
with Invalid_argument _ -> None
|
||||||
|
|
||||||
|
(*$inject
|
||||||
|
let sub_a = Sub.make [|1;2;3;4;5|] 1 ~len:3
|
||||||
|
*)
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
(Some 2) (Sub.get_safe sub_a 0)
|
||||||
|
(Some 3) (Sub.get_safe sub_a 1)
|
||||||
|
(Some 4) (Sub.get_safe sub_a 2)
|
||||||
|
None (Sub.get_safe sub_a 4)
|
||||||
|
None (Sub.get_safe sub_a max_int)
|
||||||
|
None (Sub.get_safe sub_a ~-1)
|
||||||
|
None (Sub.get_safe sub_a ~-42)
|
||||||
|
*)
|
||||||
|
|
||||||
let set a i x =
|
let set a i x =
|
||||||
let j = a.i + i in
|
let j = a.i + i in
|
||||||
if i<0 || j>=a.j then invalid_arg "Array.Sub.set";
|
if i<0 || j>=a.j then invalid_arg "Array.Sub.set";
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ module type S = sig
|
||||||
|
|
||||||
val get : 'a t -> int -> 'a
|
val get : 'a t -> int -> 'a
|
||||||
|
|
||||||
|
val get_safe : 'a t -> int -> 'a option
|
||||||
|
(** [get_safe a i] returns [Some a.(i)] if [i] is a valid index
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
val set : 'a t -> int -> 'a -> unit
|
val set : 'a t -> int -> 'a -> unit
|
||||||
|
|
||||||
val length : _ t -> int
|
val length : _ t -> int
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ val arrayi : ?start:string -> ?stop:string -> ?sep:string ->
|
||||||
val seq : ?start:string -> ?stop:string -> ?sep:string -> 'a printer -> 'a sequence printer
|
val seq : ?start:string -> ?stop:string -> ?sep:string -> 'a printer -> 'a sequence printer
|
||||||
|
|
||||||
val opt : 'a printer -> 'a option printer
|
val opt : 'a printer -> 'a option printer
|
||||||
|
(** [opt pp] prints options as follows:
|
||||||
|
[Some x] will become "some foo" if [pp x ---> "foo"]
|
||||||
|
[None] will become "none" *)
|
||||||
|
|
||||||
(** In the tuple printers, the [sep] argument is only available
|
(** In the tuple printers, the [sep] argument is only available
|
||||||
@since 0.17 *)
|
@since 0.17 *)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,16 @@ let (@@) f x = f x
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if OCAML_MAJOR >= 4 && OCAML_MINOR >= 3
|
||||||
|
|
||||||
|
let opaque_identity = Sys.opaque_identity
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
let opaque_identity x = x
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
let compose f g x = g (f x)
|
let compose f g x = g (f x)
|
||||||
|
|
||||||
let compose_binop f g x y = g (f x) (f y)
|
let compose_binop f g x y = g (f x) (f y)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,12 @@ val finally2 : h:(unit -> _) -> ('a -> 'b -> 'c) -> 'a -> 'b -> 'c
|
||||||
[h ()] is called whether [f x y] rose an exception or not.
|
[h ()] is called whether [f x y] rose an exception or not.
|
||||||
@since 0.16 *)
|
@since 0.16 *)
|
||||||
|
|
||||||
|
val opaque_identity : 'a -> 'a
|
||||||
|
(** [opaque_identity x] is like [x], but prevents Flambda from using [x]'s
|
||||||
|
definition for optimizing it (flambda is an optimization/inlining pass
|
||||||
|
in OCaml >= 4.03).
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
(** {2 Monad}
|
(** {2 Monad}
|
||||||
|
|
||||||
Functions with a fixed domain are monads in their codomain *)
|
Functions with a fixed domain are monads in their codomain *)
|
||||||
|
|
|
||||||
|
|
@ -792,6 +792,38 @@ module Idx = struct
|
||||||
*)
|
*)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let range_by ~step i j =
|
||||||
|
let rec range i j acc =
|
||||||
|
if i=j then i::acc else range i (j-step) (j::acc)
|
||||||
|
in
|
||||||
|
if step = 0 then
|
||||||
|
raise (Invalid_argument "CCList.range_by")
|
||||||
|
else if (if step > 0 then i>j else i<j) then
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
range i ((j-i)/step*step + i) []
|
||||||
|
|
||||||
|
(* note: the last test checks that no error occurs due to overflows. *)
|
||||||
|
(*$T
|
||||||
|
range_by ~step:1 0 0 = [0]
|
||||||
|
range_by ~step:1 5 0 = []
|
||||||
|
range_by ~step:2 1 0 = []
|
||||||
|
range_by ~step:2 0 4 = [0;2;4]
|
||||||
|
range_by ~step:2 0 5 = [0;2;4]
|
||||||
|
range_by ~step:~-1 0 0 = [0]
|
||||||
|
range_by ~step:~-1 0 5 = []
|
||||||
|
range_by ~step:~-2 0 1 = []
|
||||||
|
range_by ~step:~-2 5 1 = [5;3;1]
|
||||||
|
range_by ~step:~-2 5 0 = [5;3;1]
|
||||||
|
range_by ~step:max_int 0 2 = [0]
|
||||||
|
*)
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(pair small_int small_int) (fun (i,j) -> \
|
||||||
|
let i = min i j and j = max i j in \
|
||||||
|
range_by ~step:1 i j = range i j)
|
||||||
|
*)
|
||||||
|
|
||||||
let range i j =
|
let range i j =
|
||||||
let rec up i j acc =
|
let rec up i j acc =
|
||||||
if i=j then i::acc else up i (j-1) (j::acc)
|
if i=j then i::acc else up i (j-1) (j::acc)
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,13 @@ end
|
||||||
|
|
||||||
(** {2 Other Constructors} *)
|
(** {2 Other Constructors} *)
|
||||||
|
|
||||||
|
val range_by : step:int -> int -> int -> int t
|
||||||
|
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
||||||
|
where the difference between successive elements is [step].
|
||||||
|
use a negative [step] for a decreasing list.
|
||||||
|
@raise Invalid_argument if [step=0]
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
val range : int -> int -> int t
|
val range : int -> int -> int t
|
||||||
(** [range i j] iterates on integers from [i] to [j] included . It works
|
(** [range i j] iterates on integers from [i] to [j] included . It works
|
||||||
both for decreasing and increasing ranges *)
|
both for decreasing and increasing ranges *)
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ let get default x = match x with
|
||||||
| None -> default
|
| None -> default
|
||||||
| Some y -> y
|
| Some y -> y
|
||||||
|
|
||||||
|
let get_or ~default x = match x with
|
||||||
|
| None -> default
|
||||||
|
| Some y -> y
|
||||||
|
|
||||||
let get_exn = function
|
let get_exn = function
|
||||||
| Some x -> x
|
| Some x -> x
|
||||||
| None -> invalid_arg "CCOpt.get_exn"
|
| None -> invalid_arg "CCOpt.get_exn"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
|
||||||
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
|
val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
|
||||||
|
|
||||||
val return : 'a -> 'a t
|
val return : 'a -> 'a t
|
||||||
(** Monadic return *)
|
(** Monadic return, that is [return x = Some x] *)
|
||||||
|
|
||||||
val (>|=) : 'a t -> ('a -> 'b) -> 'b t
|
val (>|=) : 'a t -> ('a -> 'b) -> 'b t
|
||||||
(** Infix version of {!map} *)
|
(** Infix version of {!map} *)
|
||||||
|
|
@ -62,7 +62,13 @@ val for_all : ('a -> bool) -> 'a t -> bool
|
||||||
|
|
||||||
val get : 'a -> 'a t -> 'a
|
val get : 'a -> 'a t -> 'a
|
||||||
(** [get default x] unwraps [x], but if [x = None] it returns [default] instead.
|
(** [get default x] unwraps [x], but if [x = None] it returns [default] instead.
|
||||||
@since 0.4.1 *)
|
@since 0.4.1
|
||||||
|
@deprecated use {!get_or} @since 0.18 *)
|
||||||
|
|
||||||
|
val get_or : default:'a -> 'a t -> 'a
|
||||||
|
(** [get_or ~default o] extracts the value from [o], or
|
||||||
|
returns [default] if [o = None].
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
val get_exn : 'a t -> 'a
|
val get_exn : 'a t -> 'a
|
||||||
(** Open the option, possibly failing if it is [None]
|
(** Open the option, possibly failing if it is [None]
|
||||||
|
|
@ -103,6 +109,7 @@ val (<+>) : 'a t -> 'a t -> 'a t
|
||||||
|
|
||||||
val choice : 'a t list -> 'a t
|
val choice : 'a t list -> 'a t
|
||||||
(** [choice] returns the first non-[None] element of the list, or [None] *)
|
(** [choice] returns the first non-[None] element of the list, or [None] *)
|
||||||
|
|
||||||
(** {2 Infix Operators}
|
(** {2 Infix Operators}
|
||||||
@since 0.16 *)
|
@since 0.16 *)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -639,6 +639,26 @@ let exists2 p s1 s2 =
|
||||||
try iter2 (fun c1 c2 -> if p c1 c2 then raise MyExit) s1 s2; false
|
try iter2 (fun c1 c2 -> if p c1 c2 then raise MyExit) s1 s2; false
|
||||||
with MyExit -> true
|
with MyExit -> true
|
||||||
|
|
||||||
|
(** {2 Ascii functions} *)
|
||||||
|
|
||||||
|
#if OCAML_MAJOR >= 4 && OCAML_MINOR >= 3
|
||||||
|
|
||||||
|
let capitalize_ascii = String.capitalize_ascii
|
||||||
|
let uncapitalize_ascii = String.uncapitalize_ascii
|
||||||
|
let uppercase_ascii = String.uppercase_ascii
|
||||||
|
let lowercase_ascii = String.lowercase_ascii
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
let capitalize_ascii = String.capitalize
|
||||||
|
let uncapitalize_ascii = String.uncapitalize
|
||||||
|
let uppercase_ascii = String.uppercase
|
||||||
|
let lowercase_ascii = String.lowercase
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let pp buf s =
|
let pp buf s =
|
||||||
Buffer.add_char buf '"';
|
Buffer.add_char buf '"';
|
||||||
Buffer.add_string buf s;
|
Buffer.add_string buf s;
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,24 @@ val exists2 : (char -> char -> bool) -> string -> string -> bool
|
||||||
@raise Invalid_argument if the strings have not the same length
|
@raise Invalid_argument if the strings have not the same length
|
||||||
@since 0.12 *)
|
@since 0.12 *)
|
||||||
|
|
||||||
|
(** {2 Ascii functions}
|
||||||
|
|
||||||
|
Those functions are deprecated in {!String} since 4.03, so we provide
|
||||||
|
a stable alias for them even in older versions *)
|
||||||
|
|
||||||
|
val capitalize_ascii : string -> string
|
||||||
|
(** See {!String}. @since 0.18 *)
|
||||||
|
|
||||||
|
val uncapitalize_ascii : string -> string
|
||||||
|
(** See {!String}. @since 0.18 *)
|
||||||
|
|
||||||
|
val uppercase_ascii : string -> string
|
||||||
|
(** See {!String}. @since 0.18 *)
|
||||||
|
|
||||||
|
val lowercase_ascii : string -> string
|
||||||
|
(** See {!String}. @since 0.18 *)
|
||||||
|
|
||||||
|
|
||||||
(** {2 Splitting} *)
|
(** {2 Splitting} *)
|
||||||
|
|
||||||
module Split : sig
|
module Split : sig
|
||||||
|
|
|
||||||
|
|
@ -243,12 +243,25 @@ let append_list a b = match b with
|
||||||
*)
|
*)
|
||||||
|
|
||||||
let equal eq v1 v2 =
|
let equal eq v1 v2 =
|
||||||
let n = min v1.size v2.size in
|
v1.size = v2.size
|
||||||
|
&&
|
||||||
|
let n = v1.size in
|
||||||
let rec check i =
|
let rec check i =
|
||||||
if i = n
|
i = n || (eq (get v1 i) (get v2 i) && check (i+1))
|
||||||
then v1.size = v2.size
|
in
|
||||||
else eq (get v1 i) (get v2 i) && check (i+1)
|
check 0
|
||||||
in check 0
|
|
||||||
|
(*$T
|
||||||
|
equal (=) (create ()) (create ())
|
||||||
|
equal (=) (return 42) (return 42)
|
||||||
|
not (equal (=) (create ()) (return 42))
|
||||||
|
not (equal (=) (return 42) (create ()))
|
||||||
|
*)
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(let g = list_of_size Gen.(0--10) small_int in pair g g) (fun (l1,l2) -> \
|
||||||
|
equal (=) (of_list l1) (of_list l2) = (l1=l2))
|
||||||
|
*)
|
||||||
|
|
||||||
let compare cmp v1 v2 =
|
let compare cmp v1 v2 =
|
||||||
let n = min v1.size v2.size in
|
let n = min v1.size v2.size in
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# OASIS_START
|
# OASIS_START
|
||||||
# DO NOT EDIT (digest: 775c1a5da08322de06b23069a43379ed)
|
# DO NOT EDIT (digest: 048ee564ec86589b85b55f903119ad20)
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "bytes result"
|
requires = "bytes result"
|
||||||
archive(byte) = "containers.cma"
|
archive(byte) = "containers.cma"
|
||||||
|
|
@ -9,7 +9,7 @@ archive(native) = "containers.cmxa"
|
||||||
archive(native, plugin) = "containers.cmxs"
|
archive(native, plugin) = "containers.cmxs"
|
||||||
exists_if = "containers.cma"
|
exists_if = "containers.cma"
|
||||||
package "unix" (
|
package "unix" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "bytes unix"
|
requires = "bytes unix"
|
||||||
archive(byte) = "containers_unix.cma"
|
archive(byte) = "containers_unix.cma"
|
||||||
|
|
@ -20,7 +20,7 @@ package "unix" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "top" (
|
package "top" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires =
|
requires =
|
||||||
"compiler-libs.common containers containers.data containers.bigarray containers.string containers.unix containers.sexp containers.iter"
|
"compiler-libs.common containers containers.data containers.bigarray containers.string containers.unix containers.sexp containers.iter"
|
||||||
|
|
@ -32,7 +32,7 @@ package "top" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "thread" (
|
package "thread" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "containers threads"
|
requires = "containers threads"
|
||||||
archive(byte) = "containers_thread.cma"
|
archive(byte) = "containers_thread.cma"
|
||||||
|
|
@ -43,7 +43,7 @@ package "thread" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "string" (
|
package "string" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "bytes"
|
requires = "bytes"
|
||||||
archive(byte) = "containers_string.cma"
|
archive(byte) = "containers_string.cma"
|
||||||
|
|
@ -54,7 +54,7 @@ package "string" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "sexp" (
|
package "sexp" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "bytes"
|
requires = "bytes"
|
||||||
archive(byte) = "containers_sexp.cma"
|
archive(byte) = "containers_sexp.cma"
|
||||||
|
|
@ -65,7 +65,7 @@ package "sexp" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "iter" (
|
package "iter" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
archive(byte) = "containers_iter.cma"
|
archive(byte) = "containers_iter.cma"
|
||||||
archive(byte, plugin) = "containers_iter.cma"
|
archive(byte, plugin) = "containers_iter.cma"
|
||||||
|
|
@ -75,7 +75,7 @@ package "iter" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "io" (
|
package "io" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "bytes"
|
requires = "bytes"
|
||||||
archive(byte) = "containers_io.cma"
|
archive(byte) = "containers_io.cma"
|
||||||
|
|
@ -86,7 +86,7 @@ package "io" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "data" (
|
package "data" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "bytes"
|
requires = "bytes"
|
||||||
archive(byte) = "containers_data.cma"
|
archive(byte) = "containers_data.cma"
|
||||||
|
|
@ -97,7 +97,7 @@ package "data" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "bigarray" (
|
package "bigarray" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "containers bigarray bytes"
|
requires = "containers bigarray bytes"
|
||||||
archive(byte) = "containers_bigarray.cma"
|
archive(byte) = "containers_bigarray.cma"
|
||||||
|
|
@ -108,7 +108,7 @@ package "bigarray" (
|
||||||
)
|
)
|
||||||
|
|
||||||
package "advanced" (
|
package "advanced" (
|
||||||
version = "0.17"
|
version = "0.18"
|
||||||
description = "A modular standard library focused on data structures."
|
description = "A modular standard library focused on data structures."
|
||||||
requires = "containers sequence"
|
requires = "containers sequence"
|
||||||
archive(byte) = "containers_advanced.cma"
|
archive(byte) = "containers_advanced.cma"
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ module Seq = struct
|
||||||
a (fun x -> acc := f !acc x);
|
a (fun x -> acc := f !acc x);
|
||||||
!acc
|
!acc
|
||||||
let to_list seq = fold (fun acc x->x::acc) [] seq |> List.rev
|
let to_list seq = fold (fun acc x->x::acc) [] seq |> List.rev
|
||||||
|
exception Exit_
|
||||||
|
let exists_ f seq =
|
||||||
|
try seq (fun x -> if f x then raise Exit_); false
|
||||||
|
with Exit_ -> true
|
||||||
end
|
end
|
||||||
|
|
||||||
(** {2 Interfaces for graphs} *)
|
(** {2 Interfaces for graphs} *)
|
||||||
|
|
@ -315,6 +319,15 @@ module Traverse = struct
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(** {2 Cycles} *)
|
||||||
|
|
||||||
|
let is_dag ?(tbl=mk_table 128) ~graph vs =
|
||||||
|
Traverse.Event.dfs ~tbl ~graph vs
|
||||||
|
|> Seq.exists_
|
||||||
|
(function
|
||||||
|
| `Edge (_, `Back) -> true
|
||||||
|
| _ -> false)
|
||||||
|
|
||||||
(** {2 Topological Sort} *)
|
(** {2 Topological Sort} *)
|
||||||
|
|
||||||
exception Has_cycle
|
exception Has_cycle
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,17 @@ module Traverse : sig
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(** {2 Cycles} *)
|
||||||
|
|
||||||
|
val is_dag :
|
||||||
|
?tbl:'v set ->
|
||||||
|
graph:('v, _) t ->
|
||||||
|
'v sequence ->
|
||||||
|
bool
|
||||||
|
(** [is_dag ~graph vs] returns [true] if the subset of [graph] reachable
|
||||||
|
from [vs] is acyclic.
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
(** {2 Topological Sort} *)
|
(** {2 Topological Sort} *)
|
||||||
|
|
||||||
exception Has_cycle
|
exception Has_cycle
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,7 @@ module Make(W : WORD)
|
||||||
*)
|
*)
|
||||||
|
|
||||||
(*$Q
|
(*$Q
|
||||||
Q.(pair (list (pair printable_string int)) printable_string) (fun (l,s) -> \
|
Q.(pair (list (pair (printable_string_of_size Gen.(0 -- 30)) int)) printable_string) (fun (l,s) -> \
|
||||||
let m = String.of_list l in \
|
let m = String.of_list l in \
|
||||||
let s' = String.longest_prefix s m in \
|
let s' = String.longest_prefix s m in \
|
||||||
CCString.prefix ~pre:s' s)
|
CCString.prefix ~pre:s' s)
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,27 @@ let rec map ~f l =
|
||||||
| lazy (Cons (x,tl)) -> Cons (f x, map ~f tl)
|
| lazy (Cons (x,tl)) -> Cons (f x, map ~f tl)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let filter ~f l =
|
||||||
|
let rec aux f l = match l with
|
||||||
|
| lazy Nil -> Nil
|
||||||
|
| lazy (Cons (x,tl)) when f x -> Cons (x, lazy (aux f tl))
|
||||||
|
| lazy (Cons (_, tl)) -> aux f tl
|
||||||
|
in
|
||||||
|
lazy (aux f l)
|
||||||
|
|
||||||
|
(*$=
|
||||||
|
[2;4;6] (of_list [1;2;3;4;5;6;7] |> filter ~f:(fun x -> x mod 2=0) |> to_list)
|
||||||
|
[2;4;6] (of_gen Gen.(1 -- max_int) |> filter ~f:(fun x -> x mod 2=0) |> take 3 |> to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
let rec take n l =
|
||||||
|
lazy (
|
||||||
|
match l with
|
||||||
|
| _ when n=0 -> Nil
|
||||||
|
| lazy Nil -> Nil
|
||||||
|
| lazy (Cons (x,tl)) -> Cons (x, take (n-1) tl)
|
||||||
|
)
|
||||||
|
|
||||||
let rec append a b =
|
let rec append a b =
|
||||||
lazy (
|
lazy (
|
||||||
match a with
|
match a with
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,14 @@ val head : 'a t -> ('a * 'a t) option
|
||||||
val map : f:('a -> 'b) -> 'a t -> 'b t
|
val map : f:('a -> 'b) -> 'a t -> 'b t
|
||||||
(** Lazy map *)
|
(** Lazy map *)
|
||||||
|
|
||||||
|
val filter : f:('a -> bool) -> 'a t -> 'a t
|
||||||
|
(** Filter values.
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
|
val take : int -> 'a t -> 'a t
|
||||||
|
(** Take at most n values.
|
||||||
|
@since 0.18 *)
|
||||||
|
|
||||||
val append : 'a t -> 'a t -> 'a t
|
val append : 'a t -> 'a t -> 'a t
|
||||||
(** Lazy concatenation *)
|
(** Lazy concatenation *)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue