mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
Merge branch 'master' into prepare-1.0
This commit is contained in:
commit
56462a862b
12 changed files with 70 additions and 13 deletions
|
|
@ -17,3 +17,4 @@
|
|||
- Geoff Gole (@gsg)
|
||||
- Roma Sokolov (@little-arhat)
|
||||
- Malcolm Matalka (`orbitz`)
|
||||
- David Sheets (@dsheets)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,27 @@
|
|||
= Changelog
|
||||
|
||||
== 0.22
|
||||
|
||||
- threads/CCLock: add `try_with_lock` to wrap `Mutex.try_lock`
|
||||
- Add `CCMultiSet.remove_all`
|
||||
- document errors in `CCIO` (close #86)
|
||||
- use the new qtest/qcheck
|
||||
|
||||
== 0.21
|
||||
|
||||
- (breaking) make default `start`/`stop` arguments empty in printers (#82)
|
||||
|
||||
- add `CCFormat.{with_color_sf,fprintf_dyn_color,sprintf_dyn_color}`
|
||||
- add `CCFormat.Dump` for easy debugging (see #82)
|
||||
- add `CCArray.Sub.to_list`
|
||||
- add `CCArray.{sorted,sort_indices,sort_ranking}` (closes #81)
|
||||
|
||||
- handle '\r` in CCSexpM (fixes #83)
|
||||
- add alias `Containers.IO`
|
||||
- bugfixes in `CCArray.Sub`
|
||||
- bugfix + tests for `CCArray.Sub.sub`
|
||||
- disable parallel build to support cygwin
|
||||
|
||||
== 0.20
|
||||
|
||||
- bugfix in `CCArray.equal`
|
||||
|
|
|
|||
|
|
@ -180,7 +180,6 @@ Iterators:
|
|||
- `CCKList`, a persistent iterator structure (akin to a lazy list, without memoization)
|
||||
- `CCKTree`, an abstract lazy tree structure
|
||||
|
||||
|
||||
=== Thread
|
||||
|
||||
In the library `containers.thread`, for preemptive system threads:
|
||||
|
|
|
|||
2
_oasis
2
_oasis
|
|
@ -1,6 +1,6 @@
|
|||
OASISFormat: 0.4
|
||||
Name: containers
|
||||
Version: 0.20
|
||||
Version: 0.22
|
||||
Homepage: https://github.com/c-cube/ocaml-containers
|
||||
Authors: Simon Cruanes
|
||||
License: BSD-2-clause
|
||||
|
|
|
|||
2
opam
2
opam
|
|
@ -38,8 +38,6 @@ depopts: [
|
|||
]
|
||||
conflicts: [
|
||||
"sequence" { < "0.5" }
|
||||
"qtest" { < "2.2" }
|
||||
"qcheck"
|
||||
]
|
||||
tags: [ "stdlib" "containers" "iterators" "list" "heap" "queue" ]
|
||||
homepage: "https://github.com/c-cube/ocaml-containers/"
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ val with_color_sf : string -> ('a, t, unit, string) format4 -> 'a
|
|||
CCFormat.with_color_sf "red" "%a" CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
|
||||
]}
|
||||
{b status: experimental}
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.21 *)
|
||||
|
||||
(** {2 IO} *)
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ val sprintf_dyn_color : colors:bool -> ('a, t, unit, string) format4 -> 'a
|
|||
CCFormat.sprintf_dyn_color ~colors:false "@{<Red>%a@}"
|
||||
CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
|
||||
]}
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.21 *)
|
||||
|
||||
val fprintf : t -> ('a, t, unit ) format -> 'a
|
||||
(** Alias to {!Format.fprintf}
|
||||
|
|
@ -215,7 +215,7 @@ val fprintf : t -> ('a, t, unit ) format -> 'a
|
|||
|
||||
val fprintf_dyn_color : colors:bool -> t -> ('a, t, unit ) format -> 'a
|
||||
(** Similar to {!fprintf} but enable/disable colors depending on [colors]
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.21 *)
|
||||
|
||||
val ksprintf :
|
||||
f:(string -> 'b) ->
|
||||
|
|
@ -246,7 +246,7 @@ val to_file : string -> ('a, t, unit, unit) format4 -> 'a
|
|||
[| [1, true; 2, false]; []; [42, false] |];;
|
||||
]}
|
||||
|
||||
@since NEXT_RELEASE *)
|
||||
@since 0.21 *)
|
||||
|
||||
module Dump : sig
|
||||
type 'a t = 'a printer
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ val with_in : ?mode:int -> ?flags:open_flag list ->
|
|||
(** Open an input file with the given optional flag list, calls the function
|
||||
on the input channel. When the function raises or returns, the
|
||||
channel is closed.
|
||||
@raise Sys_error in case of error (same as {!open_in} and {!close_in})
|
||||
@param flags opening flags (default [[Open_text]]). [Open_rdonly] is used in any cases *)
|
||||
|
||||
val read_chunks : ?size:int -> in_channel -> string gen
|
||||
|
|
@ -77,12 +78,14 @@ val with_out : ?mode:int -> ?flags:open_flag list ->
|
|||
string -> (out_channel -> 'a) -> 'a
|
||||
(** Same as {!with_in} but for an output channel
|
||||
@param flags opening flags (default [[Open_creat; Open_trunc; Open_text]]).
|
||||
@raise Sys_error in case of error (same as {!open_out} and {!close_out})
|
||||
[Open_wronly] is used in any cases *)
|
||||
|
||||
val with_out_a : ?mode:int -> ?flags:open_flag list ->
|
||||
string -> (out_channel -> 'a) -> 'a
|
||||
(** Similar to {!with_out} but with the [[Open_append; Open_creat; Open_wronly]]
|
||||
flags activated, to append to the file *)
|
||||
flags activated, to append to the file.
|
||||
@raise Sys_error in case of error (same as {!open_out} and {!close_out}) *)
|
||||
|
||||
val write_line : out_channel -> string -> unit
|
||||
(** Write the given string on the channel, followed by "\n" *)
|
||||
|
|
@ -102,6 +105,7 @@ val with_in_out : ?mode:int -> ?flags:open_flag list ->
|
|||
string -> (in_channel -> out_channel -> 'a) -> 'a
|
||||
(** Combines {!with_in} and {!with_out}.
|
||||
@param flags opening flags (default [[Open_creat]])
|
||||
@raise Sys_error in case of error
|
||||
@since 0.12 *)
|
||||
|
||||
(** {2 Misc for Generators} *)
|
||||
|
|
@ -144,7 +148,7 @@ module File : sig
|
|||
(** [remove_exn path] tries to remove the file at [path] from the
|
||||
file system.
|
||||
|
||||
{b Raises} [Sys_error] if there is no file at [path].
|
||||
@raise Sys_error if there is no file at [path] or access rights are wrong.
|
||||
@since 0.8 *)
|
||||
|
||||
val remove : t -> unit or_error
|
||||
|
|
@ -158,11 +162,13 @@ module File : sig
|
|||
val read_dir : ?recurse:bool -> t -> t gen
|
||||
(** [read_dir d] returns a sequence of files and directory contained
|
||||
in the directory [d] (or an empty stream if [d] is not a directory)
|
||||
@raise Sys_error in case of error (e.g. permission denied)
|
||||
@param recurse if true (default [false]), sub-directories are also
|
||||
explored *)
|
||||
|
||||
val read_exn : t -> string
|
||||
(** Read the content of the given file, or raises some exception
|
||||
@raise Sys_error in case of error
|
||||
@since 0.16 *)
|
||||
|
||||
val read : t -> string or_error
|
||||
|
|
@ -171,6 +177,7 @@ module File : sig
|
|||
|
||||
val append_exn : t -> string -> unit
|
||||
(** Append the given string into the given file, possibly raising
|
||||
@raise Sys_error in case of error
|
||||
@since 0.16 *)
|
||||
|
||||
val append : t -> string -> unit or_error
|
||||
|
|
@ -179,6 +186,7 @@ module File : sig
|
|||
|
||||
val write_exn : t -> string -> unit
|
||||
(** Write the given string into the given file, possibly raising
|
||||
@raise Sys_error in case of error
|
||||
@since 0.16 *)
|
||||
|
||||
val write : t -> string -> unit or_error
|
||||
|
|
@ -191,7 +199,8 @@ module File : sig
|
|||
(** Similar to {!read_dir} (with [recurse=true]), this function walks
|
||||
a directory recursively and yields either files or directories.
|
||||
Is a file anything that doesn't satisfy {!is_directory} (including
|
||||
symlinks, etc.) *)
|
||||
symlinks, etc.)
|
||||
@raise Sys_error in case of error (e.g. permission denied) during iteration *)
|
||||
|
||||
val show_walk_item : walk_item -> string
|
||||
|
||||
|
|
|
|||
|
|
@ -83,4 +83,3 @@ module String = struct
|
|||
include CCString
|
||||
end
|
||||
module Vector = CCVector
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ module type S = sig
|
|||
@raise Invalid_argument if [n < 0]
|
||||
@since 0.6 *)
|
||||
|
||||
val remove_all : t -> elt -> t
|
||||
(** [remove_all set x] removes all occurrences of [x] from [set]
|
||||
@since 0.22 *)
|
||||
|
||||
val update : t -> elt -> (int -> int) -> t
|
||||
(** [update set x f] calls [f n] where [n] is the current multiplicity
|
||||
of [x] in [set] ([0] to indicate its absence); the result of [f n]
|
||||
|
|
@ -136,6 +140,8 @@ module Make(O : Set.OrderedType) = struct
|
|||
|
||||
let remove ms x = remove_mult ms x 1
|
||||
|
||||
let remove_all ms x = M.remove x ms
|
||||
|
||||
let update ms x f =
|
||||
let n = count ms x in
|
||||
match f n with
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ module type S = sig
|
|||
@raise Invalid_argument if [n < 0]
|
||||
@since 0.6 *)
|
||||
|
||||
val remove_all : t -> elt -> t
|
||||
(** [remove_all set x] removes all occurrences of [x] from [set]
|
||||
@since 0.22 *)
|
||||
|
||||
val update : t -> elt -> (int -> int) -> t
|
||||
(** [update set x f] calls [f n] where [n] is the current multiplicity
|
||||
of [x] in [set] ([0] to indicate its absence); the result of [f n]
|
||||
|
|
|
|||
|
|
@ -35,6 +35,18 @@ let with_lock l f =
|
|||
assert_equal 10 (get l)
|
||||
*)
|
||||
|
||||
let try_with_lock l f =
|
||||
if Mutex.try_lock l.mutex
|
||||
then
|
||||
try
|
||||
let x = f l.content in
|
||||
Mutex.unlock l.mutex;
|
||||
Some x
|
||||
with e ->
|
||||
Mutex.unlock l.mutex;
|
||||
raise e
|
||||
else None
|
||||
|
||||
module LockRef = struct
|
||||
type 'a t = 'a lock
|
||||
let get t = t.content
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ val with_lock : 'a t -> ('a -> 'b) -> 'b
|
|||
the lock [l], in a critical section. If [f x] fails, [with_lock l f]
|
||||
fails too but the lock is released *)
|
||||
|
||||
val try_with_lock : 'a t -> ('a -> 'b) -> 'b option
|
||||
(** [try_with_lock l f] runs [f x] in a critical section if [l] is not
|
||||
locked. [x] is the value protected by the lock [l]. If [f x]
|
||||
fails, [try_with_lock l f] fails too but the lock is released
|
||||
@since 0.22 *)
|
||||
|
||||
(** Type allowing to manipulate the lock as a reference
|
||||
@since 0.13 *)
|
||||
module LockRef : sig
|
||||
|
|
@ -48,7 +54,8 @@ val mutex : _ t -> Mutex.t
|
|||
(** Underlying mutex *)
|
||||
|
||||
val get : 'a t -> 'a
|
||||
(** Get the value in the lock. The value that is returned isn't protected! *)
|
||||
(** Atomically get the value in the lock. The value that is returned
|
||||
isn't protected! *)
|
||||
|
||||
val set : 'a t -> 'a -> unit
|
||||
(** Atomically set the value
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue