···11+## v1.1.0 (2025-04-28)
22+33+- Add missing primitive `clear` (@raphael-proust, #7)
44+- Fix documentation typo (@raphael-proust, #7)
55+66+## v1.0.1 (2021-05-21)
77+88+- Remove `lwt` dependency; it's only really needed for the tests (@aantron #1).
99+- Fix deprecation warnings with OCaml 4.08 (@aantron #1).
1010+- Add support for OCaml 4.02 (@aantron #1).
1111+1212+## v1.0.0 (2019-01-14)
1313+1414+Initial release, based on Lwt 4.1.0's source code.
+17
vendor/opam/lwt-dllist/LICENSE.md
···11+Permission is hereby granted, free of charge, to any person obtaining a copy
22+of this software and associated documentation files (the "Software"), to deal
33+in the Software without restriction, including without limitation the rights
44+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55+copies of the Software, and to permit persons to whom the Software is
66+furnished to do so, subject to the following conditions:
77+88+The above copyright notice and this permission notice shall be included in all
99+copies or substantial portions of the Software.
1010+1111+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1212+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1313+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1414+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1515+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1616+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1717+SOFTWARE.
···11+# lwt-dllist - Mutable doubly-linked list
22+33+An `Lwt_dllist` is an object holding a list of elements which support
44+the following operations:
55+66+- adding an element to the left or the right in time and space O(1)
77+- taking an element from the left or the right in time and space O(1)
88+- removing a previously added element from a sequence in time and space O(1)
99+- removing an element while the sequence is being traversed.
1010+1111+## History
1212+1313+This module was formerly part of the Lwt core distribution as the
1414+`Lwt_sequence` module, but has been pulled out into a separate library since it
1515+is really just an implementation detail of Lwt.
1616+1717+You can migrate existing uses of `Lwt_sequence` into `Lwt_dllist` by simply
1818+renaming the module. The implementation of the module remains unchanged, but
1919+the name reflects the fact that the implementation is a doubly-linked list.
2020+2121+## Further Reading
2222+2323+- Docs: <https://mirage.github.io/lwt-dllist>
2424+- Issues: <https://github.com/mirage/lwt-dllist/issues>
2525+- Discussion: <https://discuss.ocaml.org> with the MirageOS tag.
···11+opam-version: "2.0"
22+maintainer: [ "Anil Madhavapeddy <anil@recoil.org>" ]
33+authors: ["Jérôme Vouillon" "Jérémie Dimino"]
44+license: "MIT"
55+homepage: "https://github.com/mirage/lwt-dllist"
66+doc: "https://mirage.github.io/lwt-dllist/"
77+bug-reports: "https://github.com/mirage/lwt-dllist/issues"
88+depends: [
99+ "ocaml" {>= "4.02.0"}
1010+ "lwt" {with-test}
1111+ "dune"
1212+]
1313+build: [
1414+ ["dune" "subst" ] {dev}
1515+ ["dune" "build" "-p" name "-j" jobs]
1616+ ["dune" "runtest" "-p" name "-j" jobs] {with-test}
1717+]
1818+dev-repo: "git+https://github.com/mirage/lwt-dllist.git"
1919+synopsis: "Mutable doubly-linked list with Lwt iterators"
2020+description: """
2121+A sequence is an object holding a list of elements which support
2222+the following operations:
2323+2424+- adding an element to the left or the right in time and space O(1)
2525+- taking an element from the left or the right in time and space O(1)
2626+- removing a previously added element from a sequence in time and space O(1)
2727+- removing an element while the sequence is being transversed.
2828+"""
···11+(* This file is part of Lwt, released under the MIT license. See LICENSE.md for
22+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
33+44+55+66+exception Empty
77+88+type 'a t = {
99+ mutable prev : 'a t;
1010+ mutable next : 'a t;
1111+}
1212+1313+type 'a node = {
1414+ node_prev : 'a t;
1515+ node_next : 'a t;
1616+ mutable node_data : 'a;
1717+ mutable node_active : bool;
1818+}
1919+2020+external seq_of_node : 'a node -> 'a t = "%identity"
2121+external node_of_seq : 'a t -> 'a node = "%identity"
2222+2323+(* +-----------------------------------------------------------------+
2424+ | Operations on nodes |
2525+ +-----------------------------------------------------------------+ *)
2626+2727+let get node =
2828+ node.node_data
2929+3030+let set node data =
3131+ node.node_data <- data
3232+3333+let remove node =
3434+ if node.node_active then begin
3535+ node.node_active <- false;
3636+ let seq = seq_of_node node in
3737+ seq.prev.next <- seq.next;
3838+ seq.next.prev <- seq.prev
3939+ end
4040+4141+(* +-----------------------------------------------------------------+
4242+ | Operations on sequences |
4343+ +-----------------------------------------------------------------+ *)
4444+4545+let create () =
4646+ let rec seq = { prev = seq; next = seq } in
4747+ seq
4848+4949+let clear seq =
5050+ seq.prev <- seq;
5151+ seq.next <- seq
5252+5353+let is_empty seq = seq.next == seq
5454+5555+let length seq =
5656+ let rec loop curr len =
5757+ if curr == seq then
5858+ len
5959+ else
6060+ let node = node_of_seq curr in loop node.node_next (len + 1)
6161+ in
6262+ loop seq.next 0
6363+6464+let add_l data seq =
6565+ let node = { node_prev = seq; node_next = seq.next; node_data = data; node_active = true } in
6666+ seq.next.prev <- seq_of_node node;
6767+ seq.next <- seq_of_node node;
6868+ node
6969+7070+let add_r data seq =
7171+ let node = { node_prev = seq.prev; node_next = seq; node_data = data; node_active = true } in
7272+ seq.prev.next <- seq_of_node node;
7373+ seq.prev <- seq_of_node node;
7474+ node
7575+7676+let take_l seq =
7777+ if is_empty seq then
7878+ raise Empty
7979+ else begin
8080+ let node = node_of_seq seq.next in
8181+ remove node;
8282+ node.node_data
8383+ end
8484+8585+let take_r seq =
8686+ if is_empty seq then
8787+ raise Empty
8888+ else begin
8989+ let node = node_of_seq seq.prev in
9090+ remove node;
9191+ node.node_data
9292+ end
9393+9494+let take_opt_l seq =
9595+ if is_empty seq then
9696+ None
9797+ else begin
9898+ let node = node_of_seq seq.next in
9999+ remove node;
100100+ Some node.node_data
101101+ end
102102+103103+let take_opt_r seq =
104104+ if is_empty seq then
105105+ None
106106+ else begin
107107+ let node = node_of_seq seq.prev in
108108+ remove node;
109109+ Some node.node_data
110110+ end
111111+112112+let transfer_l s1 s2 =
113113+ s2.next.prev <- s1.prev;
114114+ s1.prev.next <- s2.next;
115115+ s2.next <- s1.next;
116116+ s1.next.prev <- s2;
117117+ s1.prev <- s1;
118118+ s1.next <- s1
119119+120120+let transfer_r s1 s2 =
121121+ s2.prev.next <- s1.next;
122122+ s1.next.prev <- s2.prev;
123123+ s2.prev <- s1.prev;
124124+ s1.prev.next <- s2;
125125+ s1.prev <- s1;
126126+ s1.next <- s1
127127+128128+let iter_l f seq =
129129+ let rec loop curr =
130130+ if curr != seq then begin
131131+ let node = node_of_seq curr in
132132+ if node.node_active then f node.node_data;
133133+ loop node.node_next
134134+ end
135135+ in
136136+ loop seq.next
137137+138138+let iter_r f seq =
139139+ let rec loop curr =
140140+ if curr != seq then begin
141141+ let node = node_of_seq curr in
142142+ if node.node_active then f node.node_data;
143143+ loop node.node_prev
144144+ end
145145+ in
146146+ loop seq.prev
147147+148148+let iter_node_l f seq =
149149+ let rec loop curr =
150150+ if curr != seq then begin
151151+ let node = node_of_seq curr in
152152+ if node.node_active then f node;
153153+ loop node.node_next
154154+ end
155155+ in
156156+ loop seq.next
157157+158158+let iter_node_r f seq =
159159+ let rec loop curr =
160160+ if curr != seq then begin
161161+ let node = node_of_seq curr in
162162+ if node.node_active then f node;
163163+ loop node.node_prev
164164+ end
165165+ in
166166+ loop seq.prev
167167+168168+let fold_l f seq acc =
169169+ let rec loop curr acc =
170170+ if curr == seq then
171171+ acc
172172+ else
173173+ let node = node_of_seq curr in
174174+ if node.node_active then
175175+ loop node.node_next (f node.node_data acc)
176176+ else
177177+ loop node.node_next acc
178178+ in
179179+ loop seq.next acc
180180+181181+let fold_r f seq acc =
182182+ let rec loop curr acc =
183183+ if curr == seq then
184184+ acc
185185+ else
186186+ let node = node_of_seq curr in
187187+ if node.node_active then
188188+ loop node.node_prev (f node.node_data acc)
189189+ else
190190+ loop node.node_prev acc
191191+ in
192192+ loop seq.prev acc
193193+194194+let find_node_l f seq =
195195+ let rec loop curr =
196196+ if curr != seq then
197197+ let node = node_of_seq curr in
198198+ if node.node_active then
199199+ if f node.node_data then
200200+ node
201201+ else
202202+ loop node.node_next
203203+ else
204204+ loop node.node_next
205205+ else
206206+ raise Not_found
207207+ in
208208+ loop seq.next
209209+210210+let find_node_r f seq =
211211+ let rec loop curr =
212212+ if curr != seq then
213213+ let node = node_of_seq curr in
214214+ if node.node_active then
215215+ if f node.node_data then
216216+ node
217217+ else
218218+ loop node.node_prev
219219+ else
220220+ loop node.node_prev
221221+ else
222222+ raise Not_found
223223+ in
224224+ loop seq.prev
225225+226226+let find_node_opt_l f seq =
227227+ try Some (find_node_l f seq) with Not_found -> None
228228+229229+let find_node_opt_r f seq =
230230+ try Some (find_node_r f seq) with Not_found -> None
+141
vendor/opam/lwt-dllist/src/lwt_dllist.mli
···11+(* This file is formerly part of Lwt, released under the MIT license.
22+ * See LICENSE.md for details, or visit
33+ * https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
44+55+(** Mutable double-linked list of elements *)
66+77+(** A sequence is an object holding a list of elements which support
88+ the following operations:
99+1010+ - adding an element to the left or the right in time and space O(1)
1111+ - taking an element from the left or the right in time and space O(1)
1212+ - removing a previously added element from a sequence in time and space O(1)
1313+ - removing an element while the sequence is being transversed.
1414+*)
1515+1616+type 'a t
1717+ (** Type of a sequence holding values of type ['a] *)
1818+1919+type 'a node
2020+ (** Type of a node holding one value of type ['a] in a sequence *)
2121+2222+(** {2 Operation on nodes} *)
2323+2424+val get : 'a node -> 'a
2525+ (** Returns the contents of a node *)
2626+2727+val set : 'a node -> 'a -> unit
2828+ (** Changes the contents of a node *)
2929+3030+val remove : 'a node -> unit
3131+ (** Removes a node from the sequence it is part of. It does nothing
3232+ if the node has already been removed. *)
3333+3434+(** {2 Operations on sequence} *)
3535+3636+val create : unit -> 'a t
3737+ (** [create ()] creates a new empty sequence *)
3838+3939+val clear : 'a t -> unit
4040+(** Removes all nodes from the given sequence. The nodes are not actually
4141+ mutated to note their removal. Only the sequence's pointers are updated. *)
4242+4343+val is_empty : 'a t -> bool
4444+ (** Returns [true] iff the given sequence is empty *)
4545+4646+val length : 'a t -> int
4747+ (** Returns the number of elements in the given sequence. This is a
4848+ O(n) operation where [n] is the number of elements in the
4949+ sequence. *)
5050+5151+val add_l : 'a -> 'a t -> 'a node
5252+ (** [add_l x s] adds [x] to the left of the sequence [s] *)
5353+5454+val add_r : 'a -> 'a t -> 'a node
5555+ (** [add_r x s] adds [x] to the right of the sequence [s] *)
5656+5757+exception Empty
5858+ (** Exception raised by [take_l] and [take_r] and when the sequence
5959+ is empty *)
6060+6161+val take_l : 'a t -> 'a
6262+ (** [take_l x s] removes and returns the leftmost element of [s]
6363+6464+ @raise Empty if the sequence is empty *)
6565+6666+val take_r : 'a t -> 'a
6767+ (** [take_r x s] removes and returns the rightmost element of [s]
6868+6969+ @raise Empty if the sequence is empty *)
7070+7171+val take_opt_l : 'a t -> 'a option
7272+ (** [take_opt_l x s] removes and returns [Some x] where [x] is the
7373+ leftmost element of [s] or [None] if [s] is empty *)
7474+7575+val take_opt_r : 'a t -> 'a option
7676+ (** [take_opt_r x s] removes and returns [Some x] where [x] is the
7777+ rightmost element of [s] or [None] if [s] is empty *)
7878+7979+val transfer_l : 'a t -> 'a t -> unit
8080+ (** [transfer_l s1 s2] removes all elements of [s1] and add them at
8181+ the left of [s2]. This operation runs in constant time and
8282+ space. *)
8383+8484+val transfer_r : 'a t -> 'a t -> unit
8585+ (** [transfer_r s1 s2] removes all elements of [s1] and add them at
8686+ the right of [s2]. This operation runs in constant time and
8787+ space. *)
8888+8989+(** {2 Sequence iterators} *)
9090+9191+(** Note: it is OK to remove a node while traversing a sequence *)
9292+9393+val iter_l : ('a -> unit) -> 'a t -> unit
9494+ (** [iter_l f s] applies [f] on all elements of [s] starting from
9595+ the left *)
9696+9797+val iter_r : ('a -> unit) -> 'a t -> unit
9898+ (** [iter_r f s] applies [f] on all elements of [s] starting from
9999+ the right *)
100100+101101+val iter_node_l : ('a node -> unit) -> 'a t -> unit
102102+ (** [iter_node_l f s] applies [f] on all nodes of [s] starting from
103103+ the left *)
104104+105105+val iter_node_r : ('a node -> unit) -> 'a t -> unit
106106+ (** [iter_node_r f s] applies [f] on all nodes of [s] starting from
107107+ the right *)
108108+109109+val fold_l : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
110110+ (** [fold_l f s] is:
111111+ {[
112112+ fold_l f s x = f en (... (f e2 (f e1 x)))
113113+ ]}
114114+ where [e1], [e2], ..., [en] are the elements of [s]
115115+ *)
116116+117117+val fold_r : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
118118+ (** [fold_r f s] is:
119119+ {[
120120+ fold_r f s x = f e1 (f e2 (... (f en x)))
121121+ ]}
122122+ where [e1], [e2], ..., [en] are the elements of [s]
123123+ *)
124124+125125+val find_node_opt_l : ('a -> bool) -> 'a t -> 'a node option
126126+ (** [find_node_opt_l f s] returns [Some x], where [x] is the first node of
127127+ [s] starting from the left that satisfies [f] or [None] if none
128128+ exists. *)
129129+130130+val find_node_opt_r : ('a -> bool) -> 'a t -> 'a node option
131131+ (** [find_node_opt_r f s] returns [Some x], where [x] is the first node of
132132+ [s] starting from the right that satisfies [f] or [None] if none
133133+ exists. *)
134134+135135+val find_node_l : ('a -> bool) -> 'a t -> 'a node
136136+ (** [find_node_l f s] returns the first node of [s] starting from the left
137137+ that satisfies [f] or raises [Not_found] if none exists. *)
138138+139139+val find_node_r : ('a -> bool) -> 'a t -> 'a node
140140+ (** [find_node_r f s] returns the first node of [s] starting from the right
141141+ that satisfies [f] or raises [Not_found] if none exists. *)
···11+(* This file is part of Lwt, released under the MIT license. See LICENSE.md for
22+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
33+44+[@@@warning "-4"]
55+66+type test = {
77+ test_name : string;
88+ skip_if_this_is_false : unit -> bool;
99+ run : unit -> bool Lwt.t;
1010+}
1111+1212+type outcome =
1313+ | Passed
1414+ | Failed
1515+ | Exception of exn
1616+ | Skipped
1717+1818+exception Skip
1919+2020+let test_direct test_name ?(only_if = fun () -> true) run =
2121+ let run =
2222+ fun () ->
2323+ Lwt.return (run ())
2424+ in
2525+ {test_name; skip_if_this_is_false = only_if; run}
2626+2727+let test test_name ?(only_if = fun () -> true) run =
2828+ {test_name; skip_if_this_is_false = only_if; run}
2929+3030+let run_test : test -> outcome Lwt.t = fun test ->
3131+ if test.skip_if_this_is_false () = false then
3232+ Lwt.return Skipped
3333+3434+ else begin
3535+ (* Lwt.async_exception_hook handling inspired by
3636+ https://github.com/mirage/alcotest/issues/45 *)
3737+ let async_exception_promise, async_exception_occurred = Lwt.task () in
3838+ let old_async_exception_hook = !Lwt.async_exception_hook in
3939+ Lwt.async_exception_hook := (fun exn ->
4040+ Lwt.wakeup_later async_exception_occurred (Exception exn));
4141+4242+ Lwt.finalize
4343+ (fun () ->
4444+4545+ let test_completion_promise =
4646+ Lwt.try_bind
4747+ (fun () ->
4848+ test.run ())
4949+5050+ (fun test_did_pass ->
5151+ if test_did_pass then
5252+ Lwt.return Passed
5353+ else
5454+ Lwt.return Failed)
5555+5656+ (function
5757+ | Skip ->
5858+ Lwt.return Skipped
5959+6060+ | exn_raised_by_test ->
6161+ Lwt.return (Exception exn_raised_by_test))
6262+ in
6363+6464+ Lwt.pick [test_completion_promise; async_exception_promise])
6565+6666+ (fun () ->
6767+ Lwt.async_exception_hook := old_async_exception_hook;
6868+ Lwt.return_unit)
6969+ end
7070+7171+let outcome_to_character : outcome -> string = function
7272+ | Passed -> "."
7373+ | Failed -> "F"
7474+ | Exception _ -> "E"
7575+ | Skipped -> "S"
7676+7777+7878+7979+type suite = {
8080+ suite_name : string;
8181+ suite_tests : test list;
8282+ skip_suite_if_this_is_false : unit -> bool;
8383+}
8484+8585+let suite name ?(only_if = fun () -> true) tests =
8686+ {suite_name = name;
8787+ suite_tests = tests;
8888+ skip_suite_if_this_is_false = only_if}
8989+9090+let run_test_suite : suite -> ((string * outcome) list) Lwt.t = fun suite ->
9191+ if suite.skip_suite_if_this_is_false () = false then
9292+ let outcomes =
9393+ suite.suite_tests
9494+ |> List.map (fun {test_name; _} -> (test_name, Skipped))
9595+ in
9696+ (outcome_to_character Skipped).[0]
9797+ |> String.make (List.length outcomes)
9898+ |> print_string;
9999+ flush stdout;
100100+101101+ Lwt.return outcomes
102102+103103+ else
104104+ suite.suite_tests |> Lwt_list.map_s begin fun test ->
105105+ Lwt.bind (run_test test) (fun outcome ->
106106+ outcome |> outcome_to_character |> print_string;
107107+ flush stdout;
108108+ Lwt.return (test.test_name, outcome))
109109+ end
110110+111111+let outcomes_all_ok : (string * outcome) list -> bool =
112112+ List.for_all (fun (_test_name, outcome) ->
113113+ match outcome with
114114+ | Passed | Skipped -> true
115115+ | Failed | Exception _ -> false)
116116+117117+let show_failures : (string * outcome) list -> unit =
118118+ List.iter (fun (test_name, outcome) ->
119119+ match outcome with
120120+ | Passed
121121+ | Skipped ->
122122+ ()
123123+124124+ | Failed ->
125125+ Printf.eprintf
126126+ "Test '%s' produced 'false'\n" test_name
127127+128128+ | Exception exn ->
129129+ Printf.eprintf
130130+ "Test '%s' raised '%s'\n" test_name (Printexc.to_string exn))
131131+132132+133133+134134+type aggregated_outcomes = (string * ((string * outcome) list)) list
135135+136136+let fold_over_outcomes :
137137+ ('a -> suite_name:string -> test_name:string -> outcome -> 'a) ->
138138+ 'a ->
139139+ aggregated_outcomes ->
140140+ 'a =
141141+142142+ fun f init outcomes ->
143143+144144+ List.fold_left (fun accumulator (suite_name, test_outcomes) ->
145145+ List.fold_left (fun accumulator (test_name, test_outcome) ->
146146+ f accumulator ~suite_name ~test_name test_outcome)
147147+ accumulator
148148+ test_outcomes)
149149+ init
150150+ outcomes
151151+152152+let count_ran : aggregated_outcomes -> int =
153153+ fold_over_outcomes
154154+ (fun count ~suite_name:_ ~test_name:_ -> function
155155+ | Skipped ->
156156+ count
157157+ | _ ->
158158+ count + 1)
159159+ 0
160160+161161+let count_skipped : aggregated_outcomes -> int =
162162+ fold_over_outcomes
163163+ (fun count ~suite_name:_ ~test_name:_ -> function
164164+ | Skipped ->
165165+ count + 1
166166+ | _ ->
167167+ count)
168168+ 0
169169+170170+(* Runs a series of test suites. If one of the test suites fails, does not run
171171+ subsequent suites. *)
172172+let run library_name suites =
173173+ Printexc.register_printer (function
174174+ | Failure message -> Some (Printf.sprintf "Failure(%S)" message)
175175+ | _ -> None);
176176+177177+ Printf.printf "Testing library '%s'...\n" library_name;
178178+179179+ let rec loop_over_suites aggregated_outcomes suites =
180180+ match suites with
181181+ | [] ->
182182+ Printf.printf
183183+ "\nOk. %i tests ran, %i tests skipped\n"
184184+ (count_ran aggregated_outcomes)
185185+ (count_skipped aggregated_outcomes);
186186+ Lwt.return_unit
187187+188188+ | suite::rest ->
189189+ Lwt.bind (run_test_suite suite) begin fun outcomes ->
190190+ if not (outcomes_all_ok outcomes) then begin
191191+ print_newline ();
192192+ flush stdout;
193193+ Printf.eprintf "Failures in test suite '%s':\n" suite.suite_name;
194194+ show_failures outcomes;
195195+ exit 1
196196+ end
197197+ else
198198+ loop_over_suites
199199+ ((suite.suite_name, outcomes)::aggregated_outcomes) rest
200200+ end
201201+ in
202202+203203+ loop_over_suites [] suites
204204+ |> Lwt_main.run
205205+206206+let with_async_exception_hook hook f =
207207+ let old_hook = !Lwt.async_exception_hook in
208208+ Lwt.async_exception_hook := hook;
209209+ Lwt.finalize f (fun () ->
210210+ Lwt.async_exception_hook := old_hook;
211211+ Lwt.return ())
+40
vendor/opam/lwt-dllist/test/test.mli
···11+(* This file is part of Lwt, released under the MIT license. See LICENSE.md for
22+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
33+44+55+66+(** Helpers for tests. *)
77+88+type test
99+(** Type of a test *)
1010+1111+type suite
1212+(** Type of a suite of tests *)
1313+1414+exception Skip
1515+(** In some tests, it is only clear that the test should be skipped after it has
1616+ started running (for example, after an attempted system call raises a
1717+ certain exception, indicating it is not supported).
1818+1919+ Such tests should raise [Test.Skip], or reject their final promise with
2020+ [Test.Skip]. *)
2121+2222+val test_direct : string -> ?only_if:(unit -> bool) -> (unit -> bool) -> test
2323+(** Defines a test. [run] must returns [true] if the test succeeded
2424+ and [false] otherwise. [only_if] is used to conditionally skip the
2525+ test. *)
2626+2727+val test : string -> ?only_if:(unit -> bool) -> (unit -> bool Lwt.t) -> test
2828+(** Like [test_direct], but defines a test which runs a thread. *)
2929+3030+val suite : string -> ?only_if:(unit -> bool) -> test list -> suite
3131+(** Defines a suite of tests *)
3232+3333+val run : string -> suite list -> unit
3434+(** Run all the given tests and exit the program with an exit code
3535+ of [0] if all tests succeeded and with [1] otherwise. *)
3636+3737+val with_async_exception_hook : (exn -> unit) -> (unit -> 'a Lwt.t) -> 'a Lwt.t
3838+(** [Test.with_async_exception_hook hook f] sets [!Lwt.async_exception_hook] to
3939+ [hook], runs [f ()], and then restores [!Lwt.async_exception_hook] to its
4040+ former value. *)
+417
vendor/opam/lwt-dllist/test/test_lwt_dllist.ml
···11+(* This file is part of Lwt, released under the MIT license. See LICENSE.md for
22+ details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)
33+44+open Test
55+66+let filled_sequence () =
77+ let s = Lwt_dllist.create () in
88+ let _ = Lwt_dllist.add_r 1 s in
99+ let _ = Lwt_dllist.add_r 2 s in
1010+ let _ = Lwt_dllist.add_r 3 s in
1111+ let _ = Lwt_dllist.add_r 4 s in
1212+ let _ = Lwt_dllist.add_r 5 s in
1313+ let _ = Lwt_dllist.add_r 6 s in
1414+ s
1515+1616+let filled_length = 6
1717+1818+let leftmost_value = 1
1919+2020+let rightmost_value = 6
2121+2222+let transfer_sequence () =
2323+ let s = Lwt_dllist.create () in
2424+ let _ = Lwt_dllist.add_r 7 s in
2525+ let _ = Lwt_dllist.add_r 8 s in
2626+ s
2727+2828+let transfer_length = 2
2929+3030+let empty_array = [||]
3131+3232+let l_filled_array = [|1; 2; 3; 4; 5; 6|]
3333+3434+let r_filled_array = [|6; 5; 4; 3; 2; 1|]
3535+3636+let factorial_sequence = 720
3737+3838+let test_iter iter_f array_values seq =
3939+ let index = ref 0 in
4040+ Lwt.catch
4141+ (fun () ->
4242+ iter_f (fun v ->
4343+ assert (v = array_values.(!index));
4444+ index := (!index + 1)) seq;
4545+ Lwt.return_true)
4646+ (function _ -> Lwt.return_false)
4747+4848+let test_iter_node iter_f array_values seq =
4949+ let index = ref 0 in
5050+ Lwt.catch
5151+ (fun () ->
5252+ iter_f (fun n ->
5353+ assert ((Lwt_dllist.get n) = array_values.(!index));
5454+ index := (!index + 1)) seq;
5555+ Lwt.return_true)
5656+ (function _ -> Lwt.return_false)
5757+5858+let test_iter_rem iter_f array_values seq =
5959+ let index = ref 0 in
6060+ Lwt.catch
6161+ (fun () ->
6262+ iter_f (fun n ->
6363+ assert ((Lwt_dllist.get n) = array_values.(!index));
6464+ Lwt_dllist.remove n;
6565+ index := (!index + 1)) seq;
6666+ Lwt.return_true)
6767+ (function _ -> Lwt.return_false)
6868+6969+let suite = suite "lwt_sequence" [
7070+7171+ test "create" begin fun () ->
7272+ let s = Lwt_dllist.create () in
7373+ let _ = assert (Lwt_dllist.is_empty s) in
7474+ let len = Lwt_dllist.length s in
7575+ Lwt.return (len = 0)
7676+ end;
7777+7878+ test "add_l" begin fun () ->
7979+ let s = Lwt_dllist.create () in
8080+ let n = Lwt_dllist.add_l 1 s in
8181+ let _ = assert ((Lwt_dllist.get n) = 1) in
8282+ let len = Lwt_dllist.length s in
8383+ Lwt.return (len = 1)
8484+ end;
8585+8686+ test "add_r" begin fun () ->
8787+ let s = Lwt_dllist.create () in
8888+ let n = Lwt_dllist.add_r 1 s in
8989+ let _ = assert ((Lwt_dllist.get n) = 1) in
9090+ let len = Lwt_dllist.length s in
9191+ Lwt.return (len = 1)
9292+ end;
9393+9494+ test "take_l Empty" begin fun () ->
9595+ let s = Lwt_dllist.create () in
9696+ Lwt.catch
9797+ (fun () ->
9898+ let _ = Lwt_dllist.take_l s in
9999+ Lwt.return_false)
100100+ (function
101101+ | Lwt_dllist.Empty -> Lwt.return_true
102102+ | _ -> Lwt.return_false)
103103+ end;
104104+105105+ test "take_l" begin fun () ->
106106+ let s = filled_sequence () in
107107+ Lwt.catch
108108+ (fun () ->
109109+ let v = Lwt_dllist.take_l s in
110110+ Lwt.return (leftmost_value = v))
111111+ (function _ -> Lwt.return_false)
112112+ end;
113113+114114+ test "take_r Empty" begin fun () ->
115115+ let s = Lwt_dllist.create () in
116116+ Lwt.catch
117117+ (fun () ->
118118+ let _ = Lwt_dllist.take_r s in Lwt.return_false)
119119+ (function
120120+ | Lwt_dllist.Empty -> Lwt.return_true
121121+ | _ -> Lwt.return_false)
122122+ end;
123123+124124+ test "take_r" begin fun () ->
125125+ let s = filled_sequence () in
126126+ Lwt.catch
127127+ (fun () ->
128128+ let v = Lwt_dllist.take_r s in Lwt.return (rightmost_value = v))
129129+ (function _ -> Lwt.return_false)
130130+ end;
131131+132132+ test "take_opt_l Empty" begin fun () ->
133133+ let s = Lwt_dllist.create () in
134134+ match Lwt_dllist.take_opt_l s with
135135+ | None -> Lwt.return_true
136136+ | _ -> Lwt.return_false
137137+ end;
138138+139139+ test "take_opt_l" begin fun () ->
140140+ let s = filled_sequence () in
141141+ match Lwt_dllist.take_opt_l s with
142142+ | None -> Lwt.return_false
143143+ | Some v -> Lwt.return (leftmost_value = v)
144144+ end;
145145+146146+ test "take_opt_r Empty" begin fun () ->
147147+ let s = Lwt_dllist.create () in
148148+ match Lwt_dllist.take_opt_r s with
149149+ | None -> Lwt.return_true
150150+ | _ -> Lwt.return_false
151151+ end;
152152+153153+ test "take_opt_r" begin fun () ->
154154+ let s = filled_sequence () in
155155+ match Lwt_dllist.take_opt_r s with
156156+ | None -> Lwt.return_false
157157+ | Some v -> Lwt.return (rightmost_value = v)
158158+ end;
159159+160160+ test "transfer_l Empty" begin fun () ->
161161+ let s = filled_sequence () in
162162+ let ts = Lwt_dllist.create () in
163163+ let _ = Lwt_dllist.transfer_l ts s in
164164+ let len = Lwt_dllist.length s in
165165+ Lwt.return (filled_length = len)
166166+ end;
167167+168168+ test "transfer_l " begin fun () ->
169169+ let s = filled_sequence () in
170170+ let ts = transfer_sequence () in
171171+ let _ = Lwt_dllist.transfer_l ts s in
172172+ let len = Lwt_dllist.length s in
173173+ let _ = assert ((filled_length + transfer_length) = len) in
174174+ match Lwt_dllist.take_opt_l s with
175175+ | None -> Lwt.return_false
176176+ | Some v -> Lwt.return (7 = v)
177177+ end;
178178+179179+ test "transfer_r Empty" begin fun () ->
180180+ let s = filled_sequence () in
181181+ let ts = Lwt_dllist.create () in
182182+ let _ = Lwt_dllist.transfer_r ts s in
183183+ let len = Lwt_dllist.length s in
184184+ Lwt.return (filled_length = len)
185185+ end;
186186+187187+ test "transfer_r " begin fun () ->
188188+ let s = filled_sequence () in
189189+ let ts = transfer_sequence () in
190190+ let _ = Lwt_dllist.transfer_r ts s in
191191+ let len = Lwt_dllist.length s in
192192+ let _ = assert ((filled_length + transfer_length) = len) in
193193+ match Lwt_dllist.take_opt_r s with
194194+ | None -> Lwt.return_false
195195+ | Some v -> Lwt.return (8 = v)
196196+ end;
197197+198198+ test "iter_l Empty" begin fun () ->
199199+ test_iter Lwt_dllist.iter_l empty_array (Lwt_dllist.create ())
200200+ end;
201201+202202+ test "iter_l" begin fun () ->
203203+ test_iter Lwt_dllist.iter_l l_filled_array (filled_sequence ())
204204+ end;
205205+206206+ test "iter_r Empty" begin fun () ->
207207+ test_iter Lwt_dllist.iter_r empty_array (Lwt_dllist.create ())
208208+ end;
209209+210210+ test "iter_r" begin fun () ->
211211+ test_iter Lwt_dllist.iter_r r_filled_array (filled_sequence ())
212212+ end;
213213+214214+ test "iter_node_l Empty" begin fun () ->
215215+ test_iter_node Lwt_dllist.iter_node_l empty_array (Lwt_dllist.create ())
216216+ end;
217217+218218+ test "iter_node_l" begin fun () ->
219219+ test_iter_node Lwt_dllist.iter_node_l l_filled_array (filled_sequence ())
220220+ end;
221221+222222+ test "iter_node_r Empty" begin fun () ->
223223+ test_iter_node Lwt_dllist.iter_node_r empty_array (Lwt_dllist.create ())
224224+ end;
225225+226226+ test "iter_node_r" begin fun () ->
227227+ test_iter_node Lwt_dllist.iter_node_r r_filled_array (filled_sequence ())
228228+ end;
229229+230230+ test "iter_node_l with removal" begin fun () ->
231231+ test_iter_rem Lwt_dllist.iter_node_l l_filled_array (filled_sequence ())
232232+ end;
233233+234234+ test "iter_node_r with removal" begin fun () ->
235235+ test_iter_rem Lwt_dllist.iter_node_r r_filled_array (filled_sequence ())
236236+ end;
237237+238238+ test "fold_l" begin fun () ->
239239+ let acc = Lwt_dllist.fold_l (fun v e -> v * e) (filled_sequence ()) 1 in
240240+ Lwt.return (factorial_sequence = acc)
241241+ end;
242242+243243+ test "fold_l Empty" begin fun () ->
244244+ let acc = Lwt_dllist.fold_l (fun v e -> v * e) (Lwt_dllist.create ()) 1 in
245245+ Lwt.return (acc = 1)
246246+ end;
247247+248248+ test "fold_r" begin fun () ->
249249+ let acc = Lwt_dllist.fold_r (fun v e -> v * e) (filled_sequence ()) 1 in
250250+ Lwt.return (factorial_sequence = acc)
251251+ end;
252252+253253+ test "fold_r Empty" begin fun () ->
254254+ let acc = Lwt_dllist.fold_r (fun v e -> v * e) (Lwt_dllist.create ()) 1 in
255255+ Lwt.return (acc = 1)
256256+ end;
257257+258258+ test "find_node_opt_l Empty" begin fun () ->
259259+ let s = Lwt_dllist.create () in
260260+ match Lwt_dllist.find_node_opt_l (fun v -> v = 1) s with
261261+ | None -> Lwt.return_true
262262+ | _ -> Lwt.return_false
263263+ end;
264264+265265+ test "find_node_opt_l not found " begin fun () ->
266266+ let s = transfer_sequence () in
267267+ match Lwt_dllist.find_node_opt_l (fun v -> v = 1) s with
268268+ | None -> Lwt.return_true
269269+ | _ -> Lwt.return_false
270270+ end;
271271+272272+ test "find_node_opt_l" begin fun () ->
273273+ let s = filled_sequence () in
274274+ match Lwt_dllist.find_node_opt_l (fun v -> v = 1) s with
275275+ | None -> Lwt.return_false
276276+ | Some n -> if ((Lwt_dllist.get n) = 1) then Lwt.return_true
277277+ else Lwt.return_false
278278+ end;
279279+280280+ test "find_node_opt_r Empty" begin fun () ->
281281+ let s = Lwt_dllist.create () in
282282+ match Lwt_dllist.find_node_opt_r (fun v -> v = 1) s with
283283+ | None -> Lwt.return_true
284284+ | _ -> Lwt.return_false
285285+ end;
286286+287287+ test "find_node_opt_r not found " begin fun () ->
288288+ let s = transfer_sequence () in
289289+ match Lwt_dllist.find_node_opt_r (fun v -> v = 1) s with
290290+ | None -> Lwt.return_true
291291+ | _ -> Lwt.return_false
292292+ end;
293293+294294+ test "find_node_opt_r" begin fun () ->
295295+ let s = filled_sequence () in
296296+ match Lwt_dllist.find_node_opt_r (fun v -> v = 1) s with
297297+ | None -> Lwt.return_false
298298+ | Some n -> if ((Lwt_dllist.get n) = 1) then Lwt.return_true
299299+ else Lwt.return_false
300300+ end;
301301+302302+ test "find_node_l Empty" begin fun () ->
303303+ let s = Lwt_dllist.create () in
304304+ Lwt.catch
305305+ (fun () -> let n = Lwt_dllist.find_node_l (fun v -> v = 1) s in
306306+ if ((Lwt_dllist.get n) = 1) then Lwt.return_false
307307+ else Lwt.return_false)
308308+ (function
309309+ | Not_found -> Lwt.return_true
310310+ | _ -> Lwt.return_false)
311311+ end;
312312+313313+ test "find_node_l" begin fun () ->
314314+ let s = filled_sequence () in
315315+ Lwt.catch
316316+ (fun () -> let n = Lwt_dllist.find_node_l (fun v -> v = 1) s in
317317+ if ((Lwt_dllist.get n) = 1) then Lwt.return_true
318318+ else Lwt.return_false)
319319+ (function _ -> Lwt.return_false)
320320+ end;
321321+322322+ test "find_node_r Empty" begin fun () ->
323323+ let s = Lwt_dllist.create () in
324324+ Lwt.catch
325325+ (fun () -> let n = Lwt_dllist.find_node_r (fun v -> v = 1) s in
326326+ if ((Lwt_dllist.get n) = 1) then Lwt.return_false
327327+ else Lwt.return_false)
328328+ (function
329329+ | Not_found -> Lwt.return_true
330330+ | _ -> Lwt.return_false)
331331+ end;
332332+333333+ test "find_node_r" begin fun () ->
334334+ let s = filled_sequence () in
335335+ Lwt.catch
336336+ (fun () -> let n = Lwt_dllist.find_node_r (fun v -> v = 1) s in
337337+ if ((Lwt_dllist.get n) = 1) then Lwt.return_true
338338+ else Lwt.return_false)
339339+ (function _ -> Lwt.return_false)
340340+ end;
341341+342342+ test "set" begin fun () ->
343343+ let s = filled_sequence () in
344344+ match Lwt_dllist.find_node_opt_l (fun v -> v = 4) s with
345345+ | None -> Lwt.return_false
346346+ | Some n -> let _ = Lwt_dllist.set n 10 in
347347+ let data = [|1; 2; 3; 10; 5; 6|] in
348348+ test_iter Lwt_dllist.iter_l data s
349349+ end;
350350+351351+ test "fold_r with multiple removal" begin fun () ->
352352+ let s = filled_sequence () in
353353+ let n_three = Lwt_dllist.find_node_r (fun v' -> v' = 3) s in
354354+ let n_two = Lwt_dllist.find_node_r (fun v' -> v' = 2) s in
355355+ let n_four = Lwt_dllist.find_node_r (fun v' -> v' = 4) s in
356356+ let acc = Lwt_dllist.fold_r begin fun v e ->
357357+ if v = 3 then begin
358358+ let _ = Lwt_dllist.remove n_three in
359359+ let _ = Lwt_dllist.remove n_two in
360360+ ignore(Lwt_dllist.remove n_four)
361361+ end;
362362+ v * e
363363+ end s 1 in
364364+ Lwt.return (acc = (factorial_sequence / 2))
365365+ end;
366366+367367+ test "fold_l multiple removal" begin fun () ->
368368+ let s = filled_sequence () in
369369+ let n_four = Lwt_dllist.find_node_r (fun v' -> v' = 4) s in
370370+ let n_five = Lwt_dllist.find_node_r (fun v' -> v' = 5) s in
371371+ let n_three = Lwt_dllist.find_node_r (fun v' -> v' = 3) s in
372372+ let acc = Lwt_dllist.fold_l begin fun v e ->
373373+ if v = 4 then begin
374374+ let _ = Lwt_dllist.remove n_four in
375375+ let _ = Lwt_dllist.remove n_five in
376376+ ignore(Lwt_dllist.remove n_three)
377377+ end;
378378+ v * e
379379+ end s 1 in
380380+ Lwt.return (acc = (factorial_sequence / 5))
381381+ end;
382382+383383+ test "find_node_r with multiple removal" begin fun () ->
384384+ let s = filled_sequence () in
385385+ let n_three = Lwt_dllist.find_node_r (fun v' -> v' = 3) s in
386386+ let n_two = Lwt_dllist.find_node_r (fun v' -> v' = 2) s in
387387+ Lwt.catch
388388+ begin fun () ->
389389+ let n = Lwt_dllist.find_node_r begin fun v ->
390390+ if v = 3 then (
391391+ let _ = Lwt_dllist.remove n_three in
392392+ ignore(Lwt_dllist.remove n_two));
393393+ v = 1
394394+ end s in
395395+ let v = Lwt_dllist.get n in
396396+ Lwt.return (v = 1)
397397+ end
398398+ (function _ -> Lwt.return_false)
399399+ end;
400400+401401+ test "find_node_l with multiple removal" begin fun () ->
402402+ let s = filled_sequence () in
403403+ let n_three = Lwt_dllist.find_node_r (fun v' -> v' = 3) s in
404404+ let n_four = Lwt_dllist.find_node_r (fun v' -> v' = 4) s in
405405+ Lwt.catch
406406+ begin fun () ->
407407+ let n = Lwt_dllist.find_node_l begin fun v ->
408408+ if v = 3 then (
409409+ let _ = Lwt_dllist.remove n_three in
410410+ ignore(Lwt_dllist.remove n_four));
411411+ v = 6 end s in
412412+ let v = Lwt_dllist.get n in
413413+ Lwt.return (v = 6)
414414+ end
415415+ (function _ -> Lwt.return_false)
416416+ end;
417417+]