Merge branch 'master' into prepare-1.0

This commit is contained in:
Simon Cruanes 2017-01-25 00:15:03 +01:00
commit 56462a862b
12 changed files with 70 additions and 13 deletions

View file

@ -17,3 +17,4 @@
- Geoff Gole (@gsg) - Geoff Gole (@gsg)
- Roma Sokolov (@little-arhat) - Roma Sokolov (@little-arhat)
- Malcolm Matalka (`orbitz`) - Malcolm Matalka (`orbitz`)
- David Sheets (@dsheets)

View file

@ -1,5 +1,27 @@
= Changelog = 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 == 0.20
- bugfix in `CCArray.equal` - bugfix in `CCArray.equal`

View file

@ -180,7 +180,6 @@ Iterators:
- `CCKList`, a persistent iterator structure (akin to a lazy list, without memoization) - `CCKList`, a persistent iterator structure (akin to a lazy list, without memoization)
- `CCKTree`, an abstract lazy tree structure - `CCKTree`, an abstract lazy tree structure
=== Thread === Thread
In the library `containers.thread`, for preemptive system threads: In the library `containers.thread`, for preemptive system threads:

2
_oasis
View file

@ -1,6 +1,6 @@
OASISFormat: 0.4 OASISFormat: 0.4
Name: containers Name: containers
Version: 0.20 Version: 0.22
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

2
opam
View file

@ -38,8 +38,6 @@ depopts: [
] ]
conflicts: [ conflicts: [
"sequence" { < "0.5" } "sequence" { < "0.5" }
"qtest" { < "2.2" }
"qcheck"
] ]
tags: [ "stdlib" "containers" "iterators" "list" "heap" "queue" ] tags: [ "stdlib" "containers" "iterators" "list" "heap" "queue" ]
homepage: "https://github.com/c-cube/ocaml-containers/" homepage: "https://github.com/c-cube/ocaml-containers/"

View file

@ -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;; CCFormat.with_color_sf "red" "%a" CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
]} ]}
{b status: experimental} {b status: experimental}
@since NEXT_RELEASE *) @since 0.21 *)
(** {2 IO} *) (** {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.sprintf_dyn_color ~colors:false "@{<Red>%a@}"
CCFormat.Dump.(list int) [1;2;3] |> print_endline;; CCFormat.Dump.(list int) [1;2;3] |> print_endline;;
]} ]}
@since NEXT_RELEASE *) @since 0.21 *)
val fprintf : t -> ('a, t, unit ) format -> 'a val fprintf : t -> ('a, t, unit ) format -> 'a
(** Alias to {!Format.fprintf} (** 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 val fprintf_dyn_color : colors:bool -> t -> ('a, t, unit ) format -> 'a
(** Similar to {!fprintf} but enable/disable colors depending on [colors] (** Similar to {!fprintf} but enable/disable colors depending on [colors]
@since NEXT_RELEASE *) @since 0.21 *)
val ksprintf : val ksprintf :
f:(string -> 'b) -> f:(string -> 'b) ->
@ -246,7 +246,7 @@ val to_file : string -> ('a, t, unit, unit) format4 -> 'a
[| [1, true; 2, false]; []; [42, false] |];; [| [1, true; 2, false]; []; [42, false] |];;
]} ]}
@since NEXT_RELEASE *) @since 0.21 *)
module Dump : sig module Dump : sig
type 'a t = 'a printer type 'a t = 'a printer

View file

@ -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 (** Open an input file with the given optional flag list, calls the function
on the input channel. When the function raises or returns, the on the input channel. When the function raises or returns, the
channel is closed. 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 *) @param flags opening flags (default [[Open_text]]). [Open_rdonly] is used in any cases *)
val read_chunks : ?size:int -> in_channel -> string gen 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 string -> (out_channel -> 'a) -> 'a
(** Same as {!with_in} but for an output channel (** Same as {!with_in} but for an output channel
@param flags opening flags (default [[Open_creat; Open_trunc; Open_text]]). @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 *) [Open_wronly] is used in any cases *)
val with_out_a : ?mode:int -> ?flags:open_flag list -> val with_out_a : ?mode:int -> ?flags:open_flag list ->
string -> (out_channel -> 'a) -> 'a string -> (out_channel -> 'a) -> 'a
(** Similar to {!with_out} but with the [[Open_append; Open_creat; Open_wronly]] (** 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 val write_line : out_channel -> string -> unit
(** Write the given string on the channel, followed by "\n" *) (** 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 string -> (in_channel -> out_channel -> 'a) -> 'a
(** Combines {!with_in} and {!with_out}. (** Combines {!with_in} and {!with_out}.
@param flags opening flags (default [[Open_creat]]) @param flags opening flags (default [[Open_creat]])
@raise Sys_error in case of error
@since 0.12 *) @since 0.12 *)
(** {2 Misc for Generators} *) (** {2 Misc for Generators} *)
@ -144,7 +148,7 @@ module File : sig
(** [remove_exn path] tries to remove the file at [path] from the (** [remove_exn path] tries to remove the file at [path] from the
file system. 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 *) @since 0.8 *)
val remove : t -> unit or_error val remove : t -> unit or_error
@ -158,11 +162,13 @@ module File : sig
val read_dir : ?recurse:bool -> t -> t gen val read_dir : ?recurse:bool -> t -> t gen
(** [read_dir d] returns a sequence of files and directory contained (** [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) 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 @param recurse if true (default [false]), sub-directories are also
explored *) explored *)
val read_exn : t -> string val read_exn : t -> string
(** Read the content of the given file, or raises some exception (** Read the content of the given file, or raises some exception
@raise Sys_error in case of error
@since 0.16 *) @since 0.16 *)
val read : t -> string or_error val read : t -> string or_error
@ -171,6 +177,7 @@ module File : sig
val append_exn : t -> string -> unit val append_exn : t -> string -> unit
(** Append the given string into the given file, possibly raising (** Append the given string into the given file, possibly raising
@raise Sys_error in case of error
@since 0.16 *) @since 0.16 *)
val append : t -> string -> unit or_error val append : t -> string -> unit or_error
@ -179,6 +186,7 @@ module File : sig
val write_exn : t -> string -> unit val write_exn : t -> string -> unit
(** Write the given string into the given file, possibly raising (** Write the given string into the given file, possibly raising
@raise Sys_error in case of error
@since 0.16 *) @since 0.16 *)
val write : t -> string -> unit or_error val write : t -> string -> unit or_error
@ -191,7 +199,8 @@ module File : sig
(** Similar to {!read_dir} (with [recurse=true]), this function walks (** Similar to {!read_dir} (with [recurse=true]), this function walks
a directory recursively and yields either files or directories. a directory recursively and yields either files or directories.
Is a file anything that doesn't satisfy {!is_directory} (including 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 val show_walk_item : walk_item -> string

View file

@ -83,4 +83,3 @@ module String = struct
include CCString include CCString
end end
module Vector = CCVector module Vector = CCVector

View file

@ -33,6 +33,10 @@ module type S = sig
@raise Invalid_argument if [n < 0] @raise Invalid_argument if [n < 0]
@since 0.6 *) @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 val update : t -> elt -> (int -> int) -> t
(** [update set x f] calls [f n] where [n] is the current multiplicity (** [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] 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 ms x = remove_mult ms x 1
let remove_all ms x = M.remove x ms
let update ms x f = let update ms x f =
let n = count ms x in let n = count ms x in
match f n with match f n with

View file

@ -33,6 +33,10 @@ module type S = sig
@raise Invalid_argument if [n < 0] @raise Invalid_argument if [n < 0]
@since 0.6 *) @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 val update : t -> elt -> (int -> int) -> t
(** [update set x f] calls [f n] where [n] is the current multiplicity (** [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] of [x] in [set] ([0] to indicate its absence); the result of [f n]

View file

@ -35,6 +35,18 @@ let with_lock l f =
assert_equal 10 (get l) 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 module LockRef = struct
type 'a t = 'a lock type 'a t = 'a lock
let get t = t.content let get t = t.content

View file

@ -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] the lock [l], in a critical section. If [f x] fails, [with_lock l f]
fails too but the lock is released *) 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 (** Type allowing to manipulate the lock as a reference
@since 0.13 *) @since 0.13 *)
module LockRef : sig module LockRef : sig
@ -48,7 +54,8 @@ val mutex : _ t -> Mutex.t
(** Underlying mutex *) (** Underlying mutex *)
val get : 'a t -> 'a 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 val set : 'a t -> 'a -> unit
(** Atomically set the value (** Atomically set the value