From 96398bf91d27540ae66dbe83f5b53ab81f0255b3 Mon Sep 17 00:00:00 2001 From: davesnx Date: Mon, 9 Sep 2024 02:13:12 +0000 Subject: [PATCH] Deploy to GitHub pages --- docs/findlib-0/index.html | 2 + docs/findlib-0/str/Str/index.html | 4 + docs/findlib-0/str/index.html | 2 + .../Bigarray_compat/index.html | 24 + docs/findlib-1/bigarray-compat/index.html | 2 + docs/findlib-1/ctypes/ComplexL/index.html | 2 + .../ctypes/Cstubs_internals/index.html | 12 + .../findlib-1/ctypes/Ctypes/CArray/index.html | 2 + .../ctypes/Ctypes/Intptr/Infix/index.html | 2 + .../findlib-1/ctypes/Ctypes/Intptr/index.html | 2 + .../ctypes/Ctypes/Ptrdiff/Infix/index.html | 2 + .../ctypes/Ctypes/Ptrdiff/index.html | 2 + docs/findlib-1/ctypes/Ctypes/Root/index.html | 2 + .../ctypes/Ctypes/Uintptr/Infix/index.html | 2 + .../ctypes/Ctypes/Uintptr/index.html | 2 + docs/findlib-1/ctypes/Ctypes/index.html | 118 ++ .../Ctypes/module-type-FOREIGN/index.html | 2 + .../module-type-TYPE/Intptr/Infix/index.html | 2 + .../Ctypes/module-type-TYPE/Intptr/index.html | 2 + .../module-type-TYPE/Ptrdiff/Infix/index.html | 2 + .../module-type-TYPE/Ptrdiff/index.html | 2 + .../module-type-TYPE/Uintptr/Infix/index.html | 2 + .../module-type-TYPE/Uintptr/index.html | 2 + .../ctypes/Ctypes/module-type-TYPE/index.html | 49 + .../ctypes/Ctypes_bigarray/index.html | 25 + .../ctypes/Ctypes_bigarray_stubs/index.html | 22 + .../findlib-1/ctypes/Ctypes_coerce/index.html | 2 + .../ctypes/Ctypes_memory/CArray/index.html | 15 + .../ctypes/Ctypes_memory/Root/index.html | 2 + .../findlib-1/ctypes/Ctypes_memory/index.html | 171 ++ .../Ctypes_memory_stubs/Pointer/index.html | 2 + .../ctypes/Ctypes_memory_stubs/index.html | 10 + .../ctypes/Ctypes_primitive_types/index.html | 2 + .../ctypes/Ctypes_primitives/index.html | 2 + .../ctypes/Ctypes_ptr/Fat/index.html | 2 + .../ctypes/Ctypes_ptr/Raw/index.html | 3 + docs/findlib-1/ctypes/Ctypes_ptr/index.html | 2 + .../ctypes/Ctypes_roots_stubs/index.html | 2 + .../findlib-1/ctypes/Ctypes_static/index.html | 52 + .../ctypes/Ctypes_std_view_stubs/index.html | 2 + .../Ctypes_std_views/Intptr/Infix/index.html | 2 + .../ctypes/Ctypes_std_views/Intptr/index.html | 2 + .../Ctypes_std_views/Ptrdiff/Infix/index.html | 2 + .../Ctypes_std_views/Ptrdiff/index.html | 2 + .../Ctypes_std_views/Uintptr/Infix/index.html | 2 + .../Ctypes_std_views/Uintptr/index.html | 2 + .../ctypes/Ctypes_std_views/index.html | 30 + .../module-type-Signed_type/Infix/index.html | 2 + .../module-type-Signed_type/index.html | 2 + .../Infix/index.html | 2 + .../module-type-Unsigned_type/index.html | 2 + .../ctypes/Ctypes_structs/index.html | 2 + .../Ctypes_structs/module-type-S/index.html | 8 + .../ctypes/Ctypes_structs_computed/index.html | 10 + .../ctypes/Ctypes_type_printing/index.html | 15 + docs/findlib-1/ctypes/Ctypes_types/index.html | 2 + .../module-type-TYPE/Intptr/Infix/index.html | 2 + .../module-type-TYPE/Intptr/index.html | 2 + .../module-type-TYPE/Ptrdiff/Infix/index.html | 2 + .../module-type-TYPE/Ptrdiff/index.html | 2 + .../module-type-TYPE/Uintptr/Infix/index.html | 2 + .../module-type-TYPE/Uintptr/index.html | 2 + .../Ctypes_types/module-type-TYPE/index.html | 36 + .../ctypes/Ctypes_value_printing/index.html | 13 + .../Ctypes_value_printing_stubs/index.html | 2 + docs/findlib-1/ctypes/LDouble/index.html | 2 + .../ctypes/PosixTypes/Dev/Infix/index.html | 2 + .../ctypes/PosixTypes/Dev/index.html | 2 + .../ctypes/PosixTypes/Ino/Infix/index.html | 2 + .../ctypes/PosixTypes/Ino/index.html | 2 + .../ctypes/PosixTypes/Mode/Infix/index.html | 2 + .../ctypes/PosixTypes/Mode/index.html | 2 + .../ctypes/PosixTypes/Nlink/Infix/index.html | 2 + .../ctypes/PosixTypes/Nlink/index.html | 2 + .../ctypes/PosixTypes/Off/Infix/index.html | 2 + .../ctypes/PosixTypes/Off/index.html | 2 + .../ctypes/PosixTypes/Pid/Infix/index.html | 2 + .../ctypes/PosixTypes/Pid/index.html | 2 + .../ctypes/PosixTypes/Ssize/Infix/index.html | 2 + .../ctypes/PosixTypes/Ssize/index.html | 2 + .../ctypes/PosixTypes/Time/Infix/index.html | 2 + .../ctypes/PosixTypes/Time/index.html | 2 + docs/findlib-1/ctypes/PosixTypes/index.html | 2 + docs/findlib-1/ctypes/index.html | 2 + .../ctypes/stubs/Cstubs/Types/index.html | 2 + .../argument-1-F/Intptr/Infix/index.html | 2 + .../argument-1-F/Intptr/index.html | 2 + .../argument-1-F/Ptrdiff/Infix/index.html | 2 + .../argument-1-F/Ptrdiff/index.html | 2 + .../argument-1-F/Uintptr/Infix/index.html | 2 + .../argument-1-F/Uintptr/index.html | 2 + .../argument-1-F/index.html | 49 + .../Types/module-type-BINDINGS/index.html | 2 + docs/findlib-1/ctypes/stubs/Cstubs/index.html | 16 + .../argument-1-F/index.html | 2 + .../Cstubs/module-type-BINDINGS/index.html | 2 + .../ctypes/stubs/Cstubs_analysis/index.html | 2 + .../stubs/Cstubs_c_language/Type_C/index.html | 6 + .../Unchecked_function_types/index.html | 5 + .../ctypes/stubs/Cstubs_c_language/index.html | 2 + .../ctypes/stubs/Cstubs_emit_c/index.html | 18 + .../ctypes/stubs/Cstubs_errors/index.html | 2 + .../ctypes/stubs/Cstubs_generate_c/index.html | 23 + .../stubs/Cstubs_generate_ml/index.html | 33 + .../ctypes/stubs/Cstubs_inverted/index.html | 6 + .../argument-1-F/index.html | 7 + .../module-type-BINDINGS/index.html | 2 + .../module-type-INTERNAL/index.html | 7 + .../stubs/Cstubs_public_name/index.html | 7 + .../ctypes/stubs/Cstubs_structs/index.html | 2 + .../argument-1-F/Intptr/Infix/index.html | 2 + .../argument-1-F/Intptr/index.html | 2 + .../argument-1-F/Ptrdiff/Infix/index.html | 2 + .../argument-1-F/Ptrdiff/index.html | 2 + .../argument-1-F/Uintptr/Infix/index.html | 2 + .../argument-1-F/Uintptr/index.html | 2 + .../argument-1-F/index.html | 41 + .../module-type-BINDINGS/index.html | 2 + .../module-type-TYPE/Intptr/Infix/index.html | 2 + .../module-type-TYPE/Intptr/index.html | 2 + .../module-type-TYPE/Ptrdiff/Infix/index.html | 2 + .../module-type-TYPE/Ptrdiff/index.html | 2 + .../module-type-TYPE/Uintptr/Infix/index.html | 2 + .../module-type-TYPE/Uintptr/index.html | 2 + .../module-type-TYPE/index.html | 41 + .../ctypes/stubs/Ctypes_path/index.html | 2 + docs/findlib-1/ctypes/stubs/index.html | 2 + docs/findlib-1/index.html | 2 + .../integers/Signed/Int/Infix/index.html | 2 + docs/findlib-1/integers/Signed/Int/index.html | 2 + .../integers/Signed/Int32/Infix/index.html | 2 + .../integers/Signed/Int32/index.html | 2 + .../integers/Signed/Int64/Infix/index.html | 2 + .../integers/Signed/Int64/index.html | 2 + .../integers/Signed/LLong/Infix/index.html | 2 + .../integers/Signed/LLong/index.html | 2 + .../integers/Signed/Long/Infix/index.html | 2 + .../findlib-1/integers/Signed/Long/index.html | 2 + .../integers/Signed/SInt/Infix/index.html | 2 + .../findlib-1/integers/Signed/SInt/index.html | 2 + docs/findlib-1/integers/Signed/index.html | 2 + .../Signed/module-type-Infix/index.html | 2 + .../Signed/module-type-S/Infix/index.html | 2 + .../integers/Signed/module-type-S/index.html | 2 + .../integers/Unsigned/Size_t/Infix/index.html | 2 + .../integers/Unsigned/Size_t/index.html | 2 + .../integers/Unsigned/UChar/Infix/index.html | 2 + .../integers/Unsigned/UChar/index.html | 2 + .../integers/Unsigned/UInt/Infix/index.html | 2 + .../integers/Unsigned/UInt/index.html | 2 + .../integers/Unsigned/UInt16/Infix/index.html | 2 + .../integers/Unsigned/UInt16/index.html | 2 + .../integers/Unsigned/UInt32/Infix/index.html | 2 + .../integers/Unsigned/UInt32/index.html | 2 + .../integers/Unsigned/UInt64/Infix/index.html | 2 + .../integers/Unsigned/UInt64/index.html | 2 + .../integers/Unsigned/UInt8/Infix/index.html | 2 + .../integers/Unsigned/UInt8/index.html | 2 + .../integers/Unsigned/ULLong/Infix/index.html | 2 + .../integers/Unsigned/ULLong/index.html | 2 + .../integers/Unsigned/ULong/Infix/index.html | 2 + .../integers/Unsigned/ULong/index.html | 2 + .../integers/Unsigned/UShort/Infix/index.html | 2 + .../integers/Unsigned/UShort/index.html | 2 + docs/findlib-1/integers/Unsigned/index.html | 2 + .../Unsigned/module-type-Infix/index.html | 2 + .../Unsigned/module-type-S/Infix/index.html | 2 + .../Unsigned/module-type-S/index.html | 2 + docs/findlib-1/integers/index.html | 2 + docs/findlib-1/stdlib-shims/index.html | 2 + docs/index.html | 2 + docs/local/index.html | 2 + docs/local/quickjs/Quickjs/RegExp/index.html | 12 + docs/local/quickjs/Quickjs/index.html | 2 + .../bindings/Bindings/C/Functions/index.html | 40 + .../quickjs/bindings/Bindings/C/index.html | 2 + .../Functions/argument-1-F/index.html | 2 + .../Function_description/Functions/index.html | 24 + .../Bindings/Function_description/index.html | 2 + .../argument-1-T/Intptr/Infix/index.html | 2 + .../Types/argument-1-T/Intptr/index.html | 2 + .../argument-1-T/Ptrdiff/Infix/index.html | 2 + .../Types/argument-1-T/Ptrdiff/index.html | 2 + .../argument-1-T/Uintptr/Infix/index.html | 2 + .../Types/argument-1-T/Uintptr/index.html | 2 + .../Types/argument-1-T/index.html | 49 + .../Type_description/Types/index.html | 2 + .../Bindings/Type_description/index.html | 2 + .../Bindings/Types_generated/index.html | 2 + .../quickjs/bindings/Bindings/index.html | 2 + docs/local/quickjs/bindings/index.html | 2 + docs/local/quickjs/index.html | 2 + .../fonts/KaTeX_AMS-Regular.woff2 | Bin 0 -> 28076 bytes .../fonts/KaTeX_Caligraphic-Bold.woff2 | Bin 0 -> 6912 bytes .../fonts/KaTeX_Caligraphic-Regular.woff2 | Bin 0 -> 6908 bytes .../fonts/KaTeX_Fraktur-Bold.woff2 | Bin 0 -> 11348 bytes .../fonts/KaTeX_Fraktur-Regular.woff2 | Bin 0 -> 11316 bytes docs/odoc.support/fonts/KaTeX_Main-Bold.woff2 | Bin 0 -> 25324 bytes .../fonts/KaTeX_Main-BoldItalic.woff2 | Bin 0 -> 16780 bytes .../fonts/KaTeX_Main-Italic.woff2 | Bin 0 -> 16988 bytes .../fonts/KaTeX_Main-Regular.woff2 | Bin 0 -> 26272 bytes .../fonts/KaTeX_Math-BoldItalic.woff2 | Bin 0 -> 16400 bytes .../fonts/KaTeX_Math-Italic.woff2 | Bin 0 -> 16440 bytes .../fonts/KaTeX_SansSerif-Bold.woff2 | Bin 0 -> 12216 bytes .../fonts/KaTeX_SansSerif-Italic.woff2 | Bin 0 -> 12028 bytes .../fonts/KaTeX_SansSerif-Regular.woff2 | Bin 0 -> 10344 bytes .../fonts/KaTeX_Script-Regular.woff2 | Bin 0 -> 9644 bytes .../fonts/KaTeX_Size1-Regular.woff2 | Bin 0 -> 5468 bytes .../fonts/KaTeX_Size2-Regular.woff2 | Bin 0 -> 5208 bytes .../fonts/KaTeX_Size3-Regular.woff2 | Bin 0 -> 3624 bytes .../fonts/KaTeX_Size4-Regular.woff2 | Bin 0 -> 4928 bytes .../fonts/KaTeX_Typewriter-Regular.woff2 | Bin 0 -> 13568 bytes .../fonts/fira-mono-v14-latin-500.woff2 | Bin 0 -> 16148 bytes .../fonts/fira-mono-v14-latin-regular.woff2 | Bin 0 -> 16284 bytes .../fonts/fira-sans-v17-latin-500.woff2 | Bin 0 -> 24020 bytes .../fonts/fira-sans-v17-latin-500italic.woff2 | Bin 0 -> 24896 bytes .../fonts/fira-sans-v17-latin-700.woff2 | Bin 0 -> 24964 bytes .../fonts/fira-sans-v17-latin-700italic.woff2 | Bin 0 -> 26072 bytes .../fonts/fira-sans-v17-latin-italic.woff2 | Bin 0 -> 24936 bytes .../fonts/fira-sans-v17-latin-regular.woff2 | Bin 0 -> 23880 bytes .../fonts/noticia-text-v15-latin-700.woff2 | Bin 0 -> 21972 bytes .../fonts/noticia-text-v15-latin-italic.woff2 | Bin 0 -> 17356 bytes .../noticia-text-v15-latin-regular.woff2 | Bin 0 -> 22308 bytes docs/odoc.support/highlight.pack.js | 634 ++++++++ docs/odoc.support/katex.min.css | 1 + docs/odoc.support/katex.min.js | 1 + docs/odoc.support/odoc.css | 1393 +++++++++++++++++ docs/odoc.support/odoc_search.js | 66 + docs/stdlib/CamlinternalFormat/index.html | 53 + .../CamlinternalFormatBasics/index.html | 308 ++++ docs/stdlib/CamlinternalLazy/index.html | 2 + docs/stdlib/CamlinternalMod/index.html | 2 + docs/stdlib/CamlinternalOO/index.html | 18 + docs/stdlib/Std_exit/index.html | 2 + docs/stdlib/Stdlib/Arg/index.html | 38 + docs/stdlib/Stdlib/Array/index.html | 19 + docs/stdlib/Stdlib/ArrayLabels/index.html | 25 + docs/stdlib/Stdlib/Atomic/index.html | 64 + docs/stdlib/Stdlib/Bigarray/Array0/index.html | 2 + docs/stdlib/Stdlib/Bigarray/Array1/index.html | 2 + docs/stdlib/Stdlib/Bigarray/Array2/index.html | 15 + docs/stdlib/Stdlib/Bigarray/Array3/index.html | 28 + .../Stdlib/Bigarray/Genarray/index.html | 15 + docs/stdlib/Stdlib/Bigarray/index.html | 24 + docs/stdlib/Stdlib/Bool/index.html | 2 + docs/stdlib/Stdlib/Buffer/index.html | 5 + docs/stdlib/Stdlib/Bytes/index.html | 17 + docs/stdlib/Stdlib/BytesLabels/index.html | 29 + docs/stdlib/Stdlib/Callback/index.html | 2 + docs/stdlib/Stdlib/Char/index.html | 2 + docs/stdlib/Stdlib/Complex/index.html | 2 + docs/stdlib/Stdlib/Condition/index.html | 31 + docs/stdlib/Stdlib/Digest/index.html | 2 + docs/stdlib/Stdlib/Domain/DLS/index.html | 12 + docs/stdlib/Stdlib/Domain/index.html | 5 + docs/stdlib/Stdlib/Effect/Deep/index.html | 6 + docs/stdlib/Stdlib/Effect/Shallow/index.html | 7 + docs/stdlib/Stdlib/Effect/index.html | 2 + docs/stdlib/Stdlib/Either/index.html | 17 + .../Stdlib/Ephemeron/K1/Bucket/index.html | 2 + .../Ephemeron/K1/Make/argument-1-H/index.html | 2 + .../Stdlib/Ephemeron/K1/Make/index.html | 2 + .../K1/MakeSeeded/argument-1-H/index.html | 2 + .../Stdlib/Ephemeron/K1/MakeSeeded/index.html | 2 + docs/stdlib/Stdlib/Ephemeron/K1/index.html | 2 + .../Stdlib/Ephemeron/K2/Bucket/index.html | 2 + .../K2/Make/argument-1-H1/index.html | 2 + .../K2/Make/argument-2-H2/index.html | 2 + .../Stdlib/Ephemeron/K2/Make/index.html | 2 + .../K2/MakeSeeded/argument-1-H1/index.html | 2 + .../K2/MakeSeeded/argument-2-H2/index.html | 2 + .../Stdlib/Ephemeron/K2/MakeSeeded/index.html | 2 + docs/stdlib/Stdlib/Ephemeron/K2/index.html | 8 + .../Stdlib/Ephemeron/Kn/Bucket/index.html | 2 + .../Ephemeron/Kn/Make/argument-1-H/index.html | 2 + .../Stdlib/Ephemeron/Kn/Make/index.html | 2 + .../Kn/MakeSeeded/argument-1-H/index.html | 2 + .../Stdlib/Ephemeron/Kn/MakeSeeded/index.html | 2 + docs/stdlib/Stdlib/Ephemeron/Kn/index.html | 4 + docs/stdlib/Stdlib/Ephemeron/index.html | 2 + .../Stdlib/Ephemeron/module-type-S/index.html | 2 + .../Ephemeron/module-type-SeededS/index.html | 2 + docs/stdlib/Stdlib/Filename/index.html | 14 + docs/stdlib/Stdlib/Float/Array/index.html | 13 + .../Stdlib/Float/ArrayLabels/index.html | 13 + docs/stdlib/Stdlib/Float/index.html | 2 + docs/stdlib/Stdlib/Format/index.html | 148 ++ docs/stdlib/Stdlib/Fun/index.html | 2 + docs/stdlib/Stdlib/Gc/Memprof/index.html | 6 + docs/stdlib/Stdlib/Gc/index.html | 2 + .../Hashtbl/Make/argument-1-H/index.html | 2 + docs/stdlib/Stdlib/Hashtbl/Make/index.html | 2 + .../MakeSeeded/argument-1-H/index.html | 2 + .../Stdlib/Hashtbl/MakeSeeded/index.html | 2 + docs/stdlib/Stdlib/Hashtbl/index.html | 80 + .../Hashtbl/module-type-HashedType/index.html | 2 + .../Stdlib/Hashtbl/module-type-S/index.html | 2 + .../module-type-SeededHashedType/index.html | 2 + .../Hashtbl/module-type-SeededS/index.html | 2 + docs/stdlib/Stdlib/In_channel/index.html | 3 + docs/stdlib/Stdlib/Int/index.html | 2 + docs/stdlib/Stdlib/Int32/index.html | 4 + docs/stdlib/Stdlib/Int64/index.html | 4 + docs/stdlib/Stdlib/LargeFile/index.html | 2 + docs/stdlib/Stdlib/Lazy/index.html | 5 + docs/stdlib/Stdlib/Lexing/index.html | 2 + docs/stdlib/Stdlib/List/index.html | 16 + docs/stdlib/Stdlib/ListLabels/index.html | 16 + .../Stdlib/Map/Make/argument-1-Ord/index.html | 2 + docs/stdlib/Stdlib/Map/Make/index.html | 8 + docs/stdlib/Stdlib/Map/index.html | 13 + .../Map/module-type-OrderedType/index.html | 2 + .../Stdlib/Map/module-type-S/index.html | 8 + docs/stdlib/Stdlib/Marshal/index.html | 2 + .../Hashtbl/Make/argument-1-H/index.html | 2 + .../Stdlib/MoreLabels/Hashtbl/Make/index.html | 2 + .../MakeSeeded/argument-1-H/index.html | 2 + .../MoreLabels/Hashtbl/MakeSeeded/index.html | 2 + .../Stdlib/MoreLabels/Hashtbl/index.html | 91 ++ .../Hashtbl/module-type-HashedType/index.html | 2 + .../Hashtbl/module-type-S/index.html | 2 + .../module-type-SeededHashedType/index.html | 2 + .../Hashtbl/module-type-SeededS/index.html | 2 + .../Map/Make/argument-1-Ord/index.html | 2 + .../Stdlib/MoreLabels/Map/Make/index.html | 8 + docs/stdlib/Stdlib/MoreLabels/Map/index.html | 15 + .../Map/module-type-OrderedType/index.html | 2 + .../MoreLabels/Map/module-type-S/index.html | 8 + .../Set/Make/argument-1-Ord/index.html | 2 + .../Stdlib/MoreLabels/Set/Make/index.html | 3 + docs/stdlib/Stdlib/MoreLabels/Set/index.html | 15 + .../Set/module-type-OrderedType/index.html | 2 + .../MoreLabels/Set/module-type-S/index.html | 3 + docs/stdlib/Stdlib/MoreLabels/index.html | 4 + docs/stdlib/Stdlib/Mutex/index.html | 4 + docs/stdlib/Stdlib/Nativeint/index.html | 5 + docs/stdlib/Stdlib/Obj/Closure/index.html | 2 + docs/stdlib/Stdlib/Obj/Ephemeron/index.html | 2 + .../Obj/Extension_constructor/index.html | 2 + docs/stdlib/Stdlib/Obj/index.html | 2 + docs/stdlib/Stdlib/Oo/index.html | 2 + docs/stdlib/Stdlib/Option/index.html | 2 + docs/stdlib/Stdlib/Out_channel/index.html | 5 + docs/stdlib/Stdlib/Parsing/index.html | 2 + docs/stdlib/Stdlib/Printexc/Slot/index.html | 2 + docs/stdlib/Stdlib/Printexc/index.html | 18 + docs/stdlib/Stdlib/Printf/index.html | 14 + docs/stdlib/Stdlib/Queue/index.html | 78 + docs/stdlib/Stdlib/Random/State/index.html | 2 + docs/stdlib/Stdlib/Random/index.html | 2 + docs/stdlib/Stdlib/Result/index.html | 12 + docs/stdlib/Stdlib/Scanf/Scanning/index.html | 2 + docs/stdlib/Stdlib/Scanf/index.html | 26 + .../stdlib/Stdlib/Semaphore/Binary/index.html | 2 + .../Stdlib/Semaphore/Counting/index.html | 2 + docs/stdlib/Stdlib/Semaphore/index.html | 2 + docs/stdlib/Stdlib/Seq/index.html | 2 + .../Stdlib/Set/Make/argument-1-Ord/index.html | 2 + docs/stdlib/Stdlib/Set/Make/index.html | 3 + docs/stdlib/Stdlib/Set/index.html | 13 + .../Set/module-type-OrderedType/index.html | 2 + .../Stdlib/Set/module-type-S/index.html | 3 + docs/stdlib/Stdlib/Stack/index.html | 2 + docs/stdlib/Stdlib/StdLabels/index.html | 6 + docs/stdlib/Stdlib/String/index.html | 6 + docs/stdlib/Stdlib/StringLabels/index.html | 12 + .../Make/argument-1-Immediate/index.html | 2 + .../Make/argument-2-Non_immediate/index.html | 2 + .../Stdlib/Sys/Immediate64/Make/index.html | 2 + docs/stdlib/Stdlib/Sys/Immediate64/index.html | 5 + .../module-type-Immediate/index.html | 2 + .../module-type-Non_immediate/index.html | 2 + docs/stdlib/Stdlib/Sys/index.html | 4 + docs/stdlib/Stdlib/Type/Id/index.html | 40 + docs/stdlib/Stdlib/Type/index.html | 2 + docs/stdlib/Stdlib/Uchar/index.html | 2 + docs/stdlib/Stdlib/Unit/index.html | 2 + .../Stdlib/Weak/Make/argument-1-H/index.html | 2 + docs/stdlib/Stdlib/Weak/Make/index.html | 2 + docs/stdlib/Stdlib/Weak/index.html | 2 + .../Stdlib/Weak/module-type-S/index.html | 2 + docs/stdlib/Stdlib/index.html | 8 + docs/stdlib/index.html | 2 + 383 files changed, 5102 insertions(+) create mode 100644 docs/findlib-0/index.html create mode 100644 docs/findlib-0/str/Str/index.html create mode 100644 docs/findlib-0/str/index.html create mode 100644 docs/findlib-1/bigarray-compat/Bigarray_compat/index.html create mode 100644 docs/findlib-1/bigarray-compat/index.html create mode 100644 docs/findlib-1/ctypes/ComplexL/index.html create mode 100644 docs/findlib-1/ctypes/Cstubs_internals/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/CArray/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Root/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-FOREIGN/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes/module-type-TYPE/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_bigarray/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_bigarray_stubs/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_coerce/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_memory/CArray/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_memory/Root/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_memory/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_memory_stubs/Pointer/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_memory_stubs/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_primitive_types/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_primitives/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_ptr/Fat/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_ptr/Raw/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_ptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_roots_stubs/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_static/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_view_stubs/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_structs/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_structs/module-type-S/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_structs_computed/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_type_printing/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_value_printing/index.html create mode 100644 docs/findlib-1/ctypes/Ctypes_value_printing_stubs/index.html create mode 100644 docs/findlib-1/ctypes/LDouble/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Dev/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Dev/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Ino/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Ino/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Mode/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Mode/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Nlink/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Nlink/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Off/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Off/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Pid/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Pid/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Ssize/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Ssize/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Time/Infix/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/Time/index.html create mode 100644 docs/findlib-1/ctypes/PosixTypes/index.html create mode 100644 docs/findlib-1/ctypes/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/argument-1-F/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_analysis/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_c_language/Type_C/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_c_language/Unchecked_function_types/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_c_language/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_emit_c/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_errors/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_generate_c/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_generate_ml/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_inverted/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/argument-1-F/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-INTERNAL/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_public_name/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/Infix/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/index.html create mode 100644 docs/findlib-1/ctypes/stubs/Ctypes_path/index.html create mode 100644 docs/findlib-1/ctypes/stubs/index.html create mode 100644 docs/findlib-1/index.html create mode 100644 docs/findlib-1/integers/Signed/Int/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/Int/index.html create mode 100644 docs/findlib-1/integers/Signed/Int32/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/Int32/index.html create mode 100644 docs/findlib-1/integers/Signed/Int64/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/Int64/index.html create mode 100644 docs/findlib-1/integers/Signed/LLong/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/LLong/index.html create mode 100644 docs/findlib-1/integers/Signed/Long/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/Long/index.html create mode 100644 docs/findlib-1/integers/Signed/SInt/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/SInt/index.html create mode 100644 docs/findlib-1/integers/Signed/index.html create mode 100644 docs/findlib-1/integers/Signed/module-type-Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/module-type-S/Infix/index.html create mode 100644 docs/findlib-1/integers/Signed/module-type-S/index.html create mode 100644 docs/findlib-1/integers/Unsigned/Size_t/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/Size_t/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UChar/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UChar/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt16/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt16/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt32/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt32/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt64/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt64/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt8/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UInt8/index.html create mode 100644 docs/findlib-1/integers/Unsigned/ULLong/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/ULLong/index.html create mode 100644 docs/findlib-1/integers/Unsigned/ULong/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/ULong/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UShort/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/UShort/index.html create mode 100644 docs/findlib-1/integers/Unsigned/index.html create mode 100644 docs/findlib-1/integers/Unsigned/module-type-Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/module-type-S/Infix/index.html create mode 100644 docs/findlib-1/integers/Unsigned/module-type-S/index.html create mode 100644 docs/findlib-1/integers/index.html create mode 100644 docs/findlib-1/stdlib-shims/index.html create mode 100644 docs/index.html create mode 100644 docs/local/index.html create mode 100644 docs/local/quickjs/Quickjs/RegExp/index.html create mode 100644 docs/local/quickjs/Quickjs/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/C/Functions/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/C/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Function_description/Functions/argument-1-F/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Function_description/Functions/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Function_description/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/Infix/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/Infix/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/Infix/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/Types/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Type_description/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/Types_generated/index.html create mode 100644 docs/local/quickjs/bindings/Bindings/index.html create mode 100644 docs/local/quickjs/bindings/index.html create mode 100644 docs/local/quickjs/index.html create mode 100644 docs/odoc.support/fonts/KaTeX_AMS-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Caligraphic-Bold.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Caligraphic-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Fraktur-Bold.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Fraktur-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Main-Bold.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Main-BoldItalic.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Main-Italic.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Main-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Math-BoldItalic.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Math-Italic.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_SansSerif-Bold.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_SansSerif-Italic.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_SansSerif-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Script-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Size1-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Size2-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Size3-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Size4-Regular.woff2 create mode 100644 docs/odoc.support/fonts/KaTeX_Typewriter-Regular.woff2 create mode 100644 docs/odoc.support/fonts/fira-mono-v14-latin-500.woff2 create mode 100644 docs/odoc.support/fonts/fira-mono-v14-latin-regular.woff2 create mode 100644 docs/odoc.support/fonts/fira-sans-v17-latin-500.woff2 create mode 100644 docs/odoc.support/fonts/fira-sans-v17-latin-500italic.woff2 create mode 100644 docs/odoc.support/fonts/fira-sans-v17-latin-700.woff2 create mode 100644 docs/odoc.support/fonts/fira-sans-v17-latin-700italic.woff2 create mode 100644 docs/odoc.support/fonts/fira-sans-v17-latin-italic.woff2 create mode 100644 docs/odoc.support/fonts/fira-sans-v17-latin-regular.woff2 create mode 100644 docs/odoc.support/fonts/noticia-text-v15-latin-700.woff2 create mode 100644 docs/odoc.support/fonts/noticia-text-v15-latin-italic.woff2 create mode 100644 docs/odoc.support/fonts/noticia-text-v15-latin-regular.woff2 create mode 100644 docs/odoc.support/highlight.pack.js create mode 100644 docs/odoc.support/katex.min.css create mode 100644 docs/odoc.support/katex.min.js create mode 100644 docs/odoc.support/odoc.css create mode 100644 docs/odoc.support/odoc_search.js create mode 100644 docs/stdlib/CamlinternalFormat/index.html create mode 100644 docs/stdlib/CamlinternalFormatBasics/index.html create mode 100644 docs/stdlib/CamlinternalLazy/index.html create mode 100644 docs/stdlib/CamlinternalMod/index.html create mode 100644 docs/stdlib/CamlinternalOO/index.html create mode 100644 docs/stdlib/Std_exit/index.html create mode 100644 docs/stdlib/Stdlib/Arg/index.html create mode 100644 docs/stdlib/Stdlib/Array/index.html create mode 100644 docs/stdlib/Stdlib/ArrayLabels/index.html create mode 100644 docs/stdlib/Stdlib/Atomic/index.html create mode 100644 docs/stdlib/Stdlib/Bigarray/Array0/index.html create mode 100644 docs/stdlib/Stdlib/Bigarray/Array1/index.html create mode 100644 docs/stdlib/Stdlib/Bigarray/Array2/index.html create mode 100644 docs/stdlib/Stdlib/Bigarray/Array3/index.html create mode 100644 docs/stdlib/Stdlib/Bigarray/Genarray/index.html create mode 100644 docs/stdlib/Stdlib/Bigarray/index.html create mode 100644 docs/stdlib/Stdlib/Bool/index.html create mode 100644 docs/stdlib/Stdlib/Buffer/index.html create mode 100644 docs/stdlib/Stdlib/Bytes/index.html create mode 100644 docs/stdlib/Stdlib/BytesLabels/index.html create mode 100644 docs/stdlib/Stdlib/Callback/index.html create mode 100644 docs/stdlib/Stdlib/Char/index.html create mode 100644 docs/stdlib/Stdlib/Complex/index.html create mode 100644 docs/stdlib/Stdlib/Condition/index.html create mode 100644 docs/stdlib/Stdlib/Digest/index.html create mode 100644 docs/stdlib/Stdlib/Domain/DLS/index.html create mode 100644 docs/stdlib/Stdlib/Domain/index.html create mode 100644 docs/stdlib/Stdlib/Effect/Deep/index.html create mode 100644 docs/stdlib/Stdlib/Effect/Shallow/index.html create mode 100644 docs/stdlib/Stdlib/Effect/index.html create mode 100644 docs/stdlib/Stdlib/Either/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K1/Bucket/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K1/Make/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K1/Make/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K1/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/Bucket/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-1-H1/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-2-H2/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/Make/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-1-H1/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-2-H2/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/K2/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/Kn/Bucket/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/Kn/Make/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/Kn/Make/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/Kn/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/Ephemeron/module-type-SeededS/index.html create mode 100644 docs/stdlib/Stdlib/Filename/index.html create mode 100644 docs/stdlib/Stdlib/Float/Array/index.html create mode 100644 docs/stdlib/Stdlib/Float/ArrayLabels/index.html create mode 100644 docs/stdlib/Stdlib/Float/index.html create mode 100644 docs/stdlib/Stdlib/Format/index.html create mode 100644 docs/stdlib/Stdlib/Fun/index.html create mode 100644 docs/stdlib/Stdlib/Gc/Memprof/index.html create mode 100644 docs/stdlib/Stdlib/Gc/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/Make/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/Make/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/MakeSeeded/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/MakeSeeded/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/module-type-HashedType/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/module-type-SeededHashedType/index.html create mode 100644 docs/stdlib/Stdlib/Hashtbl/module-type-SeededS/index.html create mode 100644 docs/stdlib/Stdlib/In_channel/index.html create mode 100644 docs/stdlib/Stdlib/Int/index.html create mode 100644 docs/stdlib/Stdlib/Int32/index.html create mode 100644 docs/stdlib/Stdlib/Int64/index.html create mode 100644 docs/stdlib/Stdlib/LargeFile/index.html create mode 100644 docs/stdlib/Stdlib/Lazy/index.html create mode 100644 docs/stdlib/Stdlib/Lexing/index.html create mode 100644 docs/stdlib/Stdlib/List/index.html create mode 100644 docs/stdlib/Stdlib/ListLabels/index.html create mode 100644 docs/stdlib/Stdlib/Map/Make/argument-1-Ord/index.html create mode 100644 docs/stdlib/Stdlib/Map/Make/index.html create mode 100644 docs/stdlib/Stdlib/Map/index.html create mode 100644 docs/stdlib/Stdlib/Map/module-type-OrderedType/index.html create mode 100644 docs/stdlib/Stdlib/Map/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/Marshal/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-HashedType/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededHashedType/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededS/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Map/Make/argument-1-Ord/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Map/Make/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Map/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Map/module-type-OrderedType/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Map/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Set/Make/argument-1-Ord/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Set/Make/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Set/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Set/module-type-OrderedType/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/Set/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/MoreLabels/index.html create mode 100644 docs/stdlib/Stdlib/Mutex/index.html create mode 100644 docs/stdlib/Stdlib/Nativeint/index.html create mode 100644 docs/stdlib/Stdlib/Obj/Closure/index.html create mode 100644 docs/stdlib/Stdlib/Obj/Ephemeron/index.html create mode 100644 docs/stdlib/Stdlib/Obj/Extension_constructor/index.html create mode 100644 docs/stdlib/Stdlib/Obj/index.html create mode 100644 docs/stdlib/Stdlib/Oo/index.html create mode 100644 docs/stdlib/Stdlib/Option/index.html create mode 100644 docs/stdlib/Stdlib/Out_channel/index.html create mode 100644 docs/stdlib/Stdlib/Parsing/index.html create mode 100644 docs/stdlib/Stdlib/Printexc/Slot/index.html create mode 100644 docs/stdlib/Stdlib/Printexc/index.html create mode 100644 docs/stdlib/Stdlib/Printf/index.html create mode 100644 docs/stdlib/Stdlib/Queue/index.html create mode 100644 docs/stdlib/Stdlib/Random/State/index.html create mode 100644 docs/stdlib/Stdlib/Random/index.html create mode 100644 docs/stdlib/Stdlib/Result/index.html create mode 100644 docs/stdlib/Stdlib/Scanf/Scanning/index.html create mode 100644 docs/stdlib/Stdlib/Scanf/index.html create mode 100644 docs/stdlib/Stdlib/Semaphore/Binary/index.html create mode 100644 docs/stdlib/Stdlib/Semaphore/Counting/index.html create mode 100644 docs/stdlib/Stdlib/Semaphore/index.html create mode 100644 docs/stdlib/Stdlib/Seq/index.html create mode 100644 docs/stdlib/Stdlib/Set/Make/argument-1-Ord/index.html create mode 100644 docs/stdlib/Stdlib/Set/Make/index.html create mode 100644 docs/stdlib/Stdlib/Set/index.html create mode 100644 docs/stdlib/Stdlib/Set/module-type-OrderedType/index.html create mode 100644 docs/stdlib/Stdlib/Set/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/Stack/index.html create mode 100644 docs/stdlib/Stdlib/StdLabels/index.html create mode 100644 docs/stdlib/Stdlib/String/index.html create mode 100644 docs/stdlib/Stdlib/StringLabels/index.html create mode 100644 docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-1-Immediate/index.html create mode 100644 docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-2-Non_immediate/index.html create mode 100644 docs/stdlib/Stdlib/Sys/Immediate64/Make/index.html create mode 100644 docs/stdlib/Stdlib/Sys/Immediate64/index.html create mode 100644 docs/stdlib/Stdlib/Sys/Immediate64/module-type-Immediate/index.html create mode 100644 docs/stdlib/Stdlib/Sys/Immediate64/module-type-Non_immediate/index.html create mode 100644 docs/stdlib/Stdlib/Sys/index.html create mode 100644 docs/stdlib/Stdlib/Type/Id/index.html create mode 100644 docs/stdlib/Stdlib/Type/index.html create mode 100644 docs/stdlib/Stdlib/Uchar/index.html create mode 100644 docs/stdlib/Stdlib/Unit/index.html create mode 100644 docs/stdlib/Stdlib/Weak/Make/argument-1-H/index.html create mode 100644 docs/stdlib/Stdlib/Weak/Make/index.html create mode 100644 docs/stdlib/Stdlib/Weak/index.html create mode 100644 docs/stdlib/Stdlib/Weak/module-type-S/index.html create mode 100644 docs/stdlib/Stdlib/index.html create mode 100644 docs/stdlib/index.html diff --git a/docs/findlib-0/index.html b/docs/findlib-0/index.html new file mode 100644 index 00000000..e84b37e1 --- /dev/null +++ b/docs/findlib-0/index.html @@ -0,0 +1,2 @@ + +findlib-0 (docs.findlib-0)

Opam index

Packages installed in /Users/runner/work/quickjs.ml/quickjs.ml/_opam/lib/ocaml

Sub-indexes

diff --git a/docs/findlib-0/str/Str/index.html b/docs/findlib-0/str/Str/index.html new file mode 100644 index 00000000..bd96eeba --- /dev/null +++ b/docs/findlib-0/str/Str/index.html @@ -0,0 +1,4 @@ + +Str (docs.findlib-0.str.Str)

Module Str

Regular expressions and high-level string processing

Regular expressions

The Str library provides regular expressions on sequences of bytes. It is, in general, unsuitable to match Unicode characters.

type regexp

The type of compiled regular expressions.

val regexp : string -> regexp

Compile a regular expression. The following constructs are recognized:

  • . Matches any character except newline.
  • * (postfix) Matches the preceding expression zero, one or several times
  • + (postfix) Matches the preceding expression one or several times
  • ? (postfix) Matches the preceding expression once or not at all
  • [..] Character set. Ranges are denoted with -, as in [a-z]. An initial ^, as in [^0-9], complements the set. To include a ] character in a set, make it the first character of the set. To include a - character in a set, make it the first or the last character of the set.
  • ^ Matches at beginning of line: either at the beginning of the matched string, or just after a '\n' character.
  • $ Matches at end of line: either at the end of the matched string, or just before a '\n' character.
  • \| (infix) Alternative between two expressions.
  • \(..\) Grouping and naming of the enclosed expression.
  • \1 The text matched by the first \(...\) expression (\2 for the second expression, and so on up to \9).
  • \b Matches word boundaries.
  • \ Quotes special characters. The special characters are $^\.*+?[].

In regular expressions you will often use backslash characters; it's easier to use a quoted string literal {|...|} to avoid having to escape backslashes.

For example, the following expression:

let r = Str.regexp {|hello \([A-Za-z]+\)|} in
+Str.replace_first r {|\1|} "hello world" 

returns the string "world".

If you want a regular expression that matches a literal backslash character, you need to double it: Str.regexp {|\\|}.

You can use regular string literals "..." too, however you will have to escape backslashes. The example above can be rewritten with a regular string literal as:

let r = Str.regexp "hello \\([A-Za-z]+\\)" in
+Str.replace_first r "\\1" "hello world" 

And the regular expression for matching a backslash becomes a quadruple backslash: Str.regexp "\\\\".

val regexp_case_fold : string -> regexp

Same as regexp, but the compiled expression will match text in a case-insensitive way: uppercase and lowercase letters will be considered equivalent.

val quote : string -> string

Str.quote s returns a regexp string that matches exactly s and nothing else.

val regexp_string : string -> regexp

Str.regexp_string s returns a regular expression that matches exactly s and nothing else.

val regexp_string_case_fold : string -> regexp

Str.regexp_string_case_fold is similar to Str.regexp_string, but the regexp matches in a case-insensitive way.

String matching and searching

val string_match : regexp -> string -> int -> bool

string_match r s start tests whether a substring of s that starts at position start matches the regular expression r. The first character of a string has position 0, as usual.

val search_forward : regexp -> string -> int -> int

search_forward r s start searches the string s for a substring matching the regular expression r. The search starts at position start and proceeds towards the end of the string. Return the position of the first character of the matched substring.

val search_backward : regexp -> string -> int -> int

search_backward r s last searches the string s for a substring matching the regular expression r. The search first considers substrings that start at position last and proceeds towards the beginning of string. Return the position of the first character of the matched substring.

val string_partial_match : regexp -> string -> int -> bool

Similar to Str.string_match, but also returns true if the argument string is a prefix of a string that matches. This includes the case of a true complete match.

val matched_string : string -> string

matched_string s returns the substring of s that was matched by the last call to one of the following matching or searching functions:

provided that none of the following functions was called in between:

Note: in the case of global_substitute and substitute_first, a call to matched_string is only valid within the subst argument, not after global_substitute or substitute_first returns.

The user must make sure that the parameter s is the same string that was passed to the matching or searching function.

val match_beginning : unit -> int

match_beginning() returns the position of the first character of the substring that was matched by the last call to a matching or searching function (see Str.matched_string for details).

val match_end : unit -> int

match_end() returns the position of the character following the last character of the substring that was matched by the last call to a matching or searching function (see Str.matched_string for details).

val matched_group : int -> string -> string

matched_group n s returns the substring of s that was matched by the nth group \(...\) of the regular expression that was matched by the last call to a matching or searching function (see Str.matched_string for details). When n is 0, it returns the substring matched by the whole regular expression. The user must make sure that the parameter s is the same string that was passed to the matching or searching function.

  • raises Not_found

    if the nth group of the regular expression was not matched. This can happen with groups inside alternatives \|, options ? or repetitions *. For instance, the empty string will match \(a\)*, but matched_group 1 "" will raise Not_found because the first group itself was not matched.

val group_beginning : int -> int

group_beginning n returns the position of the first character of the substring that was matched by the nth group of the regular expression that was matched by the last call to a matching or searching function (see Str.matched_string for details).

  • raises Not_found

    if the nth group of the regular expression was not matched.

  • raises Invalid_argument

    if there are fewer than n groups in the regular expression.

val group_end : int -> int

group_end n returns the position of the character following the last character of substring that was matched by the nth group of the regular expression that was matched by the last call to a matching or searching function (see Str.matched_string for details).

  • raises Not_found

    if the nth group of the regular expression was not matched.

  • raises Invalid_argument

    if there are fewer than n groups in the regular expression.

Replacement

val global_replace : regexp -> string -> string -> string

global_replace regexp templ s returns a string identical to s, except that all substrings of s that match regexp have been replaced by templ. The replacement template templ can contain \1, \2, etc; these sequences will be replaced by the text matched by the corresponding group in the regular expression. \0 stands for the text matched by the whole regular expression.

val replace_first : regexp -> string -> string -> string

Same as Str.global_replace, except that only the first substring matching the regular expression is replaced.

val global_substitute : regexp -> (string -> string) -> string -> string

global_substitute regexp subst s returns a string identical to s, except that all substrings of s that match regexp have been replaced by the result of function subst. The function subst is called once for each matching substring, and receives s (the whole text) as argument.

val substitute_first : regexp -> (string -> string) -> string -> string

Same as Str.global_substitute, except that only the first substring matching the regular expression is replaced.

val replace_matched : string -> string -> string

replace_matched repl s returns the replacement text repl in which \1, \2, etc. have been replaced by the text matched by the corresponding groups in the regular expression that was matched by the last call to a matching or searching function (see Str.matched_string for details). s must be the same string that was passed to the matching or searching function.

Splitting

val split : regexp -> string -> string list

split r s splits s into substrings, taking as delimiters the substrings that match r, and returns the list of substrings. For instance, split (regexp "[ \t]+") s splits s into blank-separated words. An occurrence of the delimiter at the beginning or at the end of the string is ignored.

val bounded_split : regexp -> string -> int -> string list

Same as Str.split, but splits into at most n substrings, where n is the extra integer parameter.

val split_delim : regexp -> string -> string list

Same as Str.split but occurrences of the delimiter at the beginning and at the end of the string are recognized and returned as empty strings in the result. For instance, split_delim (regexp " ") " abc " returns [""; "abc"; ""], while split with the same arguments returns ["abc"].

val bounded_split_delim : regexp -> string -> int -> string list

Same as Str.bounded_split, but occurrences of the delimiter at the beginning and at the end of the string are recognized and returned as empty strings in the result.

type split_result =
  1. | Text of string
  2. | Delim of string
val full_split : regexp -> string -> split_result list

Same as Str.split_delim, but returns the delimiters as well as the substrings contained between delimiters. The former are tagged Delim in the result list; the latter are tagged Text. For instance, full_split (regexp "[{}]") "{ab}" returns [Delim "{"; Text "ab"; Delim "}"].

val bounded_full_split : regexp -> string -> int -> split_result list

Same as Str.bounded_split_delim, but returns the delimiters as well as the substrings contained between delimiters. The former are tagged Delim in the result list; the latter are tagged Text.

Extracting substrings

val string_before : string -> int -> string

string_before s n returns the substring of all characters of s that precede position n (excluding the character at position n).

val string_after : string -> int -> string

string_after s n returns the substring of all characters of s that follow position n (including the character at position n).

val first_chars : string -> int -> string

first_chars s n returns the first n characters of s. This is the same function as Str.string_before.

val last_chars : string -> int -> string

last_chars s n returns the last n characters of s.

diff --git a/docs/findlib-0/str/index.html b/docs/findlib-0/str/index.html new file mode 100644 index 00000000..b42b2123 --- /dev/null +++ b/docs/findlib-0/str/index.html @@ -0,0 +1,2 @@ + +str (docs.findlib-0.str)

Directory str

Libraries

The following libraries are found in this directory.

Modules

The following is a list of all of the modules found at this filesystem path.

diff --git a/docs/findlib-1/bigarray-compat/Bigarray_compat/index.html b/docs/findlib-1/bigarray-compat/Bigarray_compat/index.html new file mode 100644 index 00000000..dd3f480f --- /dev/null +++ b/docs/findlib-1/bigarray-compat/Bigarray_compat/index.html @@ -0,0 +1,24 @@ + +Bigarray_compat (docs.findlib-1.bigarray-compat.Bigarray_compat)

Module Bigarray_compat

include module type of struct include Bigarray end

Element kinds

Bigarrays can contain elements of the following kinds:

Each element kind is represented at the type level by one of the *_elt types defined below (defined with a single constructor instead of abstract types for technical injectivity reasons).

  • since 4.07 Moved from otherlibs to stdlib.
type float32_elt = Bigarray.float32_elt =
  1. | Float32_elt
type float64_elt = Bigarray.float64_elt =
  1. | Float64_elt
type int8_signed_elt = Bigarray.int8_signed_elt =
  1. | Int8_signed_elt
type int8_unsigned_elt = Bigarray.int8_unsigned_elt =
  1. | Int8_unsigned_elt
type int16_signed_elt = Bigarray.int16_signed_elt =
  1. | Int16_signed_elt
type int16_unsigned_elt = Bigarray.int16_unsigned_elt =
  1. | Int16_unsigned_elt
type int32_elt = Bigarray.int32_elt =
  1. | Int32_elt
type int64_elt = Bigarray.int64_elt =
  1. | Int64_elt
type int_elt = Bigarray.int_elt =
  1. | Int_elt
type nativeint_elt = Bigarray.nativeint_elt =
  1. | Nativeint_elt
type complex32_elt = Bigarray.complex32_elt =
  1. | Complex32_elt
type complex64_elt = Bigarray.complex64_elt =
  1. | Complex64_elt
type ('a, 'b) kind = ('a, 'b) Bigarray.kind =
  1. | Float32 : (float, float32_elt) kind
  2. | Float64 : (float, float64_elt) kind
  3. | Int8_signed : (int, int8_signed_elt) kind
  4. | Int8_unsigned : (int, int8_unsigned_elt) kind
  5. | Int16_signed : (int, int16_signed_elt) kind
  6. | Int16_unsigned : (int, int16_unsigned_elt) kind
  7. | Int32 : (int32, int32_elt) kind
  8. | Int64 : (int64, int64_elt) kind
  9. | Int : (int, int_elt) kind
  10. | Nativeint : (nativeint, nativeint_elt) kind
  11. | Complex32 : (Complex.t, complex32_elt) kind
  12. | Complex64 : (Complex.t, complex64_elt) kind
  13. | Char : (char, int8_unsigned_elt) kind

To each element kind is associated an OCaml type, which is the type of OCaml values that can be stored in the Bigarray or read back from it. This type is not necessarily the same as the type of the array elements proper: for instance, a Bigarray whose elements are of kind float32_elt contains 32-bit single precision floats, but reading or writing one of its elements from OCaml uses the OCaml type float, which is 64-bit double precision floats.

The GADT type ('a, 'b) kind captures this association of an OCaml type 'a for values read or written in the Bigarray, and of an element kind 'b which represents the actual contents of the Bigarray. Its constructors list all possible associations of OCaml types with element kinds, and are re-exported below for backward-compatibility reasons.

Using a generalized algebraic datatype (GADT) here allows writing well-typed polymorphic functions whose return type depend on the argument type, such as:

let zero : type a b. (a, b) kind -> a = function
+  | Float32 -> 0.0 | Complex32 -> Complex.zero
+  | Float64 -> 0.0 | Complex64 -> Complex.zero
+  | Int8_signed -> 0 | Int8_unsigned -> 0
+  | Int16_signed -> 0 | Int16_unsigned -> 0
+  | Int32 -> 0l | Int64 -> 0L
+  | Int -> 0 | Nativeint -> 0n
+  | Char -> '\000'
val float32 : (float, float32_elt) kind
val float64 : (float, float64_elt) kind
val complex32 : (Complex.t, complex32_elt) kind
val complex64 : (Complex.t, complex64_elt) kind
val int8_signed : (int, int8_signed_elt) kind
val int8_unsigned : (int, int8_unsigned_elt) kind
val int16_signed : (int, int16_signed_elt) kind
val int16_unsigned : (int, int16_unsigned_elt) kind
val int : (int, int_elt) kind
val int32 : (int32, int32_elt) kind
val int64 : (int64, int64_elt) kind
val nativeint : (nativeint, nativeint_elt) kind
val char : (char, int8_unsigned_elt) kind

As shown by the types of the values above, Bigarrays of kind float32_elt and float64_elt are accessed using the OCaml type float. Bigarrays of complex kinds complex32_elt, complex64_elt are accessed with the OCaml type Complex.t. Bigarrays of integer kinds are accessed using the smallest OCaml integer type large enough to represent the array elements: int for 8- and 16-bit integer Bigarrays, as well as OCaml-integer Bigarrays; int32 for 32-bit integer Bigarrays; int64 for 64-bit integer Bigarrays; and nativeint for platform-native integer Bigarrays. Finally, Bigarrays of kind int8_unsigned_elt can also be accessed as arrays of characters instead of arrays of small integers, by using the kind value char instead of int8_unsigned.

val kind_size_in_bytes : ('a, 'b) kind -> int

kind_size_in_bytes k is the number of bytes used to store an element of type k.

  • since 4.03

Array layouts

type c_layout = Bigarray.c_layout =
  1. | C_layout_typ
type fortran_layout = Bigarray.fortran_layout =
  1. | Fortran_layout_typ

To facilitate interoperability with existing C and Fortran code, this library supports two different memory layouts for Bigarrays, one compatible with the C conventions, the other compatible with the Fortran conventions.

In the C-style layout, array indices start at 0, and multi-dimensional arrays are laid out in row-major format. That is, for a two-dimensional array, all elements of row 0 are contiguous in memory, followed by all elements of row 1, etc. In other terms, the array elements at (x,y) and (x, y+1) are adjacent in memory.

In the Fortran-style layout, array indices start at 1, and multi-dimensional arrays are laid out in column-major format. That is, for a two-dimensional array, all elements of column 0 are contiguous in memory, followed by all elements of column 1, etc. In other terms, the array elements at (x,y) and (x+1, y) are adjacent in memory.

Each layout style is identified at the type level by the phantom types Bigarray.c_layout and Bigarray.fortran_layout respectively.

Supported layouts

The GADT type 'a layout represents one of the two supported memory layouts: C-style or Fortran-style. Its constructors are re-exported as values below for backward-compatibility reasons.

type 'a layout = 'a Bigarray.layout =
  1. | C_layout : c_layout layout
  2. | Fortran_layout : fortran_layout layout
val c_layout : c_layout layout
val fortran_layout : fortran_layout layout

Generic arrays (of arbitrarily many dimensions)

module Genarray = Bigarray.Genarray

Zero-dimensional arrays

module Array0 = Bigarray.Array0

Zero-dimensional arrays. The Array0 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of zero-dimensional arrays that only contain a single scalar value. Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking.

One-dimensional arrays

module Array1 = Bigarray.Array1

One-dimensional arrays. The Array1 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of one-dimensional arrays. (The Array2 and Array3 structures below provide operations specialized for two- and three-dimensional arrays.) Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking.

Two-dimensional arrays

module Array2 = Bigarray.Array2

Two-dimensional arrays. The Array2 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of two-dimensional arrays.

Three-dimensional arrays

module Array3 = Bigarray.Array3

Three-dimensional arrays. The Array3 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of three-dimensional arrays.

Coercions between generic Bigarrays and fixed-dimension Bigarrays

val genarray_of_array0 : ('a, 'b, 'c) Array0.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given zero-dimensional Bigarray.

  • since 4.05
val genarray_of_array1 : ('a, 'b, 'c) Array1.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given one-dimensional Bigarray.

val genarray_of_array2 : ('a, 'b, 'c) Array2.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given two-dimensional Bigarray.

val genarray_of_array3 : ('a, 'b, 'c) Array3.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given three-dimensional Bigarray.

val array0_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array0.t

Return the zero-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly zero dimension.

  • since 4.05
val array1_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array1.t

Return the one-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly one dimension.

val array2_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array2.t

Return the two-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly two dimensions.

val array3_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array3.t

Return the three-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly three dimensions.

Re-shaping Bigarrays

val reshape : ('a, 'b, 'c) Genarray.t -> int array -> ('a, 'b, 'c) Genarray.t

reshape b [|d1;...;dN|] converts the Bigarray b to a N-dimensional array of dimensions d1...dN. The returned array and the original array b share their data and have the same layout. For instance, assuming that b is a one-dimensional array of dimension 12, reshape b [|3;4|] returns a two-dimensional array b' of dimensions 3 and 4. If b has C layout, the element (x,y) of b' corresponds to the element x * 3 + y of b. If b has Fortran layout, the element (x,y) of b' corresponds to the element x + (y - 1) * 4 of b. The returned Bigarray must have exactly the same number of elements as the original Bigarray b. That is, the product of the dimensions of b must be equal to i1 * ... * iN. Otherwise, Invalid_argument is raised.

val reshape_0 : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array0.t

Specialized version of Bigarray.reshape for reshaping to zero-dimensional arrays.

  • since 4.05
val reshape_1 : ('a, 'b, 'c) Genarray.t -> int -> ('a, 'b, 'c) Array1.t

Specialized version of Bigarray.reshape for reshaping to one-dimensional arrays.

val reshape_2 : ('a, 'b, 'c) Genarray.t -> int -> int -> ('a, 'b, 'c) Array2.t

Specialized version of Bigarray.reshape for reshaping to two-dimensional arrays.

val reshape_3 : + ('a, 'b, 'c) Genarray.t -> + int -> + int -> + int -> + ('a, 'b, 'c) Array3.t

Specialized version of Bigarray.reshape for reshaping to three-dimensional arrays.

Bigarrays and concurrency safety

Care must be taken when concurrently accessing bigarrays from multiple domains: accessing a bigarray will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every bigarray operation that accesses more than one array element is not atomic. This includes slicing, bliting, and filling bigarrays.

For example, consider the following program:

open Bigarray
+let size = 100_000_000
+let a = Array1.init Int C_layout size (fun _ -> 1)
+let update f a () =
+  for i = 0 to size - 1 do a.{i} <- f a.{i} done
+let d1 = Domain.spawn (update (fun x -> x + 1) a)
+let d2 = Domain.spawn (update (fun x -> 2 * x + 1) a)
+let () = Domain.join d1; Domain.join d2

After executing this code, each field of the bigarray a is either 2, 3, 4 or 5. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of the bigarray, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same bigarray element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the bigarray elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains.

Tearing

Bigarrays have a distinct caveat in the presence of data races: concurrent bigarray operations might produce surprising values due to tearing. More precisely, the interleaving of partial writes and reads might create values that would not exist with a sequential execution. For instance, at the end of

let res = Array1.init Complex64 c_layout size (fun _ -> Complex.zero)
+let d1 = Domain.spawn (fun () -> Array1.fill res Complex.one)
+let d2 = Domain.spawn (fun () -> Array1.fill res Complex.i)
+let () = Domain.join d1; Domain.join d2

the res bigarray might contain values that are neither Complex.i nor Complex.one (for instance 1 + i).

diff --git a/docs/findlib-1/bigarray-compat/index.html b/docs/findlib-1/bigarray-compat/index.html new file mode 100644 index 00000000..da7330fd --- /dev/null +++ b/docs/findlib-1/bigarray-compat/index.html @@ -0,0 +1,2 @@ + +bigarray-compat (docs.findlib-1.bigarray-compat)

Package bigarray-compat

Library bigarray-compat

The entry point of this library is the module: Bigarray_compat.

diff --git a/docs/findlib-1/ctypes/ComplexL/index.html b/docs/findlib-1/ctypes/ComplexL/index.html new file mode 100644 index 00000000..42a22dd7 --- /dev/null +++ b/docs/findlib-1/ctypes/ComplexL/index.html @@ -0,0 +1,2 @@ + +ComplexL (docs.findlib-1.ctypes.ComplexL)

Module ComplexL

type t

The type of long double complex values

val make : LDouble.t -> LDouble.t -> t

make x y creates the long double complex value x + y * i

val of_complex : Complex.t -> t

create a long double complex from a Complex.t

val to_complex : t -> Complex.t

Convert a long double complex to a Complex.t. The real and imaginary components are converted by calling LDouble.to_float which can produce unspecified results.

val zero : t

0 + i0

val one : t

1 + i0

val i : t

0 + i

val re : t -> LDouble.t

return the real part of the long double complex

val im : t -> LDouble.t

return the imaginary part of the long double complex

val neg : t -> t

Unary negation

val conj : t -> t

Conjugate: given the complex x + i.y, returns x - i.y.

val add : t -> t -> t

Addition

val sub : t -> t -> t

Subtraction

val mul : t -> t -> t

Multiplication

val div : t -> t -> t

Division

val inv : t -> t

Multiplicative inverse (1/z).

val sqrt : t -> t

Square root.

val norm2 : t -> LDouble.t

Norm squared: given x + i.y, returns x^2 + y^2.

val norm : t -> LDouble.t

Norm: given x + i.y, returns sqrt(x^2 + y^2).

val polar : LDouble.t -> LDouble.t -> t

polar norm arg returns the complex having norm norm and argument arg.

val arg : t -> LDouble.t

Argument. The argument of a complex number is the angle in the complex plane between the positive real axis and a line passing through zero and the number.

val exp : t -> t

Exponentiation. exp z returns e to the z power.

val log : t -> t

Natural logarithm (in base e).

val pow : t -> t -> t

Power function. pow z1 z2 returns z1 to the z2 power.

diff --git a/docs/findlib-1/ctypes/Cstubs_internals/index.html b/docs/findlib-1/ctypes/Cstubs_internals/index.html new file mode 100644 index 00000000..a728b303 --- /dev/null +++ b/docs/findlib-1/ctypes/Cstubs_internals/index.html @@ -0,0 +1,12 @@ + +Cstubs_internals (docs.findlib-1.ctypes.Cstubs_internals)

Module Cstubs_internals

type voidp = Ctypes_ptr.voidp
type ('m, 'a) fatptr = ('m, 'a Ctypes.typ) Ctypes_ptr.Fat.t
type ('m, 'a) fatfunptr = ('m, 'a Ctypes.fn) Ctypes_ptr.Fat.t
val make_structured : + ('a, 's) Ctypes.structured Ctypes.typ -> + managed_buffer -> + ('a, 's) Ctypes.structured
val make_ptr : 'a Ctypes.typ -> voidp -> 'a Ctypes.ptr
val make_fun_ptr : 'a Ctypes.fn -> voidp -> 'a Ctypes_static.static_funptr
type 'a ocaml_type = 'a Ctypes_static.ocaml_type =
  1. | String : string ocaml_type
  2. | Bytes : bytes ocaml_type
  3. | FloatArray : float array ocaml_type
type 'a typ = 'a Ctypes_static.typ =
  1. | Void : unit typ
  2. | Primitive : 'a Ctypes_primitive_types.prim -> 'a typ
  3. | Pointer : 'a typ -> 'a ptr typ
  4. | Funptr : 'a Ctypes.fn -> 'a static_funptr typ
  5. | Struct : 'a Ctypes_static.structure_type -> 'a Ctypes_static.structure typ
  6. | Union : 'a Ctypes_static.union_type -> 'a Ctypes_static.union typ
  7. | Abstract : Ctypes_static.abstract_type -> 'a Ctypes_static.abstract typ
  8. | View : ('a, 'b) view -> 'a typ
  9. | Qualified : Ctypes_static.qualifier * 'a typ -> 'a typ
  10. | Array : 'a typ * int -> 'a Ctypes_static.carray typ
  11. | Bigarray : (_, 'a, _) Ctypes_bigarray.t -> 'a typ
  12. | OCaml : 'a ocaml_type -> 'a ocaml typ
and ('a, 'b) pointer = ('a, 'b) Ctypes_static.pointer =
  1. | CPointer : (Obj.t option, 'a typ) Ctypes_ptr.Fat.t -> ('a, [ `C ]) pointer
  2. | OCamlRef : int * 'a * 'a ocaml_type -> ('a, [ `OCaml ]) pointer
and 'a ptr = ('a, [ `C ]) pointer
and 'a ocaml = ('a, [ `OCaml ]) pointer
and 'a static_funptr = 'a Ctypes_static.static_funptr =
  1. | Static_funptr : (Obj.t option, 'a Ctypes.fn) Ctypes_ptr.Fat.t -> 'a + static_funptr
and ('a, 'b) view = ('a, 'b) Ctypes_static.view = {
  1. read : 'b -> 'a;
  2. write : 'a -> 'b;
  3. format_typ : ((Format.formatter -> unit) -> Format.formatter -> unit) option;
  4. format : (Format.formatter -> 'a -> unit) option;
  5. ty : 'b typ;
}
type 'a fn = 'a Ctypes_static.fn =
  1. | Returns : 'a typ -> 'a fn
  2. | Function : 'a typ * 'b fn -> ('a -> 'b) fn
type 'a prim = 'a Ctypes_primitive_types.prim =
  1. | Char : char prim
  2. | Schar : int prim
  3. | Uchar : Unsigned.uchar prim
  4. | Bool : bool prim
  5. | Short : int prim
  6. | Int : int prim
  7. | Long : Signed.long prim
  8. | Llong : Signed.llong prim
  9. | Ushort : Unsigned.ushort prim
  10. | Sint : Signed.sint prim
  11. | Uint : Unsigned.uint prim
  12. | Ulong : Unsigned.ulong prim
  13. | Ullong : Unsigned.ullong prim
  14. | Size_t : Unsigned.size_t prim
  15. | Int8_t : int prim
  16. | Int16_t : int prim
  17. | Int32_t : int32 prim
  18. | Int64_t : int64 prim
  19. | Uint8_t : Unsigned.uint8 prim
  20. | Uint16_t : Unsigned.uint16 prim
  21. | Uint32_t : Unsigned.uint32 prim
  22. | Uint64_t : Unsigned.uint64 prim
  23. | Camlint : int prim
  24. | Nativeint : nativeint prim
  25. | Float : float prim
  26. | Double : float prim
  27. | LDouble : LDouble.t prim
  28. | Complex32 : Complex.t prim
  29. | Complex64 : Complex.t prim
  30. | Complexld : ComplexL.t prim
val build_enum_type : + string -> + Ctypes_static.arithmetic -> + ?typedef:bool -> + ?unexpected:(int64 -> 'a) -> + ('a * int64) list -> + 'a typ
val use_value : 'a -> unit
diff --git a/docs/findlib-1/ctypes/Ctypes/CArray/index.html b/docs/findlib-1/ctypes/Ctypes/CArray/index.html new file mode 100644 index 00000000..ba894668 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/CArray/index.html @@ -0,0 +1,2 @@ + +CArray (docs.findlib-1.ctypes.Ctypes.CArray)

Module Ctypes.CArray

Operations on C arrays.

type 'a t = 'a carray
val get : 'a t -> int -> 'a

get a n returns the nth element of the zero-indexed array a. The semantics for non-scalar types are non-copying, as for (!@).

If you rebind the CArray module to Array then you can also use the syntax a.(n) instead of Array.get a n.

Raise Invalid_argument "index out of bounds" if n is outside of the range 0 to (CArray.length a - 1).

val set : 'a t -> int -> 'a -> unit

set a n v overwrites the nth element of the zero-indexed array a with v.

If you rebind the CArray module to Array then you can also use the a.(n) <- v syntax instead of Array.set a n v.

Raise Invalid_argument "index out of bounds" if n is outside of the range 0 to (CArray.length a - 1).

val unsafe_get : 'a t -> int -> 'a

unsafe_get a n behaves like get a n except that the check that n between 0 and (CArray.length a - 1) is not performed.

val unsafe_set : 'a t -> int -> 'a -> unit

unsafe_set a n v behaves like set a n v except that the check that n between 0 and (CArray.length a - 1) is not performed.

val of_string : string -> char t

of_string s builds an array of the same length as s plus one, and writes the elements of s to the corresponding elements of the array with the null character '\0' as a last element.

val of_list : 'a typ -> 'a list -> 'a t

of_list t l builds an array of type t of the same length as l, and writes the elements of l to the corresponding elements of the array.

val to_list : 'a t -> 'a list

to_list a builds a list of the same length as a such that each element of the list is the result of reading the corresponding element of a.

val iter : ('a -> unit) -> 'a t -> unit

iter f a is analogous to Array.iter f a: it applies f in turn to all the elements of a.

val iteri : (int -> 'a -> unit) -> 'a t -> unit

iter f a is analogous to Array.iteri f a: it applies f in turn to all the elements of a but the function is applied to the index of the element as first argument, and the element itself as second argument

val map : 'b typ -> ('a -> 'b) -> 'a t -> 'b t

map t f a is analogous to Array.map f a: it creates a new array with element type t whose elements are obtained by applying f to the elements of a.

val mapi : 'b typ -> (int -> 'a -> 'b) -> 'a t -> 'b t

mapi behaves like Array.mapi, except that it also passes the index of each element as the first argument to f and the element itself as the second argument.

val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a

CArray.fold_left (@) x a computes (((x @ a.(0)) @ a.(1)) ...) @ a.(n-1) where n is the length of the array a.

val fold_right : ('b -> 'a -> 'a) -> 'b t -> 'a -> 'a

CArray.fold_right f a x computes a.(0) @ (a.(1) @ ( ... (a.(n-1) @ x) ...)) where n is the length of the array a.

val length : 'a t -> int

Return the number of elements of the given array.

val start : 'a t -> 'a ptr

Return the address of the first element of the given array.

val from_ptr : 'a ptr -> int -> 'a t

from_ptr p n creates an n-length array reference to the memory at address p.

val make : ?finalise:('a t -> unit) -> 'a typ -> ?initial:'a -> int -> 'a t

make t n creates an n-length array of type t. If the optional argument ?initial is supplied, it indicates a value that should be used to initialise every element of the array. The argument ?finalise, if present, will be called just before the memory is freed.

val copy : 'a t -> 'a t

copy a creates a fresh array with the same elements as a.

val sub : 'a t -> pos:int -> length:int -> 'a t

sub a ~pos ~length creates a fresh array of length length containing the elements a.(pos) to a.(pos + length - 1) of a.

Raise Invalid_argument "CArray.sub" if pos and length do not designate a valid subarray of a.

val element_type : 'a t -> 'a typ

Retrieve the element type of an array.

diff --git a/docs/findlib-1/ctypes/Ctypes/Intptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes/Intptr/Infix/index.html new file mode 100644 index 00000000..2addd7f3 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes/Intptr/index.html b/docs/findlib-1/ctypes/Ctypes/Intptr/index.html new file mode 100644 index 00000000..5453d6c3 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.Ctypes.Intptr)

Module Ctypes.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/Ctypes/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..071f60d6 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes/Ptrdiff/index.html b/docs/findlib-1/ctypes/Ctypes/Ptrdiff/index.html new file mode 100644 index 00000000..989f4555 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.Ctypes.Ptrdiff)

Module Ctypes.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes/Root/index.html b/docs/findlib-1/ctypes/Ctypes/Root/index.html new file mode 100644 index 00000000..75e940ab --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Root/index.html @@ -0,0 +1,2 @@ + +Root (docs.findlib-1.ctypes.Ctypes.Root)

Module Ctypes.Root

Registration of OCaml values as roots

val create : 'a -> unit ptr

create v allocates storage for the address of the OCaml value v, registers the storage as a root, and returns its address.

val get : unit ptr -> 'a

get p retrieves the OCaml value whose address is stored at p.

val set : unit ptr -> 'a -> unit

set p v updates the OCaml value stored as a root at p.

val release : unit ptr -> unit

release p unregsiters the root p.

diff --git a/docs/findlib-1/ctypes/Ctypes/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes/Uintptr/Infix/index.html new file mode 100644 index 00000000..8fbcad15 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes/Uintptr/index.html b/docs/findlib-1/ctypes/Ctypes/Uintptr/index.html new file mode 100644 index 00000000..ae8fb92b --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.Ctypes.Uintptr)

Module Ctypes.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/Ctypes/index.html b/docs/findlib-1/ctypes/Ctypes/index.html new file mode 100644 index 00000000..3454c67f --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/index.html @@ -0,0 +1,118 @@ + +Ctypes (docs.findlib-1.ctypes.Ctypes)

Module Ctypes

The core ctypes module.

The main points of interest are the set of functions for describing C types (see Values representing C types) and the set of functions for accessing C values (see Values representing C values). The Foreign.foreign function uses C type descriptions to bind external C values.

Pointer types
type ('a, 'b) pointer = ('a, 'b) Ctypes_static.pointer

The type of pointer values. A value of type ('a, [`C]) pointer contains a C-compatible pointer, and a value of type ('a, [`OCaml]) pointer contains a pointer to a value that can be moved by OCaml runtime.

C-compatible pointers
type 'a ptr = ('a, [ `C ]) pointer

The type of C-compatible pointer values. A value of type t ptr can be used to read and write values of type t at particular addresses.

type 'a ocaml = 'a Ctypes_static.ocaml

The type of pointer values pointing directly into OCaml values. Pointers of this type should never be captured by external code. In particular, functions accepting 'a ocaml pointers must not invoke any OCaml code.

C array types
type 'a carray = 'a Ctypes_static.carray

The type of C array values. A value of type t carray can be used to read and write array objects in C-managed storage.

Bigarray types
type 'a bigarray_class = 'a Ctypes_static.bigarray_class

The type of Bigarray classes. There are four instances, one for each of the Bigarray submodules.

val genarray : + < element : 'a + ; layout : 'l + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Genarray.t + ; carray : 'a carray + ; dims : int array > + bigarray_class

The class of Bigarray.Genarray.t values

val array1 : + < element : 'a + ; layout : 'l + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Array1.t + ; carray : 'a carray + ; dims : int > + bigarray_class

The class of Bigarray.Array1.t values

val array2 : + < element : 'a + ; layout : 'l + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Array2.t + ; carray : 'a carray carray + ; dims : int * int > + bigarray_class

The class of Bigarray.Array2.t values

val array3 : + < element : 'a + ; layout : 'l + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Array3.t + ; carray : 'a carray carray carray + ; dims : int * int * int > + bigarray_class

The class of Bigarray.Array3.t values

Struct and union types

type ('a, 'kind) structured = ('a, 'kind) Ctypes_static.structured

The base type of values representing C struct and union types. The 'kind parameter is a polymorphic variant type indicating whether the type represents a struct (`Struct) or a union (`Union).

type 'a structure = ('a, [ `Struct ]) structured

The type of values representing C struct types.

type 'a union = ('a, [ `Union ]) structured

The type of values representing C union types.

type ('a, 't) field = ('a, 't) Ctypes_static.field

The type of values representing C struct or union members (called "fields" here). A value of type (a, s) field represents a field of type a in a struct or union of type s.

type 'a abstract = 'a Ctypes_static.abstract

The type of abstract values. The purpose of the abstract type is to represent values whose type varies from platform to platform.

For example, the type pthread_t is a pointer on some platforms, an integer on other platforms, and a struct on a third set of platforms. One way to deal with this kind of situation is to have possibly-platform-specific code which interrogates the C type in some way to help determine an appropriate representation. Another way is to use abstract, leaving the representation opaque.

(Note, however, that although pthread_t is a convenient example, since the type used to implement it varies significantly across platforms, it's not actually a good match for abstract, since values of type pthread_t are passed and returned by value.)

include Ctypes_types.TYPE + with type 'a typ = 'a Ctypes_static.typ + and type ('a, 's) field := ('a, 's) field

Values representing C types

type 'a typ = 'a Ctypes_static.typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

Qualified types

val const : 'a typ -> 'a typ

const t const-qualifies the type t. At present the only effect is that the type is marked 'const' in generated code.

val volatile : 'a typ -> 'a typ

volatile t volatile-qualifies the type t. At present the only effect is that the type is marked 'volatile' in generated code.

Operations on types

val sizeof : 'a typ -> int

sizeof t computes the size in bytes of the type t. The exception IncompleteType is raised if t is incomplete.

val alignment : 'a typ -> int

alignment t computes the alignment requirements of the type t. The exception IncompleteType is raised if t is incomplete.

val format_typ : ?name:string -> Format.formatter -> 'a typ -> unit

Pretty-print a C representation of the type to the specified formatter.

val format_fn : ?name:string -> Format.formatter -> 'a fn -> unit

Pretty-print a C representation of the function type to the specified formatter.

val string_of_typ : ?name:string -> 'a typ -> string

Return a C representation of the type.

val string_of_fn : ?name:string -> 'a fn -> string

Return a C representation of the function type.

Values representing C values

val format : 'a typ -> Format.formatter -> 'a -> unit

Pretty-print a representation of the C value to the specified formatter.

val string_of : 'a typ -> 'a -> string

Return a string representation of the C value.

Pointer values

val null : unit ptr

A null pointer.

val (!@) : 'a ptr -> 'a

!@ p dereferences the pointer p. If the reference type is a scalar type then dereferencing constructs a new value. If the reference type is an aggregate type then dereferencing returns a value that references the memory pointed to by p.

val (<-@) : 'a ptr -> 'a -> unit

p <-@ v writes the value v to the address p.

val (+@) : ('a, 'b) pointer -> int -> ('a, 'b) pointer

If p is a pointer to an array element then p +@ n computes the address of the nth next element.

val (-@) : ('a, 'b) pointer -> int -> ('a, 'b) pointer

If p is a pointer to an array element then p -@ n computes the address of the nth previous element.

val ptr_diff : ('a, 'b) pointer -> ('a, 'b) pointer -> int

ptr_diff p q computes q - p. As in C, both p and q must point into the same array, and the result value is the difference of the subscripts of the two array elements.

val from_voidp : 'a typ -> unit ptr -> 'a ptr

Conversion from void *.

val to_voidp : _ ptr -> unit ptr

Conversion to void *.

val allocate : ?finalise:('a ptr -> unit) -> 'a typ -> 'a -> 'a ptr

allocate t v allocates a fresh value of type t, initialises it with v and returns its address. The argument ?finalise, if present, will be called just before the memory is freed. The value will be automatically freed after no references to the pointer remain within the calling OCaml program.

val allocate_n : ?finalise:('a ptr -> unit) -> 'a typ -> count:int -> 'a ptr

allocate_n t ~count:n allocates a fresh array with element type t and length n, and returns its address. The argument ?finalise, if present, will be called just before the memory is freed. The array will be automatically freed after no references to the pointer remain within the calling OCaml program. The memory is allocated with libc's calloc and is guaranteed to be zero-filled.

val ptr_compare : 'a ptr -> 'a ptr -> int

If p and q are pointers to elements i and j of the same array then ptr_compare p q compares the indexes of the elements. The result is negative if i is less than j, positive if i is greater than j, and zero if i and j are equal.

val is_null : 'a ptr -> bool

is_null p is true when p is a null pointer.

val reference_type : 'a ptr -> 'a typ

Retrieve the reference type of a pointer.

val ptr_of_raw_address : nativeint -> unit ptr

Convert the numeric representation of an address to a pointer

val funptr_of_raw_address : + nativeint -> + (unit -> unit) Ctypes_static.static_funptr

Convert the numeric representation of an address to a function pointer

val raw_address_of_ptr : unit ptr -> nativeint

raw_address_of_ptr p returns the numeric representation of p.

Note that the return value remains valid only as long as the pointed-to object is alive. If p is a managed object (e.g. a value returned by make) then unless the caller retains a reference to p, the object may be collected, invalidating the returned address.

val string_from_ptr : char ptr -> length:int -> string

string_from_ptr p ~length creates a string initialized with the length characters at address p.

Raise Invalid_argument "Ctypes.string_from_ptr" if length is negative.

val ocaml_string_start : string -> string ocaml

ocaml_string_start s allows to pass a pointer to the contents of an OCaml string directly to a C function.

val ocaml_bytes_start : bytes -> bytes ocaml

ocaml_bytes_start s allows to pass a pointer to the contents of an OCaml byte array directly to a C function.

Array values

C array values
module CArray : sig ... end

Operations on C arrays.

Bigarray values
val bigarray_start : + < element : 'a + ; layout : 'l + ; ba_repr : _ + ; bigarray : 'b + ; carray : _ + ; dims : _ > + bigarray_class -> + 'b -> + 'a ptr

Return the address of the first element of the given Bigarray value.

val bigarray_of_ptr : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'f + ; bigarray : 'b + ; carray : _ + ; dims : 'i > + bigarray_class -> + 'i -> + ('a, 'f) Bigarray_compat.kind -> + 'a ptr -> + 'b

bigarray_of_ptr c dims k p converts the C pointer p to a C-layout bigarray value. No copy is made; the bigarray references the memory pointed to by p.

val fortran_bigarray_of_ptr : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'f + ; bigarray : 'b + ; carray : _ + ; dims : 'i > + bigarray_class -> + 'i -> + ('a, 'f) Bigarray_compat.kind -> + 'a ptr -> + 'b

fortran_bigarray_of_ptr c dims k p converts the C pointer p to a Fortran-layout bigarray value. No copy is made; the bigarray references the memory pointed to by p.

val array_of_bigarray : + < element : _ + ; layout : Bigarray_compat.c_layout + ; ba_repr : _ + ; bigarray : 'b + ; carray : 'c + ; dims : _ > + bigarray_class -> + 'b -> + 'c

array_of_bigarray c b converts the bigarray value b to a value of type CArray.t. No copy is made; the result occupies the same memory as b.

Convert a Bigarray value to a C array.

val bigarray_of_array : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'f + ; bigarray : 'b + ; carray : 'c carray + ; dims : 'i > + bigarray_class -> + ('a, 'f) Bigarray_compat.kind -> + 'c carray -> + 'b

bigarray_of_array c k a converts the CArray.t value a to a C-layout bigarray value. No copy is made; the result occupies the same memory as a.

Struct and union values

val make : ?finalise:('s -> unit) -> (_, _) structured as 's typ -> 's

Allocate a fresh, uninitialised structure or union value. The argument ?finalise, if present, will be called just before the underlying memory is freed.

val setf : (_, _) structured as 's -> ('a, 's) field -> 'a -> unit

setf s f v overwrites the value of the field f in the structure or union s with v.

val getf : (_, _) structured as 's -> ('a, 's) field -> 'a

getf s f retrieves the value of the field f in the structure or union s. The semantics for non-scalar types are non-copying, as for (!@).

val (@.) : (_, _) structured as 's -> ('a, 's) field -> 'a ptr

s @. f computes the address of the field f in the structure or union value s.

val (|->) : (_, _) structured as 's ptr -> ('a, 's) field -> 'a ptr

p |-> f computes the address of the field f in the structure or union value pointed to by p.

val offsetof : (_, _ structure) field -> int

offsetof f returns the offset, in bytes, of the field f from the beginning of the associated struct type.

val field_type : ('a, _) field -> 'a typ

field_type f returns the type of the field f.

val field_name : (_, _) field -> string

field_name f returns the name of the field f.

val addr : (_, _) structured as 's -> 's ptr

addr s returns the address of the structure or union s.

Coercions

val coerce : 'a typ -> 'b typ -> 'a -> 'b

coerce t1 t2 returns a coercion function between the types represented by t1 and t2. If t1 cannot be coerced to t2, coerce raises Uncoercible.

The following coercions are currently supported:

  • All function and object pointer types are intercoercible.
  • Any type may be coerced to void
  • There is a coercion between a view and another type t (in either direction) if there is a coercion between the representation type underlying the view and t.
  • Coercion is transitive: if t1 is coercible to t2 and t2 is coercible to t3, then t1 is directly coercible to t3.

The set of supported coercions is subject to change. Future versions of ctypes may both add new types of coercion and restrict the existing coercions.

val coerce_fn : 'a fn -> 'b fn -> 'a -> 'b

coerce_fn f1 f2 returns a coercion function between the function types represented by f1 and f2. If f1 cannot be coerced to f2, coerce_fn raises Uncoercible.

A function type f1 may be coerced to another function type f2 if all of the following hold:

  • the C types described by f1 and f2 have the same arity
  • each argument of f2 may be coerced to the corresponding argument of f1
  • the return type of f1 may be coerced to the return type of f2

The set of supported coercions is subject to change. Future versions of ctypes may both add new types of coercion and restrict the existing coercions.

module type FOREIGN = sig ... end
module type TYPE = sig ... end

Foreign types binding interface.

module Root : sig ... end

Exceptions

exception Unsupported of string

An attempt was made to use a feature not currently supported by ctypes. In practice this refers to attempts to use an union, array or abstract type as an argument or return type of a function.

exception ModifyingSealedType of string

An attempt was made to modify a sealed struct or union type description.

exception IncompleteType

An attempt was made to compute the size or alignment of an incomplete type.

The incomplete types are struct and union types that have not been sealed, and the void type.

It is not permitted to compute the size or alignment requirements of an incomplete type, to use it as a struct or union member, to read or write a value of the type through a pointer or to use it as the referenced type in pointer arithmetic. Additionally, incomplete struct and union types cannot be used as argument or return types.

type uncoercible_info
exception Uncoercible of uncoercible_info

An attempt was made to coerce between uncoercible types.

diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-FOREIGN/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-FOREIGN/index.html new file mode 100644 index 00000000..c56ec8aa --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-FOREIGN/index.html @@ -0,0 +1,2 @@ + +FOREIGN (docs.findlib-1.ctypes.Ctypes.FOREIGN)

Module type Ctypes.FOREIGN

binding interfaces

Foreign function binding interface.

The Foreign and Cstubs modules provide concrete implementations.

type 'a fn
type 'a return
val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn
val returning : 'a typ -> 'a return fn
type 'a result
val foreign : string -> ('a -> 'b) fn -> ('a -> 'b) result
val foreign_value : string -> 'a typ -> 'a ptr result
diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/Infix/index.html new file mode 100644 index 00000000..1dff6648 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes.TYPE.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/index.html new file mode 100644 index 00000000..95dd6991 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.Ctypes.TYPE.Intptr)

Module TYPE.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..4939dfe4 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes.TYPE.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/index.html new file mode 100644 index 00000000..0bc1c4b7 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.Ctypes.TYPE.Ptrdiff)

Module TYPE.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/Infix/index.html new file mode 100644 index 00000000..2c234076 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes.TYPE.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/index.html new file mode 100644 index 00000000..d3bc83c5 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.Ctypes.TYPE.Uintptr)

Module TYPE.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/index.html b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/index.html new file mode 100644 index 00000000..5810fcec --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes/module-type-TYPE/index.html @@ -0,0 +1,49 @@ + +TYPE (docs.findlib-1.ctypes.Ctypes.TYPE)

Module type Ctypes.TYPE

Foreign types binding interface.

The Cstubs module builds concrete implementations.

include Ctypes_types.TYPE

Values representing C types

type 'a typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

type ('a, 't) field
val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

val const : 'a typ -> 'a typ
type 'a const
val constant : string -> 'a typ -> 'a const

constant name typ retrieves the value of the compile-time constant name of type typ. It can be used to retrieve enum constants, #defined values and other integer constant expressions.

The type typ must be either an integer type such as bool, char, int, uint8, etc., or a view (or perhaps multiple views) where the underlying type is an integer type.

When the value of the constant cannot be represented in the type there will typically be a diagnostic from either the C compiler or the OCaml compiler. For example, gcc will say

warning: overflow in implicit constant conversion

val enum : + string -> + ?typedef:bool -> + ?unexpected:(int64 -> 'a) -> + ('a * int64 const) list -> + 'a typ

enum name ?unexpected alist builds a type representation for the enum named name. The size and alignment are retrieved so that the resulting type can be used everywhere an integer type can be used: as an array element or struct member, as an argument or return value, etc.

The value alist is an association list of OCaml values and values retrieved by the constant function. For example, to expose the enum

enum letters { A, B, C = 10, D };

you might first retrieve the values of the enumeration constants:

let a = constant "A" int64_t
+and b = constant "B" int64_t
+and c = constant "C" int64_t
+and d = constant "D" int64_t

and then build the enumeration type

let letters = enum "letters" [
+   `A, a;
+   `B, b;
+   `C, c;
+   `D, d;
+] ~unexpected:(fun i -> `E i)

The unexpected function specifies the value to return in the case that some unexpected value is encountered -- for example, if a function with the return type 'enum letters' actually returns the value -1.

The optional flag typedef specifies whether the first argument, name, indicates an tag or an alias. If typedef is false (the default) then name is treated as an enumeration tag:

enum letters { ... }

If typedef is true then name is instead treated as an alias:

typedef enum { ... } letters

diff --git a/docs/findlib-1/ctypes/Ctypes_bigarray/index.html b/docs/findlib-1/ctypes/Ctypes_bigarray/index.html new file mode 100644 index 00000000..d4d1b3b3 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_bigarray/index.html @@ -0,0 +1,25 @@ + +Ctypes_bigarray (docs.findlib-1.ctypes.Ctypes_bigarray)

Module Ctypes_bigarray

Types

type ('a, 'b, 'l) t

The type of bigarray values of particular sizes. A value of type (a, b, l) t can be used to read and write values of type b.

Type constructors

val bigarray : + int array -> + ('a, 'b) Bigarray_compat.kind -> + 'l Bigarray_compat.layout -> + ('a, ('a, 'b, 'l) Bigarray_compat.Genarray.t, 'l) t

Create a t value for the Bigarray.Genarray.t type.

val bigarray1 : + int -> + ('a, 'b) Bigarray_compat.kind -> + 'l Bigarray_compat.layout -> + ('a, ('a, 'b, 'l) Bigarray_compat.Array1.t, 'l) t

Create a t value for the Bigarray.Array1.t type.

val bigarray2 : + int -> + int -> + ('a, 'b) Bigarray_compat.kind -> + 'l Bigarray_compat.layout -> + ('a, ('a, 'b, 'l) Bigarray_compat.Array2.t, 'l) t

Create a t value for the Bigarray.Array2.t type.

val bigarray3 : + int -> + int -> + int -> + ('a, 'b) Bigarray_compat.kind -> + 'l Bigarray_compat.layout -> + ('a, ('a, 'b, 'l) Bigarray_compat.Array3.t, 'l) t

Create a t value for the Bigarray.Array3.t type.

val prim_of_kind : + ('a, _) Bigarray_compat.kind -> + 'a Ctypes_primitive_types.prim

Create a Ctypes_ptr.Types.ctype for a Bigarray.kind.

Type eliminators

val sizeof : (_, _, _) t -> int

Compute the size of a bigarray type.

val alignment : (_, _, _) t -> int

Compute the alignment of a bigarray type.

val element_type : ('a, _, _) t -> 'a Ctypes_primitive_types.prim

Compute the element type of a bigarray type.

val dimensions : (_, _, _) t -> int array

Compute the dimensions of a bigarray type.

val type_expression : + ('a, 'b, 'l) t -> + [> `Appl of string list * 'c list | `Ident of string list ] as 'c

Compute a type expression that denotes a bigarray type.

Values

val unsafe_address : 'a -> Ctypes_ptr.voidp

Return the address of a bigarray value. This function is unsafe because it dissociates the raw address of the C array from the OCaml object that manages the lifetime of the array. If the caller does not hold a reference to the OCaml object then the array might be freed, invalidating the address.

val view : (_, 'a, _) t -> (_ option, _) Ctypes_ptr.Fat.t -> 'a

view b ptr creates a bigarray view onto existing memory.

If ptr references an OCaml object then view will ensure that that object is not collected before the bigarray returned by view.

diff --git a/docs/findlib-1/ctypes/Ctypes_bigarray_stubs/index.html b/docs/findlib-1/ctypes/Ctypes_bigarray_stubs/index.html new file mode 100644 index 00000000..55c6b338 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_bigarray_stubs/index.html @@ -0,0 +1,22 @@ + +Ctypes_bigarray_stubs (docs.findlib-1.ctypes.Ctypes_bigarray_stubs)

Module Ctypes_bigarray_stubs

type _ kind =
  1. | Kind_float32 : float kind
  2. | Kind_float64 : float kind
  3. | Kind_int8_signed : int kind
  4. | Kind_int8_unsigned : int kind
  5. | Kind_int16_signed : int kind
  6. | Kind_int16_unsigned : int kind
  7. | Kind_int32 : int32 kind
  8. | Kind_int64 : int64 kind
  9. | Kind_int : int kind
  10. | Kind_nativeint : nativeint kind
  11. | Kind_complex32 : Complex.t kind
  12. | Kind_complex64 : Complex.t kind
  13. | Kind_char : char kind
val kind : 'a 'b. ('a, 'b) Bigarray_compat.kind -> 'a kind
val address : 'b -> Ctypes_ptr.voidp
val view : + 'a kind -> + dims:int array -> + (_, _) Ctypes_ptr.Fat.t -> + 'l Bigarray_compat.layout -> + ('a, 'b, 'l) Bigarray_compat.Genarray.t
val view1 : + 'a kind -> + dims:int array -> + (_, _) Ctypes_ptr.Fat.t -> + 'l Bigarray_compat.layout -> + ('a, 'b, 'l) Bigarray_compat.Array1.t
val view2 : + 'a kind -> + dims:int array -> + (_, _) Ctypes_ptr.Fat.t -> + 'l Bigarray_compat.layout -> + ('a, 'b, 'l) Bigarray_compat.Array2.t
val view3 : + 'a kind -> + dims:int array -> + (_, _) Ctypes_ptr.Fat.t -> + 'l Bigarray_compat.layout -> + ('a, 'b, 'l) Bigarray_compat.Array3.t
diff --git a/docs/findlib-1/ctypes/Ctypes_coerce/index.html b/docs/findlib-1/ctypes/Ctypes_coerce/index.html new file mode 100644 index 00000000..f7c57ba7 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_coerce/index.html @@ -0,0 +1,2 @@ + +Ctypes_coerce (docs.findlib-1.ctypes.Ctypes_coerce)

Module Ctypes_coerce

type uncoercible_info
exception Uncoercible of uncoercible_info
val coerce : 'a Ctypes_static.typ -> 'b Ctypes_static.typ -> 'a -> 'b
val coerce_fn : 'a Ctypes_static.fn -> 'b Ctypes_static.fn -> 'a -> 'b
diff --git a/docs/findlib-1/ctypes/Ctypes_memory/CArray/index.html b/docs/findlib-1/ctypes/Ctypes_memory/CArray/index.html new file mode 100644 index 00000000..216ed3b4 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_memory/CArray/index.html @@ -0,0 +1,15 @@ + +CArray (docs.findlib-1.ctypes.Ctypes_memory.CArray)

Module Ctypes_memory.CArray

type 'a t = 'a Ctypes_static.carray
val check_bound : 'a Ctypes_static.carray -> int -> unit
val unsafe_get : 'a Ctypes_static.carray -> int -> 'b
val unsafe_set : 'a Ctypes_static.carray -> int -> 'b -> unit
val get : 'a Ctypes_static.carray -> int -> 'b
val set : 'a Ctypes_static.carray -> int -> 'b -> unit
val length : 'a Ctypes_static.carray -> int
val from_ptr : 'a Ctypes_static.ptr -> int -> 'a Ctypes_static.carray
val fill : 'a Ctypes_static.carray -> 'b -> unit
val make : + 'a. ?finalise:('a t -> unit) -> + 'a Ctypes_static.typ -> + ?initial:'a -> + int -> + 'a t
val sub : + 'a Ctypes_static.carray -> + pos:int -> + length:int -> + 'b Ctypes_static.carray
val element_type : 'a Ctypes_static.carray -> 'b Ctypes_static.typ
val of_string : string -> char t
val of_list : 'a Ctypes_static.typ -> 'b list -> 'a t
val to_list : 'a Ctypes_static.carray -> 'b list
val iter : ('a -> 'b) -> 'c Ctypes_static.carray -> unit
val iteri : (int -> 'a -> 'b) -> 'c Ctypes_static.carray -> unit
val map : 'a Ctypes_static.typ -> ('b -> 'c) -> 'd Ctypes_static.carray -> 'a t
val mapi : + 'a Ctypes_static.typ -> + (int -> 'b -> 'c) -> + 'd Ctypes_static.carray -> + 'a t
val fold_left : ('a -> 'b -> 'c) -> 'd -> 'e Ctypes_static.carray -> 'f
val fold_right : ('a -> 'b -> 'c) -> 'd Ctypes_static.carray -> 'e -> 'f
diff --git a/docs/findlib-1/ctypes/Ctypes_memory/Root/index.html b/docs/findlib-1/ctypes/Ctypes_memory/Root/index.html new file mode 100644 index 00000000..dcd080eb --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_memory/Root/index.html @@ -0,0 +1,2 @@ + +Root (docs.findlib-1.ctypes.Ctypes_memory.Root)

Module Ctypes_memory.Root

module Stubs = Ctypes_roots_stubs
val raw_addr : unit Ctypes_static.ptr -> Raw.t
val create : 'a. 'a -> unit Ctypes_static.ptr
val get : 'a. unit Ctypes_static.ptr -> 'a
val set : 'a. unit Ctypes_static.ptr -> 'a -> unit
val release : unit Ctypes_static.ptr -> unit
diff --git a/docs/findlib-1/ctypes/Ctypes_memory/index.html b/docs/findlib-1/ctypes/Ctypes_memory/index.html new file mode 100644 index 00000000..aadf94d2 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_memory/index.html @@ -0,0 +1,171 @@ + +Ctypes_memory (docs.findlib-1.ctypes.Ctypes_memory)

Module Ctypes_memory

module Stubs = Ctypes_memory_stubs
module Raw = Ctypes_ptr.Raw
module Fat = Ctypes_ptr.Fat
val castp : + 'a Ctypes_static.typ -> + ('b, [ `C ]) Ctypes_static.pointer -> + ('a, [ `C ]) Ctypes_static.pointer
val make_unmanaged : reftyp:'a -> Ctypes_ptr.voidp -> ('b option, 'c) Fat.t
val build : + 'a 'b. 'a Ctypes_static.typ -> + ('c, 'b Ctypes_static.typ) Fat.t -> + 'a
val write : 'a 'b. 'a Ctypes_static.typ -> 'a -> ('c, 'b) Fat.t -> unit
val null : unit Ctypes_static.ptr
val (!@) : 'a. 'a Ctypes_static.ptr -> 'a
val ptr_diff : + 'a 'b. ('a, 'b) Ctypes_static.pointer -> + ('a, 'b) Ctypes_static.pointer -> + int
val (+@) : + 'a 'b. ('a, 'b) Ctypes_static.pointer -> + int -> + ('a, 'b) Ctypes_static.pointer
val (-@) : + ('a, 'b) Ctypes_static.pointer -> + int -> + ('a, 'b) Ctypes_static.pointer
val (<-@) : 'a. 'a Ctypes_static.ptr -> 'a -> unit
val from_voidp : + 'a Ctypes_static.typ -> + ('b, [ `C ]) Ctypes_static.pointer -> + ('a, [ `C ]) Ctypes_static.pointer
val to_voidp : + ('a, [ `C ]) Ctypes_static.pointer -> + (unit, [ `C ]) Ctypes_static.pointer
val allocate_n : + 'a. ?finalise:('a Ctypes_static.ptr -> unit) -> + 'a Ctypes_static.typ -> + count:int -> + 'a Ctypes_static.ptr
val allocate : + 'a. ?finalise:('a Ctypes_static.ptr -> unit) -> + 'a Ctypes_static.typ -> + 'a -> + 'a Ctypes_static.ptr
val ptr_compare : + ('a, [ `C ]) Ctypes_static.pointer -> + ('b, [ `C ]) Ctypes_static.pointer -> + int
val reference_type : ('a, [ `C ]) Ctypes_static.pointer -> 'b Ctypes_static.typ
val ptr_of_raw_address : + Ctypes_ptr.voidp -> + (unit, [ `C ]) Ctypes_static.pointer
val funptr_of_raw_address : + Ctypes_ptr.voidp -> + (unit -> unit) Ctypes_static.static_funptr
val raw_address_of_ptr : ('a, [ `C ]) Ctypes_static.pointer -> Ctypes_ptr.voidp
module CArray : sig ... end
val make : + ?finalise:(('a, 'b) Ctypes_static.structured -> unit) -> + ('c, 'd) Ctypes_static.structured Ctypes_static.typ -> + ('c, 'd) Ctypes_static.structured
val (|->) : + ('a, [ `C ]) Ctypes_static.pointer -> + ('b, 'c) Ctypes_static.field -> + ('d, [ `C ]) Ctypes_static.pointer
val (@.) : + ('a, 'b) Ctypes_static.structured -> + ('c, 'd) Ctypes_static.field -> + ('c, [ `C ]) Ctypes_static.pointer
val setf : + ('a, 'b) Ctypes_static.structured -> + ('c, 'd) Ctypes_static.field -> + 'e -> + unit
val getf : + ('a, 'b) Ctypes_static.structured -> + ('c, 'd) Ctypes_static.field -> + 'e
val _bigarray_start : + ('a, 'b) Bigarray_compat.kind -> + 'c -> + ('d, [ `C ]) Ctypes_static.pointer
val bigarray_kind : + 'a 'b 'c 'd 'f 'l. < ba_repr : 'f + ; bigarray : 'b + ; carray : 'c + ; dims : 'd + ; element : 'a + ; layout : 'l > + Ctypes_static.bigarray_class -> + 'b -> + ('a, 'f) Bigarray.kind
val bigarray_start : + < ba_repr : 'a + ; bigarray : 'b + ; carray : 'c + ; dims : 'd + ; element : 'e + ; layout : 'f > + Ctypes_static.bigarray_class -> + 'g -> + ('h, [ `C ]) Ctypes_static.pointer
val array_of_bigarray : + 'a 'b 'c 'd 'e. < ba_repr : 'e + ; bigarray : 'b + ; carray : 'c + ; dims : 'd + ; element : 'a + ; layout : Bigarray.c_layout > + Ctypes_static.bigarray_class -> + 'b -> + 'c
val bigarray_elements : + 'a 'b 'c 'd 'f 'l. < ba_repr : 'f + ; bigarray : 'b + ; carray : 'c + ; dims : 'd + ; element : 'a + ; layout : 'l > + Ctypes_static.bigarray_class -> + 'd -> + int
val bigarray_of_ptr : + < ba_repr : 'a + ; bigarray : 'b + ; carray : 'c + ; dims : 'd + ; element : 'e + ; layout : Bigarray_compat.c_layout > + Ctypes_static.bigarray_class -> + 'f -> + ('e, 'a) Bigarray_compat.kind -> + ('g, [ `C ]) Ctypes_static.pointer -> + 'h
val fortran_bigarray_of_ptr : + < ba_repr : 'a + ; bigarray : 'b + ; carray : 'c + ; dims : 'd + ; element : 'e + ; layout : Bigarray_compat.fortran_layout > + Ctypes_static.bigarray_class -> + 'f -> + ('e, 'a) Bigarray_compat.kind -> + ('g, [ `C ]) Ctypes_static.pointer -> + 'h
val array_dims : + 'a 'b 'c 'd 'f 'l. < ba_repr : 'f + ; bigarray : 'b + ; carray : 'c Ctypes_static.carray + ; dims : 'd + ; element : 'a + ; layout : 'l > + Ctypes_static.bigarray_class -> + 'c Ctypes_static.carray -> + 'd
val bigarray_of_array : + < ba_repr : 'a + ; bigarray : 'b + ; carray : 'c Ctypes_static.carray + ; dims : 'd + ; element : 'e + ; layout : Bigarray_compat.c_layout > + Ctypes_static.bigarray_class -> + ('e, 'a) Bigarray_compat.kind -> + 'f Ctypes_static.carray -> + 'g
val genarray : + < ba_repr : 'a + ; bigarray : ('b, 'a, 'c) Bigarray_compat.Genarray.t + ; carray : 'b Ctypes_static.carray + ; dims : int array + ; element : 'b + ; layout : 'c > + Ctypes_static.bigarray_class
val array1 : + < ba_repr : 'a + ; bigarray : ('b, 'a, 'c) Bigarray_compat.Array1.t + ; carray : 'b Ctypes_static.carray + ; dims : int + ; element : 'b + ; layout : 'c > + Ctypes_static.bigarray_class
val array2 : + < ba_repr : 'a + ; bigarray : ('b, 'a, 'c) Bigarray_compat.Array2.t + ; carray : 'b Ctypes_static.carray Ctypes_static.carray + ; dims : int * int + ; element : 'b + ; layout : 'c > + Ctypes_static.bigarray_class
val array3 : + < ba_repr : 'a + ; bigarray : ('b, 'a, 'c) Bigarray_compat.Array3.t + ; carray : + 'b Ctypes_static.carray Ctypes_static.carray Ctypes_static.carray + ; dims : int * int * int + ; element : 'b + ; layout : 'c > + Ctypes_static.bigarray_class
val typ_of_bigarray_kind : + ('a, 'b) Bigarray_compat.kind -> + 'c Ctypes_static.typ
val string_from_ptr : + ('a, [ `C ]) Ctypes_static.pointer -> + length:int -> + string
val ocaml_string_start : string -> (string, [ `OCaml ]) Ctypes_static.pointer
val ocaml_bytes_start : bytes -> (bytes, [ `OCaml ]) Ctypes_static.pointer
val ocaml_float_array_start : + float array -> + (float array, [ `OCaml ]) Ctypes_static.pointer
module Root : sig ... end
val is_null : ('a, [ `C ]) Ctypes_static.pointer -> bool
diff --git a/docs/findlib-1/ctypes/Ctypes_memory_stubs/Pointer/index.html b/docs/findlib-1/ctypes/Ctypes_memory_stubs/Pointer/index.html new file mode 100644 index 00000000..1fe27340 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_memory_stubs/Pointer/index.html @@ -0,0 +1,2 @@ + +Pointer (docs.findlib-1.ctypes.Ctypes_memory_stubs.Pointer)

Module Ctypes_memory_stubs.Pointer

val read : (_, _) Ctypes_ptr.Fat.t -> Ctypes_ptr.voidp
val write : (_, _) Ctypes_ptr.Fat.t -> (_, _) Ctypes_ptr.Fat.t -> unit
diff --git a/docs/findlib-1/ctypes/Ctypes_memory_stubs/index.html b/docs/findlib-1/ctypes/Ctypes_memory_stubs/index.html new file mode 100644 index 00000000..eefac961 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_memory_stubs/index.html @@ -0,0 +1,10 @@ + +Ctypes_memory_stubs (docs.findlib-1.ctypes.Ctypes_memory_stubs)

Module Ctypes_memory_stubs

type managed_buffer
val allocate : int -> int -> managed_buffer
val block_address : managed_buffer -> Ctypes_ptr.voidp
val read : 'a Ctypes_primitive_types.prim -> (_, _) Ctypes_ptr.Fat.t -> 'a
val write : + 'a Ctypes_primitive_types.prim -> + 'a -> + (_, _) Ctypes_ptr.Fat.t -> + unit
module Pointer : sig ... end
val memcpy : + dst:(_, _) Ctypes_ptr.Fat.t -> + src:(_, _) Ctypes_ptr.Fat.t -> + size:int -> + unit
val string_of_array : (_, _) Ctypes_ptr.Fat.t -> len:int -> string
val use_value : 'a -> unit
diff --git a/docs/findlib-1/ctypes/Ctypes_primitive_types/index.html b/docs/findlib-1/ctypes/Ctypes_primitive_types/index.html new file mode 100644 index 00000000..08cb62bd --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_primitive_types/index.html @@ -0,0 +1,2 @@ + +Ctypes_primitive_types (docs.findlib-1.ctypes.Ctypes_primitive_types)

Module Ctypes_primitive_types

type _ prim =
  1. | Char : char prim
  2. | Schar : int prim
  3. | Uchar : Unsigned.uchar prim
  4. | Bool : bool prim
  5. | Short : int prim
  6. | Int : int prim
  7. | Long : Signed.long prim
  8. | Llong : Signed.llong prim
  9. | Ushort : Unsigned.ushort prim
  10. | Sint : Signed.sint prim
  11. | Uint : Unsigned.uint prim
  12. | Ulong : Unsigned.ulong prim
  13. | Ullong : Unsigned.ullong prim
  14. | Size_t : Unsigned.size_t prim
  15. | Int8_t : int prim
  16. | Int16_t : int prim
  17. | Int32_t : int32 prim
  18. | Int64_t : int64 prim
  19. | Uint8_t : Unsigned.uint8 prim
  20. | Uint16_t : Unsigned.uint16 prim
  21. | Uint32_t : Unsigned.uint32 prim
  22. | Uint64_t : Unsigned.uint64 prim
  23. | Camlint : int prim
  24. | Nativeint : nativeint prim
  25. | Float : float prim
  26. | Double : float prim
  27. | LDouble : LDouble.t prim
  28. | Complex32 : Complex.t prim
  29. | Complex64 : Complex.t prim
  30. | Complexld : ComplexL.t prim
type _ ml_prim =
  1. | ML_char : char ml_prim
  2. | ML_complex : Complex.t ml_prim
  3. | ML_complexld : ComplexL.t ml_prim
  4. | ML_float : float ml_prim
  5. | ML_ldouble : LDouble.t ml_prim
  6. | ML_int : int ml_prim
  7. | ML_int32 : int32 ml_prim
  8. | ML_int64 : int64 ml_prim
  9. | ML_llong : Signed.llong ml_prim
  10. | ML_long : Signed.long ml_prim
  11. | ML_sint : Signed.sint ml_prim
  12. | ML_nativeint : nativeint ml_prim
  13. | ML_size_t : Unsigned.size_t ml_prim
  14. | ML_uchar : Unsigned.uchar ml_prim
  15. | ML_bool : bool ml_prim
  16. | ML_uint : Unsigned.uint ml_prim
  17. | ML_uint16 : Unsigned.uint16 ml_prim
  18. | ML_uint32 : Unsigned.uint32 ml_prim
  19. | ML_uint64 : Unsigned.uint64 ml_prim
  20. | ML_uint8 : Unsigned.uint8 ml_prim
  21. | ML_ullong : Unsigned.ullong ml_prim
  22. | ML_ulong : Unsigned.ulong ml_prim
  23. | ML_ushort : Unsigned.ushort ml_prim
val ml_prim : 'a prim -> 'a ml_prim
diff --git a/docs/findlib-1/ctypes/Ctypes_primitives/index.html b/docs/findlib-1/ctypes/Ctypes_primitives/index.html new file mode 100644 index 00000000..1cb9e059 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_primitives/index.html @@ -0,0 +1,2 @@ + +Ctypes_primitives (docs.findlib-1.ctypes.Ctypes_primitives)

Module Ctypes_primitives

val sizeof : 'a. 'a Ctypes_primitive_types.prim -> int
val alignment : 'a. 'a Ctypes_primitive_types.prim -> int
val name : 'a. 'a Ctypes_primitive_types.prim -> string
val format_string : 'a. 'a Ctypes_primitive_types.prim -> string option
val pointer_size : int
val pointer_alignment : int
diff --git a/docs/findlib-1/ctypes/Ctypes_ptr/Fat/index.html b/docs/findlib-1/ctypes/Ctypes_ptr/Fat/index.html new file mode 100644 index 00000000..cc02ddf6 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_ptr/Fat/index.html @@ -0,0 +1,2 @@ + +Fat (docs.findlib-1.ctypes.Ctypes_ptr.Fat)

Module Ctypes_ptr.Fat

type (_, _) t

A fat pointer, which holds a reference to the reference type, the C memory location, and an OCaml object.

val make : managed:'m -> reftyp:'typ -> voidp -> ('m, 'typ) t

make ?managed ~reftyp raw builds a fat pointer from the reference type reftyp, the C memory location raw, and (optionally) an OCaml value, managed. The managed argument may be used to manage the lifetime of the C object; a typical use it to attach a finaliser to managed which releases the memory associated with the C object whose address is stored in raw_ptr.

val is_null : (_, _) t -> bool
val reftype : (_, 'typ) t -> 'typ
val managed : ('m, _) t -> 'm
val set_managed : ('m, _) t -> 'm -> unit
val coerce : ('m, _) t -> 'typ -> ('m, 'typ) t
val unsafe_raw_addr : (_, _) t -> voidp

Return the raw pointer address. The function is unsafe in the sense that it dissociates the address from the value which manages the memory, which may trigger associated finalisers, invalidating the address.

val add_bytes : ('m, 'typ) t -> int -> ('m, 'typ) t
val compare : (_, 'typ) t -> (_, 'typ) t -> int
val diff_bytes : (_, 'typ) t -> (_, 'typ) t -> int
diff --git a/docs/findlib-1/ctypes/Ctypes_ptr/Raw/index.html b/docs/findlib-1/ctypes/Ctypes_ptr/Raw/index.html new file mode 100644 index 00000000..57dff225 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_ptr/Raw/index.html @@ -0,0 +1,3 @@ + +Raw (docs.findlib-1.ctypes.Ctypes_ptr.Raw)

Module Ctypes_ptr.Raw

include module type of struct include Nativeint end
val zero : nativeint

The native integer 0.

val one : nativeint

The native integer 1.

val minus_one : nativeint

The native integer -1.

val neg : nativeint -> nativeint

Unary negation.

val add : nativeint -> nativeint -> nativeint

Addition.

val sub : nativeint -> nativeint -> nativeint

Subtraction.

val mul : nativeint -> nativeint -> nativeint

Multiplication.

val div : nativeint -> nativeint -> nativeint

Integer division. This division rounds the real quotient of its arguments towards zero, as specified for Stdlib.(/).

val unsigned_div : nativeint -> nativeint -> nativeint

Same as div, except that arguments and result are interpreted as unsigned native integers.

  • since 4.08
val rem : nativeint -> nativeint -> nativeint

Integer remainder. If y is not zero, the result of Nativeint.rem x y satisfies the following properties: Nativeint.zero <= Nativeint.rem x y < Nativeint.abs y and x = Nativeint.add (Nativeint.mul (Nativeint.div x y) y) + (Nativeint.rem x y). If y = 0, Nativeint.rem x y raises Division_by_zero.

val unsigned_rem : nativeint -> nativeint -> nativeint

Same as rem, except that arguments and result are interpreted as unsigned native integers.

  • since 4.08
val succ : nativeint -> nativeint

Successor. Nativeint.succ x is Nativeint.add x Nativeint.one.

val pred : nativeint -> nativeint

Predecessor. Nativeint.pred x is Nativeint.sub x Nativeint.one.

val abs : nativeint -> nativeint

abs x is the absolute value of x. On min_int this is min_int itself and thus remains negative.

val size : int

The size in bits of a native integer. This is equal to 32 on a 32-bit platform and to 64 on a 64-bit platform.

val max_int : nativeint

The greatest representable native integer, either 231 - 1 on a 32-bit platform, or 263 - 1 on a 64-bit platform.

val min_int : nativeint

The smallest representable native integer, either -231 on a 32-bit platform, or -263 on a 64-bit platform.

val logand : nativeint -> nativeint -> nativeint

Bitwise logical and.

val logor : nativeint -> nativeint -> nativeint

Bitwise logical or.

val logxor : nativeint -> nativeint -> nativeint

Bitwise logical exclusive or.

val lognot : nativeint -> nativeint

Bitwise logical negation.

val shift_left : nativeint -> int -> nativeint

Nativeint.shift_left x y shifts x to the left by y bits. The result is unspecified if y < 0 or y >= bitsize, where bitsize is 32 on a 32-bit platform and 64 on a 64-bit platform.

val shift_right : nativeint -> int -> nativeint

Nativeint.shift_right x y shifts x to the right by y bits. This is an arithmetic shift: the sign bit of x is replicated and inserted in the vacated bits. The result is unspecified if y < 0 or y >= bitsize.

val shift_right_logical : nativeint -> int -> nativeint

Nativeint.shift_right_logical x y shifts x to the right by y bits. This is a logical shift: zeroes are inserted in the vacated bits regardless of the sign of x. The result is unspecified if y < 0 or y >= bitsize.

val of_int : int -> nativeint

Convert the given integer (type int) to a native integer (type nativeint).

val to_int : nativeint -> int

Convert the given native integer (type nativeint) to an integer (type int). The high-order bit is lost during the conversion.

val unsigned_to_int : nativeint -> int option

Same as to_int, but interprets the argument as an unsigned integer. Returns None if the unsigned value of the argument cannot fit into an int.

  • since 4.08
val of_float : float -> nativeint

Convert the given floating-point number to a native integer, discarding the fractional part (truncate towards 0). If the truncated floating-point number is outside the range [Nativeint.min_int, Nativeint.max_int], no exception is raised, and an unspecified, platform-dependent integer is returned.

val to_float : nativeint -> float

Convert the given native integer to a floating-point number.

val of_int32 : int32 -> nativeint

Convert the given 32-bit integer (type int32) to a native integer.

val to_int32 : nativeint -> int32

Convert the given native integer to a 32-bit integer (type int32). On 64-bit platforms, the 64-bit native integer is taken modulo 232, i.e. the top 32 bits are lost. On 32-bit platforms, the conversion is exact.

val of_string : string -> nativeint

Convert the given string to a native integer. The string is read in decimal (by default, or if the string begins with 0u) or in hexadecimal, octal or binary if the string begins with 0x, 0o or 0b respectively.

The 0u prefix reads the input as an unsigned integer in the range [0, 2*Nativeint.max_int+1]. If the input exceeds Nativeint.max_int it is converted to the signed integer Int64.min_int + input - Nativeint.max_int - 1.

  • raises Failure

    if the given string is not a valid representation of an integer, or if the integer represented exceeds the range of integers representable in type nativeint.

val of_string_opt : string -> nativeint option

Same as of_string, but return None instead of raising.

  • since 4.05
val to_string : nativeint -> string

Return the string representation of its argument, in decimal.

type t = nativeint

An alias for the type of native integers.

val compare : t -> t -> int

The comparison function for native integers, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Nativeint to be passed as argument to the functors Set.Make and Map.Make.

val unsigned_compare : t -> t -> int

Same as compare, except that arguments are interpreted as unsigned native integers.

  • since 4.08
val equal : t -> t -> bool

The equal function for native ints.

  • since 4.03
val min : t -> t -> t

Return the smaller of the two arguments.

  • since 4.13
val max : t -> t -> t

Return the greater of the two arguments.

  • since 4.13
val seeded_hash : int -> t -> int

A seeded hash function for native ints, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : t -> int

An unseeded hash function for native ints, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
val of_nativeint : 'a -> 'b
val to_nativeint : 'a -> 'b
val null : nativeint
diff --git a/docs/findlib-1/ctypes/Ctypes_ptr/index.html b/docs/findlib-1/ctypes/Ctypes_ptr/index.html new file mode 100644 index 00000000..d8ca7f63 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_ptr/index.html @@ -0,0 +1,2 @@ + +Ctypes_ptr (docs.findlib-1.ctypes.Ctypes_ptr)

Module Ctypes_ptr

module Raw : sig ... end
type voidp = Raw.t
module Fat : sig ... end
diff --git a/docs/findlib-1/ctypes/Ctypes_roots_stubs/index.html b/docs/findlib-1/ctypes/Ctypes_roots_stubs/index.html new file mode 100644 index 00000000..b6bcdfc9 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_roots_stubs/index.html @@ -0,0 +1,2 @@ + +Ctypes_roots_stubs (docs.findlib-1.ctypes.Ctypes_roots_stubs)

Module Ctypes_roots_stubs

val root : 'a -> Ctypes_ptr.voidp
val set : Ctypes_ptr.voidp -> 'a -> unit
val get : Ctypes_ptr.voidp -> 'a
val release : Ctypes_ptr.voidp -> unit
diff --git a/docs/findlib-1/ctypes/Ctypes_static/index.html b/docs/findlib-1/ctypes/Ctypes_static/index.html new file mode 100644 index 00000000..0b42b55a --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_static/index.html @@ -0,0 +1,52 @@ + +Ctypes_static (docs.findlib-1.ctypes.Ctypes_static)

Module Ctypes_static

type abstract_type = {
  1. aname : string;
  2. asize : int;
  3. aalignment : int;
}
type _ ocaml_type =
  1. | String : string ocaml_type
  2. | Bytes : bytes ocaml_type
  3. | FloatArray : float array ocaml_type
type incomplete_size = {
  1. mutable isize : int;
}
type structured_spec = {
  1. size : int;
  2. align : int;
}
type 'a structspec =
  1. | Incomplete of incomplete_size
  2. | Complete of structured_spec
type qualifier =
  1. | Const
  2. | Volatile
type _ typ =
  1. | Void : unit typ
  2. | Primitive : 'a Ctypes_primitive_types.prim -> 'a typ
  3. | Pointer : 'a typ -> 'a ptr typ
  4. | Funptr : 'a fn -> 'a static_funptr typ
  5. | Struct : 'a structure_type -> 'a structure typ
  6. | Union : 'a union_type -> 'a union typ
  7. | Abstract : abstract_type -> 'a abstract typ
  8. | View : ('a, 'b) view -> 'a typ
  9. | Qualified : qualifier * 'a typ -> 'a typ
  10. | Array : 'a typ * int -> 'a carray typ
  11. | Bigarray : (_, 'a, _) Ctypes_bigarray.t -> 'a typ
  12. | OCaml : 'a ocaml_type -> 'a ocaml typ
and 'a carray = {
  1. astart : 'a ptr;
  2. alength : int;
}
and ('a, 'kind) structured = {
  1. structured : ('a, 'kind) structured ptr;
}
and 'a union = ('a, [ `Union ]) structured
and 'a structure = ('a, [ `Struct ]) structured
and 'a abstract = ('a, [ `Abstract ]) structured
and (_, _) pointer =
  1. | CPointer : (Obj.t option, 'a typ) Ctypes_ptr.Fat.t -> ('a, [ `C ]) pointer
  2. | OCamlRef : int * 'a * 'a ocaml_type -> ('a, [ `OCaml ]) pointer
and 'a ptr = ('a, [ `C ]) pointer
and 'a ocaml = ('a, [ `OCaml ]) pointer
and 'a static_funptr =
  1. | Static_funptr : (Obj.t option, 'a fn) Ctypes_ptr.Fat.t -> 'a static_funptr
and ('a, 'b) view = {
  1. read : 'b -> 'a;
  2. write : 'a -> 'b;
  3. format_typ : ((Format.formatter -> unit) -> Format.formatter -> unit) option;
  4. format : (Format.formatter -> 'a -> unit) option;
  5. ty : 'b typ;
}
and ('a, 's) field = {
  1. ftype : 'a typ;
  2. foffset : int;
  3. fname : string;
}
and 'a structure_type = {
  1. tag : string;
  2. mutable spec : 'a structspec;
  3. mutable fields : 'a structure boxed_field list;
}
and 'a union_type = {
  1. utag : string;
  2. mutable uspec : structured_spec option;
  3. mutable ufields : 'a union boxed_field list;
}
and 's boxed_field =
  1. | BoxedField : ('a, 's) field -> 's boxed_field
and _ fn =
  1. | Returns : 'a typ -> 'a fn
  2. | Function : 'a typ * 'b fn -> ('a -> 'b) fn
type _ bigarray_class =
  1. | Genarray : < element : 'a + ; layout : 'l + ; dims : int array + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Genarray.t + ; carray : 'a carray > + bigarray_class
  2. | Array1 : < element : 'a + ; layout : 'l + ; dims : int + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Array1.t + ; carray : 'a carray > + bigarray_class
  3. | Array2 : < element : 'a + ; layout : 'l + ; dims : int * int + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Array2.t + ; carray : 'a carray carray > + bigarray_class
  4. | Array3 : < element : 'a + ; layout : 'l + ; dims : int * int * int + ; ba_repr : 'b + ; bigarray : ('a, 'b, 'l) Bigarray_compat.Array3.t + ; carray : 'a carray carray carray > + bigarray_class
type boxed_typ =
  1. | BoxedType : 'a typ -> boxed_typ
val sizeof : 'a typ -> int
val alignment : 'a typ -> int
val passable : 'a typ -> bool
val ocaml_value : 'a typ -> bool
val has_ocaml_argument : 'a fn -> bool
val void : unit typ
val char : char typ
val schar : int typ
val float : float typ
val double : float typ
val ldouble : LDouble.t typ
val complex32 : Complex.t typ
val complex64 : Complex.t typ
val complexld : ComplexL.t typ
val short : int typ
val int : int typ
val sint : Signed.sint typ
val long : Signed.long typ
val llong : Signed.llong typ
val nativeint : nativeint typ
val int8_t : int typ
val int16_t : int typ
val int32_t : Signed.Int32.t typ
val int64_t : Signed.Int64.t typ
val camlint : int typ
val uchar : Unsigned.uchar typ
val bool : bool typ
val uint8_t : Unsigned.UInt8.t typ
val uint16_t : Unsigned.UInt16.t typ
val uint32_t : Unsigned.UInt32.t typ
val uint64_t : Unsigned.UInt64.t typ
val size_t : Unsigned.size_t typ
val ushort : Unsigned.ushort typ
val uint : Unsigned.uint typ
val ulong : Unsigned.ulong typ
val ullong : Unsigned.ullong typ
val array : int -> 'a typ -> 'a carray typ
val ocaml_string : string ocaml typ
val ocaml_bytes : bytes ocaml typ
val ocaml_float_array : float array ocaml typ
val ptr : 'a typ -> 'a ptr typ
val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn
val abstract : name:string -> size:int -> alignment:int -> 'a abstract typ
val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ
val typedef : 'a typ -> string -> 'a typ
val bigarray : + < ba_repr : 'c + ; bigarray : 'd + ; carray : 'e + ; dims : 'b + ; layout : Bigarray_compat.c_layout + ; element : 'a > + bigarray_class -> + 'b -> + ('a, 'c) Bigarray_compat.kind -> + 'd typ
val fortran_bigarray : + < ba_repr : 'c + ; bigarray : 'd + ; carray : 'e + ; dims : 'b + ; layout : Bigarray_compat.fortran_layout + ; element : 'a > + bigarray_class -> + 'b -> + ('a, 'c) Bigarray_compat.kind -> + 'd typ
val returning : 'a typ -> 'a fn
val static_funptr : 'a fn -> 'a static_funptr typ
val structure : string -> 'a structure typ
val union : string -> 'a union typ
val offsetof : ('a, 'b) field -> int
val field_type : ('a, 'b) field -> 'a typ
val field_name : ('a, 'b) field -> string
val const : 'a typ -> 'a typ
val volatile : 'a typ -> 'a typ
exception IncompleteType
exception ModifyingSealedType of string
exception Unsupported of string
val unsupported : ('a, unit, string, _) format4 -> 'a
type arithmetic =
  1. | Int8
  2. | Int16
  3. | Int32
  4. | Int64
  5. | Uint8
  6. | Uint16
  7. | Uint32
  8. | Uint64
  9. | Float
  10. | Double
diff --git a/docs/findlib-1/ctypes/Ctypes_std_view_stubs/index.html b/docs/findlib-1/ctypes/Ctypes_std_view_stubs/index.html new file mode 100644 index 00000000..c2cfab66 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_view_stubs/index.html @@ -0,0 +1,2 @@ + +Ctypes_std_view_stubs (docs.findlib-1.ctypes.Ctypes_std_view_stubs)

Module Ctypes_std_view_stubs

val string_of_cstring : (_, char Ctypes_static.typ) Ctypes_ptr.Fat.t -> string
val cstring_of_string : string -> Ctypes_memory_stubs.managed_buffer
val uintptr_t_size : unit -> int
val intptr_t_size : unit -> int
val ptrdiff_t_size : unit -> int
diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/Intptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/Intptr/Infix/index.html new file mode 100644 index 00000000..cff6f0d8 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_std_views.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/Intptr/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/Intptr/index.html new file mode 100644 index 00000000..959ec207 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.Ctypes_std_views.Intptr)

Module Ctypes_std_views.Intptr

include Signed.S
type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..7aa2e77d --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_std_views.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/index.html new file mode 100644 index 00000000..031d5b84 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.Ctypes_std_views.Ptrdiff)

Module Ctypes_std_views.Ptrdiff

include Signed.S
type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/Infix/index.html new file mode 100644 index 00000000..b8b46938 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_std_views.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/index.html new file mode 100644 index 00000000..9cd0a8cb --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.Ctypes_std_views.Uintptr)

Module Ctypes_std_views.Uintptr

include Unsigned.S
type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/index.html new file mode 100644 index 00000000..1231dc37 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/index.html @@ -0,0 +1,30 @@ + +Ctypes_std_views (docs.findlib-1.ctypes.Ctypes_std_views)

Module Ctypes_std_views

val string_of_char_ptr : (char, [ `C ]) Ctypes_static.pointer -> string
val char_ptr_of_string : string -> (char, [ `C ]) Ctypes_static.pointer
val string : string Ctypes_static.typ
val read_nullable : + 'a Ctypes_static.typ -> + 'b Ctypes_static.typ -> + 'b Ctypes_static.ptr -> + 'c option
val write_nullable : + 'a Ctypes_static.typ -> + 'b Ctypes_static.typ -> + 'c option -> + 'd Ctypes_static.ptr
val nullable_view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'a option -> unit) -> + 'b Ctypes_static.typ -> + 'c Ctypes_static.typ -> + 'a option Ctypes_static.typ
val read_nullable_funptr : + 'a Ctypes_static.typ -> + 'b Ctypes_static.fn -> + 'c Ctypes_static.static_funptr -> + 'd option
val write_nullable_funptr : + 'a Ctypes_static.typ -> + 'b Ctypes_static.fn -> + 'c option -> + 'b Ctypes_static.static_funptr
val nullable_funptr_view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'a option -> unit) -> + 'b Ctypes_static.typ -> + 'c Ctypes_static.fn -> + 'a option Ctypes_static.typ
val ptr_opt : + 'a Ctypes_static.typ -> + 'b Ctypes_static.ptr option Ctypes_static.typ
val string_opt : string option Ctypes_static.typ
module type Signed_type = sig ... end
module type Unsigned_type = sig ... end
val signed_typedef : string -> size:int -> (module Signed_type)
val unsigned_typedef : string -> size:int -> (module Unsigned_type)
diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/Infix/index.html new file mode 100644 index 00000000..b0ff80c6 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_std_views.Signed_type.Infix)

Module Signed_type.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/index.html new file mode 100644 index 00000000..cdc8fc7a --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Signed_type/index.html @@ -0,0 +1,2 @@ + +Signed_type (docs.findlib-1.ctypes.Ctypes_std_views.Signed_type)

Module type Ctypes_std_views.Signed_type

include Signed.S
type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/Infix/index.html new file mode 100644 index 00000000..2d6ea29f --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_std_views.Unsigned_type.Infix)

Module Unsigned_type.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/index.html b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/index.html new file mode 100644 index 00000000..b01c444b --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_std_views/module-type-Unsigned_type/index.html @@ -0,0 +1,2 @@ + +Unsigned_type (docs.findlib-1.ctypes.Ctypes_std_views.Unsigned_type)

Module type Ctypes_std_views.Unsigned_type

include Unsigned.S
type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/Ctypes_structs/index.html b/docs/findlib-1/ctypes/Ctypes_structs/index.html new file mode 100644 index 00000000..eda6ca8f --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_structs/index.html @@ -0,0 +1,2 @@ + +Ctypes_structs (docs.findlib-1.ctypes.Ctypes_structs)

Module Ctypes_structs

module type S = sig ... end
diff --git a/docs/findlib-1/ctypes/Ctypes_structs/module-type-S/index.html b/docs/findlib-1/ctypes/Ctypes_structs/module-type-S/index.html new file mode 100644 index 00000000..16f05310 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_structs/module-type-S/index.html @@ -0,0 +1,8 @@ + +S (docs.findlib-1.ctypes.Ctypes_structs.S)

Module type Ctypes_structs.S

type (_, _) field
val field : + 't Ctypes_static.typ -> + string -> + 'a Ctypes_static.typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field
val seal : + (_, [< `Struct | `Union ]) Ctypes_static.structured Ctypes_static.typ -> + unit
diff --git a/docs/findlib-1/ctypes/Ctypes_structs_computed/index.html b/docs/findlib-1/ctypes/Ctypes_structs_computed/index.html new file mode 100644 index 00000000..787ef896 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_structs_computed/index.html @@ -0,0 +1,10 @@ + +Ctypes_structs_computed (docs.findlib-1.ctypes.Ctypes_structs_computed)

Module Ctypes_structs_computed

Structs and unions whose layouts are computed from the sizes and alignment requirements of the constituent field types.

include Ctypes_structs.S + with type ('a, 's) field := ('a, 's) Ctypes_static.field
val field : + 't Ctypes_static.typ -> + string -> + 'a Ctypes_static.typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) + Ctypes_static.field
val seal : + (_, [< `Struct | `Union ]) Ctypes_static.structured Ctypes_static.typ -> + unit
diff --git a/docs/findlib-1/ctypes/Ctypes_type_printing/index.html b/docs/findlib-1/ctypes/Ctypes_type_printing/index.html new file mode 100644 index 00000000..4bf1c9c0 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_type_printing/index.html @@ -0,0 +1,15 @@ + +Ctypes_type_printing (docs.findlib-1.ctypes.Ctypes_type_printing)

Module Ctypes_type_printing

type format_context = [
  1. | `toplevel
  2. | `array
  3. | `nonarray
]
val format_name : ?name:string -> Format.formatter -> unit
val format_typ' : + 'a Ctypes_static.typ -> + (format_context -> Format.formatter -> unit) -> + format_context -> + Format.formatter -> + unit
val format_typ : + ?name:string -> + Format.formatter -> + 'a Ctypes_static.typ -> + unit
val format_fn' : + 'a Ctypes_static.fn -> + (Format.formatter -> unit) -> + Format.formatter -> + unit
val format_fn : ?name:string -> Format.formatter -> 'a Ctypes_static.fn -> unit
val string_of_typ : ?name:string -> 'a Ctypes_static.typ -> string
val string_of_fn : ?name:string -> 'a Ctypes_static.fn -> string
diff --git a/docs/findlib-1/ctypes/Ctypes_types/index.html b/docs/findlib-1/ctypes/Ctypes_types/index.html new file mode 100644 index 00000000..3e6dca60 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/index.html @@ -0,0 +1,2 @@ + +Ctypes_types (docs.findlib-1.ctypes.Ctypes_types)

Module Ctypes_types

module type TYPE = sig ... end

Abstract interface to C object type descriptions

diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/Infix/index.html new file mode 100644 index 00000000..aa371b32 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_types.TYPE.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/index.html new file mode 100644 index 00000000..c0dafc9a --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.Ctypes_types.TYPE.Intptr)

Module TYPE.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..785281fc --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_types.TYPE.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/index.html new file mode 100644 index 00000000..dfb33eda --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.Ctypes_types.TYPE.Ptrdiff)

Module TYPE.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/Infix/index.html new file mode 100644 index 00000000..729b5d44 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.Ctypes_types.TYPE.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/index.html new file mode 100644 index 00000000..ae5e8a7a --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.Ctypes_types.TYPE.Uintptr)

Module TYPE.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/index.html b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/index.html new file mode 100644 index 00000000..e0da0440 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_types/module-type-TYPE/index.html @@ -0,0 +1,36 @@ + +TYPE (docs.findlib-1.ctypes.Ctypes_types.TYPE)

Module type Ctypes_types.TYPE

Abstract interface to C object type descriptions

Values representing C types

type 'a typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

type ('a, 't) field
val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

val const : 'a typ -> 'a typ
diff --git a/docs/findlib-1/ctypes/Ctypes_value_printing/index.html b/docs/findlib-1/ctypes/Ctypes_value_printing/index.html new file mode 100644 index 00000000..63f4b160 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_value_printing/index.html @@ -0,0 +1,13 @@ + +Ctypes_value_printing (docs.findlib-1.ctypes.Ctypes_value_printing)

Module Ctypes_value_printing

val format : 'a. 'a Ctypes_static.typ -> Format.formatter -> 'a -> unit
val format_structured : + 'a 'b. Format.formatter -> + ('a, 'b) Ctypes_static.structured -> + unit
val format_array : 'a. Format.formatter -> 'a Ctypes_static.carray -> unit
val format_ocaml : 'a. Format.formatter -> 'a Ctypes_static.ocaml -> unit
val format_fields : + 'a 'b. string -> + ('a, 'b) Ctypes_static.structured Ctypes_static.boxed_field list -> + Format.formatter -> + ('a, 'b) Ctypes_static.structured -> + unit
val format_ptr : 'a. Format.formatter -> 'a Ctypes_static.ptr -> unit
val format_funptr : + 'a. Format.formatter -> + 'a Ctypes_static.static_funptr -> + unit
val string_of : 'a Ctypes_static.typ -> 'b -> string
diff --git a/docs/findlib-1/ctypes/Ctypes_value_printing_stubs/index.html b/docs/findlib-1/ctypes/Ctypes_value_printing_stubs/index.html new file mode 100644 index 00000000..6f7b5901 --- /dev/null +++ b/docs/findlib-1/ctypes/Ctypes_value_printing_stubs/index.html @@ -0,0 +1,2 @@ + +Ctypes_value_printing_stubs (docs.findlib-1.ctypes.Ctypes_value_printing_stubs)

Module Ctypes_value_printing_stubs

val string_of_prim : 'a Ctypes_primitive_types.prim -> 'a -> string
val string_of_pointer : (_, _) Ctypes_ptr.Fat.t -> string
diff --git a/docs/findlib-1/ctypes/LDouble/index.html b/docs/findlib-1/ctypes/LDouble/index.html new file mode 100644 index 00000000..a5a5dcf7 --- /dev/null +++ b/docs/findlib-1/ctypes/LDouble/index.html @@ -0,0 +1,2 @@ + +LDouble (docs.findlib-1.ctypes.LDouble)

Module LDouble

type t

The type of long doubles.

val to_float : t -> float

Convert a long double to a float. The result is unspecified if the argument is either too large or too small to be represented as a float.

val of_float : float -> t

Create a long double from a float

val to_int : t -> int

Convert a long double to an int. The result is unspecified if the argument is NAN or falls outside the range of representable integers.

val of_int : int -> t

Create a long double from an int

val to_string : ?width:int -> ?prec:int -> t -> string

Convert a long double to a string.

width specifies the minimum number of digits to format the string with. A negative value left aligns. The default is 0.

prec specifies the number of digits after the decimal point. The default is 6.

val of_string : string -> t

Create a long double from a string

val add : t -> t -> t

Addition

val sub : t -> t -> t

Subtraction

val mul : t -> t -> t

Multiplication

val div : t -> t -> t

Division

val neg : t -> t

Negation

val pow : t -> t -> t

Exponentiation

val sqrt : t -> t

Square root

val exp : t -> t

Exponential

val log : t -> t

Natural logarithm

val log10 : t -> t

Base 10 logarithm

val expm1 : t -> t

expm1 x computes exp x -. 1.0, giving numerically-accurate results even if x is close to 0.0.

val log1p : t -> t

log1p x computes log(1.0 +. x) (natural logarithm), giving numerically-accurate results even if x is close to 0.0.

val cos : t -> t

Cosine. Argument is in radians.

val sin : t -> t

Sine. Argument is in radians.

val tan : t -> t

Tangent. Argument is in radians.

val acos : t -> t

Arc cosine

val asin : t -> t

Arc sine

val atan : t -> t

Arc tangent

val atan2 : t -> t -> t

atan2 y x returns the arc tangent of y /. x.

val hypot : t -> t -> t
val cosh : t -> t

Hyperbolic cosine

val sinh : t -> t

Hyperbolic sine

val tanh : t -> t

Hyperbolic tangent

val acosh : t -> t

Inverse hyperbolic cosine

val asinh : t -> t

Inverse hyperbolic sine

val atanh : t -> t

Inverse hyperbolic tangent

val ceil : t -> t

Round above to an integer value.

val floor : t -> t

Round below to an integer value.

val abs : t -> t

abs f returns absolute value of f

val rem : t -> t -> t

rem x y is the remainder of dividing x by y

val copysign : t -> t -> t

copysign x y returns a float whose absolute value is that of x and whose sign is that of y.

val frexp : t -> t * int

frexp f returns the pair of the significant and the exponent of f.

val ldexp : t -> int -> t

ldexp x n returns x *. 2 ** n.

val modf : t -> t * t

return (fractional,integer) parts of number.

Known fatal bug on mingw32; see https://sourceforge.net/p/mingw-w64/bugs/478

val classify : t -> fpclass

Return the class of the given floating-point number: normal, subnormal, zero, infinite, or not a number.

val min_float : t

The smallest positive, non-zero, non-denormalized value

val max_float : t

The largest positive finite value

val epsilon : t

The difference between 1.0 and the smallest exactly representable floating-point number greater than 1.0.

val nan : t

A special floating-point value denoting the result of an undefined operation such as 0.0 /. 0.0. Stands for 'not a number'.

val infinity : t

Positive infinity

val neg_infinity : t

Negative infinity

val zero : t

0.0

val one : t

1.0

val byte_sizes : int * int

size, in bytes, used for storing long doubles, and the actual number of bytes used by the value. (unused bytes may contain undefined values)

val mant_dig : int

size of mantissa

diff --git a/docs/findlib-1/ctypes/PosixTypes/Dev/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Dev/Infix/index.html new file mode 100644 index 00000000..7ffc505c --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Dev/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Dev.Infix)

Module Dev.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Dev/index.html b/docs/findlib-1/ctypes/PosixTypes/Dev/index.html new file mode 100644 index 00000000..ccd75731 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Dev/index.html @@ -0,0 +1,2 @@ + +Dev (docs.findlib-1.ctypes.PosixTypes.Dev)

Module PosixTypes.Dev

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/PosixTypes/Ino/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Ino/Infix/index.html new file mode 100644 index 00000000..f3042cff --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Ino/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Ino.Infix)

Module Ino.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Ino/index.html b/docs/findlib-1/ctypes/PosixTypes/Ino/index.html new file mode 100644 index 00000000..35595be6 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Ino/index.html @@ -0,0 +1,2 @@ + +Ino (docs.findlib-1.ctypes.PosixTypes.Ino)

Module PosixTypes.Ino

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/PosixTypes/Mode/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Mode/Infix/index.html new file mode 100644 index 00000000..c0dff30e --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Mode/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Mode.Infix)

Module Mode.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Mode/index.html b/docs/findlib-1/ctypes/PosixTypes/Mode/index.html new file mode 100644 index 00000000..1b07e8ea --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Mode/index.html @@ -0,0 +1,2 @@ + +Mode (docs.findlib-1.ctypes.PosixTypes.Mode)

Module PosixTypes.Mode

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/PosixTypes/Nlink/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Nlink/Infix/index.html new file mode 100644 index 00000000..9334f054 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Nlink/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Nlink.Infix)

Module Nlink.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Nlink/index.html b/docs/findlib-1/ctypes/PosixTypes/Nlink/index.html new file mode 100644 index 00000000..26b7e9dc --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Nlink/index.html @@ -0,0 +1,2 @@ + +Nlink (docs.findlib-1.ctypes.PosixTypes.Nlink)

Module PosixTypes.Nlink

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/PosixTypes/Off/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Off/Infix/index.html new file mode 100644 index 00000000..f15cd3d9 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Off/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Off.Infix)

Module Off.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Off/index.html b/docs/findlib-1/ctypes/PosixTypes/Off/index.html new file mode 100644 index 00000000..fd1371cc --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Off/index.html @@ -0,0 +1,2 @@ + +Off (docs.findlib-1.ctypes.PosixTypes.Off)

Module PosixTypes.Off

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Pid/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Pid/Infix/index.html new file mode 100644 index 00000000..5979d61e --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Pid/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Pid.Infix)

Module Pid.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Pid/index.html b/docs/findlib-1/ctypes/PosixTypes/Pid/index.html new file mode 100644 index 00000000..1edf103c --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Pid/index.html @@ -0,0 +1,2 @@ + +Pid (docs.findlib-1.ctypes.PosixTypes.Pid)

Module PosixTypes.Pid

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Ssize/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Ssize/Infix/index.html new file mode 100644 index 00000000..89a30826 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Ssize/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Ssize.Infix)

Module Ssize.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Ssize/index.html b/docs/findlib-1/ctypes/PosixTypes/Ssize/index.html new file mode 100644 index 00000000..c4b24f60 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Ssize/index.html @@ -0,0 +1,2 @@ + +Ssize (docs.findlib-1.ctypes.PosixTypes.Ssize)

Module PosixTypes.Ssize

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Time/Infix/index.html b/docs/findlib-1/ctypes/PosixTypes/Time/Infix/index.html new file mode 100644 index 00000000..2f244afc --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Time/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.PosixTypes.Time.Infix)

Module Time.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/PosixTypes/Time/index.html b/docs/findlib-1/ctypes/PosixTypes/Time/index.html new file mode 100644 index 00000000..89832993 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/Time/index.html @@ -0,0 +1,2 @@ + +Time (docs.findlib-1.ctypes.PosixTypes.Time)

Module PosixTypes.Time

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/PosixTypes/index.html b/docs/findlib-1/ctypes/PosixTypes/index.html new file mode 100644 index 00000000..c9789058 --- /dev/null +++ b/docs/findlib-1/ctypes/PosixTypes/index.html @@ -0,0 +1,2 @@ + +PosixTypes (docs.findlib-1.ctypes.PosixTypes)

Module PosixTypes

Some POSIX types.

POSIX arithmetic types

module Dev : Unsigned.S
module Ino : Unsigned.S
module Mode : Unsigned.S
module Off : Signed.S
module Pid : Signed.S
module Ssize : Signed.S
module Time : Unsigned.S
type clock_t
type dev_t = Dev.t
type ino_t = Ino.t
type mode_t = Mode.t
type off_t = Off.t
type pid_t = Pid.t
type size_t = Unsigned.size_t
type ssize_t = Ssize.t
type time_t = Time.t
type useconds_t

Values representing POSIX arithmetic types

val clock_t : clock_t Ctypes.typ
val dev_t : dev_t Ctypes.typ
val ino_t : ino_t Ctypes.typ
val mode_t : mode_t Ctypes.typ
val off_t : off_t Ctypes.typ
val pid_t : pid_t Ctypes.typ
val size_t : size_t Ctypes.typ
val ssize_t : ssize_t Ctypes.typ
val time_t : time_t Ctypes.typ
val useconds_t : useconds_t Ctypes.typ

POSIX non-arithmetic types

type sigset_t

Values representing POSIX non-arithmetic types

val sigset_t : sigset_t Ctypes.typ
diff --git a/docs/findlib-1/ctypes/index.html b/docs/findlib-1/ctypes/index.html new file mode 100644 index 00000000..012eb958 --- /dev/null +++ b/docs/findlib-1/ctypes/index.html @@ -0,0 +1,2 @@ + +ctypes (docs.findlib-1.ctypes)

Package ctypes

Sub-indexes

Library ctypes

This library exposes the following toplevel modules:

Library ctypes.stubs

This library exposes the following toplevel modules:

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/index.html new file mode 100644 index 00000000..2c6e4a25 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/index.html @@ -0,0 +1,2 @@ + +Types (docs.findlib-1.ctypes.stubs.Cstubs.Types)

Module Cstubs.Types

module type TYPE = Ctypes.TYPE
module type BINDINGS = functor (F : TYPE) -> sig ... end
val write_c : Format.formatter -> (module BINDINGS) -> unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html new file mode 100644 index 00000000..703bd048 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/index.html new file mode 100644 index 00000000..25b1b695 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F.Intptr)

Module F.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..17284b93 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html new file mode 100644 index 00000000..fcfe8a61 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F.Ptrdiff)

Module F.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html new file mode 100644 index 00000000..78607fab --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/index.html new file mode 100644 index 00000000..c7c24910 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F.Uintptr)

Module F.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/index.html new file mode 100644 index 00000000..7757527e --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/argument-1-F/index.html @@ -0,0 +1,49 @@ + +F (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS.F)

Parameter BINDINGS.F

include Ctypes_types.TYPE

Values representing C types

type 'a typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

type ('a, 't) field
val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

val const : 'a typ -> 'a typ
type 'a const
val constant : string -> 'a typ -> 'a const

constant name typ retrieves the value of the compile-time constant name of type typ. It can be used to retrieve enum constants, #defined values and other integer constant expressions.

The type typ must be either an integer type such as bool, char, int, uint8, etc., or a view (or perhaps multiple views) where the underlying type is an integer type.

When the value of the constant cannot be represented in the type there will typically be a diagnostic from either the C compiler or the OCaml compiler. For example, gcc will say

warning: overflow in implicit constant conversion

val enum : + string -> + ?typedef:bool -> + ?unexpected:(int64 -> 'a) -> + ('a * int64 const) list -> + 'a typ

enum name ?unexpected alist builds a type representation for the enum named name. The size and alignment are retrieved so that the resulting type can be used everywhere an integer type can be used: as an array element or struct member, as an argument or return value, etc.

The value alist is an association list of OCaml values and values retrieved by the constant function. For example, to expose the enum

enum letters { A, B, C = 10, D };

you might first retrieve the values of the enumeration constants:

let a = constant "A" int64_t
+and b = constant "B" int64_t
+and c = constant "C" int64_t
+and d = constant "D" int64_t

and then build the enumeration type

let letters = enum "letters" [
+   `A, a;
+   `B, b;
+   `C, c;
+   `D, d;
+] ~unexpected:(fun i -> `E i)

The unexpected function specifies the value to return in the case that some unexpected value is encountered -- for example, if a function with the return type 'enum letters' actually returns the value -1.

The optional flag typedef specifies whether the first argument, name, indicates an tag or an alias. If typedef is false (the default) then name is treated as an enumeration tag:

enum letters { ... }

If typedef is true then name is instead treated as an alias:

typedef enum { ... } letters

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/index.html new file mode 100644 index 00000000..67e1e92f --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/Types/module-type-BINDINGS/index.html @@ -0,0 +1,2 @@ + +BINDINGS (docs.findlib-1.ctypes.stubs.Cstubs.Types.BINDINGS)

Module type Types.BINDINGS

Parameters

module F : TYPE

Signature

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/index.html new file mode 100644 index 00000000..86773d23 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/index.html @@ -0,0 +1,16 @@ + +Cstubs (docs.findlib-1.ctypes.stubs.Cstubs)

Module Cstubs

Operations for generating C bindings stubs.

module Types : sig ... end
module type FOREIGN = Ctypes.FOREIGN
module type BINDINGS = + functor (F : FOREIGN with type 'a result = unit) -> + sig ... end
type errno_policy

Values of the errno_policy type specify the errno support provided by the generated code. See ignore_errno for the available option.

val ignore_errno : errno_policy

Generate code with no special support for errno. This is the default.

val return_errno : errno_policy

Generate code that returns errno in addition to the return value of each function.

Passing return_errno as the errno argument to Cstubs.write_c and Cstubs.write_ml changes the return type of bound functions from a single value to a pair of values. For example, the binding specification

let realpath = foreign "realpath" (string @-> string @-> returning string)

generates a value of the following type by default:

val realpath : string -> string -> string

but when using return_errno the generated type is as follows:

val realpath : string -> string -> string * int

and when using both return_errno and lwt_jobs the generated type is as follows:

val realpath : string -> string -> (string * int) Lwt.t

type concurrency_policy

Values of the concurrency_policy type specify the concurrency support provided by the generated code. See sequential and lwt_jobs for the available options.

val sequential : concurrency_policy

Generate code with no special support for concurrency. This is the default.

val unlocked : concurrency_policy

Generate code that releases the runtime lock during C calls.

val lwt_preemptive : concurrency_policy

Generate code which runs C function calls with the Lwt_preemptive module:

http://ocsigen.org/lwt/2.5.1/api/Lwt_preemptive

Passing lwt_preemptive as the concurrency argument to Cstubs.write_c and Cstubs.write_ml changes the return type of bound functions to include the Lwt.t constructor. For example, the binding specification

let unlink = foreign "unlink" (string @-> returning int)

generates a value of the following type by default:

val unlink : string -> int

but when using lwt_preemptive the generated type is as follows:

val unlink : string -> int Lwt.t

Additionally, the OCaml runtime lock is released during calls to functions bound with lwt_preemptive.

val lwt_jobs : concurrency_policy

Generate code which implements C function calls as Lwt jobs:

http://ocsigen.org/lwt/2.5.1/api/Lwt_unix#TYPEjob

Passing lwt_jobs as the concurrency argument to Cstubs.write_c and Cstubs.write_ml changes the return type of bound functions to include the Lwt.t constructor. For example, the binding specification

let unlink = foreign "unlink" (string @-> returning int)

generates a value of the following type by default:

val unlink : string -> int

but when using lwt_jobs the generated type is as follows:

val unlink : string -> int Lwt.t

val write_c : + ?concurrency:concurrency_policy -> + ?errno:errno_policy -> + Format.formatter -> + prefix:string -> + (module BINDINGS) -> + unit

write_c fmt ~prefix bindings generates C stubs for the functions bound with foreign in bindings. The stubs are intended to be used in conjunction with the ML code generated by write_ml.

The optional argument concurrency specifies the concurrency support provided by the generated code. The default is sequential.

The generated code uses definitions exposed in the header file ctypes_cstubs_internals.h.

val write_ml : + ?concurrency:concurrency_policy -> + ?errno:errno_policy -> + Format.formatter -> + prefix:string -> + (module BINDINGS) -> + unit

write_ml fmt ~prefix bindings generates ML bindings for the functions bound with foreign in bindings. The generated code conforms to the FOREIGN interface.

The optional argument concurrency specifies the concurrency support provided by the generated code. The default is sequential.

The generated code uses definitions exposed in the module Cstubs_internals.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/argument-1-F/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/argument-1-F/index.html new file mode 100644 index 00000000..2c956bd9 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/argument-1-F/index.html @@ -0,0 +1,2 @@ + +F (docs.findlib-1.ctypes.stubs.Cstubs.BINDINGS.F)

Parameter BINDINGS.F

type 'a fn
type 'a return
val (@->) : 'a Ctypes.typ -> 'b fn -> ('a -> 'b) fn
val returning : 'a Ctypes.typ -> 'a return fn
type 'a result = unit
val foreign : string -> ('a -> 'b) fn -> ('a -> 'b) result
val foreign_value : string -> 'a Ctypes.typ -> 'a Ctypes.ptr result
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/index.html b/docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/index.html new file mode 100644 index 00000000..e7287942 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs/module-type-BINDINGS/index.html @@ -0,0 +1,2 @@ + +BINDINGS (docs.findlib-1.ctypes.stubs.Cstubs.BINDINGS)

Module type Cstubs.BINDINGS

Parameters

module F : FOREIGN with type 'a result = unit

Signature

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_analysis/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_analysis/index.html new file mode 100644 index 00000000..62c32f3c --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_analysis/index.html @@ -0,0 +1,2 @@ + +Cstubs_analysis (docs.findlib-1.ctypes.stubs.Cstubs_analysis)

Module Cstubs_analysis

val float : 'a Ctypes_static.fn -> bool
val may_allocate : 'a Ctypes_static.fn -> bool
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_c_language/Type_C/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_c_language/Type_C/index.html new file mode 100644 index 00000000..cde1a896 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_c_language/Type_C/index.html @@ -0,0 +1,6 @@ + +Type_C (docs.findlib-1.ctypes.stubs.Cstubs_c_language.Type_C)

Module Cstubs_c_language.Type_C

val cexp : cexp -> ty
val camlop : camlop -> ty
val ceff : ceff -> ty
val reference_ceff : ceff -> ty
val field_ceff : ceff -> fieldname -> ty
val lookup_field : + 's 'a. string -> + 'a Ctypes_static.typ -> + 's Ctypes_static.boxed_field list -> + ty
val ccomp : ccomp -> ty
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_c_language/Unchecked_function_types/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_c_language/Unchecked_function_types/index.html new file mode 100644 index 00000000..d08e281c --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_c_language/Unchecked_function_types/index.html @@ -0,0 +1,5 @@ + +Unchecked_function_types (docs.findlib-1.ctypes.stubs.Cstubs_c_language.Unchecked_function_types)

Module Cstubs_c_language.Unchecked_function_types

val (@->) : + 'a Ctypes_static.typ -> + 'b Ctypes_static.fn -> + ('a -> 'b) Ctypes_static.fn
val returning : 'a Ctypes_static.typ -> 'a Ctypes_static.fn
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_c_language/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_c_language/index.html new file mode 100644 index 00000000..539bbe37 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_c_language/index.html @@ -0,0 +1,2 @@ + +Cstubs_c_language (docs.findlib-1.ctypes.stubs.Cstubs_c_language)

Module Cstubs_c_language

val fresh_var : ?prefix:string -> unit -> string
type ty =
  1. | Ty : _ Ctypes_static.typ -> ty
type tfn =
  1. | Fn : _ Ctypes_static.fn -> tfn
type fieldname = string
type cfunction = {
  1. fname : string;
  2. allocates : bool;
  3. reads_ocaml_heap : bool;
  4. fn : tfn;
}
type cglobal = {
  1. name : string;
  2. typ : ty;
  3. references_ocaml_heap : bool;
}
type clocal = [
  1. | `Local of string * ty
]
type cvar = [
  1. | clocal
  2. | `Global of cglobal
]
type storage_class = [
  1. | `Static
  2. | `Extern
]
type cconst = [
  1. | `Int of Signed.sint
]
type cexp = [
  1. | cconst
  2. | clocal
  3. | `Cast of ty * cexp
  4. | `Addr of cvar
]
type clvalue = [
  1. | cvar
  2. | `Index of clvalue * cexp
  3. | `Field of clvalue * fieldname
  4. | `PointerField of clvalue * fieldname
]
type camlop = [
  1. | `CAMLparam0
  2. | `CAMLlocalN of cexp * cexp
  3. | `CAMLdrop
]
type ceff = [
  1. | cexp
  2. | camlop
  3. | `Global of cglobal
  4. | `App of cfunction * cexp list
  5. | `Index of ceff * cexp
  6. | `Deref of cexp
  7. | `DerefField of cexp * fieldname
]
type cbind = clocal * ceff
type ccomp = [
  1. | ceff
  2. | `CAMLparam of string list * ccomp
  3. | `LetConst of clocal * cconst * ccomp
  4. | `LetAssign of clvalue * ceff * ccomp
  5. | `CAMLreturnT of ty * cexp
  6. | `Return of ty * cexp
  7. | `Let of cbind * ccomp
]
type cfundec = [
  1. | `Fundec of string * (string * ty) list * ty
]
type cfundef = [
  1. | `Function of cfundec * ccomp * storage_class
]
val return_type : 'a. 'a Ctypes_static.fn -> ty
val args : 'a. 'a Ctypes_static.fn -> (string * ty) list
module Type_C : sig ... end
val reader : string -> 'a Ctypes_static.fn -> cfunction
val conser : string -> 'a Ctypes_static.fn -> cfunction
val immediater : string -> 'a Ctypes_static.fn -> cfunction
module Unchecked_function_types : sig ... end
val prim_prj : 'a. 'a Ctypes_primitive_types.prim -> cfunction
val prim_inj : 'a. 'a Ctypes_primitive_types.prim -> cfunction
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_emit_c/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_emit_c/index.html new file mode 100644 index 00000000..ec623d68 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_emit_c/index.html @@ -0,0 +1,18 @@ + +Cstubs_emit_c (docs.findlib-1.ctypes.stubs.Cstubs_emit_c)

Module Cstubs_emit_c

val format_seq : + string -> + (Format.formatter -> 'a -> unit) -> + string -> + string -> + Format.formatter -> + 'b list -> + unit
val format_ty : Format.formatter -> Cstubs_c_language.ty -> unit
val cvar_name : + [< `Global of Cstubs_c_language.cglobal | `Local of string * 'a ] -> + string
val cvar : + Format.formatter -> + [< `Global of Cstubs_c_language.cglobal | `Local of string * 'a ] -> + unit
val cconst : Format.formatter -> [< `Int of Signed.SInt.t ] -> unit
val camlxParam : Format.formatter -> string list -> unit
val camlParam : Format.formatter -> string list -> unit
val cast_unnecessary : Cstubs_c_language.ty -> Cstubs_c_language.cexp -> bool
val format_parameter_list : + (string * Cstubs_c_language.ty) list -> + (Format.formatter -> unit) -> + Format.formatter -> + unit
val storage_class : Format.formatter -> [< `Extern | `Static ] -> unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_errors/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_errors/index.html new file mode 100644 index 00000000..5a8908e7 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_errors/index.html @@ -0,0 +1,2 @@ + +Cstubs_errors (docs.findlib-1.ctypes.stubs.Cstubs_errors)

Module Cstubs_errors

exception Cstubs_internal_error of string
val internal_error : ('a, unit, string, 'b) format4 -> 'a
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_generate_c/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_generate_c/index.html new file mode 100644 index 00000000..02248a71 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_generate_c/index.html @@ -0,0 +1,23 @@ + +Cstubs_generate_c (docs.findlib-1.ctypes.stubs.Cstubs_generate_c)

Module Cstubs_generate_c

val fn : + concurrency:[ `Sequential | `Lwt_jobs | `Lwt_preemptive | `Unlocked ] -> + errno:[ `Ignore_errno | `Return_errno ] -> + cname:string -> + stub_name:string -> + Format.formatter -> + 'a Ctypes.fn -> + unit
val value : + cname:string -> + stub_name:string -> + Format.formatter -> + 'a Ctypes.typ -> + unit
val inverse_fn : + stub_name:string -> + runtime_lock:bool -> + Format.formatter -> + 'a Ctypes.fn -> + unit
val inverse_fn_decl : + stub_name:string -> + Format.formatter -> + 'a Ctypes.fn -> + unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_generate_ml/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_generate_ml/index.html new file mode 100644 index 00000000..1e2ab912 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_generate_ml/index.html @@ -0,0 +1,33 @@ + +Cstubs_generate_ml (docs.findlib-1.ctypes.stubs.Cstubs_generate_ml)

Module Cstubs_generate_ml

val extern : + concurrency:[ `Sequential | `Lwt_jobs | `Lwt_preemptive | `Unlocked ] -> + errno:[ `Ignore_errno | `Return_errno ] -> + stub_name:string -> + external_name:string -> + Format.formatter -> + ('a -> 'b) Ctypes.fn -> + unit
val case : + concurrency:[ `Sequential | `Lwt_jobs | `Lwt_preemptive | `Unlocked ] -> + errno:[ `Ignore_errno | `Return_errno ] -> + stub_name:string -> + external_name:string -> + Format.formatter -> + ('a -> 'b) Ctypes.fn -> + unit
val val_case : + stub_name:string -> + external_name:string -> + Format.formatter -> + 'a Ctypes.typ -> + unit
val constructor_decl : + concurrency:[ `Sequential | `Lwt_jobs | `Lwt_preemptive | `Unlocked ] -> + errno:[ `Ignore_errno | `Return_errno ] -> + string -> + 'a Ctypes.fn -> + Format.formatter -> + unit
val inverse_case : + register_name:string -> + constructor:string -> + string -> + Format.formatter -> + ('a -> 'b) Ctypes.fn -> + unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_inverted/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/index.html new file mode 100644 index 00000000..9852971d --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/index.html @@ -0,0 +1,6 @@ + +Cstubs_inverted (docs.findlib-1.ctypes.stubs.Cstubs_inverted)

Module Cstubs_inverted

Operations for exposing OCaml code as C libraries.

module type INTERNAL = sig ... end
module type BINDINGS = functor (F : INTERNAL) -> sig ... end
val write_c : Format.formatter -> prefix:string -> (module BINDINGS) -> unit

write_c fmt ~prefix bindings generates C stubs for the functions bound with internal in bindings. The stubs are intended to be used in conjunction with the ML code generated by write_ml.

The generated code uses definitions exposed in the header file cstubs_internals.h.

val write_c_header : + Format.formatter -> + prefix:string -> + (module BINDINGS) -> + unit

write_c_header fmt ~prefix bindings generates a C header file for the functions bound with internal in bindings. The stubs are intended to be used in conjunction with the C code generated by write_c.

val write_ml : Format.formatter -> prefix:string -> (module BINDINGS) -> unit

write_ml fmt ~prefix bindings generates ML bindings for the functions bound with internal in bindings. The generated code conforms to the INTERNAL interface.

The generated code uses definitions exposed in the module Cstubs_internals.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/argument-1-F/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/argument-1-F/index.html new file mode 100644 index 00000000..eb30eddb --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/argument-1-F/index.html @@ -0,0 +1,7 @@ + +F (docs.findlib-1.ctypes.stubs.Cstubs_inverted.BINDINGS.F)

Parameter BINDINGS.F

val enum : (string * int64) list -> 'a Ctypes.typ -> unit
val structure : _ Ctypes.structure Ctypes.typ -> unit
val union : _ Ctypes.union Ctypes.typ -> unit
val typedef : _ Ctypes.typ -> string -> unit
val internal : + ?runtime_lock:bool -> + string -> + ('a -> 'b) Ctypes.fn -> + ('a -> 'b) -> + unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/index.html new file mode 100644 index 00000000..f98ec91f --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-BINDINGS/index.html @@ -0,0 +1,2 @@ + +BINDINGS (docs.findlib-1.ctypes.stubs.Cstubs_inverted.BINDINGS)

Module type Cstubs_inverted.BINDINGS

Parameters

module F : INTERNAL

Signature

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-INTERNAL/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-INTERNAL/index.html new file mode 100644 index 00000000..42f57797 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_inverted/module-type-INTERNAL/index.html @@ -0,0 +1,7 @@ + +INTERNAL (docs.findlib-1.ctypes.stubs.Cstubs_inverted.INTERNAL)

Module type Cstubs_inverted.INTERNAL

val enum : (string * int64) list -> 'a Ctypes.typ -> unit
val structure : _ Ctypes.structure Ctypes.typ -> unit
val union : _ Ctypes.union Ctypes.typ -> unit
val typedef : _ Ctypes.typ -> string -> unit
val internal : + ?runtime_lock:bool -> + string -> + ('a -> 'b) Ctypes.fn -> + ('a -> 'b) -> + unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_public_name/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_public_name/index.html new file mode 100644 index 00000000..097a0293 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_public_name/index.html @@ -0,0 +1,7 @@ + +Cstubs_public_name (docs.findlib-1.ctypes.stubs.Cstubs_public_name)

Module Cstubs_public_name

val constructor_ident_of_prim : + 'a Ctypes_primitive_types.prim -> + Ctypes_path.path
val constructor_cident_of_prim : + ?module_name:string -> + 'a Ctypes_primitive_types.prim -> + Ctypes_path.path
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/index.html new file mode 100644 index 00000000..556a7254 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/index.html @@ -0,0 +1,2 @@ + +Cstubs_structs (docs.findlib-1.ctypes.stubs.Cstubs_structs)

Module Cstubs_structs

module type TYPE = sig ... end
module type BINDINGS = functor (F : TYPE) -> sig ... end
val write_c : Format.formatter -> (module BINDINGS) -> unit
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html new file mode 100644 index 00000000..3f3f28b9 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/index.html new file mode 100644 index 00000000..bf584d37 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F.Intptr)

Module F.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..76b0e663 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html new file mode 100644 index 00000000..d3c2e03b --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F.Ptrdiff)

Module F.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html new file mode 100644 index 00000000..afd9265a --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/index.html new file mode 100644 index 00000000..f6886a56 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F.Uintptr)

Module F.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/index.html new file mode 100644 index 00000000..6a6599d8 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/argument-1-F/index.html @@ -0,0 +1,41 @@ + +F (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS.F)

Parameter BINDINGS.F

include Ctypes_types.TYPE

Values representing C types

type 'a typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

type ('a, 't) field
val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

val const : 'a typ -> 'a typ
type 'a const
val constant : string -> 'a typ -> 'a const
val enum : + string -> + ?typedef:bool -> + ?unexpected:(int64 -> 'a) -> + ('a * int64 const) list -> + 'a typ
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/index.html new file mode 100644 index 00000000..4bfe29e1 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-BINDINGS/index.html @@ -0,0 +1,2 @@ + +BINDINGS (docs.findlib-1.ctypes.stubs.Cstubs_structs.BINDINGS)

Module type Cstubs_structs.BINDINGS

Parameters

module F : TYPE

Signature

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/Infix/index.html new file mode 100644 index 00000000..2ba06ff7 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/index.html new file mode 100644 index 00000000..f0f9a56c --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE.Intptr)

Module TYPE.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..c7af9ce4 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/index.html new file mode 100644 index 00000000..f903e5ca --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE.Ptrdiff)

Module TYPE.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/Infix/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/Infix/index.html new file mode 100644 index 00000000..36c15e62 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/index.html new file mode 100644 index 00000000..8bfb4080 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE.Uintptr)

Module TYPE.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/index.html b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/index.html new file mode 100644 index 00000000..721d3945 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Cstubs_structs/module-type-TYPE/index.html @@ -0,0 +1,41 @@ + +TYPE (docs.findlib-1.ctypes.stubs.Cstubs_structs.TYPE)

Module type Cstubs_structs.TYPE

include Ctypes_types.TYPE

Values representing C types

type 'a typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

type ('a, 't) field
val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

val const : 'a typ -> 'a typ
type 'a const
val constant : string -> 'a typ -> 'a const
val enum : + string -> + ?typedef:bool -> + ?unexpected:(int64 -> 'a) -> + ('a * int64 const) list -> + 'a typ
diff --git a/docs/findlib-1/ctypes/stubs/Ctypes_path/index.html b/docs/findlib-1/ctypes/stubs/Ctypes_path/index.html new file mode 100644 index 00000000..09014193 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/Ctypes_path/index.html @@ -0,0 +1,2 @@ + +Ctypes_path (docs.findlib-1.ctypes.stubs.Ctypes_path)

Module Ctypes_path

type path
val path_of_string : string -> path
val format_path : Format.formatter -> path -> unit
diff --git a/docs/findlib-1/ctypes/stubs/index.html b/docs/findlib-1/ctypes/stubs/index.html new file mode 100644 index 00000000..7ea40cb6 --- /dev/null +++ b/docs/findlib-1/ctypes/stubs/index.html @@ -0,0 +1,2 @@ + +stubs (docs.findlib-1.ctypes.stubs)

Package ctypes.stubs

Library ctypes.stubs

This library exposes the following toplevel modules:

diff --git a/docs/findlib-1/index.html b/docs/findlib-1/index.html new file mode 100644 index 00000000..14fcd8e5 --- /dev/null +++ b/docs/findlib-1/index.html @@ -0,0 +1,2 @@ + +findlib-1 (docs.findlib-1)

Opam index

Packages installed in /Users/runner/work/quickjs.ml/quickjs.ml/_opam/lib

Sub-indexes

diff --git a/docs/findlib-1/integers/Signed/Int/Infix/index.html b/docs/findlib-1/integers/Signed/Int/Infix/index.html new file mode 100644 index 00000000..028ae383 --- /dev/null +++ b/docs/findlib-1/integers/Signed/Int/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.Int.Infix)

Module Int.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/Int/index.html b/docs/findlib-1/integers/Signed/Int/index.html new file mode 100644 index 00000000..b3056f5d --- /dev/null +++ b/docs/findlib-1/integers/Signed/Int/index.html @@ -0,0 +1,2 @@ + +Int (docs.findlib-1.integers.Signed.Int)

Module Signed.Int

Signed integer type and operations.

type t = int
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Signed/Int32/Infix/index.html b/docs/findlib-1/integers/Signed/Int32/Infix/index.html new file mode 100644 index 00000000..b5aab49e --- /dev/null +++ b/docs/findlib-1/integers/Signed/Int32/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.Int32.Infix)

Module Int32.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/Int32/index.html b/docs/findlib-1/integers/Signed/Int32/index.html new file mode 100644 index 00000000..9eacded0 --- /dev/null +++ b/docs/findlib-1/integers/Signed/Int32/index.html @@ -0,0 +1,2 @@ + +Int32 (docs.findlib-1.integers.Signed.Int32)

Module Signed.Int32

Signed 32-bit integer type and operations.

type t = int32
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Signed/Int64/Infix/index.html b/docs/findlib-1/integers/Signed/Int64/Infix/index.html new file mode 100644 index 00000000..a468d9af --- /dev/null +++ b/docs/findlib-1/integers/Signed/Int64/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.Int64.Infix)

Module Int64.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/Int64/index.html b/docs/findlib-1/integers/Signed/Int64/index.html new file mode 100644 index 00000000..01d7cf7d --- /dev/null +++ b/docs/findlib-1/integers/Signed/Int64/index.html @@ -0,0 +1,2 @@ + +Int64 (docs.findlib-1.integers.Signed.Int64)

Module Signed.Int64

Signed 64-bit integer type and operations.

type t = int64
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Signed/LLong/Infix/index.html b/docs/findlib-1/integers/Signed/LLong/Infix/index.html new file mode 100644 index 00000000..6273861a --- /dev/null +++ b/docs/findlib-1/integers/Signed/LLong/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.LLong.Infix)

Module LLong.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/LLong/index.html b/docs/findlib-1/integers/Signed/LLong/index.html new file mode 100644 index 00000000..3cbc3eb2 --- /dev/null +++ b/docs/findlib-1/integers/Signed/LLong/index.html @@ -0,0 +1,2 @@ + +LLong (docs.findlib-1.integers.Signed.LLong)

Module Signed.LLong

The signed long long integer type and operations.

type t
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Signed/Long/Infix/index.html b/docs/findlib-1/integers/Signed/Long/Infix/index.html new file mode 100644 index 00000000..5b5a3340 --- /dev/null +++ b/docs/findlib-1/integers/Signed/Long/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.Long.Infix)

Module Long.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/Long/index.html b/docs/findlib-1/integers/Signed/Long/index.html new file mode 100644 index 00000000..257657cd --- /dev/null +++ b/docs/findlib-1/integers/Signed/Long/index.html @@ -0,0 +1,2 @@ + +Long (docs.findlib-1.integers.Signed.Long)

Module Signed.Long

The signed long integer type and operations.

type t
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Signed/SInt/Infix/index.html b/docs/findlib-1/integers/Signed/SInt/Infix/index.html new file mode 100644 index 00000000..c9424ab6 --- /dev/null +++ b/docs/findlib-1/integers/Signed/SInt/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.SInt.Infix)

Module SInt.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/SInt/index.html b/docs/findlib-1/integers/Signed/SInt/index.html new file mode 100644 index 00000000..074d3b5f --- /dev/null +++ b/docs/findlib-1/integers/Signed/SInt/index.html @@ -0,0 +1,2 @@ + +SInt (docs.findlib-1.integers.Signed.SInt)

Module Signed.SInt

C's signed integer type and operations.

type t
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Signed/index.html b/docs/findlib-1/integers/Signed/index.html new file mode 100644 index 00000000..fab93893 --- /dev/null +++ b/docs/findlib-1/integers/Signed/index.html @@ -0,0 +1,2 @@ + +Signed (docs.findlib-1.integers.Signed)

Module Signed

Types and operations for signed integers.

module type Infix = sig ... end
module type S = sig ... end

Signed integer operations

module Int : S with type t = int

Signed integer type and operations.

module Int32 : S with type t = int32

Signed 32-bit integer type and operations.

module Int64 : S with type t = int64

Signed 64-bit integer type and operations.

module SInt : S

C's signed integer type and operations.

module Long : S

The signed long integer type and operations.

module LLong : S

The signed long long integer type and operations.

type sint = SInt.t

C's signed integer type.

type long = Long.t

The signed long integer type.

type llong = LLong.t

The signed long long integer type.

val of_byte_size : int -> (module S)

of_byte_size b is a module of type S that implements a signed type with b bytes.

Raise Invalid_argument if no suitable type is available.

diff --git a/docs/findlib-1/integers/Signed/module-type-Infix/index.html b/docs/findlib-1/integers/Signed/module-type-Infix/index.html new file mode 100644 index 00000000..f835c4dd --- /dev/null +++ b/docs/findlib-1/integers/Signed/module-type-Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.Infix)

Module type Signed.Infix

type t
include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/module-type-S/Infix/index.html b/docs/findlib-1/integers/Signed/module-type-S/Infix/index.html new file mode 100644 index 00000000..c4553e88 --- /dev/null +++ b/docs/findlib-1/integers/Signed/module-type-S/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Signed.S.Infix)

Module S.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Signed/module-type-S/index.html b/docs/findlib-1/integers/Signed/module-type-S/index.html new file mode 100644 index 00000000..a7997940 --- /dev/null +++ b/docs/findlib-1/integers/Signed/module-type-S/index.html @@ -0,0 +1,2 @@ + +S (docs.findlib-1.integers.Signed.S)

Module type Signed.S

Signed integer operations

type t
module Infix : Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/findlib-1/integers/Unsigned/Size_t/Infix/index.html b/docs/findlib-1/integers/Unsigned/Size_t/Infix/index.html new file mode 100644 index 00000000..708c51e0 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/Size_t/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.Size_t.Infix)

Module Size_t.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/Size_t/index.html b/docs/findlib-1/integers/Unsigned/Size_t/index.html new file mode 100644 index 00000000..8dd431d1 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/Size_t/index.html @@ -0,0 +1,2 @@ + +Size_t (docs.findlib-1.integers.Unsigned.Size_t)

Module Unsigned.Size_t

The size_t unsigned integer type and operations.

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/UChar/Infix/index.html b/docs/findlib-1/integers/Unsigned/UChar/Infix/index.html new file mode 100644 index 00000000..a87ddffd --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UChar/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UChar.Infix)

Module UChar.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UChar/index.html b/docs/findlib-1/integers/Unsigned/UChar/index.html new file mode 100644 index 00000000..0a45aacd --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UChar/index.html @@ -0,0 +1,2 @@ + +UChar (docs.findlib-1.integers.Unsigned.UChar)

Module Unsigned.UChar

Unsigned char type and operations.

type t = private int
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/UInt/Infix/index.html b/docs/findlib-1/integers/Unsigned/UInt/Infix/index.html new file mode 100644 index 00000000..65d9c767 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UInt.Infix)

Module UInt.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UInt/index.html b/docs/findlib-1/integers/Unsigned/UInt/index.html new file mode 100644 index 00000000..bf227954 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt/index.html @@ -0,0 +1,2 @@ + +UInt (docs.findlib-1.integers.Unsigned.UInt)

Module Unsigned.UInt

The unsigned int type and operations.

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/UInt16/Infix/index.html b/docs/findlib-1/integers/Unsigned/UInt16/Infix/index.html new file mode 100644 index 00000000..47c24754 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt16/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UInt16.Infix)

Module UInt16.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UInt16/index.html b/docs/findlib-1/integers/Unsigned/UInt16/index.html new file mode 100644 index 00000000..b96cf39f --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt16/index.html @@ -0,0 +1,2 @@ + +UInt16 (docs.findlib-1.integers.Unsigned.UInt16)

Module Unsigned.UInt16

Unsigned 16-bit integer type and operations.

type t = private int
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/UInt32/Infix/index.html b/docs/findlib-1/integers/Unsigned/UInt32/Infix/index.html new file mode 100644 index 00000000..2aa51e61 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt32/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UInt32.Infix)

Module UInt32.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UInt32/index.html b/docs/findlib-1/integers/Unsigned/UInt32/index.html new file mode 100644 index 00000000..6a008c7c --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt32/index.html @@ -0,0 +1,2 @@ + +UInt32 (docs.findlib-1.integers.Unsigned.UInt32)

Module Unsigned.UInt32

Unsigned 32-bit integer type and operations.

include S
type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
val of_int32 : int32 -> t

Convert the given 32-bit signed integer to an unsigned 32-bit integer.

If the signed integer fits within the unsigned range (in other words, if the signed integer is positive) then the numerical values represented by the signed and unsigned integers are the same.

Whether the signed integer fits or not, the function of_int32 is always the inverse of the function to_int32. In other words, to_int32 (of_int32 x) = x holds for all x : int32.

val to_int32 : t -> int32

Convert the given 32-bit unsigned integer to a signed 32-bit integer.

If the unsigned integer fits within the signed range (in other words, if the unsigned integer is less than Int32.max_int) then the numerical values represented by unsigned and signed integers are the same.

Whether the unsigned integer fits or not, the function to_int32 is always the inverse of the function of_int32. In other words, of_int32 (to_int32 x) = x holds for all x : t.

diff --git a/docs/findlib-1/integers/Unsigned/UInt64/Infix/index.html b/docs/findlib-1/integers/Unsigned/UInt64/Infix/index.html new file mode 100644 index 00000000..87d67cb1 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt64/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UInt64.Infix)

Module UInt64.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UInt64/index.html b/docs/findlib-1/integers/Unsigned/UInt64/index.html new file mode 100644 index 00000000..3d6d384e --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt64/index.html @@ -0,0 +1,2 @@ + +UInt64 (docs.findlib-1.integers.Unsigned.UInt64)

Module Unsigned.UInt64

Unsigned 64-bit integer type and operations.

include S
type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
val of_int64 : int64 -> t

Convert the given 64-bit signed integer to an unsigned 64-bit integer.

If the signed integer fits within the unsigned range (in other words, if the signed integer is positive) then the numerical values represented by the signed and unsigned integers are the same.

Whether the signed integer fits or not, the function of_int64 is always the inverse of the function to_int64. In other words, to_int64 (of_int64 x) = x holds for all x : int64.

val to_int64 : t -> int64

Convert the given 64-bit unsigned integer to a signed 64-bit integer.

If the unsigned integer fits within the signed range (in other words, if the unsigned integer is less than Int64.max_int) then the numerical values represented by unsigned and signed integers are the same.

Whether the unsigned integer fits or not, the function to_int64 is always the inverse of the function of_int64. In other words, of_int64 (to_int64 x) = x holds for all x : t.

val of_uint32 : UInt32.t -> t

Convert the given 32-bit unsigned integer to a 64-bit unsigned integer.

val to_uint32 : t -> UInt32.t

Convert the given 64-bit unsigned integer to a 32-bit unsigned integer. The 64-bit unsigned integer is taken modulo 232, i.e. the top 32 bits are lost during the conversion.

diff --git a/docs/findlib-1/integers/Unsigned/UInt8/Infix/index.html b/docs/findlib-1/integers/Unsigned/UInt8/Infix/index.html new file mode 100644 index 00000000..7ea9f5f5 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt8/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UInt8.Infix)

Module UInt8.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UInt8/index.html b/docs/findlib-1/integers/Unsigned/UInt8/index.html new file mode 100644 index 00000000..1a2de7d6 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UInt8/index.html @@ -0,0 +1,2 @@ + +UInt8 (docs.findlib-1.integers.Unsigned.UInt8)

Module Unsigned.UInt8

Unsigned 8-bit integer type and operations.

type t = private int
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/ULLong/Infix/index.html b/docs/findlib-1/integers/Unsigned/ULLong/Infix/index.html new file mode 100644 index 00000000..8d81d05d --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/ULLong/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.ULLong.Infix)

Module ULLong.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/ULLong/index.html b/docs/findlib-1/integers/Unsigned/ULLong/index.html new file mode 100644 index 00000000..2675100f --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/ULLong/index.html @@ -0,0 +1,2 @@ + +ULLong (docs.findlib-1.integers.Unsigned.ULLong)

Module Unsigned.ULLong

The unsigned long long integer type and operations.

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/ULong/Infix/index.html b/docs/findlib-1/integers/Unsigned/ULong/Infix/index.html new file mode 100644 index 00000000..4f80245a --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/ULong/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.ULong.Infix)

Module ULong.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/ULong/index.html b/docs/findlib-1/integers/Unsigned/ULong/index.html new file mode 100644 index 00000000..c296cf48 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/ULong/index.html @@ -0,0 +1,2 @@ + +ULong (docs.findlib-1.integers.Unsigned.ULong)

Module Unsigned.ULong

The unsigned long integer type and operations.

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/UShort/Infix/index.html b/docs/findlib-1/integers/Unsigned/UShort/Infix/index.html new file mode 100644 index 00000000..c2b58699 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UShort/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.UShort.Infix)

Module UShort.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/UShort/index.html b/docs/findlib-1/integers/Unsigned/UShort/index.html new file mode 100644 index 00000000..84838fea --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/UShort/index.html @@ -0,0 +1,2 @@ + +UShort (docs.findlib-1.integers.Unsigned.UShort)

Module Unsigned.UShort

The unsigned short integer type and operations.

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/Unsigned/index.html b/docs/findlib-1/integers/Unsigned/index.html new file mode 100644 index 00000000..16d4037a --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/index.html @@ -0,0 +1,2 @@ + +Unsigned (docs.findlib-1.integers.Unsigned)

Module Unsigned

Types and operations for unsigned integers.

module type Infix = sig ... end

Infix names for the unsigned integer operations.

module type S = sig ... end

Unsigned integer operations.

module UChar : S with type t = private int

Unsigned char type and operations.

module UInt8 : S with type t = private int

Unsigned 8-bit integer type and operations.

module UInt16 : S with type t = private int

Unsigned 16-bit integer type and operations.

module UInt32 : sig ... end

Unsigned 32-bit integer type and operations.

module UInt64 : sig ... end

Unsigned 64-bit integer type and operations.

module Size_t : S

The size_t unsigned integer type and operations.

module UShort : S

The unsigned short integer type and operations.

module UInt : S

The unsigned int type and operations.

module ULong : S

The unsigned long integer type and operations.

module ULLong : S

The unsigned long long integer type and operations.

type uchar = UChar.t

The unsigned char type.

type uint8 = UInt8.t

Unsigned 8-bit integer type.

type uint16 = UInt16.t

Unsigned 16-bit integer type.

type uint32 = UInt32.t

Unsigned 32-bit integer type.

type uint64 = UInt64.t

Unsigned 64-bit integer type.

type size_t = Size_t.t

The size_t unsigned integer type.

type ushort = UShort.t

The unsigned short unsigned integer type.

type uint = UInt.t

The unsigned int type.

type ulong = ULong.t

The unsigned long integer type.

type ullong = ULLong.t

The unsigned long long integer type.

val of_byte_size : int -> (module S)

of_byte_size b is a module of type S that implements an unsigned type with b bytes.

Raise Invalid_argument if no suitable type is available.

diff --git a/docs/findlib-1/integers/Unsigned/module-type-Infix/index.html b/docs/findlib-1/integers/Unsigned/module-type-Infix/index.html new file mode 100644 index 00000000..1cfebdbb --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/module-type-Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.Infix)

Module type Unsigned.Infix

Infix names for the unsigned integer operations.

type t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/module-type-S/Infix/index.html b/docs/findlib-1/integers/Unsigned/module-type-S/Infix/index.html new file mode 100644 index 00000000..f831aa20 --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/module-type-S/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.findlib-1.integers.Unsigned.S.Infix)

Module S.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/findlib-1/integers/Unsigned/module-type-S/index.html b/docs/findlib-1/integers/Unsigned/module-type-S/index.html new file mode 100644 index 00000000..80390c3a --- /dev/null +++ b/docs/findlib-1/integers/Unsigned/module-type-S/index.html @@ -0,0 +1,2 @@ + +S (docs.findlib-1.integers.Unsigned.S)

Module type Unsigned.S

Unsigned integer operations.

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Infix with type t := t
diff --git a/docs/findlib-1/integers/index.html b/docs/findlib-1/integers/index.html new file mode 100644 index 00000000..de3e4973 --- /dev/null +++ b/docs/findlib-1/integers/index.html @@ -0,0 +1,2 @@ + +integers (docs.findlib-1.integers)

Package integers

Library integers

This library exposes the following toplevel modules:

diff --git a/docs/findlib-1/stdlib-shims/index.html b/docs/findlib-1/stdlib-shims/index.html new file mode 100644 index 00000000..94c3759a --- /dev/null +++ b/docs/findlib-1/stdlib-shims/index.html @@ -0,0 +1,2 @@ + +stdlib-shims (docs.findlib-1.stdlib-shims)

Package stdlib-shims

diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..09491929 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,2 @@ + +docs (docs)

Docs

Local Packages

Switch-installed packages

diff --git a/docs/local/index.html b/docs/local/index.html new file mode 100644 index 00000000..a1efe8bf --- /dev/null +++ b/docs/local/index.html @@ -0,0 +1,2 @@ + +local (docs.local)

Local packages

Sub-indexes

diff --git a/docs/local/quickjs/Quickjs/RegExp/index.html b/docs/local/quickjs/Quickjs/RegExp/index.html new file mode 100644 index 00000000..ca7a5d5b --- /dev/null +++ b/docs/local/quickjs/Quickjs/RegExp/index.html @@ -0,0 +1,12 @@ + +RegExp (docs.local.quickjs.Quickjs.RegExp)

Module Quickjs.RegExp

type t

The RegExp object

type result

The result of a executing a RegExp on a string

val compile : + flags:string -> + string -> + (t, + [ `Unexpected_end + | `Malformed_unicode_char + | `Invalid_escape_sequence + | `Nothing_to_repeat + | `Unknown of string ] + * string) + result

Constructs a RegExp.t from a string describing a regex and their flags

val lastIndex : t -> int

returns the index where the next match will start its search

val setLastIndex : t -> int -> unit

sets the index at which the next match (RegExp.exec or RegExp.test) will start its search from

val flags : t -> string

returns the enabled flags as a string

val global : t -> bool

returns a bool indicating whether the global flag (g) is set

val ignorecase : t -> bool

returns a bool indicating whether the ignorecase (i) flag is set

val multiline : t -> bool

returns a bool indicating whether the multiline (m) flag is set

val dotall : t -> bool

returns a bool indicating whether the dot all (s) flag is set

val sticky : t -> bool

returns a bool indicating whether the sticky (y) flag is set

val unicode : t -> bool

returns a bool indicating whether the unicode (u ) flag is set

val source : t -> string

returns the regexp pattern as a string

val test : t -> string -> bool

checks whether the given RegExp.t will match (or not match) a given string

val exec : t -> string -> result

executes a search on a given string using the given RegExp.t

val captures : result -> string array

an array of the match and captures

val input : result -> string

the original input string

val index : result -> int

sets the index at which the next match (RegExp.exec or RegExp.test) will start its search from

diff --git a/docs/local/quickjs/Quickjs/index.html b/docs/local/quickjs/Quickjs/index.html new file mode 100644 index 00000000..c7c6b14b --- /dev/null +++ b/docs/local/quickjs/Quickjs/index.html @@ -0,0 +1,2 @@ + +Quickjs (docs.local.quickjs.Quickjs)

Module Quickjs

module RegExp : sig ... end
diff --git a/docs/local/quickjs/bindings/Bindings/C/Functions/index.html b/docs/local/quickjs/bindings/Bindings/C/Functions/index.html new file mode 100644 index 00000000..23f171ae --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/C/Functions/index.html @@ -0,0 +1,40 @@ + +Functions (docs.local.quickjs.bindings.Bindings.C.Functions)

Module C.Functions

val (@->) : + 'a Ctypes.typ -> + 'b + Bindings.Libregexp__c_generated_functions__Function_description__Functions.fn -> + ('a -> + 'b) + Bindings.Libregexp__c_generated_functions__Function_description__Functions.fn
val lre_compile : + (int Ctypes_static.ptr -> + char Ctypes_static.ptr -> + int -> + string Ctypes_static.ocaml -> + Unsigned.size_t -> + int -> + unit Ctypes_static.ptr -> + Unsigned.uint8 Ctypes_static.ptr + Bindings.Libregexp__c_generated_functions__Function_description__Functions.return) + Bindings.Libregexp__c_generated_functions__Function_description__Functions.result
val lre_exec : + (Unsigned.uint8 Ctypes_static.ptr Ctypes_static.ptr -> + Unsigned.uint8 Ctypes_static.ptr -> + Unsigned.uint8 Ctypes_static.ptr -> + int -> + int -> + int -> + unit Ctypes_static.ptr -> + int + Bindings.Libregexp__c_generated_functions__Function_description__Functions.return) + Bindings.Libregexp__c_generated_functions__Function_description__Functions.result
val lre_get_capture_count : + (Unsigned.uint8 Ctypes_static.ptr -> + int + Bindings.Libregexp__c_generated_functions__Function_description__Functions.return) + Bindings.Libregexp__c_generated_functions__Function_description__Functions.result
val lre_get_groupnames : + (Unsigned.uint8 Ctypes_static.ptr -> + char Ctypes_static.ptr option + Bindings.Libregexp__c_generated_functions__Function_description__Functions.return) + Bindings.Libregexp__c_generated_functions__Function_description__Functions.result
val lre_get_flags : + (Unsigned.uint8 Ctypes_static.ptr -> + int + Bindings.Libregexp__c_generated_functions__Function_description__Functions.return) + Bindings.Libregexp__c_generated_functions__Function_description__Functions.result
diff --git a/docs/local/quickjs/bindings/Bindings/C/index.html b/docs/local/quickjs/bindings/Bindings/C/index.html new file mode 100644 index 00000000..9ee9e72d --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/C/index.html @@ -0,0 +1,2 @@ + +C (docs.local.quickjs.bindings.Bindings.C)

Module Bindings.C

module Type = Types_generated
module Functions : sig ... end
diff --git a/docs/local/quickjs/bindings/Bindings/Function_description/Functions/argument-1-F/index.html b/docs/local/quickjs/bindings/Bindings/Function_description/Functions/argument-1-F/index.html new file mode 100644 index 00000000..cedd816c --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Function_description/Functions/argument-1-F/index.html @@ -0,0 +1,2 @@ + +F (docs.local.quickjs.bindings.Bindings.Function_description.Functions.F)

Parameter Functions.F

type 'a fn
type 'a return
val (@->) : 'a Ctypes.typ -> 'b fn -> ('a -> 'b) fn
val returning : 'a Ctypes.typ -> 'a return fn
type 'a result
val foreign : string -> ('a -> 'b) fn -> ('a -> 'b) result
val foreign_value : string -> 'a Ctypes.typ -> 'a Ctypes.ptr result
diff --git a/docs/local/quickjs/bindings/Bindings/Function_description/Functions/index.html b/docs/local/quickjs/bindings/Bindings/Function_description/Functions/index.html new file mode 100644 index 00000000..bd3bb967 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Function_description/Functions/index.html @@ -0,0 +1,24 @@ + +Functions (docs.local.quickjs.bindings.Bindings.Function_description.Functions)

Module Function_description.Functions

Parameters

module F : Ctypes.FOREIGN

Signature

val (@->) : 'a Ctypes.typ -> 'b F.fn -> ('a -> 'b) F.fn
val lre_compile : + (int Ctypes_static.ptr -> + char Ctypes_static.ptr -> + int -> + string Ctypes_static.ocaml -> + Unsigned.size_t -> + int -> + unit Ctypes_static.ptr -> + Unsigned.uint8 Ctypes_static.ptr F.return) + F.result
val lre_get_capture_count : + (Unsigned.uint8 Ctypes_static.ptr -> int F.return) F.result
val lre_get_groupnames : + (Unsigned.uint8 Ctypes_static.ptr -> + char Ctypes_static.ptr option F.return) + F.result
val lre_get_flags : (Unsigned.uint8 Ctypes_static.ptr -> int F.return) F.result
diff --git a/docs/local/quickjs/bindings/Bindings/Function_description/index.html b/docs/local/quickjs/bindings/Bindings/Function_description/index.html new file mode 100644 index 00000000..abceb61e --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Function_description/index.html @@ -0,0 +1,2 @@ + +Function_description (docs.local.quickjs.bindings.Bindings.Function_description)

Module Bindings.Function_description

module Functions (F : Ctypes.FOREIGN) : sig ... end
diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/Infix/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/Infix/index.html new file mode 100644 index 00000000..7bed4ed7 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.local.quickjs.bindings.Bindings.Type_description.Types.T.Intptr.Infix)

Module Intptr.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/index.html new file mode 100644 index 00000000..ccf4a066 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Intptr/index.html @@ -0,0 +1,2 @@ + +Intptr (docs.local.quickjs.bindings.Bindings.Type_description.Types.T.Intptr)

Module T.Intptr

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/Infix/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/Infix/index.html new file mode 100644 index 00000000..492fdd4b --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.local.quickjs.bindings.Bindings.Type_description.Types.T.Ptrdiff.Infix)

Module Ptrdiff.Infix

include Unsigned.Infix with type t := t
val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

val (asr) : t -> int -> t

x asr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/index.html new file mode 100644 index 00000000..33d61996 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Ptrdiff/index.html @@ -0,0 +1,2 @@ + +Ptrdiff (docs.local.quickjs.bindings.Bindings.Type_description.Types.T.Ptrdiff)

Module T.Ptrdiff

type t
module Infix : Signed.Infix with type t := t
include Unsigned.S with type t := t with module Infix := Infix
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

val neg : t -> t

Unary negation.

val abs : t -> t

Return the absolute value of its argument.

val minus_one : t

The value -1

val min_int : t

The smallest representable integer.

val shift_right_logical : t -> int -> t

shift_right_logical x y shifts x to the right by y bits. See Int32.shift_right_logical.

val of_nativeint : nativeint -> t

Convert the given nativeint value to a signed integer.

val to_nativeint : t -> nativeint

Convert the given signed integer to a nativeint value.

val of_int64 : int64 -> t

Convert the given int64 value to a signed integer.

val to_int64 : t -> int64

Convert the given signed integer to an int64 value.

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/Infix/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/Infix/index.html new file mode 100644 index 00000000..13bb8d88 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/Infix/index.html @@ -0,0 +1,2 @@ + +Infix (docs.local.quickjs.bindings.Bindings.Type_description.Types.T.Uintptr.Infix)

Module Uintptr.Infix

val (+) : t -> t -> t

Addition. See add.

val (-) : t -> t -> t

Subtraction. See sub.

val (*) : t -> t -> t

Multiplication. See mul.

val (/) : t -> t -> t

Division. See div.

val (mod) : t -> t -> t

Integer remainder. See rem.

val (land) : t -> t -> t

Bitwise logical and. See logand.

val (lor) : t -> t -> t

Bitwise logical or. See logor.

val (lxor) : t -> t -> t

Bitwise logical exclusive or. See logxor.

val (lsl) : t -> int -> t

x lsl y shifts x to the left by y bits. See shift_left.

val (lsr) : t -> int -> t

x lsr y shifts x to the right by y bits. See shift_right.

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/index.html new file mode 100644 index 00000000..759743fd --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/Uintptr/index.html @@ -0,0 +1,2 @@ + +Uintptr (docs.local.quickjs.bindings.Bindings.Type_description.Types.T.Uintptr)

Module T.Uintptr

type t
val add : t -> t -> t

Addition.

val sub : t -> t -> t

Subtraction.

val mul : t -> t -> t

Multiplication.

val div : t -> t -> t

Division. Raise Division_by_zero if the second argument is zero.

val rem : t -> t -> t

Integer remainder. Raise Division_by_zero if the second argument is zero.

val max_int : t

The greatest representable integer.

val logand : t -> t -> t

Bitwise logical and.

val logor : t -> t -> t

Bitwise logical or.

val logxor : t -> t -> t

Bitwise logical exclusive or.

val shift_left : t -> int -> t

shift_left x y shifts x to the left by y bits.

val shift_right : t -> int -> t

shift_right x y shifts x to the right by y bits.

val of_int : int -> t

Convert the given int value to an unsigned integer.

val to_int : t -> int

Convert the given unsigned integer value to an int.

val of_int64 : int64 -> t

Convert the given int64 value to an unsigned integer.

val to_int64 : t -> int64

Convert the given unsigned integer value to an int64.

val of_string : string -> t

Convert the given string to an unsigned integer. Raise Failure if the given string is not a valid representation of an unsigned integer.

val to_string : t -> string

Return the string representation of its argument.

val to_hexstring : t -> string

Return the hexadecimal string representation of its argument.

val zero : t

The integer 0.

val one : t

The integer 1.

val lognot : t -> t

Bitwise logical negation.

val succ : t -> t

Successor.

val pred : t -> t

Predecessor.

val compare : t -> t -> int

The comparison function for unsigned integers, with the same specification as Stdlib.compare.

val equal : t -> t -> bool

Tests for equality, with the same specification as Stdlib.(=).

val max : t -> t -> t

max x y is the greater of x and y

val min : t -> t -> t

min x y is the lesser of x and y

val of_string_opt : string -> t option

Convert the given string to an unsigned integer. Returns None if the given string is not a valid representation of an unsigned integer.

val pp : Format.formatter -> t -> unit

Output the result of to_string on a formatter.

val pp_hex : Format.formatter -> t -> unit

Output the result of to_hexstring on a formatter.

module Infix : Unsigned.Infix with type t := t
diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/index.html new file mode 100644 index 00000000..cbbf3205 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/argument-1-T/index.html @@ -0,0 +1,49 @@ + +T (docs.local.quickjs.bindings.Bindings.Type_description.Types.T)

Parameter Types.T

include Ctypes_types.TYPE

Values representing C types

type 'a typ

The type of values representing C types. There are two types associated with each typ value: the C type used to store and pass values, and the corresponding OCaml type. The type parameter indicates the OCaml type, so a value of type t typ is used to read and write OCaml values of type t. There are various uses of typ values, including

  • constructing function types for binding native functions using Foreign.foreign
  • constructing pointers for reading and writing locations in C-managed storage using ptr
  • describing the fields of structured types built with structure and union.

The void type

val void : unit typ

Value representing the C void type. Void values appear in OCaml as the unit type, so using void in an argument or result type specification produces a function which accepts or returns unit.

Dereferencing a pointer to void is an error, as in C, and will raise IncompleteType.

Scalar types

The scalar types consist of the Arithmetic types and the Pointer types.

Arithmetic types

The arithmetic types consist of the signed and unsigned integer types (including character types) and the floating types. There are values representing both exact-width integer types (of 8, 16, 32 and 64 bits) and types whose size depend on the platform (signed and unsigned short, int, long, long long).

val char : char typ

Value representing the C type char.

Signed integer types
val schar : int typ

Value representing the C type signed char.

val short : int typ

Value representing the C type (signed) short.

val int : int typ

Value representing the C type (signed) int.

val long : Signed.long typ

Value representing the C type (signed) long.

val llong : Signed.llong typ

Value representing the C type (signed) long long.

val nativeint : nativeint typ

Value representing the C type (signed) int.

val int8_t : int typ

Value representing an 8-bit signed integer C type.

val int16_t : int typ

Value representing a 16-bit signed integer C type.

val int32_t : int32 typ

Value representing a 32-bit signed integer C type.

val int64_t : int64 typ

Value representing a 64-bit signed integer C type.

module Intptr : Signed.S
val intptr_t : Intptr.t typ

Value representing the C type intptr_t.

module Ptrdiff : Signed.S
val ptrdiff_t : Ptrdiff.t typ

Value representing the C type ptrdiff_t.

val camlint : int typ

Value representing an integer type with the same storage requirements as an OCaml int.

Unsigned integer types
val uchar : Unsigned.uchar typ

Value representing the C type unsigned char.

val bool : bool typ

Value representing the C type bool.

val uint8_t : Unsigned.uint8 typ

Value representing an 8-bit unsigned integer C type.

val uint16_t : Unsigned.uint16 typ

Value representing a 16-bit unsigned integer C type.

val uint32_t : Unsigned.uint32 typ

Value representing a 32-bit unsigned integer C type.

val uint64_t : Unsigned.uint64 typ

Value representing a 64-bit unsigned integer C type.

val size_t : Unsigned.size_t typ

Value representing the C type size_t, an alias for one of the unsigned integer types. The actual size and alignment requirements for size_t vary between platforms.

val ushort : Unsigned.ushort typ

Value representing the C type unsigned short.

val sint : Signed.sint typ

Value representing the C type int.

val uint : Unsigned.uint typ

Value representing the C type unsigned int.

val ulong : Unsigned.ulong typ

Value representing the C type unsigned long.

val ullong : Unsigned.ullong typ

Value representing the C type unsigned long long.

val uintptr_t : Uintptr.t typ

Value representing the C type uintptr_t.

Floating types
val float : float typ

Value representing the C single-precision float type.

val double : float typ

Value representing the C type double.

val ldouble : LDouble.t typ

Value representing the C type long double.

Complex types
val complex32 : Complex.t typ

Value representing the C99 single-precision float complex type.

val complex64 : Complex.t typ

Value representing the C99 double-precision double complex type.

val complexld : ComplexL.t typ

Value representing the C99 long-double-precision long double complex type.

Pointer types
C-compatible pointers
val ptr : 'a typ -> 'a Ctypes_static.ptr typ

Construct a pointer type from an existing type (called the reference type).

val ptr_opt : 'a typ -> 'a Ctypes_static.ptr option typ

Construct a pointer type from an existing type (called the reference type). This behaves like ptr, except that null pointers appear in OCaml as None.

val string : string typ

A high-level representation of the string type.

On the C side this behaves like char *; on the OCaml side values read and written using string are simply native OCaml strings.

To avoid problems with the garbage collector, values passed using string are copied into immovable C-managed storage before being passed to C.

The string type representation is suitable for use in function argument types such as the following:

string @-> returning int

where the lifetime of the C-managed storage does not need to extend beyond the duration of the function call. However, it is not suitable for use in struct or union fields

field s "x" string

because it does not provide a way to manage the lifetime of the C-managed storage.

val string_opt : string option typ

A high-level representation of the string type. This behaves like string, except that null pointers appear in OCaml as None.

OCaml pointers
val ocaml_string : string Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml string.

val ocaml_bytes : bytes Ctypes_static.ocaml typ

Value representing the directly mapped storage of an OCaml byte array.

Array types

C array types
val array : int -> 'a typ -> 'a Ctypes_static.carray typ

Construct a sized array type from a length and an existing type (called the element type).

Bigarray types
val bigarray : + < element : 'a + ; layout : Bigarray_compat.c_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized C-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val fortran_bigarray : + < element : 'a + ; layout : Bigarray_compat.fortran_layout + ; ba_repr : 'b + ; dims : 'dims + ; bigarray : 'bigarray + ; carray : _ > + Ctypes_static.bigarray_class -> + 'dims -> + ('a, 'b) Bigarray_compat.kind -> + 'bigarray typ

Construct a sized Fortran-layout bigarray type representation from a bigarray class, the dimensions, and the Bigarray_compat.kind.

val typ_of_bigarray_kind : ('a, 'b) Bigarray_compat.kind -> 'a typ

typ_of_bigarray_kind k is the type corresponding to the Bigarray kind k.

Struct and union types

type ('a, 't) field
val structure : string -> 's Ctypes_static.structure typ

Construct a new structure type. The type value returned is incomplete and can be updated using field until it is passed to seal, at which point the set of fields is fixed.

The type ('_s structure typ) of the expression returned by the call structure tag includes a weak type variable, which can be explicitly instantiated to ensure that the OCaml values representing different C structure types have incompatible types. Typical usage is as follows:

type tagname

let tagname : tagname structure typ = structure "tagname"

val union : string -> 's Ctypes_static.union typ

Construct a new union type. This behaves analogously to structure; fields are added with field.

val field : + 't typ -> + string -> + 'a typ -> + ('a, ('s, [< `Struct | `Union ]) Ctypes_static.structured as 't) field

field ty label ty' adds a field of type ty' with label label to the structure or union type ty and returns a field value that can be used to read and write the field in structure or union instances (e.g. using getf and setf).

Attempting to add a field to a union type that has been sealed with seal is an error, and will raise ModifyingSealedType.

val seal : (_, [< `Struct | `Union ]) Ctypes_static.structured typ -> unit

seal t completes the struct or union type t so that no further fields can be added. Struct and union types must be sealed before they can be used in a way that involves their size or alignment; see the documentation for IncompleteType for further details.

View types

val view : + ?format_typ:((Format.formatter -> unit) -> Format.formatter -> unit) -> + ?format:(Format.formatter -> 'b -> unit) -> + read:('a -> 'b) -> + write:('b -> 'a) -> + 'a typ -> + 'b typ

view ~read:r ~write:w t creates a C type representation t' which behaves like t except that values read using t' are subsequently transformed using the function r and values written using t' are first transformed using the function w.

For example, given suitable definitions of string_of_char_ptr and char_ptr_of_string, the type representation

view ~read:string_of_char_ptr ~write:char_ptr_of_string (ptr char)

can be used to pass OCaml strings directly to and from bound C functions, or to read and write string members in structs and arrays. (In fact, the string type representation is defined in exactly this way.)

The optional argument format_typ is used by the Ctypes.format_typ and string_of_typ functions to print the type at the top level and elsewhere. If format_typ is not supplied the printer for t is used instead.

The optional argument format is used by the Ctypes.format and string_of functions to print the values. If format_val is not supplied the printer for t is used instead.

val typedef : 'a typ -> string -> 'a typ

typedef t name creates a C type representation t' which is equivalent to t except its name is printed as name.

This is useful when generating C stubs involving "anonymous" types, for example: typedef struct { int f } typedef_name;

Abstract types

val abstract : + name:string -> + size:int -> + alignment:int -> + 'a Ctypes_static.abstract typ

Create an abstract type specification from the size and alignment requirements for the type.

Injection of concrete types

val lift_typ : 'a Ctypes_static.typ -> 'a typ

lift_typ t turns a concrete type representation into an abstract type representation.

For example, retrieving struct layout from C involves working with an abstract representation of types which do not support operations such as sizeof. The lift_typ function makes it possible to use concrete type representations wherever such abstract type representations are needed.

Function types

Abstract interface to C function type descriptions

type 'a fn = 'a Ctypes_static.fn

The type of values representing C function types. A value of type t fn can be used to bind to C functions and to describe type of OCaml functions passed to C.

val (@->) : 'a typ -> 'b fn -> ('a -> 'b) fn

Construct a function type from a type and an existing function type. This corresponds to prepending a parameter to a C function parameter list. For example,

int @-> ptr void @-> returning float

describes a function type that accepts two arguments -- an integer and a pointer to void -- and returns a float.

val returning : 'a typ -> 'a fn

Give the return type of a C function. Note that returning is intended to be used together with (@->); see the documentation for (@->) for an example.

type 'a static_funptr = 'a Ctypes_static.static_funptr

Function pointer types

The type of values representing C function pointer types.

val static_funptr : 'a fn -> 'a Ctypes_static.static_funptr typ

Construct a function pointer type from an existing function type (called the reference type).

val const : 'a typ -> 'a typ
type 'a const
val constant : string -> 'a typ -> 'a const

constant name typ retrieves the value of the compile-time constant name of type typ. It can be used to retrieve enum constants, #defined values and other integer constant expressions.

The type typ must be either an integer type such as bool, char, int, uint8, etc., or a view (or perhaps multiple views) where the underlying type is an integer type.

When the value of the constant cannot be represented in the type there will typically be a diagnostic from either the C compiler or the OCaml compiler. For example, gcc will say

warning: overflow in implicit constant conversion

val enum : + string -> + ?typedef:bool -> + ?unexpected:(int64 -> 'a) -> + ('a * int64 const) list -> + 'a typ

enum name ?unexpected alist builds a type representation for the enum named name. The size and alignment are retrieved so that the resulting type can be used everywhere an integer type can be used: as an array element or struct member, as an argument or return value, etc.

The value alist is an association list of OCaml values and values retrieved by the constant function. For example, to expose the enum

enum letters { A, B, C = 10, D };

you might first retrieve the values of the enumeration constants:

let a = constant "A" int64_t
+and b = constant "B" int64_t
+and c = constant "C" int64_t
+and d = constant "D" int64_t

and then build the enumeration type

let letters = enum "letters" [
+   `A, a;
+   `B, b;
+   `C, c;
+   `D, d;
+] ~unexpected:(fun i -> `E i)

The unexpected function specifies the value to return in the case that some unexpected value is encountered -- for example, if a function with the return type 'enum letters' actually returns the value -1.

The optional flag typedef specifies whether the first argument, name, indicates an tag or an alias. If typedef is false (the default) then name is treated as an enumeration tag:

enum letters { ... }

If typedef is true then name is instead treated as an alias:

typedef enum { ... } letters

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/Types/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/Types/index.html new file mode 100644 index 00000000..2c0ce6a1 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/Types/index.html @@ -0,0 +1,2 @@ + +Types (docs.local.quickjs.bindings.Bindings.Type_description.Types)

Module Type_description.Types

Parameters

module T : Ctypes.TYPE

Signature

diff --git a/docs/local/quickjs/bindings/Bindings/Type_description/index.html b/docs/local/quickjs/bindings/Bindings/Type_description/index.html new file mode 100644 index 00000000..fa6f9c3a --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Type_description/index.html @@ -0,0 +1,2 @@ + +Type_description (docs.local.quickjs.bindings.Bindings.Type_description)

Module Bindings.Type_description

module Types (T : Ctypes.TYPE) : sig ... end
diff --git a/docs/local/quickjs/bindings/Bindings/Types_generated/index.html b/docs/local/quickjs/bindings/Bindings/Types_generated/index.html new file mode 100644 index 00000000..86996e16 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/Types_generated/index.html @@ -0,0 +1,2 @@ + +Types_generated (docs.local.quickjs.bindings.Bindings.Types_generated)

Module Bindings.Types_generated

include sig ... end
diff --git a/docs/local/quickjs/bindings/Bindings/index.html b/docs/local/quickjs/bindings/Bindings/index.html new file mode 100644 index 00000000..6d7f5d64 --- /dev/null +++ b/docs/local/quickjs/bindings/Bindings/index.html @@ -0,0 +1,2 @@ + +Bindings (docs.local.quickjs.bindings.Bindings)

Module Bindings

module C : sig ... end
module Function_description : sig ... end
module Type_description : sig ... end
module Types_generated : sig ... end
diff --git a/docs/local/quickjs/bindings/index.html b/docs/local/quickjs/bindings/index.html new file mode 100644 index 00000000..edea4811 --- /dev/null +++ b/docs/local/quickjs/bindings/index.html @@ -0,0 +1,2 @@ + +bindings (docs.local.quickjs.bindings)

Package quickjs.bindings

Library quickjs.bindings

The entry point of this library is the module: Bindings.

diff --git a/docs/local/quickjs/index.html b/docs/local/quickjs/index.html new file mode 100644 index 00000000..fb5498be --- /dev/null +++ b/docs/local/quickjs/index.html @@ -0,0 +1,2 @@ + +quickjs (docs.local.quickjs)

quickjs

quickjs is a set of OCaml bindings for QuickJS. QuickJS is a small and embeddable JavaScript engine. It supports the ES2020 specification including modules, asynchronous generators, proxies and BigInt.

The project exposes two libraries:

Motivation

The purpose of this project is to provide the same behaviour as the JavaScript engines from browsers SpiderMonkey, JavaScriptCore, ChakraCore, v8) into OCaml. So code that runs in the browser (via Melange) can be run in native with the same results.

Status

This is a work in progress, and currently only includes bindings to RegExp (binded to libregexp.c).

diff --git a/docs/odoc.support/fonts/KaTeX_AMS-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_AMS-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0acaaff03d4bb7606de02a827aeee338e5a86910 GIT binary patch literal 28076 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 G2<`xUL{2yW literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Caligraphic-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_Caligraphic-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..75344a1f98e37e2c631e178065854c3a81fb842f GIT binary patch literal 6908 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 CFgb+) literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Fraktur-Bold.woff2 b/docs/odoc.support/fonts/KaTeX_Fraktur-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..395f28beac23c7b0f7f3a1e714bd8dac253dd3bc GIT binary patch literal 11348 zcmV-aEUVLZPew8T0RR9104!7h4gdfE08HQj04x0f0RR9100000000000000000000 z00006U;u#x2s{a#3=s$l=RnhY0X7081A=@Dfj|HRAO(ni2ZA6BfhQYjK}92Ka2^Ov z0o}VqRBm=p{=X$q8M1cpbPUxS0!WG`C@4;IjHc?u&;+W>o%jXepM@BXgT+(Np6`yc z(p7IC8)x~5s#)!;6hBM!$6i|TH+G!ojgVxvwMV<>f6hrZ$wC)-SGcn~DA9)}RnL-z*RWekuPpCacmiMm2|#%vBmjodga!vtbS#zLV>nN#tH3xi zx24vQ-W{9R6oCZDJ)7svwFKw8dX5Ertxp852kD0_jPpq2rl)~lVfgktpU>?)kvu~$F8*Uz4iS< zmZ`8fx#t%{j6voQKRzWm;NI(ozQ zRm@Vm{LZwtM0X_?gs}l%&k&q{rMmnT*ngRw@8cYK!5!Jtxe+7lX0q?RCzcT7q#Hmo zE^0*r(`sIkAzpk%0rZDr=EenWnI~e@!ZWRw4&5YkdjWbzW}AA-v&Fz&U5v^$^*x^x z9D>=4oA;0hM2CEuwmS(iI~>@Mq%N%>10q;tU~LSNM4`9p(1S0Dl=;`tIgN5W8&hou zPvN%tJA4SbyjVH=tj?w8eUoobL6Wf2ZzU|Nb`mB zLywc}C%gcA(M%|66)j*4 zN>4qgxgPdPQyNp}{kMs#qQYEb2*2o#q5yL_>0DrUx>q|qT5aF))`^^cJ(QyK?sdw% z5#qW_n-;{pfuk=23r9`Do^BO2Xmd1xLk(tW+f+cT*Gc5gob;BZZcmO401gJ6ok>~S zr*F>a%7h)e=@U5^>@gWP)+L`j;MOKn(o>Y95bLohJz|{O74(Qp)Pk~v=`u&7Rz~5H zIz5}?SCMA>K}5qD1k9-?JM>3HY_A9J#M_dWNQlB++g$JUDn^)0fD`gdC3@zY8lw!H zYeg}GSS#YlJSonktjp~RV@BlFsl@t<%m=O8(LX z6y&&L=2R7_DC01Vw*UGr7d?L}=bU*|n1oeZ%4#CHW_$Z670 zH|hjzE@6De0$j6>L}KJGrL_Ininvg~+uMOTQ;Zpy(l=72h^OU+ixSHSHRP_aEKc0k3BsMrY=JELM3 zRP2g6(GzHr7J7vu%N1HXL>pFJOZMb#q&L_r*sC4(Ngn`HL^LmHSz7nGO9@8+^fgxb z67+4et`qyTi(?%L%ignifXMoovo zDa~GAqTo;v$#-c_OTXhqpS*Z7mM%vJxu*e59{jtNVHwmar>RU!IN<7TB|7>%97?^a zPWk!jl4)mKa){in)E>$tQnAj8*x?xiQxnP93oWKT>XmeIEMjL@w_Gj>2HItrq-7^` zI2p8ThlX|;F%u%Vm?8!wXL)++7IY}HCB(T+?FU93;}J;g zL>%SRb$ecz{m~HAL~75Iml)RFrUf)sm)>b+u64tc|j$3wC$s4>ay3Sn|4k~+;9d0-X>U=pxEkpL2fP$mdP4u7ID0UCu+Cj<=~ z66q5(6~H3VA`a#*8$nq)teS8S?Q7GE;LD$iX58Wf=pk7LZYlYjtp=j@Sz0 zfV;#2_A$UA27cUojVIN3R*e_ccufen#Q^sh_yc-_Pc`^bgKstXNeKAH0KXU}{v`am zU$;w9Ef2D*c>W;Xc{3f+)D#=*iypg8H3a3Nk)h0quG04cx||21OQ86Tlj+4iUT2R8 zo$pTh(whLV-@r*4&-Dj8j$14?y@E8_ z3u)|cq1PMWk8T6VmXP8gDDVF1q}kn3V1Yjad}-$aba;m zr!kQ#MD8v53!c31`Olgkj|rrt5*{ZhG+q)xY0~miDzUri^|hg16<-KumAQqHDgzZI z&o@UE;IJ&v!=)IqNZ;8R>njNyi9S+EdJ$n#kGVimbQ5usVQ)+dIf-8)m8b&1IiNI6 z2Q{Lw=K?#iFr`???bmT(yktyOo#J%U?x`~$TeA<&X0CZ_rP2C*+i7af+&`7Qb+*9Er%^4^6VIy^oewME%bP1f=|h20lY?Ih{0lS`T~|aAmI~ z&V9)5_)@OiQVRSE19I8nz(JqNkarcO{*R`3bk9W@C}nQyDgMRZf8O*3e&$1oVJFU7 z&a^~u8nGb!0Wz%sp6^!uU*lv^C2h5%rwi^CMud^h#YX}irAi8ZWdkbU>3b(mtOn(w zEN{Y4dTFF$s z3dn;iza^VJkQZ_D2MgqINxxJoD$$$d*)3uCP6S zCX~EjSPa*2W~pV2nzQC$Tz{w3{)SNG=a=`vu)2vT0PE#i2p6PUbrdfIw#!!4x%)`Z zU9qajna@(YNplbxj0a`{t5=l^ABncoKifv5k*JI;Y8lUAq+(Y1{EjoM$hC=LVMwb)(vzMiFM=CFeHy z`wM|=yDabV8I$TfVJy0NkcRfCl0U&(1OqJYDS~kt))t`GuY$cl%K!WGF zk;t0Nj0R-U#vkgnLTn?q3#heT{!rfJk|lbU9beJvgg7#&f05aj2k~z+vfOsOaf8if zg*yrB@^$yxr)O z85L|=+UF2qT;_|x`g?0AQ#KvNzM9uU&%u8=C2*t`dR^}wmT?(%Efjz1 zqV|ZE$5q{?)^)7Gyvf6p6P(;?eAAfV8Dv?TA0Ae{yvHzO5U-m*r)3*bCH_&$5J7Dxc7My#z6S!LA2gv4 zqP>$1zvG7+yA++Pz3bv)_)C=5* zo-F_$yDw>k$9T$pVvW4R6hIQvjejViY5b!#=_Z2z z?hjRQ;O8&x#hjavbVQEct^RLIweFBJ$UdWHuAb@;Shy7DMUo54~yHPEsJn9 zlv%M6ffvxf+w8JqF4NJjQ`+4lIZ3Ehvm8$R5#Em@93uzsa^*Ys?0eKCuBGw3yKPzx z@2IO)w~NWk@)o<1cO<$}vh$qOGblK4)(M&WmFb&pE2Y~z9T!*@wF53&AqXJWNnT=N z=mYs3MgPNueoxXV(bJ&#xk-n~zz9hGV}bVcBAQqg0F*!unDZK|6pO#r4NU1+22Te? zXh#n%itXb9jUTRbP8eMIif=bcIy30DwW`Igfr4WcAu>1$blj13hHXnXo2tXU?Ja}=wMVGv>xRYnAAlcF>Xem7r7=A1b*pnc3{jQ578{wO6BQ@ilAsRRzJ814ql6nNft9pRxGC z-HbYVX5(gxtz4Vp{0Ff8hb#AxN4}2LmKA}KyE$+QZJa=9&R$}ldVxchXdsuW%A%bb z4w;mcz3+MKko+#oN(%zd<>VL+deXgDspQlQjGQ%e^fyAkEo|{DdAFPwe@M;HVaBoW zojyoHabdHb-(_i$xu*_s;^*I0Y>d6BYc<*vyj9~ey%sUFHg}zkh3O?Nh`rIwGT8SZ z%wA$T66%{{>5Wu$@llJG47_j2m~NMVnzF+~1&2zrCR^sAj&>e(PYY`Ejar45c!n`| zy0>yTl=KA#2hr|
8iJi9&VuLl!D?|!}g_M>mOF8Np9hD)!Z1Vi=)NUxj~3huD& zyD|QQ7aI3(({H9Q#J{MlFEJmW^?D~ilCv^kGW^DwJtrX3%3lmPoqYMX$D{1PT>tY- z7&&?qIxCZ(mgn?cQ!37X+$}o(Af39P0>$~7j7f4p+>@Bi9aIj#bOl6-yFQA)naIV7 zp$RaqtO$JzbfPI|iDvvTz%%DZQ;3nI&&ZQvm|GrhS*E--9kMD12pHQ#GI%oy(ufJBQy}WA%+Fg zb{2gTOV|l#(Lp}SWgvO9bUmv48C28iNlXJO5*Z7kk&Cq+N*F$xAJ=R_wbAzj?a!dz z-1?v->KqkvLsOb+HZ+If1+3D6_rR|Lnpd@k|!GPWpb*j{dYXDsT;!&wG%w50@ z!$X2~O&VXQJ!?yxp6*gdc{-qUj^BC*;N4J)Ap{)5$EPb_8sZZA1HK0TH zdTmQk%mOe(F9JU#xBiL!jtTtjOY^dtP;*s{(b(A-qIV`0!Jw}0_{d;lEa@IU>z=9) z^uB3N7mQcy+b?ODY%5#hF(*89hX%5&Euu@f`sUi3jG9dwZF3E(gnRk33%cgDzear= zWK`GHf`>oYT;+2ubmPA&_iFX&PMZSM_+BiZ!Y-#A)*YdckLV7A8r~8g&K+l_Hwyv=a@c>BAIeuPD-ZnjuA4f}pR1E_a3AMFiQ8NasIL{hQ`(;ge= z4?i+&@?@`uvRXQbQl{QpgQ`9m*KK&^Mj1?5Lt$8Tb^d-$Qa5ws_j*=s;2BhiVj`2k zxMy1n+lpghTh;B*nzq*572+(t(wmG7Wl|D|yJHKZNnx?)75o0Ad8(V5Ok{}KKeZyd z9F1<*mPPOxt^jp`MBXAna0f`$#YP+b#`o2U_h?M!Vq&T4&J5gHzO^~h5?NZ#8>-Om zZ~cmMsXj26*%22f#S87gEGzj64&|vZ5^Hy9w>(q%E?uCpqGF;gnP4{b;+~MrqA6&d zoN0?S2EY7pq&ewXKJM-9Nl$wuE%f6WBQfzzTb|g^m1KRg?R^}!y@zTATAup?28~xP zr>jSbAWtz|Clz(Qr%8&3I0qROxN01)nYeLhc}ty!xV80)dQYQ&pm8?KtM#e|t9G|l zZ!0JDNMUaX7IE{WMeu~yU5Tf%7mZKVNsj*_0&_&dzdsiD=4yR3z zF7cDlC-JBYm0daq!H1#XmXX-|%XOdzD?)qcW#)^sJ5CXYS|P%wsFAYMscIlE*@=qw z4>eN#=+(b;3UPS1?#5tW72J+)Bx|IAB2@mhpOGrLNa0c1jP!xXoA)mE`5t}V6+g)B zbEh1QGclhnI%a2W417rsuhJ$mvN^_Hi8-P62X~url|=r2Fz4o;XK^lWIJk93Yc`rq zyBsaeLBSRYvNWFm;)`FV@2&)87VKZMk;88Ni7{*tq7;AJY7+TgsfC~7HhwzeG$;fX z`O6_sW)s>HR~cvqb6cG)Ef@C?Uz**!Qa+e>ZV*>_P;32h$bdqB$U5hRu*zOp4P}@L zMIM;~XxTo~8?6)dFpY3#g}JJr=)1*kmBC2i@lTov$d4CMw`GoIy-z_N1+h(AOJQp$ zOl@sAQ?;U2r4hlWnC&-qjMW&#pw>ogkFuZI;IOhJ6lfAcJ|Q(mHB##476GHV*o5#Z%vGnF>1Xa@muz^z5<@=U3j7k#$?7u*F?=&_}7ehUv$4lqTF1 zdrNPsJ>_*@sTc%q?ZfNU8*X#dbvZ@h2s5b{<5(4YQwb;xO#v;Kf zg00+UVhKk!Do1#9jLotBAOB%*>3|8QKucY+D2ujP?mHgn@RFKU(1v1yQh_)s#cfBG zLTp7syF{)sYb5;I?IIZ9>Gz!J_Vs=jx-p5I7b82hc!NPVPkqBOad;nzMv?qm8lBy0 zohsY-==OIY@}u3v{(Qfgwi@O9mkuL~{IBzNMt3~idRN3h^1b5c_N$v8`>ewR75pXq z&sy^&2W%&}Ce4g;R)U0kZY!R=>g;)#gU-cw^^#G&&&}A3rVjmNYpvf=VO`kKO@3#~ z)haw@4B-`|-BApsAm4f{=VKIe3s7n!-!H7$^3w93-x2|^~2?L z&&?!?^hR~84mnDoHSQm#q;Sr*UMKBq5=y+6j;UTBXfSZthyo(fa(cYc*%fH`e!p4f zz;dKb;lpJJ(s-=|;5HyHWOj4$Crb-$cV1acqn+w1TrIH&32DP(|DfC4t&H)_+E)z% z-H0{bvkaWop(xr=RV;^=uA6yplmq>s&{9uj8N5$gPH4RZE8XL(zGkGRkzTSLB*i%M zVH6zj_o@|v;{@Nu2+it@eXLJiRcNpkceyY>!)KO>?bbFi@r_7zLp*r$14u7Cpso%R$kdP;Bd3b(%3C-a7Z;+eQ8<| z`Rp`L4Cht<-+5F(BMUcgfeR(KUbQ=vNq^3+3WyKv6I!foG>L%TA_##3IZI5}$m)QL zk&zzgt80yI5=P)&#((_kF1<^Bk%N?*#6m^d{qOUOl4wob=z@Nfx`1*g{DyRMcyjQ) zZ5_#u_}=yNJ3NbI?YM_y>UtX2K(jpFwKDF+1G10TkB`jC6|vGyAp*~02zbbxq4~wpE<5^Jz_s_ML8s)Qhx552)Dx-Rw?zbI^K^Mab%;b{;-xo>fHeO!u+B z;pok~fzC(CW@PrfPRM$V3=D?{piBLv4t?qJ4>v$dA)N*8;$No;@Q)M^dTnzSw5RFH z+ja>vgY4+ujBUezJW#*EG%)ySUwYpjgjlF*@{s}Y33p5AhyN~^WKR zZ@c{EN)N2QmF$|IaCyt6n#t;6rJ|;``qm#K{&w}uDgmd|L-$!_5)qXYzaJfMGV19>%7Mct6yNwe?$#%M!6&CG1 z$xuk^7qfk3J_#G{;8<;fLt7_ZzXo_=G869N{15jruSy_=+deVnFOrw<`mz2XSn#5g zqcE_A=lQ%kvkr!Vu^)cD2ByQjsjr79<)$SyzrXlZd8~QeFMm##BZK9>pj6Ftk#P?r zHDD_5p9hbA+MbC?oB#b)rLtAa+8g-42f5h8k?VoOp5UFH_Lfg&jUO?yz0OXZ zCeC;a)NNvt0SD~HBdYmAk~^slIxDRFo0Cd5)1wIovwp#{BQ{~R$Hd5HFEdfaKOOj% zbacdT-3R=$`Bb6Q&19Q<`-42{sryGhds0L?eE-2Na3h5GR!JUg3{Gb5Xmv%I8DdET zwD<^2Xrivi+rc)jYyaIi-w1=M{B~$2R$cC5O_za<=OxC=FclQG8wGsyU?r5g3h5ex zw7s?l*nV|22sb^_<|vv#uZ95J_omLm zKN}{CexLXj(OdCm|BDK4qjAa-$$&m{`jAZsb0qB$1RMd_d=CC=ETb+3%n#mMy28ap zF#o{v9&bA|m`)eExmk2z$l_U92diU zQAN;VfV}fp?&7MH@dZCQ&uYDk>2O7d!}H@hgc)w^aTTw>32G=XD0NO>{@-TRljCI% zH_rk0@UZSq!y`&Hs}?{<&KMgzeU1P)SXWix3O5q#^^4XI6{J1LJP)$uVF~yyBI&Tt z_*@@=;PV$ZYfB5#p53^)O^w6;pFYpNAI0Rx(Zvw3Tt>|`JpGs7F?YgmkAS)d3vLEp zxBLom*$J-PClkCMJoJF3R&`u$rsLiVgc=JE^zy=Hj{4ghnQ$VMqjg zg34RyZ}QjgxDgZNhp0~E`|E&z=@IGaeC{B6Zl^k{cZpi@MY039K!-I;Z0{#kJP0v9 z=@RxjHK3n%^@|GuAa5~P__^eP zd;h*2uDsG}WY4EFbAVr4Hx@XV?BU#5#p&LhWrfaI}BfRk5*{-7Bfq{eL zh_Q(qBwxgNNaRpNN9%*fST1S&BiSX2Y6mi?jrKr5neJl>Wwz^#4;e!4fIG8=* zA?I#{xFEqN7f5P(?M4Uu@)~$qX|;_B5a;mA4M1Al?W?rzp?8T3>ug8SMGCEJ$xokF zv1SeXM32+J@{@gdPz9t;FT$Yb%Y%iWMq2RXDklkaAaJHP={UQNsM~@iq${WBHB?vf zezJkz^!A%&3;*u&Qd1gMUvl&2T9lVE<4@U zrg+QCe)H*w<^>Qg#90rx$mpp=}9AQ)yi8iZz>%K0nPCN_|0 z-PY&G@}KB@Vy0(Rst}wq@G!&{GG**Pi>}S^qglm({`;2~%S=w+ym@DdDkI7~h0?|< zLHqB1rw-F`zxrn>WEe?Z&%*LeNuYMccZf%wZ`3W36uk%B&qxPQ_|lh4@}8cnvSD+c zm1i)md1fs$-#(|Qi}oq5?8>@2adLjykwyISo#K^yTT(%_SygB>d%)K2oXs;`*=Jw` z7YeP3=TEhcPaEtJhOhaJc;ewMcV5n4fr3qcM0R`Ty>C)2pNKT2L#;xktUjE{XHhE2 zc;C@TMDZcZvLNT*bDP!~%UHcWi?IpfY7}dU==X>`+?<=^9|&{JjFFP4e3^xtKm~>G zP;GM;mZUq1(Ni09-}ixoyylqP&z)GA^XZ1UMZb4l65hJ_34K5xIe+Hk-(8^3s$LlS zitP5t{meg-qR|oiTJ;B+m!H3f`Obqu=9C|@H+g%k6|>>xbu#4B_SXU{pSpZI`rt8k zd(SOot!YkLt%y*@!R@+jh@@G#A$+$=I(?-2U?5$LJd22Biy|-ekN)~_{)M9gY zj|&7WebrFeFrD)D)lZpRLf?*66bv=mZq_R=SgKbm6-FB-p_IJ+=5v+Z!b6A0z&J%7 z4;{tax0^oBm54k!acoUXhoXqyqY|`IhZI9YP}ib)n=%yHuQ>2{>{;LjcskGkvZZoQ z&qtbMh{@^QI#grgRy^6hSqUY?nr~B&Y)I5Inm)1?pP(e$jcDRL+MddWc%nX+Rgedm zO7kg)OvMaoftxyAEu)r62|B}-^2!XHF6NXK=RH;)WJ=j3v^`gvOYbD1u#DT}D~C-@ zMW;8VDsWOQ-qC8TR8Vu>IxmU9%gyU1}Fx zn-&9^Ci(eR%@x_QWczx#9-SI7Lw0f{O3hjz`JO3ZgdWkxje9`{^`IWRNo1&VJGPCa zPp=mPqV+h_J&tGGYZAI?*_AzgM8D29t=LXiht$xtF!rboMraR(){nk4s>7;q_;2P5 z@ryKld@cOa{W94v0{Kb(`0tYn18FVI@UV3H*a5$=%-WN`%3tU!`e_ILZb_&5{RgKv z5rpFGyl(QT?8s!SK0&Rq5i1vEY7V}@N)#dsOAwKg=Ao!a_CHa9*7{l}!sI@kdKU6j zfV$pi?~hPA#FTmuyzex%=gHv*t-3z`6f#hq17-Rcp~cL16!*K3_wb$$#b76(j6E5w zKZ2j$N9{Ri{Rv#BUIq`LePvKHaI617HGEg%0e7Rwu;Qgllf~CLIqBtUi1u6- zXVO@-7?S6`0YW-r3(qPpY+BCA0~3QNKSf4~YVP(~8O3PKWi-cPj|uJ)!@;-)HiJ~` zGHe8kCVjfS+@_E3HLM$Mn-(LM81ntqqA3{=E!SL*N5L8-Kf82 z9KvQCv6^96G+k2o#*g<0jVv*M`Q2n6_!2%go^p1c)178_^fj>R|9Bi!B#X`A z^7sOw2pj?u3K|9$4jus!2^j?q0}C4m7Z0C6IUx}-3D>?|atcZnDygVxXjRdvre|Pe zVP#|I;N;@w;Z@7WFCZu+EFvlB}U8T zMzB?gr+a~R;~(48<%7kiMqgf>1?x%Y;Y$Yd5XK)8mpUz%x?)bF$$R&@`ES|j$<79b Wg04?dcHtp;A))8;;A&?XTgw>?+~w4ijH#pv#Ou(S+JuTfhf>O^sW6;Fx#b2@rkj)P z-d}ewUs&r@x;?8bxf$`O*x4$w9`>Zp>GY6YYWOpppm0Tacj>9iMat?P7M zeq?N4er^2~ix2%ro%X&YLuBF*x1rn;Z`+whNU)8Qx?Rs|;h>c+(BThy{Z&%F@&w1yt=VV>r?H~L?6BF>5 zfJa7O#Hzbje%F80X)XY&@YP=+`+y2QQsM%pInqCr8y^i@=8oQ`C%0^%Ub%S)hpm7f zP~X1guWio2E3?dm>`7kJJ;Y@9;7<=tN!J0-=kELQvE7zHBF{AQTJXu*2qOWdrif8+I3s)9ni^D z#kH^$TnqQgMRvcEbW|EmSS4OD{6f0G(M!k6sOlQ}% z*;c`2gC|~H&<{<>%StNx;=zm+u-fT(FzM8F}SU;Atw&ec}8x^On? zguk%zd*;cMfG;)?qQg7bdxubOzFO?ABY$##DF5;Z=IOnjbPqK?S6Tx10xv3_0h&v_Si)5*QLc|Uv&m&^8kq`Vx6HZ+D9Z7L(kv*uQ>6qJ#+Jatmu{(X}0MRx#^&#bGc zv?`WG3*qv{5>wAp~q zyeu*@;mYg1NfecNl!;l@@q>)gcrr~@76o^UA>2`t_o{DomkZSVqAFeMxO7_*+TAVXR&@vmp0(C^bf-eNCzWa`UGR~+ zK|`J@b=TCTJCPppUWG?T`K=1ohPbYe!;jXBud>X;YPhbWAbVyHKOEyqmr!uV5FUQ% zli~9sP&M#E40D+q@0`Fb04*_r`_8-*{Sa>QzdC!$9cdnJ?J$)PVj9ygIf297MMbSw z#%I-d@_-%)xC|n2UXalFIg1c@Z1baqZ-x@sW?&hp7;?AiN&~!LC@{v*fWo5&RUb}H z@GsWqBt#64Xe~q{FrgGPlwpplSfCnKP#vqNfi={`I%?rc=L8&tK&a*Lqh*RfZ%am9 z)|`%MjKklToiz@_KMz|Q0j9#*ET~=|NmXJcbf67gQ0Rd|9~1_lFa(7WDCD591qx%( z%p4TQEn4^-(n2LoSjn>_71^A*xdK?k%NXq^E@^p;F+KmU7RkDHP`SEaWfW{N|hXm~Zm zF@PA!5*Pl`N7wgex`x5E-}&5#;{5RM3QlHHr1U1JW@IGcwy+dlUfD~bEp5f!+)@=& zZs$o--jjQfyyKuUX_+f|EuW^H2)c}+FwIuA7Ecv1SMJJ6S}D_vC-Y9ap^B8;`D`U5 zp|c{XU-><;wdXTRzhT5uv5;X<#Yu=L(aBSLMZiSDY;5=ykTfOOF#-4J3!_p zp=>)B&`oNgTh%Y{*+vwzR@07M1jQp3RM*zp|AA@oWkt?ML&hxf*Sx^fMz1mVom1BE zR!_T^V2Y?zS^b2zqN-vkmdFc1dd}~?+Q4HyuA^o?O=ZR zg6c{!LNSNd3B)WlGyU^Zm}VS6;?&^5xfJmRi2nv&b_S+e)sg*;*yS>@j1;rm$Go95 zYi4Odi=K7jc#RtRTvNAMnzzKJ5=X!bGfI9@V3`|3-KPD~Re70v1rMslaX_ipz|jwS zvnRv}Q$#y?uTm!7BCg|jQ^|XW0=P-=9&-`W6aXEE8G`T(o1{XP0$}6hJGdl38Nm$^ z@`eHUp|C(06Am#1M;L-*3}Fc{tZ@oY{wvoRuP2O5g^KD4xy@H z8>X-eQ*++}3LRn?hmH}TQv~QdhcKmZ2{X8c8Qj7Q?$HW8B0zlv^a+g|USSUJFo#c= z!#7%?Uj*nML1r!g@NfLyK7Od{g=q1$Wv#S`S%cny?^NpV?0_(6K;0a*avL;l?BXZ5 z7eMqTs4rmxTL}tf@rF5ClQn>KajYU;CBm&krE+9l9zYjvRa;J8Usn=eH&7w^`5lF{ z4D+bNG=tHZZm(I_Oxd1Z8ES1!ciK+cne<30gJvNIl{bUEXRpoYm6`I$+|c5F&-&u_ zZnE-yz#6kT^>%#tG;yU)sU|(m-gITGy*J%qwF0 zvF`ClrurB3;(S+ce7#FC#Mdq^zw*scomvf62>j&$E<<@L()7Z|25_iJl%Xv-68Lx0 z&bYmAYH6MDOcC!h?c$hxMs3&GK`vy(AzfX?xuli;o@#wfbv7-KIRXX~h)#XEm5mh& z80$lPtOqAOZ$BE~Q)C#-z~LrG;ww}AKFh~g|H@Rn#!g|Ao45?Ikr~5B1`k%+kCY#m z&UvctPz&wbSN6CI-i_0)+_~YvcbmTRl~Z5+PV0BSdRBFqI11Bn%2XW@zx-b7_svk< z=zwsi{3nOO@1NSS`SR+npjpdej`dRFS&vrQz}42p@HIPijo z7!d*ZP8g-vup0vHdyVha83yh8iQ}uC`=k{4fB<+2i)?e|*0522Vgb~N{vvYxzIH*$$}#0@zd`9@sYKU>UAa$WoyJekvUWOG0hGRWEUQU01{_ElaicFLJ;OvYmA=bwpdi=}e3vRvoQs z2ZBc$;gA4j@q8XurOT`{j(OTniTVZ3&21xpgtWN0;Vz?a%rY*`KSVCCBkKLF%L}_UKE6Zs ze6B2-IycOjkDdD*9SUBke0qJHTAwsWaTy|jj!0ud+9h02CQa(qeCyHSJJk3s^A?$? z)Hb40OeHS(kFo&m%hW=O01m`W>U`l(mEOI&MVGS`yFNRr$Gk?9%fcV@$?Tj*KI_}4(2 zVhaNb85A?tV7q*nH?wjwG%{dmDih>>SdGNBe_k2 z>&pU>UF}W?e~FW?TWAzX%sF2@g}SwcRH~fein4lnagS=Z(G%MhZGzFJJqC)FDz1n< zslQHgX6^%bjlfsvyq=s-Qc>vHQJ^uxp;!p!Mxi z0eKE7Qa@NsSZ40#fn=}vw@v=*B=2|%I-|309^PCB0yJw<>byqjK0Lfxx%hAk3r8I$Udb>}Z zM`Y7?{p}1daY5iwJZt|K!X>oP8{{-q9ZqNCj28_sZwAU{kt_+2=gHd%-%wHb#y98b zgyG29Z@eKT|5)`haQLBitp|tm;>~Oy)O<1Rl!0LuW;}>%KJq^1_OPpBDH=v?-q-K; z&nm%avn1tIe}asG_0dtB7L6tRu=zK1>m&nv229t)4Osv;@U%&f`n;4A;@u~p z0>idTi)zy0wm?(nRX^4TpR)D5>J})5-I4RwZ99w>wk7zJ+@*Nkk{kiHEzgG}5{w)S zRB|aidoc)oA3f2oJsFLDh%xa-MxL_bdps zWg+OApY~XRQ9dXi-?)p+%lhddlq08|R?wb-YPXS!0p#IA!STb;b15h?#~x&}*hPI^ zufliGG(w;^ftI_qcw`FQ?j=5b(f$BqgZ=pZ>9|X>G}nsX zuq8we`gm$TPtubp;aNsPL6uvf^lTJ|v^2*lg=afBPrCb&ed56nZ!TWXmlp?RhZ_5- zFD4v<+>y{h-rC>uG8mUK$T0O|*%g%ps&%67w1cd`LY%Zx9FPM_UU(YfiL%m?5iXZj z%9RuoXJE$RRrt6)$atahoxzI;)htC_?p4G$?xuZE1Js_G9QryU8%d{-89fL_r$UK5${CZ4`TM1(mLOc|%n{j3ObqnD_sYQnRJxfq}C+=~4I@TP6qv(y4P@=7uu8&Gpm2486pIb8DV5*L#=F zgdsRIgy+EKrw}$;2Kg%g@(ku>oZ_SZ9dr;0^p0VKWh&cK$k%-ifqJ(XDsQC0uCCyQAyCmZoA>&ARm>Abd|!(TeFE%I;bW z7CvNKXFJ6s!WC-61>dmz2(_e4NxW&y&ZQ(Frp#e@}HIs+rhh{dFTlS%+v5WH*v>Qih zZXn+U2Q=xu`N|3b)w&-HvIMkSxXiS8&>Gix%&;?6K$$s`xS5pU*um&80w-im_8&hn zeF8ZECFvS6lL65{7)<0#>~Sp&DP6;oYUDw2KT3F>y2B}yiEwU=G3&Vu?FB1}DaR<$ z0s`el)SdnrO_V=j%gm{HNp63u(o-DhYn_Q(Y~h4ye~ByE;g(-l*zW1V2Bu^0f<@KA z9K)=dA7%G%9REnWvU3G1x_SNbE!L@ox!GMe*X3{Ca&@;Z`zVuhJ zB2P#tVm%4w9%4EW;bp`)xpmD_YO~_qaa#6-a7#I~hPaR&Hd?^gE7{M=P8wk$%p6uk z9Q`M6g--(5A&Hg_u6Hi}YxvIASQ76m2t z(VR{wVHAvar$P0vjaYl+{nl>Vb6Xo>m_G0e*EXhQ1HZX$+uD#25H&;EO|1#9>K$e5 zndj}pVgm$4`WFfQ^`Xq)7V|c4U)1DuDjr!xx?r-+V~bU`BPtN05BJaG@s;r$e%7Oq z->J73>YBm%Us_>DV>Qs!ZXn2xk5Gv!3)SWgU)v>I(`}Q!V5OZJSVUySBG&L;U!b zs1CX?Bg_3(shRm^mzpufu$G?^+2zU-kCe|4NFG?_Pvn}1{gxu9qe%AA-M2jhG{Iri zhO&!?b5G5_@I}PVgEx*hJW_Z4wX-$^Z>B4R2@3vB!-ifMH~rSO(zdAT_M_ftW{T&v zo^Z@N-r-4ix>Yull6Y176;)xg|NZEXT->>}-*;qFrTOH^{z8+xHSKB!S?r=0Jravw zdu6_BbrsSFdc1Qo14ZiM9AcuE<(XG}Z@~fvc8jW#s};p!X=RnQrllj3V>^WpGc6oz z8@=Bzf9`mqEL30ZR9Cmg>&xbiUcM#!e&2}y8MHI)6;zAn>4oq>0HmPI4~uhqFaUDODpXLE8Sf5ZN><&1=AZ9!?FJ~->g|ie5ybHRXS@e-DYbk#Xp0#N>2_Vvv{=To%C7S*U)?ce<6=t23Ryi@j;h1 z7H8EYi;l~;MIw>#g?eQ?Wpndq?e=^w^u zH}_SyN||}r)bz@#r)}Wo{(C33?09cZ7hm6E0LpShx69jAI>%vTH&jij8pa1@IUsuf zdAF@f_1Cs97JQ1UH*UnJ`u%N|+#VyJsyaLx{J3Ygh-aO7N5TJi?5r@4yorOOIfIqT z$12PP8p3K(->FQdPt}03{c<_(fBBb}uUm#%%aBPdpmbzS$x9D4b9?%qaY zex$G{|5F2&T;LB`9*Wp%t@3+jY+`lT@yo81aj=FeL5YDQxrSSieRbk3*vEI zDZV#%_^Ja>&$+1$2FDtB5nG`J^R9w^@ufVv$^43tQX@+rUYOxm;Hx=m#Gke{hs&7` zSV~J5E)UZ=GtUd9*sb9e7Os26(OP6%cb2oF`xI*Ml}DtSyt;Y1^b^5yjyNy!9Q0Yw z+Y7F~ji+zo-<@UiY7c9(#Y*@3s_23N0?dl!S5ii}xM#@lUZ&xarl87F$l6!x*e0Pj zWw29~4OO;xz$1mXtMwWOH(c9c*Ktt?pI~N95`X>q|CL=+k(*@7Aaz4`;X>fFiRk(D z;S2azulblBeF*QA?JM6tZ`&7)tlr<>b+z&7D@Ir?u&9mBSh2YVw?<*rwwaR$tu`N<6%S>2%GjM_H#oOLeZKH2!FJBHEYm6$kVc@2Z)uR-!j~9le<~Lv#GsnB zNOq9=GBEJ@i^tGLfBjsKU9T22>=kiT#?Q#r@er5qB8c(>I%S;NWDW|tZhPtAu78(7 zRBqN?r4=W-BNnFDifFT6#Jo^H^Qgn3Dv``zS!0#yv#o6WNbp+7!Qpy_ef?1?HsNY@3hUbVmroKybpi#Tof2c% zZ_N;#Ek5F;bU+!Ts0x!sOk>L)pnEho;V@r8o*7|B*+?U4 zd8T|24y`0--Vx<-ekYCV{deYOnr$5A!}Fgakz$G>>C&mTjVzoOxFgE-$UPmN53g%WUr8L<6lZllHU2B}rWo$N$u<+$`6|c(#ge{R@)Z;+u3^aw^BMZ(3a` zp*qg`*{pMen8sX%8GLPI?!qH{&4F?m=vya#7~8O3^yBcq&?Ikwnkya(~YB ziq{u0CCSjGp#3fMhVkUXQ*3X67Wo!FfOSF`+?%uwo#5CvwXTEAP;HT(GgNk&!DC~_ zZHL@ZeuqtnhwR+BV|WkpC1h`#NfmuwN|+|SSCBBsS$h~tQRLOZD2@k~RvSCZwf2Vd zWsVBP=7*5#=rU)5kd$J6{YK*X&&CgLHr#R9Lh$yX2X|SjF|6l;mxfnj`A6a4GUAOzkO? z5;jY7*ZsV6(5&27Dt8N?g&u%a+&YpifAmd3h1CEvd9{iNxwZgO9bN9s*m+-EWurW1 z)&n6$D;iLB!4mEk&mv8;TeweHYxH)`W@}dvwI$`8yR0OrcAop&YO1BdY^5bXAeNhiI)(eY$x$yQ-+6pFE$TXTc6w zng?pKIt;v=sSS{#c;O`F^+z8gB@V?!g(g^ZP7?PTf1C7xSB&RgZfY;f{+gRT7mc#3 zYz?G^7}75nnHWEuVt8FKbh_R07o%To`^!8Y9PUX?7@v|UUtp4z&-u$s_&9^~9ih&n zmxn3UnrOAxsoM(DUmwO1hH=a;V^d}n9D1ta8O<~qyO`-uGr&h*|M8&n{ZGIBsta_b z&W-PVom)CgO`YgC!?p^C2$|Lze91^%_q?85mmB!YlwgY}UU9BmVY1+}P%GmjaUA5$ zxvUlk9*RpRJlYCLfi`c9TE8^Xm=p2r#=8#BfNNkRpC0@$P{m=wf2!uW3ZHjz|3J0Y zoE~Kt+u@$#C?V>!t1hx&e&z9L#*~)URFXEX4cRw)}S> zLV;TrOxS{XK{v}&68Beyic_!s2!XOu@7BZK?W8Tv)>X?`Nz^A>0B`bpH;Ua)t;#rJ zZJL^me4ECgr8;%>PF?>MkhoM7b~+QVN^uLJ$*Qg|IO8BX<*}a0EFem!+Bpkr`W?0r zTup04Wd60m+7t~2ZK6SG_F8jqXgR83h`5`Rta9dKu0Q_wWnLFNWfQZ}D`9fs3-GHZ zU&xc6!aRR&3!?EN!#h|F#|#K-Oh8Xhw{M%94mLZVVyB9t9U+k2_YSjJvIJ@CQ{`N1 zrKp;kD-9;EBwh~-I49TNU9%DqdwkCZ)bSi^sLuOa;#~u^2i6iD*;kwZ5u%sA>Zotr z@;hP|AHHDEmwj&>Le=%W$6b-?tgq!xJC>IH1A1WQl|D$)KK!sr>~vI)g`do2x5iQp zA5C2WpaYjbIQ(0Vvs5X#eS~SrN5RkjYboS3E>1!&U%Z+X+PJ7w??rBS>{1zaLX83;V|!etuGWVPWUE7UNr`R3XM5ygG7dJH&eF3j*mu%=OmVuhyAe z+XGo|zKYJi5(wM#f^FsPu*k0CPtU0(L&5WNHgu71BVz&BLdb^1niUA>;LYd9d-EgX z5g$Ch?MOuq>^*AxP}~zgd#<$*mL3+r-I9d<(hVNTt}MEFfIQ*PO*?%C2R@)5pw*B0 z@!;k{p@F-->?37Y)yVX3@Ql+Kci)dXD|$5 z%K5S@8}2GzI%h@aI>i8R;x}!NY2y+lBJ}H@PocJ53g@0gzT9goXtzY_R5|nL4Sl6W z<&$>pFs19;Yggu*tBN`4P%h{jT+(kc@GV|O+hDd?6W zcOntn(Nd+JCa`B3YW!`8|MVroAIUiI`r?_Bt=U-ncsDc!T>nuRzep#W8pAIDpQL_w zp8=12+=6ReiJVa22kPyGd2<_H``A~|lop;j(DJgS+a098S|=p2y~ zQ>Dyb@I~i`sDr)hT0j1;wTV%vJYgooo@%aCTKLGiu%p7Q&qA*=>+!%^iSe$-^Vf-~ z8cnGNHxK5WAqW*tG`R!;3WzBAEJ%X51#)Fp$fYj(O7`r3sOLwz6Xj5=8Mz98{p}R; zEO37Z%|QB2xV8Nc(;FIvOAbfh?_-xUHMgE?jOM#U-=g6{=o@iMp`*+SCjN)GLEIQs z1o)R|U57hoJ*KX9Gq-)i(CF@}um2|s$KXjH+KS11MWb8wbOt_8`-aE!_i>CB6gEu` zOb&-ZtuUT;xm@}dgO2udRou;rUk$nvtNs~G9cA%cdKrh) zZ7D?!Q-6Jk#+TsehP0F+v0wRgCNCmlfbP|gC=!L2LVR6u6@x9sW$DvGdR}k{JoT8w z6F@iQ=E~zAxoo#en~~Y!fcwdhawMzkMae9Qd%3m=T_^@4vP~8>5tY>Wml=S&&tthY zg^T!(f)iHXOB!`g-!diVUVm35<-a}g0#)uIS(mL~#OumWaEcnS4JRUIAiR_02)`uE zE@PX@+lO9iTSjhrik`P^by4kiL1a>s@99u;yA3E2@ctNXf;gvLs&F?o6ruQ@gjDm* zklW_E-~43u5{|sI;)6VEtJNbvBQ~wm4_*S!85gWZXj@$lS^a^jWWGuJl}<_@ys|jl zfaAhRgCuXW?FE8`V3!ZFDrRI^E2!iT!ad#$a#0Eu;G`Q$>!yL@^>;61;842=T-8t$ zLyR0PhiabyGk?S6F9R)&t(P8IXmq-Gqv&*N&jn1%pgI7P@IW7?<5ICL=@%F!SkN`yGJQ(k6cq)$jj z++{)ygb@ZOl!9laAV*ZB@6qd6w;I9gm8j@GO3caBNK3$Xyw3gr+F+AOy1_QsT5_@3M!0J4uE1v zf(M~qA%K}_T}~F@xNI6p;Zuba{j87xA)rW2Rq*LZ+nS$4kD}ut1`$XI=?WA)LI+I8 zAOHe*dR#9JO#DA3mi*I+usZ+%3l{n}jf2kK_}?SHZUTS;1<0wY+Uu4Y*`B7pN4iUE zx6vcpRWoD@J?a-^S;{q_Qr}zp1XyK-xmVwK=s5MKxrkIc{`_qOumy8Cfgwm(zzhbE zpIGx5uuY2(UcLQvQrCOpVUVs`6b}`$YlnC>!wzKD`k)__3a1qPbL~Z{-2@|Bw%g(k z#m@E;U_pBkYbeJZ>1g$Sw?7u_O2LM1H1wX$pTJ(dtAYUWtl-KYtZd?l z11}G_g$8_KAcWQTvjQ_r>6(QsB0$Mq*B_i{=B|_e5%YB4h#$KU0IC4MFn~ZV7Gv^< zStj}+nNxskz)Xew-@M50dQ%oJZf4vEO{v9705^ZpK|(QhDOfWAwV2jHmNSV1Y74F3 zV?jnVPB;WO6@u;1sZa#ZoC@Rd)~Rr+WSxp&P1%~@;HmiP%;Kj?U>xo#_3AUGUxzmB z1_>xMQwmEj@3D)huT+{@`>OG=wy~(>6)Ff%ZFS?-y*ap&_&pFs{K)&8$jg>rn4kl{k%S zyq}a%ucf15v{=%?owhpZ5L&(3_t+d7_^>D~WVfY(G6((b#|8BA0aEEO@5&H_^^5`mX+714k}%K4h!Vc` zfC?Is&`L*k=#L4+Xt&_a1i}DhV2EdsZ~->nqQY|Xp$zJiC{@3D_cc`n7@_e3A*M z`bKAadTovWQ{#074gn1V3kQ#Yh=h!SDhmxA0}~5dHV!Tx0TBr)894D;C+WT!U<21_4^m--^~Ip zJdkUT83C&E{3jCy!EA@cYG2ga2VMaJn-MyU{k{hbV0-A(7TnmIU00bZfh-L?l84Q6k8(p9$#9e#j zay#&*{AZqb!i{nEIFLFLjG|^yR#~$D|34+^7{d+y08OLnKP1aVk&cmYh+LTSpn$_E z1CBKUhXx(;t@HE&$&|WJnIW@OqKVmh88hLPv?y>}N=NO3GRf&N@`?quW?!+oJVOxQ z5M(%s#o|K1?dWmCdD*X(En&UgZ~Gt_YA^Nvx~wn%5b!1mvj0#^sPUTb)=5uBiepa{ zM@C#m?v<3t_GwDBor8v<ttQO?g=!#O_g2#tM`J3K$P-v8VFqW@nKOE#jm5&c;t zImW0Q^h9U_r9`no!bnamPVbB}?({-V&$u$`JiRtAy($LX{5}c6LP8)wpoZ3I{h3ux zT*ogqj5^JCz8()fNA1td9=LZUR>1qx6K~4{4g*f)xHy7d7KIz`4CS<(k&^?-P6~p; zlMpQ{@NfY^v-_L5{sv?#w238S;()WZ13){{^i}>{`-Erb{ic@G-7jf^E_BhPN zlt>z-oxOEA@1B=oe8=`38v+X$EK-^>3^bbq1mABhf0CI666W;1vn64x!~&3Y1$L_c zr&sw`Rns0{A1{arfc3$CudWOh6_5g7nN+vW4$y%^dVK; z58e;kU~zxK!!d83GNKVCq4k?7Q#mQ{M5H@a4(ONd3j}uH_I4S&O_<-{_3=;qyDfxb zNX<}8iS6^`a5!cZg$->0)^B^QbZQ{-W_Y1Y@R%{!e1dC_TUHRUe0RL&twDV>P$sB?z9jlTDbh2`HHuPsM zIl#>vCZ*h!k`m@NM_`M(vcg6cTxEr+GZn&Ay8fT4Wjo|*Q>VRZ-K|}PTy%Ht+}Ta% z(&gX}Ko0(Z0RvJu7*H|@^3D>tyH5n9XA0B?Q7JgZq@^}e7qw2gyXU5fv1?s)Zd+f| zxAyy%&hF&q(-*pmml(6x%3SJRXhoPbWuP0yL&#bb%3+jb{?}@CA-N^-Oh~3J|MfZZ zIT!D!&Y6#3GPj6`_h8n@5L)7~tW`CE#ORGh+jxKw0qeEbZ~xy<{dX~=-FEVFj5Uaa z5^}-I=-Qv!aqPFg(tT0)7q#mdg@GVFFc@V498dEk5&%EAMgZ33LqD_x15-(HdOz^v z)OUZxpK)dtiO@s#kCJsLmeY}y0UK`=0HCkj4FDPLQ$hs98x3T2#0vV=_w+-YMg^8* zkG&2$?3gps|NEZLJ@zNmMsCLCrM#9O=MO7gL4`F{Gc{LnDRD@K$Y?U2Of2)4$z^Jp zPIgz$mUHEpTqO6C$H=$J_seJHZ_3ZhKak&600luoQcx6h1*Y&(NE9-KQlV0WDv}j? zg-Kyi*cF)yr=m(xt7uj%RSYRsDK;p!D)uQ3D&A9ER{W@Vp`; zs22u43;a9q-;mUhqhHA8=K(TM<%2jX?&1%)uKpf;1-=JAAdLU5eT0KDSVom$GLg(r zCi{oc!-wSO4YN=n{~(m`|UGnlTjP3x7sQ_y0q~qQzB2UbPf^1QIN-r zksPtboYe68Oy6G05|yysZgD911CY`YO}qFY0Iyho_CI&QMn$6GmUk9@j}32LnfmCB zO~hgU-M2fV{v<;KCAbwP2E0E8_T_tO*FOU{*4TZFOXOP*M4nCzG33QUcAWPF_Xt)p z9srb8)QS*H%d#SZc<~h#px;yGFP+ks9ucD!G~a4zHCIIZx&o;Yu}wYk#cDu}2BR_? z-tdC%!CpAMyn(YzbnucV)5?BuHSF3T6WSQTT}m)uKw3|v)jHdu2Y+;UyZm$LCdSEP zLTxwr${Dx$uYk(syIJ?@#oa#9k~@p@JCB9}&D682ts2ecCpb|eKW1Tx{C7PGv15d( z7|9~PMYdElD;q)Nq+AeO4+IzHwhy_}`8XLLr(;JJ((qW7=e4u?WQ5@?^u!(mB}J{G z3QR!ksUJg~UBJ+k2KvtXa$X*V*4GqC#6|BZTEJDuZ97~jqS7^~cKyQ-PUQ6KLy9sP zZ4u|~5IdLV7R0=PC)WYdQDSY!^(yM1$0=VG!+nxFOZ0OOTxaQ-tDvrAnmrf zIL7k)*_iZ6G4SHJxD~-*&dF+`Yd&d+wKRzwYQTpfQb_DExR8sAzNaOq1%qDnw{p^3 zii&5Q@%8V7t?RP+MGh=GAvQR3yFE4|%5E3D6K`vtdN>Md?DAzzv!a8J12pHmwT)ew zngF%jb>YN{xb$E>a$6i@d6A1sml64?I%O*Q+ZTBMH55D;+g-AutSWkVza8FxS>Zb0 z9rK>vM*)K0xY#m;Rq2Mg6C>Bc_i|1T;i73Vrns2nFF$gu2S z+Q>O;sWOBCfm%uU4lMv&urVPCj(%ZE`@ggRrwX+DHBgvhLfe$gh>9W}Ma!pwD;Gpn zy(j+ugthn+CI5-FJEnUj3J9WN=<<+6c|m<$_B*~joC4~B+ z)XMv>K~NLE-co40anN#7j(yyFc(OhA`FTrmij(lMO;`_h0TdMZh72ikC<-W=P_&?E zL(zev3q=o#J~TT5nq+0;{K%-F6<<4S!wEM)9OY|uf((z2caP7@6u=CTj3lkgo%+h9 z=sYJgb0;eH*lxBR#A&yvX<-uXn}^Q4Z&ogEZ2(VDPj2EAY_n@GAPgMKiXtHYL75r9 zkoB^W0zW@5TR?*uc15t_KcI@+sIN2?ce+tWMWeKL7X^uQ)Qu)6ZYk4m^WXcn#tC7^ z-Q)I}4m$}hTwK%LdmxbC;p}4nur8`l@%Obj+RY;an!E!qWWR>mRFzs(P^2C{y+7$a zxeR+)&!=vS^ZBajy=;dNxlmRzjl3mqsu=I-%txesFk>%NnR+%nH#x+3FE>!#PlC!> zS*B^-b((PcXyp-Fc%2aw6tG3a7zkhWWCwQ8#CZ$yZY!I0FM5?7Zgcs71{*?M&7h=N zPoF&WNMw8putA7m`AEzhF-fM;^W6+J8u6~Ui@;REt*++5rnk>q%m6N%=~krB(!G3q z48#`>Fh02%=x!mr>I6~)1X6qZkfC#P3uvq^ljM&w_g%c?+;!V8^;WF>aj(F=*jRQA z?nh3w$*;#+nmNPI*A)rjtomiL^J}hQs-S2DPl44o{P}5CNAb__g7yc@bz6mjcG0_QNx#!%+7;*=3T)6z_h_tjt4f75Qdx{$+6GJ3fM$K zm~#0u>=7p<%mr*w0bwcVl?qRM?SbBa2iOXFXAir4ul5+05Cl$(avX3;0h1*Jg)=H9 z>~PK7*E)CrLog;NfF;m2cmPMZ=b{iFJmb}d$hZ4^6m-zz9z!us5+()YDgrn$KqWn5 z1}WuH#>;XDj_42`sUtw00O@(2lrAh?S-P?G8iINQsCPj60h7@uM_(L$bMzB}`UR*z z!14c>@M}G*?W49f;KuQD5bwO1j%W<2YU*jL0SN5IW+2r;dxqcx#U3Ayc>?q| z0H*{15Wc|-JoOcrH-@klaUiWI#%ggr4+0OBBsMEe8oL<4i+EAGUJA_P=!9Yv4ixCg z021$4BCNPv8rymWPw+g@(vliML;%H&2T7E&0*?n#6KhzNa<;Kz7D`MMs29H|4VRCF zp#7_h!oF3nKX}YHzc^l8 zy=h!I(YlZf$%(yEjC^}yuYMoNSsoQQ>?uz6AQnOE?{dPYqg zl+AwST-9k??`c#W%`aUzb2V9>?y?T^E!D!#Tna`;FQQx6Qvn9tCzMbm#y|dC{CFOx zfRo8nKTe#(c7Qx7X!`FI!mpJWMvw}UH~mf|o`9GLt;G=CaD?aar87Av+(%%KgNyKS z@_p2=ZAE~V*G=EH$+FB#T&6j*hVlQV0yF)jV3H|dr-lj6WN5u9!iMF=sj&y~mUnSN z1K`zgB1^zYG#BrN?9m-D!5Ymva2&}1(Q5<^>KqMS$h0W|I={$*XeM#D85Gg06~8z@ zGHlDwfF~d-NZogk_1oBOiHxvS=s|?gf8cyv5MEqHiUvTSj$P4)Y%hDYdAsXvrDU#| zzWC2D=Pf3q_$s{W0MQ*`T8XrrN9r{?G#EBF0D9%l$=jW#Uv`OoEhJzufJG*3B;&=V zL~=_wq$X6?3hhTCojeNEIjYZhu$SAZ!L!V4g%rX~fv6zI;WRXrr|4Rg5lVJyCHRqt zLXo~ZWC{{9NG^plapdH#x6$flZ?i%@&@&p0ujzh#9HQW1U=`V|b%mE4_cWH0FojIc zkSD-`ckco;iB=JJlJIZ_=zy_!h#g=c!-ZcAED|Jx92V|*dM5{wLeqBDmy@+}1@T$I zw;RN84(Vy;tb#dE;Oc^5xoxeN<&9PkA1Czw{mKAof{XvhF`?r?LA!7n;u*bINS6Gd zHCq7rr5o5ap+X*{VAgm24NZpzMCb=OO_VdCU;3Pm0ZjiSQZ#j5A*EBFyha*aHVZw)9fzb6%BMhVWD`b43Rg83E}^uK zhgFDo-hr^GA=W^eOR4C>^3}KqC#RLrh~(8UfsPLJwPRYq81(J1NXS;3T51?V7Mqpf3HAKZfGVe^;Ov#Ls_@TP>2= z^u>>U`culxx0>(?L*=`FP&EFJg@;au+L{_Q=S<@IuarHDS*j-HJnXgg5zVV?<?ulaNwP$j}huNLptN20)+MH(BL9LHIMa#RR|$&Px;mYIH_pkfx3>HRnF|LW-EhDU2!yw~O&>&~2Ys4skZ;DH@V^lDEw>c@}w*1*s zy@3W#+z1np!qvhRezqCxl@Yb3ay&S1!?v8R#58c7lM(i%)R9rT(lRpe?x=BD&ya_D z_N)2e9~%Z1L1nTUSc-4+U~Z)RsHK%AgxAOYM{tVonxgUf4fwuprEY+}+L};a%12ks zRrn3^lHklPN4iZs@Y`!XMz_&-f&$NsfKm61VRMyZtQA?D)-3Nu&}jPD*@EdPNH zZcK*6iVq*R8!7qod5~mqR*bTm0b*+?binBdm7m^9?x|JjG8ZW-T=A5mYOS}bQhgtdTO7?*e7E8&n^Tfm`-#j;f*_lq3oBULYhn7YkfV{EqThC;8w)A`>pzGDxb z4HP5KQcp15_$Lt%YD97*uZi5spBaO_r}h{86O&mOkj^=xKH{n3O@-bjRRV!G#^av` zEJ{w5d*N>>#k}iV0p@#ST9sRcylgSkvFHFPKmk*!+#gl_wEr70A*LTE@j9xZeP}#8 z_X!w0Wlz-8m};(ZmV&GwHvoEU1^x;qu>VPHw=9E@ZpJ|d1DeY_d1j^AUZol%c|2anStpGu(v>tO~m%-E&i15v4?3|F6qU* zY$G)V9I$nr|8TYF3-!!>Rz?B8wv4pG1e0CtTZJK{AM>Im@BQqK!|tDut|9 z%r6-M3F$mel!vu@v^3T0piBEa5-jG0BS#8Rai#}R7vAWdOGi<^_uerH3Klry<{lkV zyHEhjk%GJx>dt5;XO>*pu$yd7k&gO^5r~oA!Y*q={ge3xY|7ux~?v&Ksn53JA9t5EQq{Zy0M*{ew*F-#`q5 z)oikef(X~KO9f=Zi!q|RtypcR*gZ{1B#sdeCy>s*63!$_GOXbm{{f&7-rdflBEy>h z4Ml$s1vQsed98dT7qMo4^T015lJ*MXkjat2w@?+oMm?70KHe|5#3;5Pc~j zu%KHH+`{o`Ww^qwD*@kEIJ(tm6q?(cd`cCnl)vFKOxdEdBDsS60)H3%_X6`6e*k&k zq<{xfgi348>fOd}DgIIesgw6H1w9sT?OjG%cL!1W?=jD6*U%wbAPU-3H<8|gCiZK1 z*Ah@fum`uBGCTw1D-gO^5lA!dO(Vf!XCJ%mCGK23W5L0L;Qmb{U@3FxTa46R(QY<| z62s2fTsnCp1`VKT(YGw+QtwmWZZxeI)5Z%)Mbk4qg~4-_p$tpZJV%rw2uWVm%Vq-W z$xcAAs1m!7%klCz{M-(;E9FjD^J#V)3od)L{*2rNgDAXtz@KneYtgQy-*}QlQjI^u zZr50}_Zr@tFT3@XlkT1dj}Nh{f(CCL9efW*EDC;_*R*@ylN!0(wGnL{Q(mmUj%HjX@4v|WaZJU-UD z=hPu$-_ZkM5PU6A9y%ZgBIw)k9Wq)vk=A4_eN%0n61_vfgtYai^4S+?$ypRNwg73> zT7g|aX7o@37S5*J<~W0Pfd@OKl#;t;s5WRMJI?(+~Fi^{Xv&v$+Ecn2+zBb{`b zqKuW+I(8lPv^2g0YPJJzw`1a41D_!n8(?TxeWz!Wqp>tpvg zFJl>MNzy}dSaqlQa>r-5;!TNRnf4YFYQPxQUgjMxa5~8IH~Pqxvdv<@wSol=oz@*O z#AcCd1AzlE8sM9%-0;({WQ$g@r$0_n#=?{5yExMPV)LS&U-;0%?T>@f&T@gTWT0)_ z4!%BR3g2i%*%wHFq7J9CUmg})!LDP#^+rlARauEfkg`Z)VQM?Yg~TQ*nHa@ZUKGR8 zejLSx20MfkP%8mMXQ6IF2kIh(HF~Yfd;5r*RpA0+m+?$jud=Y9iF)H^`ZA>DxMo|0 z+|#H*9Y%O&=7(Ix`~uz+%;VGRf->nU>YRwfq;zI1rBTL>LW~U@6|M5S;N4MS6U8{g z&}-g?O?a{t1i{PWWJjk!HE%vKB4nSZe zwe1Vh5hz>@Qsfkiffe3HK7j=&h^iO1`BT^(>)1yIk|na1_J`~I4t~UKq`RAf?Tuf& zdBc9v^nni?18U!ECAz=A*?#YPk3$+hU;~sy7ZGbifn*7mzashi2x6C04X4is)S%UHuW zZsk`zS4wV75wwV`S~A{KrAW=s?oAuN6e#W=dxN0v$Cj&Ho#oqq;uy?4MPFJ-StCxoLTCWX5AUjxBZ5C>G8yo6s!)#}9b@lMbvZ76yNhX- zgc-LZkH;cEi&G%_S@+Ln!tns2EcJ7}BL)l*7dRPZzom@8>V3HQJr^4mTvnh9F7}F^ zmspw<5Zo3Zd;;a`NE^tH5epqLz)d#PhCBsz;4@T26vW_-G%!$wLYjWmCIgsW;@hCh z_fbH^W?B3Vtpd`pga+`n6K8=)nO!~L0cBzKO<&U!!}j zww^8LQ7sm~Nv=wk?|0Qv(~Ypb>uL_+>z^f0_nkpI5Pw`M2!%uU9)~X*D~~rtRx{W^?wsY~rA48F7yQ_P0g24e}wj ztOe}+p|_R}kbn|>-Nz}}oYNkoYM&E1x)@Sz?xw=z2=OV@KXTaR5S}aGu4$XTiMCTSvX4-gbL|iCACR# zbURFXF^v5oGI${SEBn-X5z(tWnv<{wNKN4IB#O(oSSTZlsA32l$@sB|(nd;bc%-#t zUFnvIfIwN7^iW4j`(A6bqPDQ3n={5$B#!Vb3k=VVwnTnk zKyD@GL()li!dG)pJV^99TVP!W{4;ck*qMQ1Wi4j`67aJrNYdHD6HdHz(#bFF5@hc} z`p5wY({G8YXaZ1-^Qk}h(@VxF)2#VLQI8+Qx@@QpoX;q5CESH2hNafjj`9QDjiBk& zkA?-otpdWDthAOSD7A=*Bk(RJ_8^o;NZQy>F{KK^)(RjBg_ClmD4RkVUPbT5{lVCD zc8J;FxSma{q}T%dbSxUD+WF5|`X_>}xn-LHW|0Zy0%L(asu)t;U>hj8Ik0%05*wmd zz)vEZ$WmG>S4rdk!1~LtGJYvG$d|^Un($bQIn@I;P(5lRw##D3d<*KL<^9l;#XSY%rou>QMuPeMuFN<$>06LzPVBF57&dg&L zp<{$jB8Z`3K8*i^8G?d=;gY!H^jYr!PQ3h(!M>t}d1Rx|a9tyHyWh=~pZ5#J_n>aH zP5vU9e-T+4-Jm+7P|1dgl|W-GZ_w!XKg0*tx#C#Z&AuIhS?A!o@I{E7wfc`tMk`ayPIM?&EB5 zVc$%E#MW}szBBfMoNH_YT*-{E=IZ=I8?h;(v|idG2NIxoiiZo-ddIiim05jvFAYHa z6AVr??}S>;N<*`^H0hsIPD6LfKS777papj zJAl896Wg+E!-%p&@kCxoTJ`xzu`FB(57japc{Q&_0wK)_mU0IyE*Cf>IuK}CJcIU8 z948+cl2n?QKE3pO$%%~M?cR{kfwW=WCPL4*dHL4HKQ`>rV-x(*LNub{d`4yD1N^JJ zhsUFVM+{Y%U{gVqO~45$idp_lM)L9qlB;tJ4R6pfF(b3wJ48@VT{;P5w4x%<6TsEY zFc4UBmPX-7USZ^{ii`2Sfi~S-see2*$3SZV5UK1UAma*Z-A1{@Hur;aBDA;CS-nDWuvr6z*m;7`STMV~ zCZB5>ODky)NJD$A`*|i}ZaSU8{!7RcnD{3WT;nPa^?_1qj?Z~5UFx-Fc_FCi`jo7Vjj#4c2+XNWw=G)H>)Gx6cy=N?qJd?~A4m@~ zc0xCZvX68UkIKs%WoVql9f`9p@;9UygdaiL{E$DKfhA+E_tS?D<)zcal0EB?;SIzH zuC}D_RR~JILdGpZTRD?7i#1@yv^#q;V>X%Qvv?xGMaKwa8-{kePni?P%d0U4?604w zozvO++hJs(7;As&m*H*mFWQxVb3zD;O#Gd{qWvwSz41$bqwL8ztQ=Iw^|0`nx!C%Z zzcGF|Xj@TI{2P*bg|v&4+}3K}|II(8f6D=JV!iM!IT6oYnfAp0((T-rgDu0%^V2OyOTh_GcnjL4(?6~kVk4bF5ehYIS4GuaZKr*H7AX8fau zctYhGlN$c#H?yalp%s$2IYIjeFfVJr#p69 zpdM80cxpucv!w4S)xUm0KD-<<%AuIpv7Nw9Q(SB@aBy&+$WjCzMec=sB1o&*xPh%C ziq2QU=bB!STb96m!6m_`XO;c7hm@Pk(Z+FmIH^^AITCzQA*rG72yLRd;KZZr2LG8J zcMB)i z^C%w|G{@1)@hpFdAw}5S{!1$GSWZ)qgO4lsvEX3RUCWGX<3O!e_<*i=)$gMZk%H*D zRHI`nOxNQTfyB3Sq+CbkLmcEalq#>y&ibeL+t-KF#`fImS93!9Mx@XC)V$W%FEuOq zMa8^tjAO+q#b5$|_juUwOCpIztoa$~TC?hVOmcpua>cI~rZlpEnV9;fymVvgQ@~BUjH)RjtloF!fAM= znfI|nN{N^_k`;dex1Q(a!l6W=rC|b9_JIuA9wN3Q^s*!`z_0RTawN_$@+>mN%-;J>qoVQm|qz5`7;Ll z+Cgp;M8pO9^zVRdEfM+8@&W7 z@>LxFP?K(JU%<)uHGHNXHZ3l1xv^hf;2(eu{fW{&d(rWy_#Un9m<|+n%II>%wIwix z9n+4%1}!Fz#bVn4redq*KLn_LO#7drO0r*9>0+|tr9-0f^rQo{*$>Fb!GHOAq9_O& z5(xwDYg%VJ<-vIdmqE)Rz-6VNk;nCZlni(dzLg92_kkvq)4~f`8?r{$gs$ZSb7^29p=bxV0C=qVfCzpf&&c7`d9wsPmH3iL9~qSf{59f~O5Gi(Xmdlv}rU zm17Rxf|l=O<>kBnbuJ#c3zG}B@n{2;{yJB>bOwS*a9iM5QOIGbc|NbklQ(Y(ZgwYE zvb4e__Pnn+Ou!`adHUz(ZiYlc;jNi;h6v*C*4Eu6i=}-Bvh>jj^H$5cnEXxJL460c zzx0^zXQ~Pdef=I5H52^YU%Fv`}Yb%j}k|X>I>oaq7=a`Nt8w;{SCF zCOnV7DTtC#21=*|oJbV66s6+T6_L%8`7s`+*Yck)Gi2_)oDeX>&hCrahfJeg|)6Z(6=tnF0Iu&hUnU7&r`q1|DBvbim(Vh{LV^Q619% zvoR^h$FSiH2^o3FTBUtBl_qa1a_2wQtWs0I+(-3wz9&L&b)Np_C8KF%Rv&&mEwNd@;lkiHI93VaM9lXyhdZ5==V&f6hLvZp0u&c{TB@mD1KcXNAgw!1UwPchm$r2RUZmrc_M@=@DxW?h?J zUl$kfdB*1|O?M~p^!*@1PAHH|^p3J2oG7+)XsKRdDD#DA(ittbF@yAcwOBMji;5YKE@>rS7)RGYW z@Z2F@kcuW)b~ab;oN5?i3DeNo5|FFo7*$pucXp=lZ@JZc&f1K!ZjQp=w;D=F-~bor zIbPe>TH%>!?J(8qxod>7S!7fC13{=cg#CGGut=dyIJ{2Tn^5+DW~{H7t#$gRE>0?r zb8np(dv%x&{Y3Iga(jewo6LVw77A{d1H?zJ|JJ`O1*CU$#_9jA?E!WZWuC|ylxzxZ zmv`)ZW|7=83i4_>1{5d4asn)s5~wSt2ox>}nt)b_L@001$#vm2N^dwY6Zt>L{pC%_}q|lBf&dS4t5xa(ni!jLQ*s(UyFk722+*6h8 z$qa4XAXM-A)_H$}`?qXci78cDB$IT@LIA5RGG*@z)VZErEf3AgX;^qZu>7yG{S=4U z3@de+9Cc9mxzu*LeRh6s|3bwYe5N!afbT(8>iuqKX2gk z3T4B3B2*Vsmb;l8CMSuz=|Y)ndQrl-RlikP&tP&`{VQXlMwpBdg=M>G8?yK3N=YCfUqLyoy!8QLv6!k*<%g6n0Vn_PtLIIb=s~DDo>(76>Yw~|7 zq;ZO)`5*j+dv&{8B1fXD%1eKCxxhdL=5wnvpWgr)nbp-`pqNK945FKEy)>I`P+saY z!|Avd)dB-szQ&LPv=Q1GYF<)BPksD4i!(;Ah|yb|>-}0w*^#!-v~-U=MDAe~m`p`Q zYY*L-LB}wm2vIM@pL`26Kl;bsJ+2+J72UYxNN8p4c?O=~UR@+;O}FZ@i@?P+PDVK~ z4^s?W3M-;y_nki}#_%8<6FJThD`iBRryS*f&B>U8aRL+~6pWco5DDoSOFkV-=39 z3h(LLUFT@a5p2bT4N3ypHpw88HwGOF9QL&3nkIxo&p?AWGb$?ufkF)LUqZqIJG(jrINR1c?Lv8r=hZsLGS^atf4bS=Q z0v!+OerxDohngbyG5W|Y&UJ})?}q7h7MzZ*r2d4CUW3VaQ-`OiWGiIbr!z+yhK^l} z#A)c#$xTc=KnX$T5lG`2pY!6#pr1rUOt~gB#vMnEEPRzt6XVRM1Q{OCJfuhM#2Y`{ zpiU5J#?C{9A1(yCj^uSt5CR?`7Mpwcf}THf=rEJx)w8%_xI=+1 zcpa=dd8sRM)M_yGIL6b;2+C)^59y>*vR|yv39i&0UCG+JhciqKP*PdF8Ci9n*}y$3 z*)!YOgP1tS#~9ZBbe!(4s&nUBh)zg`*i_ET-D;|@50$`SGd0#g8P#puuA}A=ap#m3 zy1m9%*}U5~<~xn81-n%PD!%mM5er%~LAp524QlT{xSSj_5t&2LYEb$DE*jw89%NCN zub@^!7y$-f@FUcl?vb*1M{^rhfN)h zBVmQh!+?uxRQ#Bnz1)ducAd%vV*~Bn4b|d^t$MKYD;jS2sd~72Rk$H8yJmDjO{H~vPz#QP+{BzkGf*u?oc`77 z&Y!9HfU7m975e68O5wha{az@!7LQ6}sm@%O(U8#yg-75>nPSV$etAvj&hFNs~01c0$MjP+tNhgV_uw z$C*wOEdQga29ioCFh>AUP*gi3;$pptM97p0CYOpBVoW0YyZJOmL=?2%GtFT=0Jo~j~<;OKpZ3`3Xeiw$P|m? z6o+z4)9THMO4@Xmte=GP5`K+U=tz$RQmb5Q@=K_WC>?myx+D{>?0Kl+jR-_D@}-NU zhw(MHuy$wxp$uUyqezbw6N(8C;%^Bms9n_CV2rE!c2iD)DKWj^3u$;bPp@U-yYlO@ zl4#w(G_yAl^vvn|zm>9l^|yw@r! zHu@urX9HX4ryhnuAFBCDyx)mgZ#Pi7C%-QaX?4*H8;iM<+O1otSt)5|l9R65_jcL@ zSIQwlzv9On-jxlkVky>DZlEnI^?kbcFD3J1O7z^)1vjX;MQ_4QNi^|a3-C-5+=^`K zD^y6k5<8{7*9gH{D={Iq9rx<{-;7%Q+^p z+9D75fRPakPMvFQaUq8lBS_=|-zZzkE)iI;K&o=1WuXX*MO*~LR`uS5f_R{auv$h| z;5g-Y{eroQO&p&jgbs@tIHi6%quwMV|6gIJn0`x2>q^XxijXu&{fDL4KZG%Q0xO;S z!R-c9v_OC-&CPJSJ~vT{Q@?5=kFxZ8AOz2U^~~-#>%xt8oN~OR38mufFXF86wn}}A z1*gn4H{GD1;|oa$?nMqoT;QGCa>9YHA0<6`Yjac>r@?tV7Sw$bk}q(yE@;gUh}~4{_8IL+iw@qa>uOFdbRsS z{?KxzDc$6uYzrPa6;b`)-;H%`ot0F!^o5oF#fY;f-ir33UV1D?<9sFUtBq5u6KbKQF2D9H;MF+oMlU+u89JvG`Ue)EPcqr&Wg~6*T(oL^)*~WjZj=9=1rW*NPnf2R@?)wFH69Z(pLM3nq6wis53f+eB)oD>g`R|Wa z1xVoQWrT79a_l4mn#XSkumg&BLrH7`$%nIGD@|4IM<}OH-)(4Mn@Jet7O&ZtoEfg5 zcYVN6zi>e$6GukR&gIzJ5!@<_OI(qxYY*r&L}*t8=-QJLSHuaeIOVvfb&iT_qPukM z1gP#C2oi~KWZ~JlJfuHyIYYwr%c_5052CmVj+S5`k%_zu#aw#SfUmhhw|prmz7RCC zSgK{f$;T^G71o4$*O^Y1DGT{$`KdU0u&^4X;9@aMD0>FEeGHL{5^&_}xia@48LvF{ zPH=+3X(`CXDaWfCP%7>hB8K3kAXO-QqqNAXB01TnNOihv`-7+Wq3mi9vvgX9;z({S z|B#?MYH2btzOUmyPfFJ;%upnR8@}oID5^t)lU-jF>mN0L3oDK1H~|@AeHmY(@E2zX zQOrmr38o(;P~Le*yO+m+u)&uH4~MqqrD+zXqmWdJ0L~Q{xpYZB!)Kxa1Bdl_26u@5 z*SF|qs|bEt^$vXpU!(YHJs4UCs)?;>-1>gfVZEHgfFQu&a1&f4z$-Ha?31?m4Z6t%`diujC}ej*2&{< zK{CIUiwB;p+4ZvZWhJC}iO<-c4EV<=S!g|{iqwawx+{TONiRQKieGwa4V-!uMn1_u zc3t^ml~AELE7NUJa8oRG5}8kav44I=t{|t#IXWcYsTq|0ObiL$%7Wsx9x`DPiV2Vr zNa~3|fpuwF4k1*YuME##oGBDP7y4vPI)Mdy5r=CI0XQTK3{Xi!Saei4mcerh zgY#bbAy{%}Nyxa+KRPD#>xzsgPNv_s1M8koeiNA^rokzn3Eou}u3V@M6`R zx7mKZ0mx6VC`agXd7o?FWlFvx4kw_D$n|U=n3=?QL%1EU^5+~w9wtSJE5D!x5#g6| z1^TS5tZ`Z57g0oxbXz2Q7BwQlbBpSaQ}Ae+x^zpos#K5n61l!V!#?98Ps@)_cTgY) zWF!Y%Bh_BK6v4oQa7G@3|4zX7DMgfwX@uK=VFa82g$e;dhv$5MFtRJM3knOvUu_^O zqX%OKAsgj_ufK%Ci)m}?Xz%Fg?1ofiL7nRxZAV9#ZhL2^?BqoOpCIIQd{gM;2?-2e zJSh`tW!Jd2))gEAGAq|+K@j}=9*IF}$#0Cz4bMK5-&1MzOe`vQ}Om%F@Xky2B*Cf}EL_ zq5c^Jk}Au`vYN@g^pA*%2V3t*WHZVbRh^6)cUw&0^iNWk^JxV?gq#fx+YlJ`tWRSn zc-F|{#~SME)xAYWm&Y*?A4nw9MVuK{yU?GR_ z*>^QAl6dOMdeO4gA*Jd}_kqti!iY?w`sjrnqBmy%J_X$tFv3Kp|$rI zG>yF5*&0R8$_16_R7(asb3X|WKsQ3I`#v|Wt~%;=EzV2OwY0qTCPhi=+OTLre0j>U zmls+SySq(^jq@zD)NDo*M6;?E=7}6TO~u%=^jfssMo9W~8ExZ&mifB#J#zx6);V^j8k^uWM)VD`V4cWVr3TkN;pmme8# ziZeqXJ}^Dd9xyeENDT4z}! zpc80?=nvK*V@%j8965hl>*J%lq-@)ywx8a)OWvh|J2orrqet^{Hf;<^@4nl3rWJhI z3MdOXVHpRC+H`yRnETg=+P7#19mT>d1(lwcdz2~e*!EHJFXjB4$$s-Xzp>@gDWzg+ z14mlx%v}R_Kfo0i75M$Q()`i3isNLw1pd5Sm3a$@1+Eq8fuEPcB{&^ju`^PL|62O{ z=~uaqtLay+h2u!fHOe)pA42wvA*9+O#eO{cYBZKc@T@g{{5CE(%JE0cGxOvdG@L-A z1Rqo$8$G^fT6r*-LL=Y;KMhr)gz>~Y@H775Qu5S5{$ojKM0=(Z0#Gg$(YAWV1|VmJ zK7G?+2<3`qWX;f)ZXoLqaBk?(Kd z7n{`3tfEXqMpv7-S`9ZJ)bv*PACj92TnU^55&Nk^Cr>|YYA0rrw@$3WS+4487QSj? zE18&SY9H3~oI>jUhyzHK?v*2$RZdOUR?^awGukuKlULHNH5I$)<|K*k{|PgC-sDC{ zK|Al!kfnI;73fchc5f#{8~8d|qu=^bZ;+t6(dor3bVk0U>V1lZgf+}_kzyir=~Bz@ zvke@=#LuAxkOM;~miMccXeUtC;_1;k2qBL4B#(Dbk)W8ERX9=r1Nnzs0!{$ZO~pLd zMGy#)2kpkvH%&F!tqtbIZy0#){7#>i(j;09ktK+r8DcWqLJfmtC=gt9@rpM|0Rbm) zS`emxKEoW8B>U~QC`iOc8i?>(q^&)>o;ZZ-7Wh40OdHYWR z{Gboz#*l88tLNm34<3*yQ(JrGNJLj}{}~V3sgf%BqBf2Zxw+=2LqER3U|tBdtqP%o z9Rl@NG)11fZ%D6Reaj?VKYlB}itRK0ISF{-wZc@n6!s5)Cg93bg==9iAbmdW>yO5w z{=VZMBM=QUAX0^w(#ASJVWYCyRNDmWJf+RcfSCT|EI}Wnj-)>D)%jAcf72dh zSem1S5xPz$g<3@B$aHiB*5)j|AoSC=0AvyL-CSP0OFro<{4R<>e&AxFEOz3Yh6BOA z9~I)&iqTEx8FFKgy4km=J^YMilqM!!Lsd9_j_z zzNQA82(`XLW3)oYS)^Vx+NFo>1Qr^Ba15tSm*uMTEp$$m+oj=?d_BW4V_0zo%{yGP} zLn3}bu#+>x-}T>%^_l=HbU#+opEn>5=a`_lD`(dJb%EI>n!#$UpCWs(qlCd zzR2fdxe7+O5y=`jmZ%XylM`=U1bljyg%ErASY>80xPB#x`*}DzxqdyPAslt*)I;RO>Qex!pYl zf}1Sn%>qGp508q4PPcJQ(wA*|HOa))xWMcIqn zoG2mM!e=j~v%FP`6#I5iR(=u{bb+$+?Wy)kg%{}mMoV_?1Yv|&1K+KM=rf!Exyyj& zbS`%D_+$tnqFkfQz;W|B7o$0b8h)?V53ks@0~7#eMzfVF6{!}>OZn{r`9fs{D{N1( zS0OKJNC%zZL>IS-vQ->fV-hc`w&tNT}VQ8+#HRL*@umk-R^96%kE&F<|TMENOf=->Uu=Tlx3^myaXULTA z@1ui1h(nv|!6}ZQ;-Y74*_4*Tgc!t>Z|EO#)cfC4$Om&0YEp`=-#;|W=iDCaSzYI2 zUciAN(&#=+&;^X=|N1&V9T(+X&Q6R$wn@kSf7f7vN?kmF`bj`F2wGk+#)>}71JcP)dk$*3Z24`o%=C4ET6?MW-$xsq(W1BMM zLtGt^MB=^6`R+L=0J#Fgx6ieEF%pTW;||GlU{q=AVv#!B_CsvHZGQO>sOJlSey*)J zz$+()hW@mqgDbGbLCEOi4cqJ>O()=^#Z92;eod?WZ2m7V{RfgBf7|hJH_unr0L5T%GW$%u49DM}I{DkcwwUN`}u!C(I z9`6x~JX&r?mZD2fj5G;NL4@M=T17(x7vI>$Bnb)~qx3zC3hCzzC$y;vd@{F&m3{JH#LGLaC8??aRcN!gOfl+b2`&;pUGn=(SRQ|S##D~w!s-HtBdBcsxshhmK#Vw zKghJf)Hya;O19e}JijQ4$X)qlQk(_NGPy$gUh<15<13%PQo_{O#AsBm)l@sS2xG95}J5P6tOHpqDe zFPbiGS4^Kgm}8nWs!y5qF*##rK*7IS0@1@Q0_8{FwrX{`0xqwBZm802x(rrvz^co) zv~S7j1w5`GSEoI1t31_+HddZGZ@Z6lPj;`w$NOzd`LR;>ag!t}=Co{fn$bEpe#)ApCZ zf)8U(H-Zz?^&#QbRDJ5mSrX;!_d>ZuD*RVKP2!q8`56d1xV4Vev21~kV+wr9S?nt5 zqd9pCCyh4weo;e#Av?)bVJXr7(EX&h#^hi4J2YU*1AYHvE}jcGi%CK(k2?Xj&fk_G zqGRpp6H)341L-;j`0<O3TvI`)u)^y0@HM&f zeU?+IfVAD)2zk&`wr?y1azGX62*y;OBL5% zWb|?jrG+M%hFrb~(bI%RXHsfnfn-1+9BW|u%zy`{ydekb7yVqHU*i?3CHDX9v7BIZ;C(bC z8d$PNcIqAf%6{kQFoQ+KAX*@$Ea}O(=f~ zl(SiYi9lW!lRLsbUpFF&QYYmKX`9W+f3c08^U<|I&VRW*Kpzc}AQtc$p+V8L>$sMc zQJZPP+$43K`QGE#GXmN;L0hg!G+;0Vg2d(BVJ2T2+WV?o=z<^|G?Up`SGEKV@y=f$ zm1pUjee_Fg5uJ6U3+H)YZAqF1%+ESp_}$9|g6#5Igc+3I@nnl)9=FykazrLqi1&jN z3;jvZ04v(x*4|Dj!QP7c{3QRDHD{hC4(aNP;LGZzl12GxF^wDNd+c!dL|b^m8Ib3t zUd2kQR#+%6sFCT|H*?pYha24G zgewHKM8C-Qmymh{5lVxv#l;(B^%X3%`8Ee;cvfX!09QEQwAF zURJ88Q7yP4b_~L^RjfWbdKqZH;&piKmS_*K&I-o=%P8Sty{-*(zMfIBb|cwJk}DyELv5ux*bYIhfl%b)1c2WBPpP? z-nmAeAjUA5QsfIsXh&1Eth&KHzC&|J>q#)6ldz^x@yYg3&ELTY^ zjDCExrG6i!flqyB6A9t@t44LvN&dDH6e|YHMJzUxF%s?A36|J+bt67UV1s9WUL}`@ z4iUtpx~5#4b9J-1=WvM*SLJAAL?)NPBcEhW^0$h&i?^BU$VH&d?8JSC47o*6-ofNB z89n9;gdhe|swXKJ17afM#(c*?GN6Mlw#Mp$d=7$t9ZWfcR>H5(H)kX*l>}Uy`y@?y zxP(SW8NPao?P7I@MCfjSDtn5f=&4)-UGX`V@#=#{J*be1ASS?#4_>{2#6evPX~H;? z$_sFtn35oTUGK|4=}l_97<2o5c!5w0RQx@1)>IqgE04zezVb9a$G{2DYQiksrYgSS zVz{(~>l*1UWb~f^#|?C9KKYMwI78KPyVQJV@x(FkWfNoPDxU?8kdXQo^W3h?c238c zL#B?M0Ifz|L+wRKc#fLXaI0wOJJ0AR1!4Il1oI7O)o2rZ(UBG6y+d#uO-oJPfKz!>>5+d*q z+!Gy}B5{?X`~p4D2lkh71h$JJBgmJ?S~0P>B>&$cUj>F(w7D-(p9%`X@)1&{Tt%r1 z4Wt7F{3ithzD<*#FJBx2gQCkQHU;)^S|yBYkbJ)`KsgPe^twTi~saQN^T`-Oj9gUN_O$fZSJDikBD)t(LWGBd=Pa|5rB{ zsGbdwTNTE#a)S3AO!v0+YuAXovmzQ6WhYK`A`~53sZ%$W7vN~v`qL**o@VKjKKiH$ z#oCE{MY69SSJ?L5w6--x-trwga%6mR_VDEB;aA3|W?#0z(f>qgA5^F4BZ3#K1m)P& z>Ye`VHjO<8_s}#lPpJLvw@sTODX>hmh!!@DKU*BM=IQvZGpRlU9xQY!8tuNlpq@|v zqD|YD>5pK8To}xrtm3V7bvN}|A)nG~9Cm1d*4dHCdq(mfLaOT<`@mubreTF~(RC$|ufBmU#JLswYptjmGG-NcaU^53Cf6ISSm<8m(FTs-tg6agR zSWrwFUhfIF9+gvxVJ6K7^{@2T=6~@YPj(s!@}7AtU_$&Bb{dw}yiVx&H~;zw5~7=IART!*Y94n{B@_N5{f5^_oM*@Oa)crYYq_Q~<^^7m{Q0t~T)ygU_61AzEjJF{|6YA&?2`h9=85_@04-EL zX&}vqhco-$Rd5BAH#6C6#@n&B*Y_>GoBYRNzk%kv-VHVamCa_dzv|fXwO_5#RNKmY zwKO*ED_|@MM3^$4FUIz0HFg=e#%3rOq`=~Br%x+gdd6k-@}aGu7!>j;D(G_ZN7k5L zl-U!#b1i{S#EO4%dCMnVE)cVJAL*FzIH)-Wz+w>DRO%2`qb3i*0#bX&-k|9kS%x08DX~6DVmE9UC^3d&sCz8x*V+qGV4w zY+&o;KmFu}#r;K0N%xTmE<#C5uw2MZMRq-wSSrr3_=o%q=7P0#&XFivuG`vsxgYdS z=*_;`3bxMFu<5t=>QQ;&oncT|$VnTrEj0F!X0cXRNWN1hs+_AGi?Cdw<5* z>(>uARwbaAD#wAjR*e16*SKDj-VQaaTj}LqR^|(7!hGdr?)h!Kw@)lmwgv3O6mS55 z7N470yEWRqe_hX6D|F<=f*lh}&F(!bfuS=ep_1)OGcT;jaV;#TS%`v4X9Bbak}Fo# z6XYawwb!MunKE)}6pILCYJKu4cD-_1>Ha*g-fBs!Tks1nehMtR_)Sev>PK83`B>0$s7aiH2h( zSYJOXh`z9J9=qa5+REFXYf#t3Nso!6nZ>X#$(u{lF7$T zu22nAtKbNo88zbDT`DxPX}T~n1%0HM54$~cK>7FdR66zTkKnhj(3l(sZz!npQN>eE z#gjViq8-o>nEyMMr=JWc@K4)HU`8^q*0&0;GsJlYzXsnLKpAo-^;Ne6#@2^B^h%e#-YioWW+L!A}MLi0?j*&x+=IgBP!_M@o6G zc{w~sao4UgEpT#(emP#(RfCP1>A6j&Q=@0?N%SWq06|BkES2krWLp!{N4vuK=6WMn>v_b&-+sy?lX}%d3U5Y9U@GwL#E&g4vuPk9OVqtTB{KM)%5Jsa}-e z-!mbMy(dobn*@s7-#_7A^B#dAX}v^N-|R=|f~eTw&m1n55>A-rF6`^TOCK~=iufG@ zE_+dBS`rz;k{hsi?m7czP zt=SU^o;qDtnxAc!61be6R+Qr~Bxpkf#8i*^@*-#ZKQQM%TMRepDZ(8|L4!j{SwP8D zm{7sjJS2dXIjHDb8VMV+ln<}^wf6l<9)$z&%=d%MvMrG^wjE4UIrX(BwsoZH@R84s z{)}L%VWn2T73uBwuNRS>jk#L|<6$eWK>TJ)qrD;>I9xOi1p$jy(!`#GHO34UMJ`m| z)z@vx8_2cJJDy3kwJLv~`)$cMU!@czxuv9zq#H<|Ktwz4vz-mV%&WdXF~Z=i!PbcDZubfbt%sO2qsPNjF{ z4YHhuQl-(`>Mh|CIbxwt_hA+;P^zYI1t$`qSu3lOdhpDsvo=|-QtMfkr3}?`wSq(^ zQ0yk!)e!$`=~jplwxSHZM$9gh8kX2=?aC~0NGfwll(X_M_vK`Qr3>| zzl~e><7EUfmgfMxPxg)Vr+M9H)yxJdRR~ff2}uQsASmcQ7x`Bid5cQK*wb-gQcd?= znBKE*5v%o zD?f~DrPw-J0*iM`D}!|C64D+*;Hljd3hUQ zaKv&RS;l~A`i9t8>9N=ppRt6f%w0<6qm;+o0tDtYDuoRS&6v31+_AI+qFnQD*Ed5CNmeT(#nFi z45_AjQEIFWIi&ErtKM@@(+Ao!jnoqcfC%faNdg8apQZW<1aLsTnqC4rARjMvAck)p ziX*($fyMZ@L$xHIwVJ4dWlfa+u5Cj;={v~f$pv&OO#}(zaqoN`&1w^bFG$M|%9zPQ zHF6r{Itnt08$CtF!9MK;&1j2OG~y{eZ?Hiad`x2BmPx<0fo{LK@v&HtBpulGPFZoU?j^1VKK6%-_TYzo2OP}bbW?4 zo=V7r{s>gTHW!g934XFR2&(xO8K%mbEf`dewj^3)941dwtEX>ZXk=_+YG!U>X=QC= zYiAD!8@9oWA>%$X>L+7X+vALBcO7*s#64e{iei|hyHPdimhHIQ9I1b@lW+Aji1H0q|XUe@XGTjY07ZJAE<-UzJ8F=X&XQS5|G+`#4;%dX-6(Gtz2ymD)RcE@wNSU=z)eoQ0Q@|99u=Wv#pOV}R)pnCF+jKJWW8`ay%5>c!WUUitQC!{QFWcE1PbhpE;- PaXo+be{0we>31`C1)00bZfi3|sW4Ge)Y8+vFJaF2oire z6Q%w*9*@UcE$Y4k+e^FZm0k67gIxW+`kdS|b}&XiMSq7>q)bYx2$o>!2#tM`J3!Of z-6gqP{3N;LV!d3FCbcw|CKZjqK>q{y!)|_X0IcwQ+DtC0gcbP84|}u$I@pj*3Huz9g3@`{>+yd*6g1KS(89qAp8!=MX|4OE;Y>cP@cH1c;ddwB&%?1p!gJ1o!rlpf(V^pj0r~kCH=* zWsD*>N^(e{cTvaIu3C46yZT&|jYrl}ORRuc*a}(a0EmPob^v?@M%l{tRjY`Hq-QO; zWx}d0etO%zeU6aoHM+(NS|#i;|GU3e^N}^VyS6T#QHYFX5HiXB>zK<>wcB!b&aoR~ z1Lg>j01-&GF979#J&Om>bGj7(Hhz5YH#QLTb58)iUH9O>KTh$L%of0nUg$XVOsuMY z_ZbIlIl}<}{;GojfOcD%=iu@vX|%{qgJ(_ur-nx>OOd8py=BJjbt@gP?tZu*>%IL%@9#s4EKSk6fByx5W|k&HtwtOSyzH0jwYpX}diyi( z>w}97t)jL6FM9rS&s}%icFRZ3JK;(D?6$_FQ42ZXkM+2{W^MnL7oIUHv?m^Sy?M<* z+Eq=7R30)`Dx0=%523N!~#qE^`M%ty+hGH2Y%l%#!bup`_#s zFZO+@wiB3N7lLar`?*10Ejn&-l03!clCA9Q{H5j9OOke|?=q5UO;d0b_F@+aw+OOB z1UUvUW+1W-xX?%=d`#eK`DfP1^XEsxV*0Xj{4r5s&7@nxl$HrA(~qZC!o z4GnD-jJ7r`hJo;Lfy||St|{0&RYcq*Y(txb$sonpdjRaXoPm=7cIVvQ9iz40bnj_C z3DXR4>O`e`{sm2rP>|&T#NPxF)klYd3zeM<=KwCQjvCw7pPbUhe?KM4aJP!gJ0VR>p2ncjMq&9jfH1sRUAdUU02X^4IL=^R z+cK{L%09!BIrOy$7-JV&5VD;8x+8>hM1}$1oxn^I^O3NCCo+@^Qa)i&t|})oJ+$RYib>jAC8GoMs%gCc z8jAcL#OrvCE-H{Yy%XMlS(c1-namSrQIPI`bJB4OR6VJPeM;DU304?xfR~&39Wx?IV=^t{xy&` zFGGCucm@|Q>A0}EjMUPpCGR~0ko~ryTC!7ZUSi`~bVMk~^&EN92nrfQhbEv?lhCCp z=+-p!Xa@9ZCiH36S{us$M09!oHK`*I{4kdTe5n*E^%X(Y9?$Teb*vlyFa;uOi*-@(-nbBvYd( z=4N%|hnrla8{I&gYF1%ikad(dj0^D-Uy5yrcG}$e&gbn%eB_b<~mq<@I1N&^pI9P`Ah(#l0W#<_tW*URku`0uo?KPRM zFrS)<|Esnhwn%USW}`)uYhW(gcwukV4G5A2^pG*q3FQERiM4ltlg@NY^x40J>r z7EKLc>43Ht;XrUxb4h`x1NvGz1MCwaF&Jh5(RF}vCL)1pq@^0POoNtd5QR%z*Gd{g zr32PlL<7MsttADW4%lmv11((BMz)6OI>0#-xhPV&W&qoDfO{tA4-{e%lxLxYTCx{v z;to0+q3%2{9w6|}AoI-t{u6}as3=*En&r|I+o4-Kh#4Tw!1FmLuw(_+tiYBP*ewNP z2ADJOCFdmWti+R*c(W3prQpv1!=GoU@q&Nn#rB6sZ*;OH)`MDOWAr`D2C+L?+^r|L ziU84^0(xOe4jj11c>uEl!15LP{&E24GN>S-HJ7+IslC|r1lS(AqI#IhHx_2Yw}sCI zqc9%D@)%|)r1%Uxly*N131}dJKiiNG(@Hg(g+eDmVrvL0Oj{C8VKM?&ITp1qC~=WK zlN@&ts0`JLMETNEnGbQvqy<*0`Ow%fn&MrNJXEHj(r_0es#n$p1DQiJ&FNub8mU7O zsb)P2lcd}s4@%R;>D?*ItCjL>JWi3GkyDvo-&j>0E*9fT%PNsmiVi19B`hjS@1|I} z%%h<(g^EFOWjI0jRftj@n`MoTsmTu2qQp?URH~u0T8&1;6LHH#9G5nh#q$KvQ=lA^ zLQ{BwrsQD|1f0Jya~?j=U!c{lJWF+W!WYk)+}a5KbRwWrDX%O3rlC4wkr&wo$H(Cv zu%QK$4b6}5G51vrtEMqHKe2@z_jjX;Civ>O ztWZ!+*>)@$a#VbXF_h#Vwo?;eIx(vtS?ETzN_2QwBU$66Ezf=gw(D`J8-E? zNGtt;k<(-^%n*ZqF~*GIyJ}MO6Px=D&i*v@iBH|a+9oB!Rx_FYi-O~Jge6VCnral+ zV!2uo?J0o^4tgO74XH#+J}}@sm!N__U7aofX-J4A>m1bu#T1s8=oIwrF!!6{aq#_+ z7Jzk?dDr3`1WbqQ-}=f2o@Uag84%VaN94Ui3q~_FAk5;sBm4=Y?uE+GM@tRH_N0}T zNU1Dv%v(bOe>xcio<>Gzl%tT=8Ce4!8{WJ%kVgK0$ODoE1Is=}_-D6i zah{`b=aq8}g#&e(c~`qz(q@r(`V>S9V0XOLWKy&7pI`zRnfn=lg=Q)A5ORRME~hy2 z=QQ-7M*;i}5*2?>_V4<^lh`uk=w>o2Xp*(!m;lw-{THnD2@cICR~ znv6-rruNsuWS@a&CC5-0pA=_~hlxa6f81KLZ(lJtqGt%TtPF}b-lldnlXXjvYcz!` zl04%=jL2h6);13A%T=AiT-{qzXaPm!Zp8;D+-iH@rEC!#=P3w{JkN2FfbKx7rl{AU zZs`P*F-oH1^fb0JX5Qn|KZ9+b$|s78>#DIi`=G9_aq|9mW=#UY#hCX9jgFFaYCu+K z^$N$+#JLy|)-=bi%*mCnZxdTcTpS8*;lTQnqsnacNSktCyJe(CUR-rs(YB_Rvi~FL zpkY|hiMABD$??|LeviUdH=Tq2l-2DW#zvDA3Vdn!8e1fgMWp4B568c(MwWFPKc}u+=n(U}x zjmh4d6jaA_T?;MpHnRbt-Q*3~$1um_O*@g65Lsi@sA?#7b>$ug9Le|SPmFTG z)Hya`5+mIti-0A`8N3o(PV}Ol-;MP5V6Yj(nLDi@Fz>$ zOu?l@Ny;6?_gCTR6Xo16L@1Kw8)HX6(};)w|Cj`OSvv~dnf4C+J&)eu9mU09BAA$< z5E?0XgA3%5&%NEKF8hPniza^=5;k_jHc%nJ4cXlJ`Sm{SrqrqR0x> zDPH_<;#wTl3BzZQ9|o&#TPVQ8(DCBI0k*a+o%PD(zO8^nuvrRn(C$h>i()*VEgqSJ z0IhVuvnMXUAm@H@RP=q~Ns7su)&%vo_0CXu^8X%Crb=?9qWhGL#It;hq}Jhd>>B zcN}IO4<_kF$u4lu;7B6WC|L>qAYNI-V&(@p(XZH*Go{xTT?iJKtTfKabVx8Zn71Zp zIl8v|<_)%m5(mRtg*?^kB`TnN39Mvp zsita4HfNtyv`(Q@lgF!}buzZ_5Zr@>?Ow?>ZmA02NAu{_idf1q;u`CU6#s@UKqHGp z0eFxPE06AY`>aXG7L);kY*Z{f9}vx~y!@Kc#2o{@75>QEjPfZ4`Rn^M=AINllimBK%sda=5@)wu2v<1^xm>-+9gyO8{5s=46jh9%IRFdT$tR7fWdYFJ2&{uXKJN&%Ts2 zBTnadCM0jMk7;|`y-`J?ep+fM#JB?kgFLlZwiItMl5xQBR*{SrEv%yJ<5EX)P-M(E z(He+^C8syzu4kr-ap<=W9g5aD*;o-)%`&lLR2*MDMlz5UK3_&n1LI(a zW`N0dnt^~OZ97TS*z*sZwo~Ff?-~@X>6!!<@0G9KyM0_TO}Wc`}K*$SwD|I z>K%3zar5h@*SzJvLAnSvxmO9fe)QlP4WOGa4=Rf7Z;f4%KHj)`sVTZY0e0CDY7+^v5vH}{W@Hh+tyrOdqo-eQk zNu!Wb7RD{Zlq7(97>Vwt6weC#~rq8%5lckCVnxIl5@HZ z55J@Ah?n*4$5-2sxY+DzFr}cGY)`kY0k#NNvWv*)ImV5vb(d||5~CLrCn(g-uu^14 zp#_l|=1~@H9VP5Fx*aN~(@;qWiZavY*ODCD-}FwYjrp)a~Q+ zCYif$u&X`xsBeKng7&WRZL^@knU+D6=t<&q`tygUVhFZ=cZl$sqb=<_(+XOx5l}9z zX(}Z+uIP;F{*l$1dBb<@woC?OCuzn+G+cvJ9KSfOs%CF-g0if^d^`uy1JB~78|F#m zo}~1wING~VVrpp-M9i_uurKMzydJNG#$U2C|EXq)$%sq%6DD(>$#Zr)`9HZXo<~rz znHI5bLhLDaH%^wTCTR#~K0%rwt-%sS)qqqJ4~cSJtpb`gPmP@ra z%w;UK)}{M{BDGUGuuiPIuc{XKZpC%?URMv&h0M`(Sw02|4PBCim1&nvsrj9p^jqQc zs>9B(AiP(ldJTTK66Ze8_k0v~wrJ)l332029Bc&J-P*@wZz)bW_Ay=}A{EY6gN+}WNuKXHOD;Oj(t{=S_}v9`z^^@)AbnKyFkk>qKb3I^FQ z9wrFkwF6|Qvw_gYpO9qb9HvHSj6P9MO6BIw8qwp$V~lsssX2R~anVU88%KhHA2et`mAepNfgsKF?X(&l%e8)( zBYox|@wZ<0_edMwJIhWxl_l)1UU{m{nf+BD9hVvB0XsI;ZhV&pGRJK5MR-``6D7_2 zz`OXS$A|%MbS!i16JMu|{n&WAbB4)o%DTqt0*$L5OW94XTAUq_gYJG;Q&3QNp9~k6 z+*iRC_j5eZG4G2}($*!yZp({oZRIhzPKk1>bhwvo`Uc*|s=w)&z#HJ}WDe)d`0ZQs zmV5We^*Aze&C8>0p?jd}U(k*e6A(_Bt~{yP9J^lkZmBCnKQOmHj)+tihCyiU2Y&ox z7n;TqXP+Uz#X8mT!4j5Q1$We~W<6z@s->vM?r!vlHp|LjmHT)cLTNi%=h)WJg(=Y< zKd)EM@PN?2zfMfW5Pf++zZY=?B+>#|s%Ls^tV$JFcg@gV+qEZeQD{KAOQ(oc#VZiek)tA?*)>IOoC#YP%)&Cd0fA{$v5 znd>A{NLj^y6Sdg zg^}2uf10~~g07v_U>Z_;1w*WOC!Aral)ot>HZiL!C#%Xi=6iB`KwwLaF-`ozaVnqv zKE7O7>D9<@=pFBgRoIt1om|E4Ir;Vn734o>W$>hrZCUAKC@_M4J@+}y&U{zh%m-`E zs1GN1+04)8ht``hs?^!Ku=+D7Wg>URUQ;662)k7d~!Jz33L8x6b}B4X3w$ zbF|aSXdJWYrW$6+gmuZ?spe(c0900MCO2By?n^W_Epu#IRP{R+TlYf(5f-WBg7{e^-%R7w*940Ie^WM~n0vf>sgfGr!Dgu8_idI2`)Dg|z(Ie;iBU)wk?}ZO zX3{nb>?!4RDnM4>c8lsU=j_-|N?Ip*s#Gd)CjPQ5-I6q^?Fc;6GWGWz)nZhsDc1|1 zJ{9ub;t=bVPK?kf1j@S9GEAvNd2qXx-Xk?4-X7&zPqxNr3<6wySSzKh>6TctJK5>T zBf=Y8iDr@4Ex&Ebt_GYl4s_l7^M#5zT}i(8jgbH0OzV#hE{AtweO z+lp8j$e8aWt6xYCNJBXG2X_h}D-iBtk_m5Fg%oPajdP|EDvAoir&J|vxo58tyoZRK z%;#(erNj%g5Ie%B-sGZ8A=A}h`vo#j_5_@CvtT>&*jZ1$4o;T8P_#Dxp6j)M9k@g9 z{v|BHeh#SQU*7Ov8n5mhik*sP)^W@MEPUC}sDUYR(-cljk{Ya(&x@PlWVWmZ?KBOd zD@X(l7mvF^lQh~YJw<5I{yqp;T@;0Xpc$@lpVo;3q;x6e|seMI2@rnu!K%)@7y2rs_ z@O$>Jzw1bGRbqN(a=A6j)zpBx#k!l0tgNo#!obZPLdkbxf!y`x*YCq(T#T5^7N^k$ z4L=^9b8{9HviXs|l9}>|kWmfO*5uxYiwHl1>|6HMCs?k${F8;C-J7_8&ay2mRm|b? z;#zr^E!r|zXTG)#UtLYaO8tXsb$I_xVN1u(Kgmm+2NJiYjGW;Y|s<||X>IX>1=e#AFSQx8-$%7jm? zm&>G)U*y;{n{C6P+v`CCd&EG0zfJiF_8_@^}nfA~#cMGUxp_cCT! zN?r*kPt$wKK#ifAbi)d)Nd`lXv6jJ4UODLYh$fTO$UWgio+HI2aBigp6~o5O7oRCa z{`Y1Nu!qB2V8*v#qF7P35!yBbbSMaAVE1moyu&mTF%I`ah5c*K@_AAKPE zW$(Bn_UV@T7AQ2IEV+sam&UBHosT|&{JKMd!r4rg27uZ;(?a>AziDQsE4&fJl{jxX z9*273#KmE@SxIc)dWURR}ccnn@a$khMsWhB7BquG1_vER&^p@UP)y4$HcmE{o za$W{+9O_fVHNm8DgY|#05eTZ%WH}4|Zfrg1mPoI5gv|q3`WveIlaDQix&kRtMtW}o^XN8ntrS84Y}zN z{jiA%le{J|OPc0m3u}uPXcyw8 zV|^9qdj$OX1N)ab9^OwLrf;n;(PEM>0GGTH=Xj&|Y%KjO>eF^GJGb~$3F(!-s6h&o z^e~~w=0`Vl3S=YAkoyCrOyya&#Adi)Qg|LE+fnj3$&Y?&ZNd$CrLra!fnlsrE*81l zU86ZuBxPt4aGmW5?H~gI9XeOm?CE7rrF8dOXG@nlK9Bb>4;d((Gs_HJed=CmQRC}| zs28{zbk1?=@cpB9t{wh%@sHM=D14E;e73iFL0#e*jaDOa=LOyL(om{8gy#;ol&9SP z?IKrHax&=G9!xp}-QhHVq(6g)3<2A@DQCWLirG^j%BN#QPgGc@xc zB)^^Y!pekx_1j9lc;6dTyRu#p=}`T?B&Hh=J&gQGX+zrR&BXz5hNBJWEa$taNOfmM zzddu^y3XP)QEw+p(z9=0b2qM9Rw34_FFne~1bhvIypi7#nQdQ?izOl6y#3<~3L?Fr z{8K4gOL|6|vk=aAaK`2>=}|-jcR2eb?jMtZ5Xj}pBkGBG2AU9vRBSW4XrN5tmJ}?A z+4EVHVPiS4_^-vJ`fDb_#V`D&1E3AxP*hg_wTYX&+|=LRY#7d#yb-VUEzEFg+)w7vx4n zu(KlGa-10`ZfG>tf%*>dm@2}*VC-ncQRH+QFH`Bqpo+&2XsC(3b`99OmFyL}jxNY` zJdkkd;>O3zNL!&ytX-=v&b8@tgm>=(cb`a}J-^srV@pCo?XZ3r%FP8PgSfV8PL&eh znf~9vv-C=OB>+`a0CO>(R-xT=DSDS9;s|LnB@GQ@ZJ+XC}#&myQ9w?Ir*$52|kBZfrvq;GcoZQg%MX zZjvXCaTVnetD-A4azMnaR(X&!9&oJ@fTCjz^A=p*;qM7y>V~O9CL-CDB4MS#vi8;M z^{MHu44ib^gMsPg>h8Q5JP?@hwPCg4j97uOK^2lMxmksn*h+g{1T1Q0U zF1k;MknBpKpyPKFF&%GHDHh%~H@iP5z$UXwR0kds04T=hHzjPlq=geW9R09vSXpen ziTOP{lq3aq!_Adfh)^R6M|3GvubXD{OBYJr8R<}RG7!$+@2(6+wt<8KMXVW#B?gv- zrz3Kbdbbtk`5zlAr5WO(j>QQNglI%Vp?K2b-40W@?WMmKE2-WwEVEn}Hl-+w zD{LqXSuX!S;qtM>B%2-bJ6AfJ(W9S=&@-jRFizYXpq~$a4+GCKfi2cGg0@m>pJla! z+9lw`l$~i0Kk@_ zzmoP~G3NkHa|2oXFs5h&^NqnBA#U58O*&9@u=HxfG#5Iw>c}cyKPpQo3wp~XgsUtK z>3Ttp>N1Ip4D+-kJrJf8PL{}-nmtAY#zquD^n^KT$ zi-J?&0AM#a1DZ`CLoO~DXK$Ba0Z^|i03|^(n7Fm7=WzX{xEs%cbxXNWKd3rxDhrmC z7?3fuVfuVfs=z(gLLun^{ot+|9P+Z1&WT5kd@Ar%@P{>O#t~8Lk_|mcINA->MU#$XGfB)3gq}{reb;KQ%xDN zzci=^);v{jod!V;xWA7qK2=BD%JCQYRWBA3NhLe9LS}UxAT~?uI z`R&voORD2Se8rA0E^gIa=oNqauN#A(a=SQC+Ao0a6m8~4Q2yP#8tZlgsbOP_WEpnI zQTU2w^@$DZZ4%|hIHWB)z9f{Acnn>~pl>7u;>};08p>i*SV`4y!{8+YqLgx79}?L@ zg5VFsJQ|)DcKTB`YY=t@&BU_M&&whgn!jhatTBE@N}4yUhQNJacqRO1(4}5%KUiL# zM;j=e%bD(w=Vz*=@M~&}nDhs-vw^8;X1&bg$4o%G>vLz_nxiG=5Jms5O8L1T;aMeC zD?2OV82`^z^czS8J1u~iVNI+$HQbLrFwXQ%L95>v@gtyUB6E_jnFbx~au9wK?Oxqb zqqJ!qZ`vWPF#8I-efg4nS*#8wFvMk(8$zf0A=Tdd-kB`ESpz{GSnD1EhD?%U7VkF z$!*w&CVSVQX?vI_Ehn9$U!c7dI+@5bJtW}$`SdS}@TbbeZm2+fv^Z{+%ExqGE)Ujl zz&Q^OX*ezoEprXMWkGZXvJ1+;hD`YYZgDJ`9Gr|>>slWf6>XRo5|g14^jMp^6;#SG zex!dM;E9k12m+IK17OY%o*WKXGN;VW@qg^GBUK`LLK4-JaMls_ooc<;cizrQHpjeNfJ9^em5fVV*Z$(bnA)@`}Q zt>NKgcMeMRG zLdz&s{gZzywc)RGi6Wv9xxF;8ernfV9@|8Qt64`#!?5QMZo!*0j6RE5*l%NMkdoY*04HM#<^Dm(7tRF@I|= z7vFPAcb65FG-svBw=lLAXbNJRk~^6EO|>n_1*~1>)h-O-r$jWM|830O5?4Z;q4t1pLbt?M5iK?jg{2S6S?=S<^ z8XvGQ(HKBmV*)BAM5ItX z@$XV^*G@XV=N@IeZKQ6h!;j%ckT%RFTU$0IAWQj**W^3r3iEN}#a^;shQt|}j*qjO zasuqeX^!f?%CP%q9-nU*)t+VUbC35BHYFxr!xtf~2r1jP%Qqy4RT)_E0jB!1r;S0Lxx`I0V1uqr}Kk=-;LYuALF`l?QRIm0p^K&q<9>e)fV2Q+LWk zsMifj#unuI@LR($@d9j^Pi4pMM8i+3-1q|MO1uGe89uyljLfXLF1;ErPWC!(7np_u z#X_oBx&I8o7yH3-5KIV*egac|Oz8&QR{3=~4AE;1>p&YyDafLPstVm`H|p6AwdPZb zzh<&|kNF`;s!HZ;9V91SH8m&@@Wgf6v@SZ_I~}NqXqdvu9*vsmQC6*5(kS^}bx=KB z)(=ftwlt?8Z{r)(Xq_st$F3BFHUDOdtVgo=QELF>45ZPrSbO36T#)iz>19=gSBNlG z%6BXAg0G%l2%?9peV7dX`U2yIl4L8q9$r#ltg7yxO7Yc_4nL7L$g0HOzkKSy@;rP{ET-6IVc5=? zOpkmQ9LL`??TVjqN+pPDoIJbB8zJ0L_+oT^rT{w1iP-+MQc8Rt7QFD3I?YZ^9C(Vy z$WK8g-$P#6T+TVr!i|A#~y({eUUa=P5(ALO6BIZ&aKxU zSZO9QnQ8+j;u8cmzVhtOnrPd<5sIsHxjdK2OhI3IDDr?^9BrA=>IrzPU(3@Qy%B8e z6G`EDNuvheuH+5hBpzL7ATkXV8elTp=UY(-KBZ?U$#qy&Z-C;ex%mmFBHLp*K#5gq z*N0?cjgR70IUi2^oYa!0En(QNN50u#LsnFZV*hyy-jkdmQPa=pM%ArGB@V7WtR|C2 zqtga)m7P8NjMLLup1-q!gRKxCcdx9)LyoN~WU#z3uTk~$PwLov(-KkBYl8`s zq|TMK`O@08Zdd-!BFN6!3%j|fJJTgbd7@r$4#7OXz~&G5aR~q1xkr9|7d*i9UJ?X$CnykkjixUM=x1x$}{w)NUhaB?zCOnNUjT!CJ z{&S?&k&$|M_~JV}P_wF>)c(q(SbZzLj6T7c-BqGr+9%A53BkNqUKYWxoOBvs_`ikO!7_0qcf2xnYTT`^HV}O}Loo>-|vo#N#ts=HipuAn6n3 z@bw4;VoSDdZv4i~ft0XH^Y!V-50;?>unX+pG-h zgLf)3blOjSh{wuLR@9m{M+1SRd-vV@qu)HUBI|FZn$O0<-$6lfdRBIcVKwT{=zsG! zXS`p1$95^|ncNJdh~JvZu*1IO#=KBv9zjT(`)14Js~gNe_$2r861$tU?mAp^hRGcl z$Dy{fdTwz+iRT9R=LV+GK`o`1-NzT}T zOrcC7{(H~v$aO_?cwEHF`c_Q7w9x)iqNy$G^9D)OE_2vBjOtHP z+s*l}${*gmB}UWO^>^-SZhJh)nT+QNv+(U4e&~Y_22VH7o*oDc2XQCGdEUTsVaV`- zK(sgDId-hAgy{XkEb4;thSK!0Z&UsUgVWv@mctwcKDDeh296q_WE%N5BWCwkfFd0F z$FZgqm@4t~m&aX%gX_a~hI@Zs@>J?7DTVU$$%c{(4T@SO`!xfuV%DP4H9`)cQx#!u zz4=NqEufqA%&}{IFh!A3V0Kb6$TsY)V@RD+#SFJq+Z!7|QkqZ;iB2b-qWnvEu#<4qk?+_D?_QB8;tJUlw$TZ<2f=4(;yy!3?F76EmQCeF42MCNw8B%{nM_I1CuR`>Ajp58*z4^HrdqZ8V>Z zZf2v|X%WwHm@p4e6sT0NkTeJTfh861ulwk@R1g8KUK4E(dgas$5{`A=7!siJpM)GG z^=C$&RVvajsN~+wc-BOnQHgWn&*8+hUeC^pIL2dS_JBk{m4*C`G9m2!@Oc1o=T83z zih{yv2QtAI`cnA*ts!>jdH8k*+rQb~xI534lViH>J)K$S1%nAtZYsWm(-X>Fm%A3` z5zHfFyO)86zNNs4T>inGy1Zs@i9#$HCLm$i10yjVZeiy|JYtU*WGW97@0bS%qwZPw z;X5fKu~{dQx3lVr7QXn6nvnYgJ1o={H(}D%pn;sU*IoJE=k#a98=lPEs+@2bMUv3X z*o=S9QLUUKc-|IfV_-TM25m8eAc<=?3>oQpv2Vg{X;eGdH&cK#rM%&ms&9R?E58Og z%6s7=l$_Mdccf?>r+Yz4b&m*Wdd7*Ug(PWjaK_Z=F&}9q_xLkU_zX=#{)sDGa68T$ zRhq*?dwWeik{KUdgIRKk7I7N$DYhs&Y^kkSRq=aCa*}6Sq6_R@6Zd|?l}|J?QnMSWuaiY_q36zt`s%!Gb5a$Vyg0h4RTIVH{(CaEN~*Fm!R(7W2YTsDI(PzKzAQ{0wqI zT>e}6#hklV4oF`b0GQLuj2r=U8KB1?Qmu3?AfrLc?)YeW!KK)ACNn9{s^W9h zQkpYT*EmI?f{vDTcy^0S#9c1Qw+okRLsrdFjz0?6bS6JLB|b{R*;J|-f7uqPm8vG` zRxgw2YEb5xdZbiOHtJePw@Y*-AW4dmnM7PJc{5_9=`*zzSqXaKHtJ|}q3c;H-2~_a zpksjECeb~Bt_Som2od|UF6DrL*l=BrqSPpgJEfLZ-csaemZQQ+iC%1qGMqZszFF+2 zFXKa&97Y7P=u0Op-A||#0=CSkWKbN;Nswl7x|0#X^*BOjah(EOt+>wv=%pr^F8y^; zAme9QE=8c&s1bo!k|DITX*C0<&*b_uTsBk?)uWa8i3)SP$r2!aCd-rRpuh%2gBHu9 zJx=SB6lSN#Vesq3s2GxRBCi7jY3Ae5XHBrc2MPpq5m4643)jU-W3`k6IlYUuYD7u_ z&}mnfrdTO@zD3HJ1}JY>(~}JKHq{pD^aP;7ilr)i)=@sYK!Q`z##`@M6$2oEkNp>y z95B?&Qh!EdoG$=>X1V#%OWBd#GM|FSXZ;QUg2BSL8`Zj-@mLdpf&l@@ur;d^gEymb+8(M|4ZCpTDE}kf&F8q9?d>jkB61-E;0bF9wuPgzj>C zo8ZZy`a7!iDqHKB?(_d{^1)c^ec~SVj92O<^=VP@1oN*d3VxlYMY&F|)oit8W`3)< z>&~w_#BAy#e9FPzPv3uRKM7PTC?Txfu^0URp#u~bCdn$(ht zTpBp7_Wswl+BjEx=FgoXAe9_<^|8dM`+8F*=chCmqT@dk3@s#@)4b$&ajF1ZGYBOo zaUWHJx2-L58bAd<)fDwL{;?t%`E?S5er_3$nM{l4W$mg(zV&QcJZj2AxGZ^cDx1~; z{i+zcDe#1IEDQ_h^5$bn*4$%RD(SqZVu}G9oX>(nnUPSHL@U%WJW2OYZpK&bzCN&9ZpUow9bncCC)2jrKcFMkB4n z%=^?U3dqY?vY(O6;wsA)cuK|xHE%<{M1_lWU|1Z;ArMat@5wk30=%Z8=Y$ib8h&fp zEYhf|9Trk;DH})sCFvrh8syOH0_|#?^*iR#82!*mE20JbB0l+0Bynv)pOjXp(W2qf zP`X97GnRJ`*zsV7ZG3pgevbw)@fd5~fGfU4$`$EEE5GVL$PWU)D19$z4Y!4c#XNJ=UcH4QBtJsQKv z#4MbJRfI@UqQ$U@O|$>44so1Z;w4CwBw317Y0|lQc==_@k}XHB1@h!8P^d_;5&=P_ zLduk@P^n6_8nqe&;oY=bW^A?2UXT0GQOCl;Z+F8bMH>IyaMN|S!zYt0vdJNrJn|`^ zFqq>`IPHv+PAxCF(`g^}*t1(l;}UN0CCzxcy}a!6ixxE&euA+iC$IEc>tG|Ce|}L@ zOCwZq9V))g3tn&U`1+xH1D)NAdpO0{IyuE>{)i(zNyvMTSC9P|f$ztU(r-VXbnh7W zyRRC6w2b?{=`v-K?fG3*t*BVA`^k9N1Q6$#hv+W2xexpR4)|YGXzkI8qswcr=J2RB z!m}nYr32#QnqT$#1?SBP;NTs9D6JuV^;112HXy(Cp8kEbvFSyv=~t>{30T_$Kmo+O literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Main-Italic.woff2 b/docs/odoc.support/fonts/KaTeX_Main-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b50920e138807f385d0b0359f4f0f09891f18406 GIT binary patch literal 16988 zcmV(>K-j-`Pew8T0RR91076^<4gdfE0E4su073x(0RR9100000000000000000000 z00006U;u(d2wDl83=s$lfzV`upmYH?0we>33=4t?00bZfh;j#m7Yuo}gkBMuFlG6J5B*sHHKd(*=umo3RRA1q&Aq{Qq;*?z?Zs zS6lWBvpA{|4kRGzglV7W)AM`dl?u#krjN&WNtdj+pK9tmbDj6g11qm=IR>q4=|=`? zti%rTtj4WAvC1G_rIr^=2^+WshA@nFohl_hT*y>e+7AVqh%8x7!MALuOl3;G|JvJS zZ2pf6{GYmVua&&rfSf~>Q|VHyoWtv{ooO}gpZNn4!G}Ns2Wky}~; z-+Rx%Qf?d6zTgLFWNq{L)|&XtUDJ@rBvM+z<#qC}{~v8;7xR!-65^qpmB9aR)86*I z(Fb`#+6{RXz>gL8A*j+OT~ahDXWkvbdrxCqZx*DH?W|_}L8Ap}LZi^ z0IlqWBQJkKu7V{2mMO|~b$%JDQZ#*va?6C3FLd5So^>i7j8{2goP1iH=I;vx?RqZ+f%D!E1Q}Uf z{0KzZ#6dL*1rA#A#nlOe2*^SaCA87WYSuH!F-~xf7kHOX_>w>4Ow>GI^i|*Yqu$(o zy|edpvIl#l$1ki=Wz?DEGei2WNuq=@I_Sp34KMx$U-n%;?B1Oo?y(DFR2sE^JKR2X z-8G;1*ayx#?E#1FbCY3f%;g&TKkL8!pWgZVe&=t0G8VL%TMb-GT|7;&|I;&j zkM`FvLW;i-j(9}~p?4@p##%xxg#6NNA;2G8NdOw#s3Z)rVoM@GbAqhjDO`sP5rWI` zddKCYp`S4K#-PLrvlAPlH{%u_3>X|uvq!cmzm;uF_#UBueexp|=;6wEg#<-aPj zO2>wF3fYv914sg zp$!>z%#4E66NKBGCU$09PCSu}|0gCgJH|;w%eD_&Chn*gwF-LfJu|~jXh6f26o5i5 zv=E$ZMC1zH2?(VfMZ%L2!B2vMv)L2^K6_*wUZT#}mw<#y zTcCP5%QzGnTzj6hJM<`XN2wET4&g$%Jpob0t-?9S17aH!^vo`#aofV)Go>6J8R8Zm zNFf2FlwhQi5Tuq+q>(VBm2jk!1V}Ft$RG)O(;y-=CEix|yr3fZoHGY4ncikgezV^v z&Dhem+25PYh=OYd+egsPPDGUiiA~su&DgL78@6J@N!YLr8&1ZC?bvV%Hk^vh&IIbb zMOpcQ%7%^xp@$fX^vESsxkHx!*` z8PkoPf1#mrca-J;XlDa&{qM;^p%zk!O@j2Oa-#+Dr;zq^zsiT4tz5uwl3bw1AczDZ zzuk*U=ApV*m(1^wCg8AZU;#2L{1hrR30daMp37-`;FlBOkIdRT&|RCaVB_{Yt6Oig zA|hGb64DR0Ku%f~);#TPQv;Nt5n_yusik-{%))wC)-f3cBRNI-@q?L75&Lhq3=ygJ zHDJp`QK_?#k|Y)}E8Es2T81J8Me@*kIve5cTC$iCirP4=sD#uX8n!GkC;~8+9 zc9a5OOd8*czk`^sP>VH@6N7g;+AfZVSF`*cjF!rZB_EQEdFFSNJwSrcm4$b6%8opo zXvYIV#if$1T0y^McGRQRDm#>2h&;LXd3Vg#!hHx;yS>VOurT}04S+?Nj4LU${h0DQ zD4{efI>u1YfcPSf75)>El0}OExlJpmQOO4qcL-TD3fFONXZCN!pp;2qWHo!)T0R(C zG~=v#izt_SQQ^)Ft$4~h&dQF2R1yhXjd7D-w9q_{-m3aTsZUF7aD6c&urUlf>Bb_X ze^7HG;!7xiehPCYT8nudXHB8*?l189t@>n0~k5)@!|=BAippP zplJt~MfMzQ;DzI*fma55O-#_6u@TV#NM}<(DohV0rU9_d;k+YYeqJPW05NhTH576H zDIGwK{I$i5iqm*>+n1Rs4YJ#e{jA8{*82y5vJ1i~ko!X=*mzljpCu#jie z1<%8NmGYRSJY^}*S<1^&dM(gf!SfDR86R23XO{7mWqdECp91|BxFq`zr;gvhJ?-;{U?B*Z z4Z#qHcQ1Sa31vZA4qiwVYhxt^5N%)GEmGIal1(-4o$PUW>&S}Umx6InD){m5;8B#5 z==BSTLIuUFlk4@yXqthNP@Kv&e^zBp4j)Kn*#cT3kr`rS6LJc z)s=K~)i&A0Qc9A%TjpT+MFEP+l+uNR$})y3(km#Q)=DUejpMv5!LzvyDQQ`WK*wB( zWJ4!Qs`MI-UT?Ge$sV_3kv(dT_za4xDG(N`BCyc+A$=}b1I-}IgtK{n7Gn*xfI_L3 zNdmaU5Jm;qQ2V#1CMHhgK#2sZW*Ww_y7MwE~SKKEVnJI8Ww; znjb!eLwzJTZyZxWxFqgs%z9QNU&UCXGWi%Z5t)O8Q7CA7;V*x2X@GzKJFXoQ?#okB zYN;mQ3Wh!~v{_uzD3yR0g)$+y?<1}HbzVXAfrKzy!UzXuVL#zxm!qn_hMJF6Pnl2C zWm2r-n}N>Z{^PX6NPJlB{^*bjVrWemY`lpPGuxe$q$CQc!soke)SQK2htF3_%SI|; zn3A4|T>#AVR@=W1I?{+V3@6Pr1xLDI3jdNyE#k!zv&n9=Pqv4|zNkB_as*j}S{WFWVj27}?Uoq5_GUyfl@>s_i3333Q$g(#pRCdm}jY~Pb(!!8lh4c!(ZF8nFP;8Ng@P7I_q-Ss^i!zr*bYe_~-*Q5tk z0W=4Ot^I&-u@pu$ph|5KiH5q5Tp$x65Y$PMwchEbTzLgF(9O1!)gycS^Mtk$EPhJZ z6mdCS& zm=bOoVVI_~*z?)u3X(_`CNY3dp;5vcCi`l=v6_d{WKCO4-3EiD7|gKqS$Q@BEfoFT z2%4!aGXYYljWUSeLJx&BA*^Gj$p!gDw~z@XLpDU4YQ1M8x~w#qi$pnm)WFPoxEpJI zjYPy|F~f2~oNe!7tiDDcg2G0`sFAaq-tZGzDi!|rrke<5jghzSDfEQ{bg%;m<6A*_ zO*V>8!30%mfsGQ+xb`L^%p^aMK^}Fcg4|q~f5=j?k+9fG!ZHOe1ry`WE>1p+Y$yG{ zKyGViW8u51|3$HUlCQ=ym4%8#J?!uIB7^#%ECceKCW!4Mni#H>q3)#MM{oe=er;XN zi7p1eLHLuzKoZu7(B+}JQ}l6gL87nxa*~3qB;2DlQrX)8Sw=Y^mkCO=400?>Z^h%J zQQQaFr_Io*kQ5XN9D1Hi(NL_rwYf)}w50n{8^wowkkZHp1<2}ePc8FZyq1A6FPHs) z>5Y| zOhwWFb?E03?7JUsxSywBb-h2ohNxl$yZq8*>AbbZQ%Do?(nQZxi){Azd?5k_RuCG@ zJd_t;toAhjapE3ALbr=GvD?kuFj}Jo#i<#MdMwPq-K=G{cNM`vxuB@ucxDTE$rE8y zBWtURlAc8@r+pvaAlnsZQ95sLmvq4v@lxzebAQyHA@>)@B{6|6uuY_TwG4RK4}#c< zV}U|i;i5Fgsu;X!1+ia!)2$>jNV!LMyG94CG|1pU-0mKo;;CjZEY)dBDA<0IRDQH8 zJ1^;{h9O3+4v?4B=Tbfrk|0bwJm}WSIdLBuP z4}c=2^8m=LPia-5c_hC2hIhl3F1P@;`22sL&&2;L$v=>tJJR131;fPc_=|~;Oc2n+ zK4H}N$4-Tf2E!)U1^RjKln;TVO=7ICOAU9nH2R~OkNizE414K<<2WVf^SA(X%Z^d0 zrHswC@7NcPVy7rk>^LFRVgO6QdXHptyM?4Oy(5w-I9_H^kB}#+`ER46swU%=myOVs zX_#gRD=##!N;5O*0m>JVb7m~al0I7LaEOW^s*qYnJDZCjB?Q>=Auj5E%VPqsomB4; zOe)2ZA6RA(Lm}E7K4^k8ZKT7tPwsMU;&ry#)1;AP>)Vyqr_m3(Zgnols_GXe$a}@E z*(SMf5pM^@^m@oSTw8I@7jbG$CKgK`buz*r+zZWxlMO{wtwClawh`xaXhMm9;4wvL z8LD!Um)v4mY>CnN$oZiBZL(P}&c-Pi67b1v$SDFXb4q+n7%UMK-BM8`+|O9Ws=RSo z)2Hc<9-7Bz>X|SI(NC>Nzg9FGOzHWKC@-EMVVKXPVh|wLJkgKI!5>b6kiXj+&M@Hi zLCcUEF#VT(qcCSQ4Ckw#jE_2s^k|B-Z<_oDw^Etu3#d@bV81I>RS;hj8OR6{ ze&!MkQV6Zp8Z+^KL5HxkyGH**DXiTM%c(_jFQgZ3wmXa*)9L?qZF%E;n5MFHgi+1} zh60(WFk#!#PEijF8nsLozR4%7f(D*rV+kAQ&?$#*81C;=4ic%~ zY{z}7Wya0e-i7x(+m7WKFz9sPhq6MEem$_Vh4@_wM(_9hmn|5I4H%elfE1o{>!1ql z9T}`xW8)?+hN>9@$_RW7glTTMh2KrA{jtU8H||DM0T+q;7_*HeLHZ`p&$Ip}p#jva zrG@7`E70}2E!8LNRg5JDzs^270W$GaD2%``ES5hHZsM3Q>2-XIt?ZcD&m|H7RK%@# z&BSx(c7z6)>wUXM&RcSb(<$&11+6IM+*@Q`Nt z=fNCl9nCAyLnK<0sR3m?+Tn0unRJN+v$qjnd^>`+(ecP*B54m{XO=k}Tl-;KoHI4o zQ%MpF>o4*@vmspqbRSoH5ycJZ5_plc3SMDiIkOR~NI}q-N4JGUEG`U*WIQlS_I061 z*Qf=TO;J-am?i)le|x+{*t9KSd`eM2O~{rYm|3jMHR*21IkR%Ri0p+$w~vL>aklU7 zcOYRthz_w4-`tktH6CuL`bLPYCp(~a!Io?;9Ji4(=Nl#%nr#O zq%sM)EzGBt$albx;6$6v);tH$ySZcuLpFV@$Gpq<;`N1d(BpJ~8mVz@o1hU>*Ru}u zU+YYfx#8y$5&NbQs64Wq%lVF6uxD1g)9H;tcWK755GNbgNfJu1ar4O9WBp87F;YsL zu6T2zd5Gx5Ibny)ci#1cV6EyUmT=ouxW!K~(tGQn`Di}MStlr5NBRe9e0+EqC0KiW zIgL=|x{a*w=U!z5ZjhsbeiD0mdSa~Jxh^%#LSvvaq*6LMC`E?**JI0(00U47!RX+oxB;Pp#FnIo}hyI zx#D@6^+kjo`3d1YQZf37YPDoSf7)wF&kSrxvF^QBCzlI!k(L-3ubX!0c5c+m8Z9j* z1f~^HX8ZSRPK=41W=O8ly$QN+qOUO<*`A(k%4=iKHo!U&>FQ+s6S}dF{~O_UqV^g*40Z^~E-_9ncFKgXFlvjoqcD zM8VQVE+q#@Vn7T}#D&C=v*6F_3D9ngb6udG$m6L@(+jQDTLWW|Ae;2)zY*Vm~#%|ApE!2^5 z2Za=xhHCVAzCzjhJHs=9dLSCxYG~Rmc;#)aJcMX(nBg4zqNA(zQVtUqpLF zX*2H@6E4&Xb_&M1)IEnWJ9!O4%G)4ae?NskC^uWIuwU&)>j&~3+w7of)=LbJNvj!= zaa;JJ6G}cy9!u-Zt>)sPq#!ZXsXT{Sph@C9_tq>jX^4oJB_^_055b}v4^mWV^}`qz z$r(Dk_j?iY6_zt9(_Ir<+oP1*EY>+nM{^?eozL?T#M|Ufek=L9HoqQee-XjzRQ{`? zgr%828U129Trd;QC#xeW$n^5jVCH!V&r#6-?AkN_DB`2N8PjdOekfKM*%nk}Xw0g<00!xi68(;S`l|-<= zzo#FoImC1FlCBCn&NH*b^U@@A5y?n5!RV$loIcwTChg@FdbqG zCD`qX$PB{>f|?4(C9qy8kCW7(PNhXYj%h6s0mL{XZ7vAXbU&k&pbdO^gO-wYu++)0 zmmKMj{d4$TCQu(U`CpQeD;_7235QN)%D50d)nE2^zWH?2oy!c12zSi0FZp0Eiv!)f zhE|*4O#=$MvL$(gJX}_6y?9^sROCySfR6|rK2gWI(?^+Nvugp-ppvR3l z@cnFohB^^-5kQorM+kDh}%64gs)d#H*+jUS3F_c_n>h}J-qnced#N8idT5` zM>_62At+WH{$okvyE7?PxRNr zN!3YVFgsy-L@GIBTD+*{p2+^Vka&_nyqjiB!9g&5WFkNa-d_A3$y%fi}whS?v!KfJ-pJ`-7{=I|Yn#ddZ}Z8h}ehmReGzyAZCX!&GNrCk4O zPH>j8t4Hdsc->JC3tkZ-fUDh9wU+YZ#N!0aS=AxV3-&?|_kCZ{b;&iEvjSYVoUB(R z`?E<5ud3a=qapD6p=VxRQN~25fS#~^G&UvrV#S!Zlv-nu;;AX2+$zsD{!de(CbZ4u zaW6}l8`n0c;>PT@sVCo^F=e)$`E8cPpIjqdoThYYK)Dl8^( zs>s8Axp3%8m5dDZJ}CU!>aVOUDq=u2pz4xKusykwVJs=Z(=L{#b^nBe^)Ru^ek8e*E5*1`t&1LuYPT8z(q4+-fED` z^>Ai}J0O)EkrC0l8bnfgM=)`Lg2f+-K-OMnZGD44tyMD>?OTI}^;2c;5dND5MH?QG zz@`7&;mxDY!^*?X@vR8#7a=WT;=B+y4jV^CM@?s>;xnf4anqRTCj9iuY(K4GI!Z&= zqM}cUW7>Omr4<3#^tnWFl-K5sg57w{-w6bLie@J}7Q5UC*3_K9@8ZrYbdTw|S9skk zc;JgXF+{zv`Prv(n&{V+|NKAC_}%+%e%Pa#XFuqVxjhy1a@81mDDS*_G`TUQWo_YC zZ|5f6ZIEFPO~2~CVn38_cyEP=)wzFv*Y%oV-7*{T$G5ClwgEN5;{k0>#VX)LW#pbP zBIr5@nVVs9Fd(K|fY}rWW-;6kICTNr)xZ1_SoRqHPMzv!HKCYPH;h3)G$aQbXH_X% zkLOO$D?L{7lXn%sO>H5mf$^NZJXsVFD*|x3B9?W|spv!>>^mit4t>AB2veZ(q0b*?Tx>u>b_GE=}LRs$(@rvE= zdnymV^>str_VrCfmn_$p`w+%9mRNl1AD1A$_iQ=u{lwHhqjv77hj0>>;r|{o-4TFS z95_SQKcu{!+OtUe5hMdAEE3O4`s2nxqx=Jt#28IL+8nnT@a zTI!vCF5X|5=k?v9Qzo|W?;sH`RuC*N?ea5mN@Z0b0@tfa_+^piZLWn1SPe%tl zUI~6lpGpEtfcjqLc>B6_0gMghl~yJN!>P)4sV~1(Fy$*udazr|2rCR3_b#3lDyR^M zwH^g(wVNp=9kf5AzpN9SOezi)o@579MuFb`l7L9R__fONL$cMT^@#Me381y=W}j(dgEeK3%drDg9p`}kwL{(gOC zG2g~Si^^Bg&dqC9Bgp?VakCU!8N0d&$8duG+G2K=x3tBw`I`6L%HlkvKIF7mh;JXF z`bf0w-_V>V{)sw&&M67xE1UE$j>SEnBzUbt&d0yMi{r>RBAWRBtVQ##q4-Xyd%o_I z7k3;AYd@Ek$aVV@-knYiR#DX+9x&5mhxR8$vkK9$Qf^{)KWj_NLwT z;YfX8;h~q4b)U71+HHGP`~*U5_Re(;$!BMFu39PSB8(;>wX`|_L%F)^c!R8(2Z2*ly{*%9YDrT3Z z%n?m}A1-Vyo73J58!J42Pj@v45}Ri)Eg3AD z)0%%aDBgG)>TKP~vpBH(!Qdn%$FWjlj)3fQW{v7QMb&O;Fi`&v;IC<~ajtDD?#L%f z5-2&Ct#{0>FmE-F1r-vfb<9um4e$9uP{=Fx2{4ow(tut#hBrDU&+mDAG9% zs@*0Wk3&o=WHLq|xr}omV#-Wi+Blk(mbmfVncF9TQ6W~Y%sJ8k?`Gwu2$-^24I2y_ z9lL)^+;ShRf?0f#K;DNTr8CUXrw9pb(xjRFTfW1v-mpgY3~Xlhkv!sEtvby!&8Q%2kSA{n)5Nc#hi3y2fZbl!)jDIn%L0oULa#?h?exHPRJ=aLmc zr>W=m%bB!D7*it?ArH8+ItV24+f2;gONzuSg(Pxc~H*1aywRJnMKG zhFH9jNkWDhI6BMgGz!@`P<0H8)@%%X1Pn$-j9W~b3HW$^U80RrH=edglB!U|yP1oW z54TlZn>5u6D*s6`?>=4MOpm9bg8k2=@VQ93-(keqcA)M&DYn_6UAoBVuC4(1g(adW zJB-qq4j)N9-Kh*fGI4n-%<+I9p%=9!t@_-a)K&LQ7h4$0ciB2j>@BdyzQkjmiQDAf zbNO%C+TJGq1W?pMv=j)H!_`x`Sm=k=v2sh;0S;_k(_fpb0I~*>uUwt1QnDN<+|FxD z1YC0x8+oTC?gX8YS#@@ESIIGTIe31O3BktVxa8>yIt(#Vj!rKNi8Iw$4~ZPSih%To z#E9?YMh?@)Wk1TD$LE!qx>RitM+xZbD=~TU@X~yEn*&BYfj&R&Z#J})^qZPtr0HLX zQBR%6?*ohnl1qik1k3ya=We2~8IML+m&puVR%Ab2KOWf%-3*-0 z3!Jw_XS{BTBgW!*b47%uPEJFBDH(W*^q$DREH-#a5tddQ7mwtM9E9k^HJI@E&myFw zsGu{c%2sX!JWnOuyT+fYx^ut`*8YJQ_A(ru1$cx3Cd7ejo|5P;H%a=p_gAPY&565@ zbsK)n>XWBxDLp!j$9GJIL zK`ID)gI&J`E|Q_g1vGX)aTR|(z0=BHjKu^J-Q{MeG zb-IYie+PZuBPk2#=CR-XFD)Xwuaz1`j2nZnK~Ap&XBvUBZ9<)4T{IL~B$=e`<~V;I z6Q*n40=u=vxzm^EHW`m-pu{p0Pg zQE`bN|8ujMBn0&gDnRpfBZK)Z-6fj4LR;+ffACN;b0g_%>c355ojtvk+WLgsN*YmE zLLdcSF_w!5%__%FJ`!Ls-z#;Ahu5G065!T%AjC--%_JjqZ!Jz9;&L)PUJJD?1BK0r zAY{)~4?VF$-w!G2llBETa?;p!_(FgW(gFmj&*({OF?8JS##eFmiTM$w8}HkTuE+I_ z)MHPp=YIfu*z8tk=;|JI6zNx6X#qGk8Y`|?KDa1VGNkWgQrzOF$IZVzfNN1O^9GwL#0SkLk?9=RpzZla% z;=vs~>+&XvZ?BOd;A{yF2S;2TFoMgsZIaAgApN;Ko4iC|XOF1xVxHR@jdN5SqTffq zT+@2&Yu{=eNU-EG0jgXM^1IYL?M@@5!ljpXWA~Y>xbz@ID5<05va8?Z^vVH)Xw7oD zIqENti+l1Hz{0V*Ot%TY71&a{1+Pc1Bzi3jo2mZQJxhyh88@YGFpphQlf=zUyr)pS zTO=_WVbPd3Ej~FRu=8-)d3f|5%UprDWJ+wK(_tmTk|q?9SHP;Alg1H&GGV3m4E$~1 zaBFtn{@h9T)=RovINk3wo`9+~HIQ7&(pjak6UfuXcX3erIdp1&Q$L+6P*SpJ^hqw` zKWE6v^31LRYu;{DCfpBZKgg`Qq_@Etj%?YL{Kc@S;+|G!V($bF$Mx__|73&xIBS%O z1StwQH-bxl;j5{^tjQaQIXTNO0Lnz|Y?oKqQ0kAE|$&c%UwU zSFV0r-EJHa>F9I`whRj@BtOiD2m4rSmxga!O8f~&p-ATvpfYqgrRPzGyV1V{~TQr zjgp@O+)UlE0qO}*@u6}C?^Tf>uNXuDpj{NRhq5uZ-z92+kQ0rW=os$?>y<^Td9gGfD<5yhA;`aw+>?r&jjG@GxZDC_@s-2b-O=hx&^Npq|fL1_gbAVVN&Aa$1~x!NjaieWMK{U&xnw)Z-xA9pg(&{E-~>xaF~T6x}~f&-0R&w~U(Kv{Z~X z1Ys7FeYx;fX=NtUDoEArP;P?L(_?&TS|TG8M!6g%zh=&}^CkqA-;6p`L&flcT5>6= zgc{)`UOhJU!~@9JZvg;Z$&C*Bz<2Hj4;*XXIrIMrd*+*@Ev1K7mW$ zzOB<)IOGI7LN0ro~l?#iZ?m zjr%Ko-Et-VO(SPfP_rq8m#5;A=Oz7OBehLj=7MN4fR-p?*)=ZO`k;+Q;pSiAD9MtH zamn-(7HLK(7sLo*6N{{9%k`p*rGw|P;)r0z*;_50AWCChGPUFR&n~+@TaxsvPs{Ru=ti9C=xPDpIG`89#8ZYOY~@ z^83YFBB;XDoI3m_uUY%N#dGgQRsZzGUz;z`iA|hz2g)`8z)De=iesurwJpUSnHT-F z;QpcAC!w+P6|$d2bBS(T`^3MxIynR5fFX0VgJ}WD5xnme_1HmE(nl7Nh8rtP-?&6+ z%L?(@5;Q|%;;HGQ|8Mv~2@(GbC;IheeH@EkOjNj&=B$2qV|ji}prO60efW3>bAvCB zv{h-!xq11|r24G-&zGv3HSMmLkywwzeHl$MA?pE;Q3jJCPhAq=KmctFT2QtnIA@M^M$wEx!wPaA}eKkaqv zP2;AU@?+4CCHxDNJ>%6CuL>GX*vtRwTysY#{(~XDe5;(wuqBl*Ypv+`V4cG7rIzZW zta8%m1lZVWmubzsA65Lv)B7qm+dPix*BUZDOwn9X=y3I7DJdrCFjEV`8JP|GcaUz& z?)bx-20Z{{j8C8beZ_mC!d^K=#TFiW_uAMsz1?D$TKAZ@LvTh$9LX$!*s0_!x=!vL zANmNF2n&D6w_g0Ua(=p;GZVqa(}6A1meluCFo~smZM!1q%n;)^Qfafn`K!Dt1<#~) zq&V@z3t|$)DT<0Fl)Zod!S~F0Jq6r%6dxI8t(mKJHo8u?EY-hh?-$8sK2MQ}4(Ow^ zQa3y0`i0fXZjvzXOu{6($i7i+brEs$&g_L;Y@P~x@*-Zl+$Yc^wox0W1QvhwbWN+(4P)qGadz`+}l(AiaYI_*}qMTcw19x}D0Va2VKxaUEgJ?BbR zrren>TAZo#yn%x_#lp~%(C)l;_(wzO<(xU$NvXZ0!VEA&dv|K=ye}O=?`V`^-;rTY zS<-FRy@jpdfuri0wTXaz#UfOw7tH-n{wa5v68bc@pYS*|27`wd+920ATj^pRg(xq=L>AQkENA3KgC@tNvH zEGnu05^`;J3N=SR#F1vz9lF%8ZmW)c?7AwoT76^r1j-)c49^n}ziNHc$P6Exj*!I} zygX@od1K6xn)T>aqdHA9zKeJZ&lReTF}|$i!3@jjxe+~%VBE7CCnS#2la5{{p`ej!ox^2JSCeoc4s&h8{ZqC7V?}2Pu)D^@Lrp+Y$&+v7+ z75AX3f+W+ZX)LKE-xfcnR(&kQ@UjIQ|K&R#n_;bf9gLez`9H@+fk&Xf`Hla54NVzee@AXUAcvPP&+Gal;mTf@J|JJiDAFeZ z3Ph24=9^KEGyL#d>P?<%1f-`^Ms8*XpypG}h5zZZcgqkv3z4vCq_@0LIIF$b{|xr! zqe`q|ZeM9~*s6S(*A(g2`T%nKtDJD}4_t#+&W=8128%M1((ao6nN*o)(Sm@lTvT>Fb9yQAA(Mp zZCD0ewHc14J2Y~Iv{PZUN~c(GA`jND{`WgL_i3==?Kd(Ke+`L0Dh)A(k}6&&cophb6_6>*2<$v#__QsJQ%|CmZM$YG$@z~946W&%=lNeC@=LkvzQiPNdnswNsem&cZD$#BZL+I4D{kR8ZU?T4_-%&2Y@gG ze?NhYo)cwfKmFcRi1GSJI@`hxD5Z<8YIz~70SbhL z%!mV#27yLhbtQ5#(j9SW-lX7L{978p%Rd;rcsK>)F?ctOcXiGx{Fgi7#Fj-UfJ$ga z5y}d85u_=a+anR6zr6Ao)U)h{w^4%jGp@eCKDPK86ohPdaSY4Tiy?UPD1uBtEJNi2 zXj9Ep(~#MiKwwmXctpm3}Jg`{!=Zjo6qzNh@*j@z$-jR#GvIcyuV@Djo{QyNN3@g8Y zL1#&j%^BNQkDORI8zxtnAOzTUZP`6OA6i(Byzu?w34LQ~RPMmhrYZZ9nk3SMVYlYN zX?k3(=m+}2%hImhRa4=8Ya%%ivak`K37^jz0Ck1(s$A;3!ks&DNI^*a8Z|N|NVF9*8!xvtBtmW&laSo{3W`aq52C{ zJ0UzCXN|$LqLHWIxyNw;Kz!1~FAfKelAxYkl#=$aa#qDzpVc6)(9{vC^gk}sL2LQo z2Ileu_al~Ws@!oLkO=4>NM4!z@J+0B&o^x`42NGa zNES+DOI`rrS0P1{%usyoriUcAQeqVOdLogyF+3badLFxS*?Km->E$syBn>k_lv zTRNgp!imG>dET6CMdnDxI+B;J5^E(_QlnBnloB0DT)Xye`+0K22dD$wJ7-$c415fMo*m34B;m48Rvbt3n9LTB)2R zmP^y+5G&GfXwa8u*R&P!gU(i#xRYrJfiZzXhuuCyNwDFL)lx=~my6(FU8P+d9PBAb z8565hK!eUU)dmYSFtUnV9Z9e>gM_)lKW?o1Sf4^p75OZ6-TKA}r7DYk#-@~bFs|B5 z(fL^_%VlE`bdjuS z3fB5knP7p_#P}+$aA}^^CL5%wA_Kur%FGZ!%jJlyM$BRfK$Ijw9U}x*V>m@%*#11D zkd6!BlEO%bq>@y161Xl0DcPlx9e|T81u3xr4k&3N5>V=no7J4T!u~R6G9`;hXoTKQ zS7U9+#k$W1O7pYq(q@sxxCPfNEXvqkN37B-hU$2NC#~3I5kQiNZw3xQFs%6z@y^h5 zWf+puQY%D&;)!0jMJYiLp$ulG$YEIl$t4801Gcwz)$(~>kz6ewm(L3p@dpcFo)7`{ zrV&gn3jz?eWslbRqrKcIFa9Is$k&{^uYEZaW3{fq(O##4AOeCR$W3vTS{iEY{}Hqp z&`NZ66My6CkgNf6mJIfIgG?U#tJ3*s;SGoK1b)RBmg2&P>oYS{^q$ z7n!fmvCw%T`pts`K!Za#Os|pR41%Dhx(J&Ynb}}GIXg$(!M9VLYMN95y%@y%vX>~# zmjIfJ{11kKJf8euroBrk#OUV1z)VNu$O=f)eUAg~z4yT`RwQ^&|F<-5o)^~=hHi*n;A4A$96(u& zz6T106j0hR3DPeTNbf1M#P-%Ug!q7F*$QAC*a{}`=vD}y|E*Bwpj%;lvCWS+ZY6Df zp#Q|mWcQ2wG`fIEz~R|2yIyCHq>JN9709?zrxh9nFf0eEDvGLz8A|2!(&v@c;kzcn zf4EaN&ZprZC$OM*A;Izny+@6(b_nHep5(q)OVVd`K?!y{?`q8aj-;f>QjS)i2dyFYrS!>kqBs}4GqHx?fK}?|FQH)>w~y5#C>4c) z(n^WMxURLFY4nL%>LqOI7zPpoce+JLmjkDL;Mgn9U?i&=Xx7mkO7Ux}anNNo1rf{i zuQGWS>*fYR9_nFbxInJ z#uoh|XEqfs9h?40SNOkmyE+ksM8qVdWaLN`8iU2*DJZF^X=v%_8JSsFC9z3nmm*b~ zbQv;b72AESi(9rFx$@*IP^d_;5~Vz{atew{$||aA>Kd9_+B&*=`UZwZ#wMm_<`$NS zz|c;cd~CM~TTR;U9VeVjp?6&m3NU~}ANbHm-t$QWfB-@u0%9NmQXm6zKmrOn<+Mkg z^@uas2$nAxaJ=~O!g$E5*Y6+D`MCLyLWh-i4-R(QPQ>evZ*Io=XD{oa1=%ve_1lg$szem2=a}pBF z({>1!YW6>)A>=45Iy@o?=U_`XF9_boBw^wWi5~%ZWLiFk5K!Q?g0XFX!t=lRfchkR z_c?-{3kuwtd~(P+Pka?%gva;py-f6~&*%sWg=MMdU_Lnd&V$AMVIMdYH~;_u7N@=P literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Main-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_Main-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..eb24a7ba282b03d830fa6c63ee897d92a5188736 GIT binary patch literal 26272 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�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 bkH82T%!~T~dOL3iZSfI!+IWoKhyte*`46Vs literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Math-BoldItalic.woff2 b/docs/odoc.support/fonts/KaTeX_Math-BoldItalic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..29657023adc09956249f6295746c8ce4469b50d3 GIT binary patch literal 16400 zcmV+rK<~eIPew8T0RR9106-7`4gdfE0D43K06(+<0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Math-Italic.woff2 b/docs/odoc.support/fonts/KaTeX_Math-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..215c143fd7805a5c2b222bd7892a1a2b09610020 GIT binary patch literal 16440 zcmV(}K+wN;Pew8T0RR9106;hZ4gdfE0D72I17PZ00bZfh;j#meGGvz8}?&GBPzE8 z1u0OUJSyttUiBVPluy!d#s9|yDnr%+PdDJI6W~D+hF7dn3876mx~G$_T&rr^uln5x z|BT}}4pu5P3e*HEr8*eDNTG<1F_;U3ZA=tqpJ7vDW=sX5YRKxDB`FY!LZL8@ z!bX`TSd8YAvLOreMkita9aZ$fQ$*@8r}n?8&fXI{KJWmoXc#0=X$40A*07 z&SI0gyJXs?ugX_CC|r4aZcQPu+bcrpYg<7f7bmfQRh4#o+@zM{cG#5I0dklZ z)z<8ItFoM}%JCB=SLYwy?cof?1GGfhVUk-3A3vRct*O30o6@Q!dZh;dM6m*cJeAl!*4z~IaFs+R8AEDeJOU?u3$8JXqZrnAU^RPh+F zU;a;L|F-we${!dyOb=Y9sM9p#JJMP+Bki*!?>>9v2ey3PS!?%!*)SOVy?*)743p>5skoe=iCPWL7}q;e-a9(G+RBfkb0t=i8_N*+ z7_N0U_z$PkZB<@dmg^}j2qDKj_ZiD2E{-^a@MxAp%Lt*{=gz|MvAU+<%dmy%)1*fC9?>djP?CJbUm!@N*vrK|8L#IrzmL7}7602l}4y?RTD= z#6!3r^5Ona!>#G)S?_S5-S-FtfgimK1aUrG4ns(0(V#gV^>8f@hf-*su5ukNasBL{ zgLBnfJJ-)mbL-qOFU-SP%s=z%Z}%T+!EL+v^$fiHW#`{Ax6jd+tNxX~{?eYf=hVw& z*ze|P61T)(fBbU{mHHA0(6Y^eWse?T|L=*6X=cUCf~xpmtLO*gUB^F|M`rr)E7$la zYxyr@6;nP4W&KEj4@Z#n<^!?2U!Fz#w7-M}Qudi}#A94=>6^>8v6fIfp`dgF1SA+- zMF4VjQ4xk%u@w=Z-$gdg7Oo{tgy1r~(YkCMCt-eDf?_AkHuglXmjgUD#^7k|E?Zl6 zkZ!J=UPd7!ZlHBtFii+0{EiNC9rFul2FYaUfe(V*>Gog^dhqy^X!7cW12aOln0e=^P-ZnLl#qLQ#7r3Oe7La2?Ib8(RC|iNyUMS;^To8AQ{T z4^tCo>P4-BzB>=fh~tcCt%`h5z;b}#Yy-Zdz@325a-~Rkv>^Ddl0S?_08q|KIX^0OZw63{Y=(8w7`DXu%dD_IbvOuaQ?^`5OLLx#r+`^All1Y!=LjPHjjUZ(Dp zgb7ocC>oFviPYQ>j!@}K=0=hMsT*Cg4dezXeE8-w`qSwRN;+9?E?sYJ`43;$fw6Ih zzAS?bQSEn^qFn^dk<1!d3Wv+G4HA10Yzc_OqH+@RM8l1DK31X;b2wyuXhR zQ$_;t*sEriPL;ZwM)xrDbaUh%C|B)G(mnu_BH$_g4aF$bJ1Kz;K_)cX+JxkLknZYU z%33bcO~&7q5}?6^MU_wxdH5NXqCVeLEbGxA;Jj24@f-8^&8W-CBQPQ@0WaYb~#;VhN_MJ#uc(}5AUf}sGTxH({yT2-N)^ckVs~?s*D4EA`<36A9?my(<&%KFXS=y6E6kPfC?XXLmg{T zFtS6Eaa=Re2s!@Rii8aHK?7z=loVctoP2p+MDnl=(KHqo5~0q=XC^{7EhQ&6te~HonR+x@XP0i2l2`P<@ytx$c>rN-x34+~ zR%E~3A+Rzh&YDX55K~!?3^CSpSsjj?s?6T9AAMSvV1{=l-79 z{}z*4CT8?u_Qj2?8Cx~;R>?wiBUDjJBV#o_&s&*0oJxtnI*)zzhXeFBcTcm2l?-2< z_+mXW1WEx*q0s=AUqIt^LGqEH#yFXqWMLDgb->0#rWpeSjXfq9faDQCFvV1*fjD6q zQjk3Y2(~cIwqh58iq>J<41o3{RRMA{Q9PIdCa{>u!X%cG17nye)Pi~hpvIzfAjX(M z3d|z_Ef#H)!_bU_C+ON1@GNLwkS<3xH}pAvV^Q*jVaTi34`d0r~=9C_s+eq2XkOvlT8@xH<~90$?vd9{SMnw8qOC zZ)2VMApk67^bso@_8zpx zArSWtf~+r)b_qNT{^^)v76(T-|u$UBFvrSsBt2{0N{Ly7_xkhen+2Q4Ml ze^vrI#GK{-EgR@=LVZCfTfvJKQ^j_QDQ1I$3YLz!)GI~?ZVVUg$gF8qs)DLwt$0k4 z?(1mW_`hynk;0)a57G`Y?q%x4W#WpV(uo8^rcWpi9?|_k5CRA;b|%z6T|B*l@uL*Bc|%h3CCoWzZ^Q*TB0sB% zJOro3q>vb~wA>$umX)$Q$AWX`zCRO&GdTu&(SER{E%P_9$Th8MBq!40 z+~t)sk{fPo2}J1;@{@xoTh1q%JsN>(7A;r;qv0DPByIIGHs?#gtVqf9kR5V^C~Ud@ zOImuX_*~ekSJbb{6>_S!N95r!OQb$Rt3!5Lat_hl4iwUl74^$GmqFuTv1^egSAEy{ z%=j5~=PXV6;6VG$!;zun!Usn2iGweZxSnXggVhbjVS6_ z#0X?d+Bj(29rr)W(@e_{u#l)s;G)LrDpr<^3@QQ!8R|_AW;ma%)eXl|G%u-NC6NAd z8d*K-k)j&ZaOYd}tU)2xy8j+CNWDmlA1#;0?^Fb!=&2+ZkC0LI zDg}%AWtUFk%d~)=x$}^G|NYjM-pk!qllU5~)H)-I=Is<+XJ)2vJ|?L`J_1MX z<(e>u=3U>Hv)@LRZESS|`7 zfz@jFVsoQZewlL+ef(?kJue}or^cKYuW_JR1finE-WMo+G`v|JzmTr}C7b2q@o z5b5^)@?z4NErhiTZbbLD$LbWK+b@&_a)$}lyP_idId<$qkb|5s5cZ2luS?lVKW<%m z9_ANFkG>e4w+TtI&L+A+SGz@BihmBnBJVbST)Er|(BQ-2z<#>ockEw6B2lW31cf?+ za)W*x8D|uG`sQbw#nOs%n`YaYPTP(g@Vs!)=~VGU3vFbw;0*WXzdM^Zlx;V4LTVja z!KCd1jaucrxkKl6UDJkSZMFnsx7rkVy^hCKLQG%1OPwUyd#bE%o1aGYQOE?F{g6QUrme= zF|ud}g2WT%(49R94K5as&Q^K)h-;!*qOVM`X;2u?8!ZPH19sSScYSDth>q#MPd%upS3ky=sk`Mh z(XE5vXzB=QiF0$ebkV#h+T}984i+~<6kQ-TQNAn?5jT+0yQJ`7pzUDIf`6>U#Gs#; zdHgenRu`dES~}{Un~AV#*;zRV18GR++48X!{5$1<*HH0dg?fq5yUFN zEw8`qbr?jyrCH$h-FRw|;Fl&Pw)OH=GGaEP5aoQLF>e&2ILOKcT z(hy~gs5vhNCLwHE()|0#>C+)_De(H+unPP4xt*BsFuY`qx=Iut?s znr-m(WXL|Z1>6FXUMbW$Y&sCsi{a+{+Tjb4HoN2iBgv<%`G7t}Y)^wyF_v1@EQp&5 zOLKuZh#sVVEH6{mmJ=Xv`V|oKY8vWzJZD{W9ulS`vNhv_3XB<(vLuBtZ}h33I21`Q zCaEZt%tJx(A(A0fJW(xNs8GV;G!{Qk9<`Xu^%w0dPh}v@Ma!XXjY&{MJjf_rj%uaC zi{Fd=vSoe^@~CkwhD4Ye_Z-G|`K+`FPFMteMyt9bckuE?RuF3~wMTL#)C?FXcv~gA zF8i#Ue{YCirT520k0nxN7hb?HmN|D;b_)r|Czx&phZdH$FzD-Z8K*WDiUZMG!`faczN6~&{m7t8lrk%|--?}Qgh>V=szV>owavKfyPifC$A4d$ zx7)eisC7Sa1*rYy--;Qvol)Bd4yDfcw!I0J?efIcCSsy`7c_7WciGYGFk&V&`$C#N z7_QrU@H9+5q<+>gRtACNpx^lyU&}(m7Zij|(W=@P1%`{;Gp0}3!3Ry}nw*YloTs#= zTf$wR`m-w>Psg}P!qEsRRgx>tF(7Zb)yfVn3Q38i3Z>Fz9U%QzskIDyF`#0|20i_l zwCuIZXO+AJC%tN}T&1!U=DsaQPYZN>nm!E*3{Pj}0(Y_%uT#-s70BQybMU~VDKY(k zHUpd2CzOdL5vgs&Ytq-x8;|TS>PcM@j-M2%4NOwfdj1F*f2sRh%rKC1b#LARMUe|qO{0Ko0%pSdyaP+VLaRN$o4Rp%rxpD zV!2SihPX6ms*6cB?*^sR=_6ArTnKcCUE`6hF0KdKy5kgUDOYAU9>ybrC7PB9#pymL zLRZl25A~le+WwG)P_B$y5?Oz4d`!B#={?kK#tzON3 z`#U;z(qhxkzF52{VRlVZFPkHy@`9s*n6If)l877^(=RQ?ipF-5^4pe~iOX@LftspK zbryT`dvOY}?$yRyAp?+EsV!=MsC{9>51ymzdQ*Omh*ub2@|r=4bsGDrhCzrs*+>wX zcM17|Z|KvCWlUQ`{mfyri+1DXou6s>9j+cz~ zMa~0wKs#E%zON(HRv6zu+J1ax-We$*0~;m62R)lqoQIQzf(QRy+U-~U)a4tI9Ps>kz+<=}^&)1G!1oRR8< zn6ae@RStqfA!6G37}ru*@_EOcg-1cPQWhb4;S zw%2djKG#&Y&ZuRqOp95e*|ilq)s8s^XUHRy44>mPOP93G>yS=K#W}5uqRVifCQZAK zmER%#J)FOxmE5>Xj^pp~Q^&7-OC$%4+G*_B6J~fEE5~4U%vJrDu@EktD~S1-N+^FI`FG_?ou%=4qI#SNw?Z1{VVe1GkimR2V+hh zuiszKUo1T!nwg3a?T)|+t1bw~*_3mqTB2d8oX{%(Vc+p$yeom+9+DVaw^L`bK#m*< zXb!k=Qz=-Hv9s;iSw2Dw7FM;K#Pc2Q%qqjcq~{zKy#;xfiw&)d9nnlJqQ&#o8>7%+ zUNT7ILRhDQaN+GUw5@Z2<>|TZ^1&OeJAxC|KH8(EjMIFJJrCprKKdY)kqzSL35*Ao zVKh3lilu&5f2VKj3Y4;BGBG8Ck|LZ$LS8i0VIo}`{3QBslpK8a;bw&s&%lgBS)_9K zVj$3R=sn$j%%*#8<55~DPd6OQk(gc8@g3gcoLOnmn_Df*OH2(nrF^n!jfgylc7+vM z29y7DdzM5D&@C>85kqp=%xF2-T4E0}vqLDo#E~G@(R2|7G#6H0)SapI$P^0;l&MQo+Y*r>QQ=#QX2|-7F+A=@ zF7-U?7%>WYq+5Md!m($K#_R-z>EPT!_9P$;Zb4u)jA{^iCLG71TiNpY-X|aoB$qXC znhp(;Ezub^isg5v7^F#mto5Rt``6Mjk$zofjn*1v2E17d&1`fm~T2WN=cVm%p0W>tELR)N-Z_ZYMFtr>)NL7U5Kw^3VC{Er45QaR@SGJp>Dd%GTBy^>(?x-EAin4aRXH z9RTfn)aG!^yFAB*6eK_3dOI!H$w)>rkSa&izm5-=@CNOSD^M*ek76#FFbVn%O=v_X z2*~EFIc8#_->|KG_hIclq>~bir=S9Iy)(xX&JVIWiS^7B=|3f<4CL+n0!q)XU-_S7 zS~=XsF)e`1O@a0UX96@){B}`LM-h|rVsRhyp zGSzLSAmCMU0a}H8BKd~8W=UwXQ97!5z14mTjk+S#e z8=%Tw8Uz#}Hs=UiKQ3purP89cEV5hWv$;h0R2urWkB05;EXMM5{{s3tYipv1LD5_n zobT~Ix96w_vb{Few{B?F@XXXVue=)KTOCJ-=M3l`STEW*)+DHN1>}J_o56Vh=p$N( z7|-tWQpy2%)#WH}^2BknB#HWzlO$0hqPs!73(%qxf}B+P(A8FO&DA4yKs|_+G**mO z#WQ17@9`*>byXP$JFZIEj}fa!s^Q^rAQ-*0HY*YPZR+(T$R68%9)SQ!$Vm9MvA@1) zD0DTI_>12s{iAw%!F~uE!c?%5-NX2h8~0yUs9WdnFaPnnH1(ghOx>Z&V`w60(n6$Co3RbQ-yCf45{m4vKHYTh( z8Fu_oR)jsZABuyWQ^hA1gKkqftboT02uhC@mw)%rWc|C2VJZ5fC zv^UZVMA?C_T<&0HdifRjwGPE8KR;#H##dX6dg1tY=L1J$Ka~nJ!BF~8ag%<{tmJ&n-nfvdr9Q4Ow})U^;J}re;+F3wdjtkl^mBRK15KVB{$!9;TB}{ zMV~B_5kBwfkG9;uD{jnvB=mk=2#^0N_S;b7v%t&q@x+6uG}wFa60gx1Ssd%Jcv6BL z=9q;(kdt=+RU((C_q|w^{1%4nsVkts>cd4I5(|AF9_o*Wd%|z=D97Z+2OfHB)<|MG zV#0TEdAhl2S@J`L+;=JF*!0!)XT0}6>#X-UxY?Od{^|oR@tB5ET<&u@7FDGpuAGk^ zi#gx2PE7E67XA*)%Ck+vDVO3Lt9bv65Sza@FX-@%&hgvwf(^vW-@L79ty=VL%RLz@ zcuDvYTrX&y6E1G`4#%$lYh!s;Q$?}r{j*Qhm~$VQ75Sn$qP#!vD9X9(!eAeHJN`FW z2k599&!UA@lt&td|I03Ep<){-vJGegngA8AVr@viGa{l=K(*wA`0u}KndG&i%P*)Z z(NezZRa(fi7qtF|F!s=$e>t1muNZ`eaKmaqx!hxzuv?5O_cD~z?}pYRFNXvJlU_5| z+U<+)^W%xS(wM)dp>724K6BF8=Lc|ef)ipI_?4J>t9dwND*S&>24ap#Brg?HHGe0Q zM>oej-f*!z|Er=z;}is&b`oJSjE;q%_HG~6KOo$8J{?;UDt>EeLDjO7Zpj8d+uq)r z#=9l9?H-L{X;ZKN#%}LQ9@~LFQ|= zc3hrT7}NaWe?vyiTTuwH25W-efH2!~P(C_-!jMG^+^M`ll&5+F$SLsv_At=4L5$e4 zfr_S3Q5Y5Qs&uheVyj!4A=fwyaqA6prAHFH3;x$(1;TKCj3@5rAvG82A&`u`dMTsd z%mzvg>kMne$zxGf9*qH6ay{l}rw;AEH2xgQ)SeOha;Kgq7f80e+}W`P!%ErL?_W;)n)T!WP#UCdjFVyk||J^rnyNfX5?UYQ?nqS&yy&AzR<2 z%s{k+rJTM1k9VH$n{-<&72iVe-n}qV@tFiRC%eUSGM+`qwppZ97Wh(tkZxLZlz)7h zq%7O=5k5NpvLOO^`9C z_;Vrhasg71cnPci96B@^T?W@bLMHmqrFu5PGun>UyW z>UI46tB}E~-L_cZV&&Akn6?Up{GRZskT}mCY~a-!y+B2AFQ3)evN^Vas?<43}z@ogV#Wtv3erPGu!ixxV(CZR{gpP++9 zNkP6y-Wjme+F)XNNJO>(BbR~*N!HSRwBm3h4!AgRs!r+>%dYQ6&}$8^4%tG`Lwzq* zUXc0B`!;Sw38Mb1?3AnFe|@C^v7`;PuPRuVYbA{T0aC?aB54R{V$hf|$%lsl%R~{R zc!OAsA^_~$quR$Hs&u-qdCrVP^I$Mx_Z6ke7bT#gwB2|AeNYfec6S>+7%zhq8zbe@ zvdw|;{h~b$I70%GRVf|Sh83W7+sGZymM!RQmWVsKS;I>Ngc(J3t=oki089uXWH_9Q zAbB8z3xcpWHm@Q4x}zxKRw2>V*v(j9{ML#TzgF~$RQ(Gpr}AM1N|PjtNMo=@9RL!k zKsm@T5t!NED5s^yi|v1{dI8^wu1HP|$w%0!r%2nL9?9hH61&+jbj`Q@G3hdW|recTm_>RYB7OO9%n;Lyn!uGQqJ zC!iDOn`-XkF)GEwo=|WZ+1&$m>85n6rO9T7)9?l=Z1-*HjzOeL?w1#9+G(7J;A9#a z3kZtuB*O>sUCkmBAN}MV+o-uhGeVcnBb#sea?H!;0S1FNKVh(auzN9Ipu`64Ghx#< zm9xTYw0zQhvY}|nW727XaWd#$UgT1?JEmWft{3WuGZQ?#AX1AhI3EyDd$c_5l-eZJ z_q-ER$45V^++Fsi}7_S;Y=t*v%J- z4T@RSmxSlG&)vtvhV|S=m=6*p?k;7Pnq2hZhzP?$ajkd{4UR`)KMI3zBXqe>Soj+o z*Bfvd@{|K;7IuwEF}rS`j{H= zwba%NU;aAYxKE+*l_WNrjE@(^i#%ncYaLOci!U0!?%u4JU-oHM!U!;g$6?oL)&lc- zqYT{d7}}};Gy#FYKGQZLcxRZxcsfHce0%#nhR%Uj5hBULn68}-eVH13Z4*Es7+|J1 zA;e8eux_FV;+yAHiYLAwI{JfiLm1kgkMd8vdfaq^feT;^W+0M7u`9Nho+(SM9Z|-6 zHVbnbQ&xuvVp`}`JtzN2;ZrrbwrjTbB$syz>v*JsRC><1p2PX;;lDaS@wt-ov<@q{ zlZ*o@O!Bj6A*_IDUII(~LvDqv-j$hDfS`8Xj zd>-Fe1GO`>9C6G*%3sbaV;qfmUxo09NaAzB*XkC>EuS%b?se=cx@jwu+naW29mVTGWUv5apKR$e3L{9Nm38p<& zS#hej^*-FXoD&T&e}SNk-t3Z=E>Lr=|0eH2&WwxtEfQHhWY8yTyBKORM~D(Wy!dPI z=s7Sgq@M$OfLO@S&Cg)AGEs=!z#q7pX~>s^Jj$85d%n)18dMJ2Cz4+*m^sb{7q|n2 z_^0YiOu|SNMVW-xr-e-3pRQiCW_0by4gv8KDTFo7h)5cSmEOJ34cO&g5$Gs-W?{pj zxdW;p^(eMP#fs1*FJQdz9qDnx7!8vd@&;jTJ2X}=$R-taFv}nSSO_xLuymHc6Ico3 z7hi-BxK)+{ruHS!SPahuHL;aDXGR3r@vV}$jmp!`-4>+l(=Gx>X&iO1>5GHL+PMY* z8ABzNL1^?DIi86=` zZ@Uxh5(2RR4>JJCY7QM$AFZrT`^K)mZ;|fmM$;-?CvczkoYr9sA7xFMK(*2I=Rl$w zo&y!{k!CY6?NBXIxu!2FjfTzo01+Xh_?^9m79E|T$=cs05cJkOQ|XyQhNvuXSR4Cz z6)F31v7|Dz6+sssvs4^-bBQELF3oMV6gUgD@eRXu{Dj2(&NQ~%xFE;*`84f%B%b6l<7UJ9`cnq+3gy1~;Bn&l@e-&rA@JZW(NceL zk;1v5;8H>^nH6cpujHjAjI``gSL6pf_E4)LtD?40@@XYCEj+0tVP(q?-vS0Ac_=2G zZc=5*n+^8r9ElI)&*aa9g(^~d%LB@^Bd8_QK6@nXvPo?u3p##+n{j(u-J&M@2~CNH znh?C8Q;Y7uJy!sif+UYGonEAi{;IZsmw0i63h+q6^}Of*Ie#?-zMWU*{Akops^|gQ z@{>tHdWd(-`c`zbb? z-+5sW{%80E}x1sKoUb)&XGH(1I5xNup z8wP8#Q}58CRE|<%x%p5Uu%tALpg!H?`>O<%SHB2+*k}R4!TiZ!Rg)%H^qhivXeOBc zVJSEEb+kQN`L!jw(6%GnEb#FNb)mF<_pW$}<6|4e#uVmkR+8YUdQ!E2@|k)%hHKd@ zfoXj)g_eDH<8Fst-ZzCxSQ-_yG{t1f;k1m)fZVA#m{cw?9lRYj0OM~je%0V-l# zN(_u4;?{|mb*La$C7ueh%;OIAXi5be>S)X17SSZtNJdR?Cyn!-;>S}_J3tiPnr2(* z1O)mVv%s5Zxp|>aAr=zb-3U(bQ5D_tnB*fd4~gi5&C^`%9jiq)aY?=X4$0Y&=wXSW z*q;f;`nHA3)6w&kd)*=_n=AY9y1m-f#_h3F*yMHe07Vx5{w&}K$nwRx!iMu-vYc#w zi!apuOz)=jj^eT%ucmtFAS2bjq9WXc@q^U>DVi+E=`>T{9b9<(jZc4I5fkbf*s}DA z6^x+{+Z@c(@O?^q1L|oWX)WcFYc?Q47;tp7n6jF=5H{ny7xKfHY=LsH=A=b7ShiDv|z18 z<2&WiG{0rPYz>v)ds-$h#*QDB)<`84pAl-MXP-t9&7EDk3Ke>)|DokU1?+;atj)LX zEp)F*$`X=-p#I%OXDz`*ZLLPxY8!U!nY?DbC4Oy^%>B>8=pBCY%bUyLxLA3WqQDYlB=KSWYrv==tqdyU#;3Mlfo&yrU8uLMr6?+7+4uE&7K6EE=k3$IQa zArn4eFt5v{0QRYU#p>t2s@M|w8Cdq`9I~FmK7HsYPj=O*_rH@1{QSE|5l$q@V!LaP zJloyU9C`7v^KyGWZU1~{Sz62pf#Q>&Bbj^szY4{`^B&3Szn-i@60NWGq}T$5>RG=u{l;i?@+wcu-v7`r@{m+9NA5 z^V{=bEO{)VB1QP7nZevX9AuX-^TG&tBhGh%n`rBc3F4(xSpvGv@ z=vDcIj|di=VuXJrEhBi&R@L7-Y#TMEmJ5VgVDJCPs%n z`qFF~VhE-SK$d?b{jma@)f>RYlZ?jIpU8*ec1E!GuYw2fm_-4E2sB#|IVB#%GGleaSK>}^v1O0?6Kq@V1dcV2#*52%6jP( zOr>=c2gm=$2J103Yg8MOuibpk&8rdqyZEq=pBGl(O%JyBKeHX$P$#*uVF0k6e=dvW z<(S$_LC1s1POP%b+L3G#BCH5xKZ9uv^qD<~hsuQ{dUc#ZG=7g!t2Gt#)o+0!nRo)r zm*WW&kGZ;{Yq9sXCugiQLR;t8)~-x*A~U@gKbRVg5Uc%O>2h%GUT zb+v8?QixI*+lH)XL+q-db?f9EiX~LDZaBC2_Td`a7uV))5@CHSCGARy=)0^Dv{py= zs!@yDut62#u}7Qn*^E#B-KLG1G~qkZH-{ojvv@xmR%!cN!L=uUJofjfUDBix2sIm* zw61ag4w$ylqoCde05#P_TiXKOve%wF;?>R;KDxJ4bWGUnIxGC>iQ?CbUgu*U_nPe@ z+YB-_vAv>=b^p1%yNX@~_kTCAO+7feTHB!Z<#FPeBR7mG>qfs+bk1Db#^wkSlFcHR zoxdC8S>!gwl{we9P=&8T!Q8Ap&$Xpmq`LfGJDgc_4c6*0i%?Ln()l^o6>#tv zTlvpOVU`Jh(2BG!EmA5MH{#9kh6kf+3q0PDQvS~Wi;kJO*Una}(|_+>^4v6h9<6PP zSGh|UT|85j7}~kBTe?@%ZVeUJ{=-rwW46jnMB1%XQs^r+>?hT&D^#gwKMzNVvI?K4 zV_+9LgjJZXaWotFws&#m;Vc5!#I;2S6IyX4 zKb0^kWpLET`g+>05Ni^DRcG1OcU35eue2=j3`8J8iamWfeV7%wU-OHKT)6(zOGNp- zGY&(vv^Otpi(h+I!_OmA&U&DYQT-k9bee-h=GO{k{iDBP~5=PB6%IYM0?<`^1AtPkyZ4v zj9=Q>kcB^3f#qzFk*S9TB*}wgEKi3(FhO(^$uT~i z+<#7_+d_;P1|FNA?BB!ID~lG_88@xX{pkk>q5gi)f2$}>Yd3?R#(AlAU#nlhrjIDXM z?_=ubu#`9Ai>Jy+Ue^(D8vzU*c%6UKizh7wc2$Xn-b|s2{pT76Mo;o!_XY_Q%vA>$ zGx8f{#J>wv)RC6ZxQ1y8-DzJB8hHy@XG4Tx2bBq6jD??w3uqyl*W#Oc2B0CmB{-7W9u@zMY{z2?lVbSKho@J7kO#e$sU1H(B zC%I?|e ze>;DP>x|}bMdJsGULrXDFlY0om?-{XglwVYI$~=haf2v?NLBf=_@zS$Nl@v6I;5fx z#ND_4W{i!u96*Fc_mEd)+>Z?#?S=LplKoDCpXOuZt=L1taJoHIyl_P}?VWuE+P@vr06>)LcYN_v@W z6(UhM)|$J>F(qZ%dy_HuU;F*tmLA*rO~4v6Di0lKv-#?)*7=krNe9G(4LxoA62)r18!E{aGE zsI!C4(azV`-Q>7vcW0Y5k(VX$9WP^R(&-Bi%kkh6Mu@I@)YqUod~RO7xE&xL{F+K4 z6v?NU*-bMWcXMlOO~!y+dPOpK70a#83$i)C%S5RQXYC7f#qa+RSdH+n;-eO1OSLVt zZZ${dgcBIQxBV!FUH`CMW@hyHv$py$rI3I`EEP8yB@AD9<7Nb4Ec4TfDLODh79=o&!F8}&uRiUawFnO<+>>-+oo!ZQLP7VZ`{@?_qt?Bc}lmD4nK=&HMW z1qO@IaaBE>17P00^X?p{hHV;T3ndqEm?tm7?(c~Ob&n6OeL$I(x7~m8t$V}4=8NcH-KEVd~pqfAH3H}#sRqUJ8n-^KDB%9rvBt>J_8RysxIi2B_D?P&c_NKhgS{Cij!5E?Cc`X&M#gD zNWr6pkHN0}_pEfQcEp8e1&d~!uQ5?~u#L5kavSO!b3}9oQ!TnhNr5h{ew}ekYgBM( z6UG;EEn<{ikkj`N>FC1J$rpm8!Lc-;FJm`D{k1Gz-H3!H`oq%bEhEvGOMT z%sr7{ZdrljjUS<*RF}-(+a*n~Nn2eRP^s#%R=H;D<8PMFnD1o88b?|x$@1_Cp^%EA z&!2*f2(A#yd=`5TXH9dTj`Oy@wI?_B?MkEU>0d_rfnc++I32Ccq0;^38~}+U zoz)k^*P!McIYc)_z>E&3l_WsHK_RTo$MUoyD3GONPO@l8Hu&8%h4-c7rPLHTqxhe>K2AIXkvsKIWm;_ZYC0 zIUYnWF!y&{PxDL_V?So-MuwrPtJgB*Vd^@RPmWyAE$uX1@w#@xf6qfEsiV_uPyua)L~!uq(!9R zqEXsjMcIDTpirW7Of8`(28r@GOJ1SLgYxrZz`f1s<*JW+c<;h?QsjaHksz081*$ye z>08RsN`@RmREzE|o{m#>JGv{#+Kg?6W2&5PE|>%C37|8#KA?mr+z2@wf@?}UO-s8g zhICC}T+#*`0tgcOkl|v0apT1>u?H_k1U!8)$`tfsomR;p;u2wG{( ztZ^fT44c5Q>yw++JX|R*SFo3E?Bs+DSnVKJcuaGH1G10G{JO4dK0PNP{;6(7SSIU* zx(6HmwI2Q0UT#)>1vBTj>Cz}C#IlaIdn_}u)*@Dp>WQn`xFJnJw3G5DufUOarQGSYi>>=D|0!q$U(83G+ZEuW&R4jdJ6jeS;omLSM2vx{*us4mFeeV&0o$! zj%ISEY76rpQX{u4!@~MYp>Nl-7z{7-F`hO;F6N}zk*IQtZtBOC@$#G|J(iCyov5u? zC?oaTuXdK{90%p}g5w?sb4p0k`KtrUNv-=SXbzd$c3PbVW15XQ4C23i0}kYmQxTq% z-ss?MPLC-qM_5jwmn{9V=$^2~FKH;+xPq`m9Oammg(+UGuXJ+EbE};c)-4nI`@c}L zhz7?9rr+enjXc(^xI5z0Nn^0&6qHodG_)+NY;xG;%Hxo)fKy=|{qObgDpIUOsWRm% zRH{-fBrGB-rcPYF2926DOGrvd%gAccs!h8NofcUf7$5)zJb(c{z<~e=fe46!1W17l z5FtZ_4ih%=D58ui>S&^MRdmtE5H7};VvZ%&*pd@_a+4QF^0z0)h|A@7@uIPOd5`Hq zc*~1;nH-qt!5U(DZ+{QmR&b(t=^ASL<=M4*WZB9UNFqm&#Af%4{pGv|c?4+hXviDF z)4YeQRQLnE0`!t|g>;b<*U!a=kIc@cF*eqNEem9$O$h|y6&s!@{>lfY@HHLJmDuXw zk(+n18JUR54re4dCi_US=<@oKfuSDEN8m=!BR6LD+~{+WD^`4F*zI-Svd3Er)qjUh zruv&?)=hdHw#v3!DrL0I>S84hMp741qEmzf5I@7;GE> z-@x7*MOh-R-d(0&hfQyWlWSYq+9C>6daQjd5wv59|LwrqrN(m2Iz zjgG#xY->=qP+|u}aS$HIaj>INeoI=nnhxdsxp%{LEI0@pN**u;qJ4SJ5gPj>cX-<7 zzYC6|;y_A{Rzc(dZIq+L1~Gd&qo<217v+!IFE@2jfBTu+e&qI}is%3T-uLI)=Z+C- z*gBQQp^RXekNZ&0?8w@zpcKM&WayL*^KngtN zhj;7%9XKS@AxJ^#?AxNgqE=Tu`8fXnPnV`iSYvluZIT0q%Fji$;JZEIy{4EScmK!T z%zUlJK+;kOKyV2ES5y68x&0sCW_C;hJ%`_tTM_Y}<)VnKfl5Th8pj#(t<+$e{$-a=4?9%!CIie7vRu^>+F`vd_m> z3D&aPaMIPF8lrvt@BgvobJIn%0VmS(iEnYYw^Eb+8e_>JV#SO;-fdn0=VD#L z0N@8c27qnx&;S(}d=9~#c@^;eSibpZ$3$*}9l(p6*C1p+qprU5*F3QE1_1#2t1|!~ zVTv0eNf!lrJreatRTh%=rcySKdd-$tVcPv>%sCgT(hK-PJy-A4`)yy2vdgo1J}>1o z_f<+NNX`Gu>9Y&Z(dsxjQDaaCOH5wIlVX8+Zz4h~3k0hXjNL%PiWxo!Ad;4wTjewFG{t1^@xS zHyI(2tkaAzM2pUd0R1ttb!%iwN(k>wg11VOOxaJEJ4Ybb2(t`5(d(lD?mBuy-Qt0+ zi68jeW8VXuabgBZlB5d>LBt-qL6+db5E_RB30kD>NG3F{u0ju9-5^?i4GD?Ix~qxx zRugfz_1jj)t5~CqT>FxDX3Th>lJVk@ib&|00Kzv~A`aO>gs#S5int}5h%Na*ChKMP zJ4r)nns=XKim;Q*j-cEU6m^ueD=HxIiScLQLMUBp_<|vAtucLYgn|X>ky}K{D8^-E z05ynu=s_kk`N%Xw+>Fw?K3X$krlyF(O3b;zF{r94(c!rv;aYcO%rvY%5y}6VaU{pk zM6_&LzoEjGv*NS^y>}L6WfMV+&N4DV7AFIM#~9(UEHeUv)@ZX#F+kFI zKD!H4+VY;&@K#p@eRbRu8v|=o{Iz+lL4!D{AX2#us-TcmS47>Tj)sQb&-!0 zdW{t#;zhOUe{OiRI*ku7$XFsiC=+wcTNfml>0K+)?zPS+K!UrT9W9ZJLW~Ij1ze)` z?3Niv;Wu2a2wjCl^xzEAD=tuJkA_AOJz|S8%_8YljO87h(4WdZC2t`|0g{Z{w9DJ) zy3(UVGPo28h|673Y#R}3hN5ulSg@NUxWK}Cgmwf(e36ssG@`x{w_wPKaHgfl`>Con z1bYm373(NqOQG;2(u`C#D?pTV=peEl8c}BPz`182E zF%XSzjEphbBk3X&YDv0m<<`mJ6PHnj1c*sSITHxQ5f~{5f|LYBD#Ac&f*}oIqIiNM zEn$tZLTqnKtS;|ZK~Cr+Qs|ItYbcR9f6tm+Vs`#LV0<0({-ZQSEl)F-nCuK&vzt(erDZ!MPuAl(4 znH_0Ln31HOeXFcAM^66CO#D&rZG}k95+iNb_N~)Ub(tpn_NW{9B=zW2jEW9=eg>hC zBXgYzWGCRRQT0t`k~8Pk#9DKchsix6U0TR#&C7TGi8+8{7Q zitS?D(poD4_CO)-Vwf2+6108ub;c|Z$S5Cl)PG!;-V;}R`^W)c~uZJ+7)TSj1sch%vM1*IozN}DN7+qQt})j!-GlN!5~@$ATA+RK+z;VqT2#F zc94)5#wbNdikWzcCrEai*a#R992m&0=M>?sOoLNY*c^pulu4kdVe63G&Mj4hVAC zj`K+b1&YfMP6+X-ITqkoICBK$

uJ`Rl(T>WUyh(#Il^}b(;p^jcl4C!H=Wktd|_LD8=O1B zj`)fCX-8idj-LzkAE7uNhIqp1!IMspy7&Y8&=Nn?h?cq_w9EyecEscBcmhB%4(`q%1dweo1+K0< zf&l^L!mk*X4fDgSrGM1V1;~nIh3= zsDo~)JdSTnpt!+gtFb8LN{!bj#FRkIOEC!a?93dF*r}38jTw?~Dp#uGS@@>ROjmLa zooX@2WD<^4Dlscaky<6;7^G6Io`;L%$=bMhT_&B)XGhD$0=YsiS133P4qC-QtONeX zM*bjlHl4SuTOcUr4>%)}5|a{9RMV?z>Aj#_oS9h~=}kK;G@)e?hCc@shRr`ib?jeH zY1{!-1#0XM+f~{8REp29qEwEl59r7ff#M%pB@ve&t@%0=-nAoQ$sKKxq#zX9OL4Q= zDguO+!`3cKF~qqPFI;OusF+D!a}3Ls zKqz{k(J-|iL7321gb0QTOxjZ$`k2%KgqS7lT@O_l+9~}#g6MHV{~>gu67{Uc_#CuE z(SwAYv+42(l+0wR972+!d5d@Ihf|Y}O|F#YuD<6=M#Ts#c_J4IDl8B}!w#MWBMl67V)zhYw`JRk89lH|8m75bcXjot5`I{?i(Pf) z*yRBt)AP_B(_t?wxwDX}&U7#a^VL8uD+f)wF+v3HifE@BAj8fWAZzpU282GXdM;c?x`gPQsmq+P)4am zkj$L{oEz*Q?I73n_E}F&!(<_9*o_>GT6f5?|0~zv9}y+VzvmBob~AiBBXkQFwjzWx zcZAM>uqDzF@L~CleWvDNXdpzWED|a@V)H1REd|grToS=%yIjd-!x9r&A(KZT5JsjW zts7h0EvrhVv3wd%>*=E+gN;0hC>1Ky$g@eXDTnV#LVsVQvy*gs*mmSI@Jy*9LA*c; z%6hp&7ZCQxKJy3#GhgBEg=bVR`K&;FFqrWA0|E83VkN1N$uLPH%?1clpDWx^ z=}KqwXQDtKjM<)fm)`<}?s0_CJNk?npNF(5jR{9Y;!_NQYj;#f5frr|?#Us{|bj2#XtXA#yFuv|5uusCt#JX zDJy{Lt^KN^Xw>A^#C^XXVL;tEf92fGrbUEepj7+l>$E7-x?E+mgn3IWm6c}LmW2Cx z#z2Ipmk9%$On}1JR=LWO?Mz zfV;9P9~@EM5JI$zzphKrUbq&+U|L6d1CvQhS363{0nNNwuF)o)Bnn~c`as3)1K%Rt zZj+fKR|fW!!TmXZ`9GDfnLj^~s`~x_fz6cAlZ%B@(^zL!&Pn6L6TRrMHzf6VY^eUv z$UCSt>)41a?b6IC79>LGwz&+SwqFfo5k(^5Rs1i9?w?Q1_`b{?+|7mj;SC5uQ!fo zNLYC%1bm+4@Mi||jW2VYXR+cmT-a3h&`7b)EoWbxi@dQW;bFodzTMEc{{G7UAy5Zw zdM~`o#mB$kk_)$(j5DD44{Xc{@c=sBjq&5Eg_BoQTxY3vsscZ~C12b8g78Kn)py?& zUvtb&_orGrW2)j8-yvZ4GW|zTwp8gxLUn}~b}p6HTP+BJgyNly^bFIudO4FJN)n1A zQ{T(cD%P-hH{RX9HgAQ2K3fbn$?p{7O~ua1q|rF1U@ssK-w`T?=K`&$KjXY8I_6;` zQ8ak9Nd7@SuEo0~Qghvqr~J*Ix2m9>k{50~hhf|ffDG!I53jb7kCclOR|Y;b0(Zvb z+K+-s^hndIR&l7VMIUAmFQZj}mDEdY)T(O3rYsveQ8Z=c5uuy|8jv%RX2Fy&& z84K9u_Dd|HL1OXr^b_^C<eQuGoraK3 zoMT-S%bnA1PK^)1{QhzZEAA$|TduJcl>}Sv&Pe4_S1jrix4F+LNj*G4kc5cIv$uD> z<9_wf^fKOt5GnvlAvBEz78iTTk<7|UQ>qN|XifS4TS9=6< zrQ9VJ7MQc@jkP74ehP1`4jku6FryuE0A#fQ%1V2dOdkA{BDhL8q3F!s=g@6TQ$?Kb zCYen&aHo};%c|OWGP;{IIc5Xv{Pbi~PcZr8O{~b<{VV94n|Y{{lqtTiV}2+0qZ?o; z9)d?IgsEFF#|N5Onu<;;n~jEq^R+RG(X2BjxJl=ON+-9OxFK(gsta}1%T!+)-hvr< zrh4ww=R&M4l?0#<)Y7tc@2q6O3&}f2lou#!MKJCBf#Rt5=E4kYSUdD5f1Qra432Zj zOVK_ST05h0&`+z?;-t`G43RQmrS%|ldJUdy1S(Klo+oyC+dwY8@ve?m-PI_D)b>f$ zS;xr%+-k|podhy09rl^T>5<>TpSkh!!Voi*m5&;!h~x>2c2(!6df8kRt4}sA+7!pBHaXs97gcFy2snx!IWG=QEhrc z6N?kqg^EZBCm(^1il>D?9_Bm4zT;M0TUD;0$PhyGXE$HmJ4qoAOi>I*LrI!FVevau zwlk7aKOpzfY7^+aONbzXWT7Dwu3@tR#R&^elS&1q-dWLoRt-G{LR@MZIunB5kTt(^ z;)`oAJFI1JEM?gn+98c%zsVKbsPx73-L}7+CO<{~9i5{+Pbem|ZZWDgSu_>dJa|ij zLWIDzgo}DDJAvPUwy9fUu(4jv0NcS^9$|2}v~hoOy?LD#>#Tvjw>4hDAnnnzO1e+y z7G(ug-Sz=y_WsKx_uEE3=O*sKpDFjEJm?WvBU;pQS)A0dTj#j;k+9yL~ zJAGEay6Dv(+dRV5J7yyo!>XJ*JTbH7$F|d^pO(f`^{tL-y-bA&^mG`-9GmxEJK9Dq zGneDM&j;(98ncryx|g>5X(ii_p@Nd)KKI>wgwegpw%@TvHVZe595_?OU9ZSY`lFpp z&+pM{Kc*MYR6njQO0AWmn;#)`$Is=t8(@{=p^ED^&epSsTfnuN>&W_)4F{mrH<1+?{8IOx zX#5>GtzHKCp9u4jHruKU|Hkc;?o-Q#bS^l5&E|ut`=Ok~6wyvOPdULK^C5!sV#xSv z>8nNq_66fvvDBxdQ%qD9Wu%D;qFh4Trt{0$R>Fsy9x+69eD9uNP2EXU|%ecz8+Bl^YZ?5Zi zY=PM8DTNCPw8M#eLbs*6!XHw}TtDJ_K%@Sr9yG{mNj^YseI2(9EGNmle571Z!@m!# z6oiBe0Bqh07vuv;5dTbD$Zr}cZ8v_f?QH?V4jNJ{xYv)*DN)AG;RysgfBg?Q0t*lQ zdE@)>fUo27A@xtJ_yb;nR3~9G>jXaQUkEDdf=oE$V3S{P3WAU2Ld+Kd8LxjIg{o>} z=_w8DdkoLbo_YS@xUc@%`h(XXA?mvnw5_c9@2Q=ayk~B49`m($y|lN*_ZUq%1a&VI^t2T!KKy>N zRL!t?UfkGOZQCCuaOj_&>kND*WqW(qgAjPfsLh(a`&@73osYWXe#~cu%=GV7i4AaB zZ-`s2%%{Ig?f7#&)ev7+QrR{f#(!j1X+|w+vStYG{3v24)g_;oD}T)M72U{=Fa2eh zWk^2FjyQgYV*THuT?HGCtkr!xv}Z{7{gKrhAYe3fBaDZe#)!w4wPY_l^f2c8T4ywD z>>z%-?}iPe<_?1dW?WrzAS+|Z;j0J}yLnlnmc{i-8IWQWa*os7X?0MoT?P#sz^HMV z_GV6V>2nRQJf>|J=2>_RaYRdr$@^^2VL5*)1;$;wiRIe(hl$<0jQ&!!8|?8>)E_1tw--iCK*83E8hUM zS6fGivki%!dy$Z~OAh=vRLS$Y^olsWi|2(Zap0GCiqH!Dtt9Qq@Ne5?;ucH&Pd~vI za%Cbyw~&ssA;NE0IheK@!fLH}6f1u(Bh_zZN4)H~N-vvHKk5EWlD0f|=?=$-UPZ}R zQQ)5)-t@h$fp&DAng*CQYNUyHEm1C^AG-uhV_Y)*$X)*YE2l7zGGV8Yh&-rxhii%`RauaVg8k6b zWfU0#BF_fbVDxU21y1jV~_zgBU;ZdE4jcx4wqo!Q~w#54Z zlZ+Z^BA1|zl!M(0lAfj|>_-r%?8Y=*^pk5i!zI#IBlyE%b8JC>C{~;v@rc4oRA2k5 zCE-+M0@Ncd4@bp)BU8`s#sdqxQN~1wZWTXmJ#}_|CK8m&ozva?Bzol37Xw+GxU*N@ z`n;vuS-P5x?6#_gWw-e2`!+8rc|C*0qUt6Va>YTNN94>^Fv8cb$Ja{I3R5#(d~8gAZYB{PUefiTzEBe`sAYkmHkH z)y14b5p_2LhO z0GoF05EX?Nf%|SdaU~NFM{`x^Zp`oH`1mr?nT(o>Q-F1QmmW zHeO(Z@%v0`&TrXO2Qsfyjuf23I+ag8SX7sBx}&hufC*&*KizUaw0O3<-N9_d2i(eE z|7{#v(Q2)FcTIkPlkY8i{P+>X!ecVt#Q$v8}}c$Q*>*bDaCU2XA%X>LRFQw z|4w(*B(cJBCWrNtd1s%%-QDEl$+4^(zXs zmZ_YsUnkjl_ss1`cRm&3G-I-nn#g~}dpjIvZ1C#{)Vrg9kC=c3pP`IbMFd-*=S)A* zwenP;ed}@k{Vh>%o|40Ko4R(jZGrzRl|U$$9SVZ$6D4Dxwkl_qibOlMFZ;7#q|1NT zhOamXW}YMSUTy7!9~`*9hyei@Jsj;hR(a+AR&N^lvjj_Bwq$n21+aYiS_YX6O>`wl zmo8g%dDSI}m?^{#=fg0;SAL;qN7Kn~zoCb|lfx2{fFJs~a!J)*(8Nn= zBmLX&jm4w}Lh|sh5B`XCe@)dkty{_^j+wPtTJzY4v975mBGJj3nEaYyiaPy`+H2J| zk_|{5HHC@Wpvo`=jO3w^X~AltC@ob8I#yKI93qV%>c@QgDe9LehT1tQC8xdRiC^d` z%(c&PTXtYyce=?{8>Yo{j1<;_y6CJnzClkL=$Dr&J+{(3VZW#ao#Wk5+M z#iZm%2%ab2u+R3^KAq;|$;c{Ao_Uj= ze2A5R>8%gETGKqAncbpy#Uhw&HL|DYt$AqN$=J@r!hDdY`rJ0YGGRDh7@yyD=o)a^WllD4w^2A2OFb;mpve`&o?M+39q5lMv}DD)!@;y>?D%0t z?Z7c`9Nl4coGM6GKl>W%P+47)ZCyN3fw|{CKY{XP@34F+^}cU1%(`PS5&NfaCVCbR zFh$9$o|1p`&D76E*^xkrD(|CXMcHTm3)rlI|IXk(c2L#UMzNPF%j#^&bg*&#Jw*tm zD_C%7?K1~7b2)2F8-J}hZ=?=%lmt!1xbf>ZPYdB`)XzW2RdL2B^@k?gU=G5pamRv1 z^#S{u&XlimW1NloX&EW@x>v7#|002>&Xv_AS`}G2jk?GFPX#oCU{hV|ca;}qgwg(9 z6E5@HQQD@iCu2gI?<;isD>qeVdpUQF$l`Gw-ube_8vlq)#cD6&_7}v`R}K>uNe!h5 zzoUB^mJmyYy#|aPQMwf}kwWZ7qUpk<1PP-~CzXL*dt@ww>Rz?1?4qFjttrRwx*eEN zw^mnVtabg~k-KUbJE){_!DM~=tzhDD*TdjgG+k&<``$m z_KIx#$H9gvPBSk>D3gT>%*sMUh{%`a-q?x1q> zsE)gzIcFF#j>lDD7oJNLU_F~mdjnCAZ~n=FdU=bgCxgvR)=bJ9Q^z`@iAmAGUQ^FT zh9sRNZGSHbvW7ihWt?%4-ff<87ury!onsWeW}k3K>lFcD$V?SdBU zT6HxeEw{wUfBo~KS-w1zRe89>Cf(JL1d^zLs*k~wGf zj+aR72lBWpIs=|L2Lk?O66okg66n>_#Mw)-Do7$uVwq6z77c}%uFW)gd)HG9O4&!ST8~B`aedc}GNCNQ+>?z1V-h^bV zt6Aq#G@9OM(1HAN)J*t{!)ybAd6>w~%Is>S60JnKj$Rso6`UV1Y9w|4z~un%*ec zBD<(?aqw|t=asHh$-|$u9z)?b2nEn1W4tHM5B$#H1u)nOF>nN*SVpp4X7m_VJ13-4 zg#8Ay8G#%v@N03ZN3}$AruUUe9^B%95VLv5RO$y0OF)IY8oe2&x@~*;qPv7>0yBzz zZi7(SPCf0((^q^w4E}wb8!HmG+Ae+2h=hhOe&!~z> z_1f#UUC|UzW{=nb<3_stc9ts=8`-;lZPa6&QBb>0H?1<;(0OzeLYpC-6_jdEoB#^D`0*z&oq+ zCN&p%Egf2@2TRUY$0A{euQ9%tTj^s1MhrNtW%G$DE`V25!I&cMPzpAci_)_@wAe&Z32cz20Bg>sr6lU5FtU_pq_7}w zUdm^|O@>mWBs>%-XM$Rwawr~i%#p-_KE`*NH7bm=FgWBZOi9xMG|~eX%rH~I!vPJSVmer0~aYV#zE;O#DS0nFqw-+2rcYeQb?~}E;@Mg zo>a30Q<*e8&|yP2l*J%{RFW|sPIGWpo~lgzNP<+x`Uu##hAm=|WK)wI~ShjNPYV+1Z|6^Sd{2c&r zFaXxBPK>JSiVF#E&|+`uE%6tpodz8y{Poq)9T+G(Q`^r|W>m)jo|Y#iPLVvM%+OYj zztsen{eytp1O&Nkl~4>eu!B}i!|sBhWRrP&F@^g+B=t4aV^@1qGOrQbE}Gt-j;07y zwi$c<6UKtFy}fQ+CFizB8nS_s1c>G`RVM&(Y%&ewYMLk2psXye%zEMjco=All9n%- z#9CAS2l0sjO`1h+{L}zoPkes~OXOW%T5AWXTY(agk_L~BaeMB4V)l{BweI{vSzm}_ zDy$~&X;4<@FQBZxdcb+_X1=r)kFdjBniptC+RTRQeLoARlL5K$_RDECAh)I^rkm~3 z8$C<10}P%_sEll@bvD6qwT^Imywoi~FT#&A18G(R0)>U{XPz8y1 zXB7;0wF(jTY!xaY!YT$|GEQS#RlFL2mV7OryM4iL(2&JO^jM(V7*c|EiENx4Uz;g8 zVv1Ii0y>StctAr;OX%cw%eFuYocr0aQHv>V$l#)~v?2m+T6NHDzr~6!sPJnviyiVP zOQ*ZMi_f6GHV$$AfH8l>0-Xe6=X;+lBtlDacsvlPT9OLxprP0eXCFMaaMvRqXEUgK zX&#U*ivUkEgPlvF>epop3B%@?$Y$;OwMx@%A@igg(&j(Om3Tk#{4W(c+y^=z>**bea`n(V9&rko|US|m)5J_~KM+@*`Ol37}G&|tH$ z??@950jGTJsCN0<z(I{S3PO5uOsC866l1 G>;nKVNojrn literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_SansSerif-Italic.woff2 b/docs/odoc.support/fonts/KaTeX_SansSerif-Italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..349c06dc609f896392fd5bc8b364d3bc3efc9330 GIT binary patch literal 12028 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 GG{*pT{>~Tx literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Script-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_Script-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b3048fc115681ee6c1bc86b0aa158cfbbf59daa3 GIT binary patch literal 9644 zcmV;dB~#jWPew8T0RR91041yd4gdfE06`=G03}%f0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Size1-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_Size1-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..c5a8462fbfe2c39a7c1857b9e296e62500a8a8a5 GIT binary patch literal 5468 zcmV-i6{G5RPew8T0RR9102N#S4gdfE059|a02KrP0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Size4-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_Size4-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..680c13085076a2f6c5a7e695935ec3f21cddb65f GIT binary patch literal 4928 zcmV-G6Tj?tPew8T0RR91024p}4gdfE04S^g021l|0RR9100000000000000000000 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/KaTeX_Typewriter-Regular.woff2 b/docs/odoc.support/fonts/KaTeX_Typewriter-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..771f1af705f5cef5f578b3a1e7d8eff66f9b76b0 GIT binary patch literal 13568 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 G0ssIW6LIfZMgH#8J91MXV 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/fira-mono-v14-latin-regular.woff2 b/docs/odoc.support/fonts/fira-mono-v14-latin-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..edc71a868ab6867ccab1e3b3b772033909548799 GIT binary patch literal 16284 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%0D3brVzzkM-$VsXg*t!-%f< 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 S=daF)={K-yhxDBb0002=D`A}g literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/fira-sans-v17-latin-500.woff2 b/docs/odoc.support/fonts/fira-sans-v17-latin-500.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..24bb8f45f89f43e11b1e6589de9f6fa9f0175e94 GIT binary patch literal 24020 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/fira-sans-v17-latin-700italic.woff2 b/docs/odoc.support/fonts/fira-sans-v17-latin-700italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..bdf8f5f9844d5d875b915e68ff4b4965df337049 GIT binary patch literal 26072 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 literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/fira-sans-v17-latin-italic.woff2 b/docs/odoc.support/fonts/fira-sans-v17-latin-italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b9619dd5d7e7d0fd16d0cd692437b3a76057ad80 GIT binary patch literal 24936 zcmV)2K+L~)Pew8T0RR910AXkV5dZ)H0QUF*0AU3H0RR9100000000000000000000 z0000QbQ^)90vwP=24Db%EC_-y37QrW2nvDlXo1i?3xyB>0X7081Bx63AO(Y92aa_N zfmIt3;}_UA?S^5!Syc((yZwZsLK(M{=uS{=`_z+n0XN2J&>ft_6#LcW|Npa+6B%PX zVc#{=>{bx7P1BBo)l-5~CbFD@qfjsmEB3L{(zdP{Iv?Xn_Uz0uv#18&@luJ5-3ncz zhp@$}>cR=Nz4;ZlPhrHFhCU}MW)y#-U>qUC+LA4bXRBKV%O$$?MlR!;Y(h&D`ToLp zKI|q}5UYnAv*2L*x7iPYvs+n)IZ z1R-EZ5g0^S=~>xL06jY}PmU_k!>zs+9nP6SjeKm~~kK`I~F2H4H=y#1AP zYj4rtMX|{9B3GBSyr}x$sR_X`T*MCW8g)a_8>mm6TU{BtvHtUxGNk&xok($hhWt{f zYPsRquNsyRf=W?h1V*|(oO}GVy*8KYC22}Y9?*bLO(-BXhK-rgW6j1+^8XA0&RMQ0 zAP+J}#(aen@A7}_0e32*TjkVNeO3VfKB&vDCt0RJ6OV04wg)gUlaETWhfA35sB7+b z6;Qhn;?yp&G6C}TL)$kiO7Jvq7<>h>lf|-M!0&v5Cf|yhqE1)6EWW5K zJz~-~LJzR$f(LxzR~i>AHwsWM=_D zioAsGtBPQyO(g@t88j!uZBu#Yiz-$4ar#7ob!{nL$x;OIZ;Co0 z*r-gTjup9oo0WHG>aQLx@R<03Bfkrh<;Xyx`Q?t)RrOW+zq(sH(#W$KEzvBH%uD(W znpV#-M+S}vFi0p#03#=flhDrYvb)sTW%vL4)3UwyJ!>u5vnT%JfF|rkPuNB0@iJ7Y zQv&P1|D+F3Ulv#!f$jNYEy&i8B+nRkW5MLe_ACGg00aZ%00EaN)7C&06=j(!70|ISqCnqb^T!fsNQ-%KH&@_{shv`Hi`=)8-r#G=S-awjV zLJ6TI;Q@Ov!H1KnAUMU>cI;op_CeHq#u+yOr^jiH9((Sv>)_3CqST*8Kr zwZ;rGSYxcnvY7Ldc2A_f9UI)ScV=d4s-mJIq9USd$A0Sfl#JPF48rA@3K&w;w?5z2 zv_1T}`o)E!LAn7wH1a$qpyZ7EofU5$Wgd*nx0|f(HF|R!?kYARA&~*y55B1+?`N-dH{0O8=wd(=-jfKD>E9v1O&q+q=92gv1Ly6S!lkM>Y0A= zp7}4ncmB3y&F@BeOfhR~)O0qbKa&1J^2Qo1bYpV?L;yj#)WdUPju}6eL=nUq8y9?V zaO>cvT%T)lWiHFPIV-2$tWFWfQmCI7gtuS@IfI=&9B-D@lS%dk6ybGMu8hwaJw zYKO_K*iY8l_4X544a<3h1@je66`|PZx-QDwcn4*ae zh*YP^L)3Ix7eFo~p6&8N2<_m$dgb@jle%9w3BBCib-qs4;q&*_ z_8Mvb+E~BUPuYIcW%U`X=Uw{k%1u%|ym)8LskUmUs_kZ#l%qA3Q&TFr;w!2wn`}oz zQQM14k9tbgo68JKOER&1OktThkbz!gEO%4g9}0;@fcyj`<|fzD^IME;3lvvIBWqS@ ztU#$tT`MSVuwtz(9-I}`UY^df*`gDb>S`aTuK!C~^}p9kUz%KujIB5)0g zzIs8Wpk`d>Lw@d_#eo``#OP0{Gn60moU zrjmE<2^g#pnr}bGLXEn#Gw;2KBAE$)wHwx}dxMOD#!deN-pqyg5c=01W-&^!f__8SrNSR7omq z8&r4Oo4r$nS6rZG?0a7=FC1owAR9e@73L6!ri;0C^>6t~qgrZvIK}PUfFov(!R*II z=+8bhSw_tR0u7-t6{-H65=QFA1@8(JAk||zxrJ44+d@HoI1KGA1lkXL;gQ0ALHq{; z|5KV?189st4clO&zdA1e8ey|7U$etbyX|$hO*r1n)zzNdX1XEFS*<)l|K0E zZn#-72`^4=-u(0`t&T(4v8bp}qG(7o@L!44mPo-qAwiKB8s-s`r_CuC&mU8en(3hD zDzfYN0K|;VCv(?)O;sN>Tpb1)Jcwn9hm1Uh?dmbDr-gQ@UvRzA}Sb4DZee?hfzXsNEmVg9bfD zgoZTKD21qt#Im0h?W9}_GxeWH3!ce~`rAp>ougJ|N@Hy*x(L_hCqoG4{s75E(Jq`3 zY6`|hBg#XvwFAhiP%U+>rtdp9v#8{NG5FoSP%nc*f3QZ>3^K8T)KTw26Nsc^YRCLY5NR+ncY z8P%)Cr}->Gy{~r7S!{K)h~$+@q~Gz&Y4n+Ru}1FA zD7+ogyC~qaE@!6o-bUu*0G}%Zq~M|2^d;s?o?n#@=RFh!PuzYs?tf%YgtX1d>NYDk zLerU;NC&!vZjdJUq0=<=$dPFe|FdLK7qQKxe^`S*aGc+nJ!b|K389oUR{pkJzkpx< z@Tb50ZvaUBm#@$-^1?a@0$<868Boa;0!MQ2aNOBhljF|$PLSGQZ}T!~-Ys#Vbnl8-?829- zQ)Qs5w9(0FnSuBp-LJNmPpT`C#X&;NA$&U0b=j`MErRYobKnBwZ+LJcC(1z{_&r0T zp?+zzLk@=dzjxeBWo9;ZB%VoOAp+Zl2~)Lx^BG!?Xob0hEM|Z;hh_ydC=GCeaH=M##RjPX1;+2iN#2k+(Aqzk%g0d}J_k z$Ou&(RF{kMb~HSd1I=WF4vjX*ClhLtr-JH!Q;fkBHz$9`?PO%1<{C3|5|}h9&~0u5 zPa_sgcB}j>M#eB-9@Che0CzuiRiCJq_{x8)CM9Pyc@5P%Ruihlw6a*jsEzd#1R|uXU z?%c46?ag&jtgS2p`*RUULM#ECnb87QM7fwVa43M1>K^QLXZ>wZe29+V z*$3A!O8~_o8@7mAVb@D_4nQpR13guqKcbM`26L*th6MFqjgGt={QvHsK-?rs<&dvj zg-TVb)u>gk!9rbnZMDrg=Up%g%R=B#;o|bMyN*B4{*mj+uOv3>Xj9nQv`kCOtN4tH zZ*Do!(w-&5TcJF8@#dKHL%n$Rqn_iwJ=G-*dxO+0^*4f zspX`nWllQf{ZFd7v+*{Fp7Z#p3@~aojzczOCnSK1BN2NvqM6yX3m#e>nyhmL4nj~O zCmu5A61a1UuHo%MRiiRirhv{@i=keB(_S1r$oi3Vk2U8(`Lk=-{kxJt{>b0R0#!4M zIf8K1bsV_$*9V+$L7dWDK8BTmsixJXEEhAnaKqZlMG@x$K`tUQZI8_MIUS#AD&2OJYdD} ze|)fC6(>AG78b%w{^%A5@%REsZyg07Gvf2(2D}X~!B&YBrv3Wgv1pJJ%c4TU zBZa$QC#iK^Hn>GAJsnS7=_x2nk!^}QZiST$EgdrXAI>>v6DO%)6U0Pu1>vHasDEL{ zkdAcTh90GYpe=V(NKE-6(!JzZj|?D*M0G^?FhPIo*S&~8NzMh%9>6_BxFk+MyWpOs z9SSKG1snyN?bEY^B-GW-^8h7+t;BMsd3XI(q|62K#C}ws#rNThp^FVHPGp^4=%#=2 z4FLF_U7jpo?zz%xtWbxvq5eID^0#OFv1GJCoa~J0NEHDBxsylQ&x;JHfDKaTLxD@L z+Xp(ZG;(@15eWuT6#NlgLozY|fn<>VzS54j29W8*Z1t^ZO57$Uxa|OOb5+(z#>Ogu z!mNfkf9*DK+vP}J%av1nz!UG$_$&3o@nb?sw8N*rUwdWHe}Yy7ZM*Z&lU(o{dWjG4 ztBuBg?HOB?j*utwK0^DsFNGB8fE+7DO-!{DHAplVlvbWW@>OH#3qTIwzqyHAOMpaZ zKWF4O)V*k6VLo;wgor1P|8qTotOk-U)!7vPf+Y$3M9yBa9xqMuA;WroImG;i1L&Cp z=o-(~i)IoPTB1cUMD>icn3%ZaeHb^8oWhl;S_2}`ZCNS0cE5@A`dW-QYZzTilAtmNWPYJ^+om8b&s`-uo=`A!vYW# z%YRzkg)CtxFRrv15Uu?Sr;3Ozg}hf@61^F)2WAF}-F*4W*7a;=XxTX1H3G52@0W9+ z3ccar)I*uJQK7z{%_=xgt_h4>b5xn+MYnIfB$V>ilc;kh2eLzRO`V95nGExr3vmX{ z>&W)%?p}!z6((3~ggY2c*}Oz}S%m9LR1B(Iqt;}SN9S9Afz^#mnlk|h#v8eyh6)Qw z=O+JJd$2L%P=GMo5{`R?(_;8(=@$VdiYBvFBs_r$f|-?ob;R@)Dz|`$F0KO*ME(i~ z9!J&Vzvw{pR}SO96ZORPx71qMGlvWfj3V(jRct$nPG2^EY(^SVZ{^+tEG)5f?c^qM z6A`Nn)_tjlmlzAR@c%BA2;N7fpx&E!v>8NIRDBJ}uK@@2s(=6dclIMJKr6w2^AX`x z8S=|qNjHkAJ;5n@qJM%R_>V)Wo2nHqel=W*S=1&Id?3rnG0x$5aDm}|?Xc$VM(YibL;ukMJ11Zj` zpp2M5y-gZ0sr%yp_K$ZsNy*a{V593_thG`6JJQYi*oI_`H zInvrQzUaWYusP>liE~8TZl=$Ij=Kz(*0buv9|2}UiRQ$UFO3jZNisq`WaiAwCgwpY zh)J|WQP0fuscH;jmWlzPH>)MBRRF`7?mVM<7SWQ(_Mx|6j`II7XQ;J?Za%N*28q*(r zoTTV3$m4g^>wE)KK!ub;5d}(6Oxcv8EJ{)u#iDP$2!Ri|W<5Td9ZuX1dd~GSN7)k# z#83L|uIZePsq+_LNrHy{%EYT-iJQ&u}^&JGoSn7)4RSa z6P4O-7)B|bKY3_-;zn?t!TedTN4_||v6_k$n(^l4xZ&YX}~5}L4tCnAw$GN}~i zf?K*?RKsLWXvHP3J$DsC@xuZcealtMOthLK6x7~5qJ@-Q*7NQUv(TIb% zh==${fP}~=G8o%3{op-^;>uV_J@k^(KoMS}M0k&nseDpDG0QBs!b+?3>a*IL`i;2a zs%wLty)F#L_;?r3UmK>s-j$^=mNnJ_UsP?bTkhk9L_%=N&GhaF>R+&tY{YX=@0_so zrJpdJzve9=6f;W6IiWdo8!FvV;^}4(tr%tS-|Dyt1bkE#S{>~6!D>PXBLXloaq4Rh z;MPXsdr~TF`yv+@cb#A!qZpk z39*4n3zM*{vZHlnPeL|#&QC?=MAfVj>tV@8)}-`ffqH4>&0}eH8bd{lj|QMlu!u`2 zWl9eM?&T}=dUx&du!!Jzh_8=Vpg$B21HB7Sr^184xe@o^dQOkX{FR@q_krt*#exaw zgzGec49Tv)YkQrpvyBLn;1Iq&>D)Z#^o%DXW0Z_P6T#T=9rzy7$jg^0G zHR77rk=WL4_-F0E9k@>F604g$ffc zLX^FR?aRx~!dN9rk|IrpOj)uy6ev`zM7es6nlx+GX0|!znrETidD!EHOa61k4OiXF zGcE~@s~#u4bRxHeN9ws>3}*H!&NdX{XG@&&yWjj_3pNr92ZhEZ;KGT7GjAR|c@gmy z$d5m@0AnVxFfj`eDOihmF=E-pu}P3@s&tc0F~c;urb|_(T7^orsytR>mUbOxny$Cy! ztBnKj_8(@!TN-bljMsY(?{S6vtC4E@Z@CVNxz3yj@kBi8XaE7DZ%Dv8T{Wb@0{qh_ zi=T$Uk2s!>X(T4pG#q?3QE~YX@P|DUs^Gv&ZQ32;M(|D~kfaS6R8+7i zdhQ`)UVEJvtP-J_x&_ppvJfG1d`RD}TRAi(S=_g{=h8ti4HB-XIy7sz_HiF%IbH`% zRs(3Xz|c&z6og48(tM@#!bPY*UCadBO&@dqkGXtJzG5l{2*pvkHVcEGl_3IE4j&~OH)0b&!rQ6V>x-~)?s@F$#F4d>{D6P984$6S$lwtHnpP>a%_R@sx3`C@fD=dk)*cGx=CL-fGD$Mex#evJsroWm<8(O5 zNDVV}zH_|0-T<&Hq>XE1_Y40>5e)qL2kdghEU- zNC<Hu>t`fngc9&$DF@ zU|P5*`!sFoRk3)K;UWMB_p&xwasMp3Uyki=Xr(wtr#P9!33%kQe#Jc=5<_tkbD*GT zgNS|sz~z~4m6H!!csIEQI!v985Rc}asNoIT3thuoc|XZi{xbZGLfz^bS{)U5)Xt zfn&JZx1aR9S-WZ=Zf3y`rYVcaoZ#1qKTgKiq!9-+{-vV=Wn3sVriIsNsk`2YgIQkM zLzNUDi#kbLPHAyMszR}Jyb;V$&~<9WL_~E>Ij>}lEOtt$BX*5^xSU{53%BoCEObo5 zdW48}TkrMHL$om31ejsggT5DHrA6*2kHjz5qEm6CXLSltPeZ^^V$$m`@H~M9&uw>a z86m%YFYlEeaBq$HbwJ*Bds6Iwh0bUr>B{SNXnXD;7`o7woewI;ys!6p;P$3h^rA_( z^L@>W86Evl^UiX8?sDt|=8Jq98C&iIJcbbECyo3pwiF$Vxutojuj*no)Ssk?R=*R| z++`hM!_=*Iy5%HG!V>(1zx3i##X|op;X1;iGk0gymgC>N;YA)C@OswH%`Oy5||nYXOgj% z#W!X6E0nSUfZF}Y0RZasBNqUu+s}~)3a*+&d2%MG*s+&V?K|*TD6R2%jfnHURrAmNxc%h1k_k2mEF-heyNtH24RSjON;`J(KzC;=L+w_3=|;L*lPk8+!lNbmd0~)vd?B6#s{E06{Zh1CSd5>XjfD1gHH6 zaJI{Nuss*_cfiH}0|`*`a10?JrEn7ogy8THLHq$Nix@vDl(uteno0zM6iY6iH325s zgR1!`eL?jBZXguFG%B^W{QQAks?Ql>K-!=}T-ND6X7GNHMh`C8wdVp?qKIIo2S#-e zWkmYSev{R-T`3k^mFx6@aDQA8bH=R7tis_2Dvf2DGL%ph&KeF%jSVZKdZX0}?4)Kz z-mD{C>A23BN!h9C$avsEy(*a4^K0d()Ksz4>6NLL?H`73U>};r#=**k0z)u0M#fck z8cIuZuSb>2xWWY7sxk(GB&8WS z9r4N)3qM^eDl@Q@z5qjpn57()(Rx=oXR;eAp+z&G5o;r{lpLwemQn8R1#^UkJ6OH+ z7y#*tUoiYeqhQ`hfUZULvp1)`VffL>$6||_Brsw)_G0+0b8d;24WP%+*gMliO=%Fg zSl5Jk&k#tEg~9impUEl}8Au2=Mh8tyQkqJFDqgSFk3g8o`;%4|F_a`A&s*&djxkjH zswyY))7YEaA^@zN+UXiU*hGRLau?PcsWCDmin)HWFjBpXqc#lIz^L*1jM>&H$2~F* zG*g;(J*L3+s$FU5Bf~?ePJ8yWLa*;Ms5KDKbwsp@FnZ)|b=67B8w8s;V6oHMG8;=dDp@bIN?>3zsk+*5D@)w>^2jM-U zs&(-O%0V8w6p7%>OC_nOECLlF=}JPJx=xk~H$@i@?-5vF1AiKXYw6XfW`TyryWw6t z)MK6PTUJ;gyLEUf2YCff9&_4j@kD>j0J{d8)ZR>)ysf5zuj5tQqXTOLt0&ZmLtXS@ zCT#dGieK|t(#W{*!hXt96c-LIsP;|iHL2a^jY`!P38L80BBn>1fx1d((15c4#%9%N zW%r(1?&-UI+4H2;K|#G)Eah`lIi72cI_~9J!0p%*3A((RI%OqlJCpnn$4it08pEXv zPOiB>T~oONjx=aRVs^!9Y^9E?CU>$dTo`>AYjGL!*6_ZOxIm5{60)ASCn>gdLC z7AzRyP6c`{OdKs8DX>|2un?iH1^emfL*n1Y1mqv8QDOUd8hD>?oD@6Br#DH^8~xpG zG?UW#3fcu?Y-(=L9eyP%)u{OVQy2@BJ~5RuJUM9h}D*?{4BG-=JcjyNf~hv&0qG8nKJ z%q^N?MF97@S-b$&yQ&EMB|vZ38X|wZW>*bxdD$u;N{jp}*_s(^-i&^-p)bRm9h z-w)CmZOqWWoyYV?aj9Lp23N|MYc~$fc6pNC^-Jf5BG-I~^hGy4riQeHOjPwQ^SR*( z$Wq;#gW<8wNCu;ZD~sGos#Y^mS8Le2S0YZmz!6UtNn9DYLvBuBA#?m0^SBN^j+Uz4 zm9o83scMFl*#dg$(d2Z1c8G=tTu_`DIGbp+n9|mGr^ZS{G}89F zs}n=}Xw1vt-Yf=3INg=h(Ce;oP906%o-EzS<>>PFjlZONN17l9rpsG9x%N5R zX~s7aq-wjJA=`Ngn(j?0UTYwgPZDmm*OaE|-?D?Je+BWbY$QtfSDGB7)~I|@ki;gj zWnGy4Jd46>%PpXbrYW$GLK1Yc#E#}DHpoj;N0*}7!HKcWqLl=_JTs265x|1C2}s++ zeY9x1&nGBgzNGILfYCqMkN*H!7}wU(7fT0C%3ds6?^6%!@r|}Yc~h-2_26)KC!0m6>)JqP#nD08suURgo_)m zM7m^SsA`_}N73F?#j8&`rsqnwtU4%;l3sy)$dPUpWgl;0Xm@Am8AdUv*WAGOUMNv- zbw6SeQ7m$uAW!^e`vi{ktZ!Q%jmn}oW?aql`;)?SztUhXd%zM=`ku0gkgvA)axHc2 z>qx^wfP`)-jG)Y5CJt^@Lbrilp93%a-K!u!ixH%#>^WBs93L6h_4@_zeWG6X?DZ2_ z!_UeU(W}h_OVj!|@SW_Em5e(kE1lxdRRyXlEQfdZ*7t4m$7u+xCoRF7;>OCX!1a;w z?~TAr45iWco!zj$#~q?d`hsdc9Kb00$^Sx%eWTel__5>-Z#Uy()}-$mbLB`gKK;GA zsdx0+GTH{4^*cgZ7a6PRJjYc)c&$6cVSpH?qpUW9if5DmW3d2RJD`4h{fB;s9jAU1 zZlZ0UFUU_kiubwcn^DCr<9q+j(;Xg3%wiqG?1NS3o zaZSi!YF#-<{4HAl>_U{J4}A7KDbU%={eLL!O_(_*?9`r!eQ@C64J$I{t6Qe~#dWm1ZRhK5ZFd#eVyX&JBJX}Z^Myz9wL&449sR5nu^Z95>4lF2l_XU08h^kFQ0GB z&C~(*8Xz^&CfpNuh}=Guoc#pRTgp~Nz@{jJJws}_eypw7ySu=q-Gm>3`qCU6fZ*}xG)d*jAV-5$|7q6^?oPuWF%PX_~^L+Y(h8=q} zH|G5D=8uoiF;mZ_^1hLtWXYqAx$N@|Mo{Y#@o*IT;KIWjRjI6eDF+IV$t z)^v1R(xLQj#(MwsgyHj507X=9OaX~p;*moLHlA-51n-Q|GWMASod5@ z#1U0X3~YOpHNDWp7@z;o3M`ddDW*5rtAnVd*CSVC#x=2Zp7_Nd-9(8qVb`#mE!9bU z&}HVyqMdbit{{i-JP~L}1sa|y@(}p%!P;lC{jELiQ3P4{YD)VG1+F-(-h$k(y`DnH zbBbKcWUe`E``1R044(cfH^I`rq8(-AVpYj^ldb&Z)g(=t`%JZSux)^MgV&MYJELoB ze&F;2)Nroq5EF4pO8vlvtw5lu!N=4Ce|nF^a9(6}aAS9r(IRDLBOAA7vq7{mn&tbu`IZvfnidYD~Z zMYVnC^U5?P8^_MkRI`bo3zt#B?q*-z&c*FbY=7y-%*{BIQlYWom|ClrR>_pF9IaJ( z0+c1XB?+~Mho4X{?;@n(Zih6IYVB`z$hMEQ$HnYHVTLVwLU=lWS7;VBdFZ z$gvk172J?u#Q!=X29^_iax0&m`|HU`U6Uf^Gw(GUu5EgYiS zLq6lOpvKKpe!)8%-B9LraZ9&Pw5GWH)Os^JT&JzBqB^`oP(KTQ;DQBW zT2g5qQ67a@xgonmi>@(le6W=Fup}YoB-9QzB;5}3z)x(eAii9_uUXc6<>OPGX1MSx;G|6&HGebdMiG|@Zy!Semrw?i8i^JU z$3=YzFzH1UKjhUgmGQQFaR^6a>&>uk!ECU&4OU}bzwx2c5z`Ox-MSbW>^80A2%|+I-Ro9QRo2+9h<2IP9Fw^R*6S9A69u7$Oq01<} zSzSgF4Y1y-kaVk-8}PD-Kl!w_MwL>>!uKCmmA=?2@=LiR#Ht!W&9b-Zt>f~}qV}Oy zyL4`%qp_*2v)d$PI~#R2X9zc`T+yx3h#%a;{`eL>sUfI|Iw+mAB9u!f=_yTZwiPB) zibeTX=uO5rZ=D>zUzWeIrMHnScWPKrWRmRTo5U@sLehR++p;DWGL?b4K2ygs18I3H zJEG9sWo}O&Bz*NILr;`)In0%>>vR%XK(M>nTeoXbd!qo4c{Nsqg}afDW?6$$kD>fs zY3my<{HgYhL@{`1!8xgwT6>q|R-H(S`kP#{Y;Fv#@6oJxGTH73R#Xs#E9sfbu_8X4 zNep7d10EX^Wl zWW|UR5NoAA%`gG2`Rs83sntsH~~kTx^}hg zB$LAlMrB&^YuzQkZA2(#1|~h=Wpjyiwer{BaM%+>nZW`vng7(&=c(uT>Pk>eYjp*) z^G>r`rBf>qD3&4)F*o2REQRIEvX$mR!RjKTQB_V5kHkd-gi_*57>>gb=7lEm8wJ$Z z;**LU`LMr)Jsq&L<*{cUBfJB90=5YK*v`i$c(7RQ%kwX{;a}eKGVN>Fvwy9vXieYR zd#me1RQ9J9|1+zep_V*Ek1gwHgFa}9=m~FTi5XaZ2KigFGGrMTD>>CH-$(yrZcKKT#YV`s?*irM0ByATNhql%w@It3&-Wf@42LW z@o6@kJXF#ehqiqb7mt*KboxMjv!E-^PqMz4pIR$l6;0FdQrlXYR<6Yzr=0Ul zsJZH2L5{JV$(;$eU_OPl-Ck1HIp3TBWU`Kp+h!)|`3T4VAohKm*KHI=_*^`jX&{9* z|Ip5>ceKqXqsDqi#9lsZv8bf-_5q_;)yVz&^Z_lFVG72r{P{XD+>F=T>~+i%Hr9k?&%E)mXps?V}t4m^l{wp#8Cr9ukH=&(DiiLx1I zmVU#mv)17QjP7*pjhj}kr?qF*#b_d^5-;u!dYWPreIw@ARxNLEtXi{HYVBAFAG8Nk zs7bvJonWEhfWI?TL^a^R7w?(<%rkZWTzyi$#5xWn$mcIgsoj7_K&JM@DVQ2`@9R}`O`Xp_E^ z-P{~YWXIcNYCU?ZcQN@&Jj}6kwZ0`Udx-lRiyg47h1g~xw!`Ls4<>NN+eZ3ADc+{ zCq1Yq*_k3+Xdfn^2GsaCr!`ai{@*}eRoREI6xY70R68OGpGLB1%%3#ucsdaeYJ?AW zMSbb!Z2!3B{h5``_A8H0$?U!B;S(u8gI_kSGgUY7r2n$He(~SrD!eS}+mNb7aj8Cf5o)L_hN!PnYvH-pTO^4Aj2r{`4L3t04d;wMS^fK0cht|7eji{snC~mmaan`_Xz zt#q*E)N{I{RP(pWycsepaVHu0qb!6_V+aTsGx?Hzq%z*u$Fe`zh5c2h%^r>ub9 zQO~E{$TY~MLA6>2NIAsir`?C$Lm7Ujnh^>b8d@7Y{Us^x}T&#*XcQ zzR|-pkm=lY5yC>2=OX8uEWQ%A7Ic-rlMotoh?Ua~(^}E!@J2kzy+T>AD@ob8LB%Zn z$q%$C>nsBeEdnLJC!z7jaJ8xOV>s-+=i6Bli$%n4J3iA^5e|}FEJ9bDc`v-xpgp9+ z;f~`l=1-(ITI@HHKg6Dr-IMk_M96OOQ!Un~JVj49>fSa$j1Ja*SAsckT3U$F_Ts9N zCL4X53trZS^VkldujHE1g@~tKNYMqZ>UZA2mb1JiiUgEhFWzD}{vwX> zG@a%klc$r7le5<%Pbp>od3F+9eSPoiP&joISNDjI_TFM&k|>F~4sui8t5 za=}*v)Imr3NyD@41&1^2&D_Xorj4J$FLNzcywGzj-UBK*kZ-g&d#;Yc!)eZ@&ts6} zjxnk~)?}!OUuILxlnzV3_k17?(uOZu8Un$UL!B=t18d`RsAymFwd?_8%YoP0UwdTz zJH4Q_$PMrIUVF#1|FyQ)Km%XEsw*Zx4XsgWA8o**hcI)#<2F`Y?z|+Bk@wQXB0^3UJEkW9!olFJ%9K7TpYdE{c2to z@3hhNh@nF7fVG0v)|Y)?B$_oBMFTxHYX6prWX3MfBG1rP?49>9-hW>SCJFy+fpx#M z=B2Xn=3fj-1hB8r=IGJHN(Xdnbfp7DzMga_W8V3tzJF$Aadc&NWyN%=VtQ3}b#Zj{ z%)qQZGe*5h?ZQ{lJf(iwVET%gw z`xNo02l41HRtljNWMgGTQsUdwA^J@&$9?p~6gjdxq2 z(cmHresbGXMmfFDE(F&1hq90+(JDsD#^0HGw|w~lrn+OT%cpcxy7EOga&J1OXwLl> zdPug0niebGQK$_d_?GohU_E?uAX&3eV0ILzX(=~V%VXDmQvJX2wy95BCRa~(O=E4@ z$88E!UOrCsA1whjArm(nNS`H=ZRjRZurltS4-KwUv~Wu#^Oi}tc?|gEQ$Rhf9F>mHQJwI1lI8RxYbqhNy%@1BQoC5SblaMB8!xZ)-e`>j>u3Gxh77U7 zx;$N>9=p`idTwa6{hN>XoK*Hc{wndiuSqdrV{@A$dU&DHqv5diMt=9Ud7&F^_hR@h zN>{4QB=RL;JzPV5l*4riboz8eY@=A{Ts9D7D|rSJ2Y2x$9r2uouq6~n?pO^5w zl;LBK8&~EE-LIV*Z_smD9PMAr>}#XR_U zw#5J7SL-~!b+MRl-8y$DH0$2ID zdQB;_rdRXdOPf8Kj@7e*HWnv6|IM&bKVmlPhldRo(~tpV9-@&Uqp9xYm{^!pDut<- zL?Mq#K<1l#Uot9|cYi6pW*aorcT{)Q!CjMqbquVOiP(>+O`piQ$2n#P$Gmv<`U*Sz zEpeiIDOz8TL__`LSFGk0ZGy7NvM%tktlOp)a{XSOP;;;Yljy3l-WP$rhylhiu7w-!2j?scZ{R!EE5Vd&t56!vT z1QaI^wjcmMH1i=6EksxC?O%3Z303R9uf~jG(Ep`;jtbdCxG?b43qep`q`){n2x>u~ z3CHIC`qBP{em^STZ(PCPTMS|@{TcUuK_lA{m_ihC3?XZtEyY~=9a3@iH;p)`MLxl~ z{yU`X`QI8=J&M(!wwHp9rTDR@GSfA+WZWyrc@bAbqyKqf!pI-B<^2)2XoqEwu>KVE zpi-P9TeZx!>C82Mk?G{s`Gu+JEicv!aHf4wH~r|(m*S6e;x75l`|Bu4e{>1-zvF-s z0d#`%Gw@h#PTQcIx0(!DU4BgHGm6*-XUJ-E&IaXTLX+QJ8jGK#WJpSmqyz@!NjX4F zem;JUGNCV}t7P}@YO5^|6I4Da9Q_}V6$;`)5b}Y9fFuMeA-7!-yFX6}Q{Fz*=fwPH z$&&KFvAF!NEg}E9CFd_VC36Qf#{}?}0Nxb9X#!Jx-WNJ61VI4+1y0*zvjk0XzVu|9 zV!nTmdt>H&sx%js=AP2rRoWk?tPr1QkaHU3wg$PSL9X~De3d85<_u})7-Lu2^%sx^ z>-guC@lzDrKDT|*vR-iUwhwI|k&k8YtCsWmwUu{y`*3K0fbHY${zh!dC4CcfEqvGP z=fKfJD23O*4d^$oh52_Bgvq((pnzP-A$cH9^P5k*CC+$kXXr)gq9MFcGJlqaEgBMV zQv-JO2%!AROKq}(PM6!&vtW1xTu?htSscpww|7FoBQ+OsuZGM-c?j}7Cy)>MmAA5Q}#Gjp0y1HlN0vmgAAy8hP2ihU&SzVfr zfr~nmBJLNnr~PJkj|e~0u=`>%AdSPuZ!nf~a)1^wS{I`PI`uKDL7gOeK?izH z(+kO51-iNAOx?qJsZ)0^9nem{~N411RwhKJCy4WnzjUhJS>L;H%Oaz6BNE>+V)sF>Mo#^RE`pIyH3iG8aGpU%|`7tEF3#qa!sH`ZD$pq%=%wy+s?WvzVLK4 z#}t3n&3mY4)LnGgBHOs{*3s^HC~82L;=WIB4bJUxIJrjldcVT$4G}PY<<1kh z^0azIQq)W8X1=HgaCrFK2$VOn${x);PgUI&$G4H1&1`G?bC?w53nk;V_lk{0P*yFv zgNJS;m4(33k~CGca{XN__MPSr>q)yJiyF;UWqc_=Tdu9$&tXa0VNM0e!q=>2&)wgY zOu83&ly0T^8cnTPt;uj5;+W2)wPKPH!3JV^GcTXCRN<`7r!@i11Z*QrpLJ=j(eBY} zNqpNmrawP61$FZ%GrCv81>)(vdeNrE&#>@GoQKKkRce<<7Il%5IiOxQN6k6$!GS3a*lyu?UP%Y0|;r9@yBYIgJy=bH7-uOo9O2 z1cLVnSE8|+W>o?Q_rN|Vxfu{m7VZ#9mag>EEaSu+p3lW%>x7A(<`}tQvT}zA0u@3j zxfvU=SWpPuNBRk=NF+U%ROaI)azB;Zg%m0}v0Z>$6Q^#B!0Bm$h*Y5OwGctn+ze1~ zFR(V4puV^32h4~DgYC#MWDFwM0kVyfnER)vF!t~ zmS)Z zO_MkZFvVIwkt2tVO;m{ijM^)AI0Y;Vpo{KGajmpF<*K|^+=F`#-BhAvDTC9SxY8&C zD-5EUAdM0{rQ_nT7<>^WcRdL;Do_Lz`)(0pYb3#na+3 z4k&qZpi;LG%&Ik{n3aw&Wk_t$#I$-gm769>nq@O2b+TAtY^c8em01&#z4ja+HKcT4 z7MDE^>L#REM=J^>sXapu1DqxL%@YlBa1MtFPlm1G zLUrdsR!)-(b|)l9$xvdvm>K>#RX4k~0IWs(W};w21|Q8%r*+8=WOdQq49Z~6cVU(e zxn+T3GhMa?z?vcRk*P@3wVAY){({1I#mBq_1tF^nFm=FrRvU_A;FO4YRUksRyZ8p| z>$l|(f2eFl8h1F6$0HU$m5jw=6Edps1f@5&@vw6+6!fC4EJdIhnF3Z{+XRr1qdEgY zZ7DlZ9%d-ZCJ$9q>2?cz^!#$(-fnNO!CE}T20k&18qX&%o`hCT``W4CY!i+HoG6?; z4lzd$b<&Omu-@u8u;KMOT3M$Ni@*yU9CvK#l5gDF{sX$2eIIKoRymI7Iwxta3Rik! z9o9ltVKn-3s$AuJWqyt;Sy4@sFsO3NL2|t_E|Ym=E+eVBD)KCe!@&1Om;uQ#TR~8* z3Ijvc^TwaU@I4wzlLjkDsKTsY&mj{pQgADIbmtxI=NX}@_Qa{ZO@H`9CF6dm-Wi2N ztpO~^6;uQ!aZY%&JJ}R`v%uJ#yZ*!UcS_jJgjRG&l?1(tU%IXF(s6SH_Cn-j;1|P+ z0yw`c1~UjbGAY3*Gz7N1{6sW^RBk7A!?}hCeHps_?RGBeJXp}MiBAlI!#C5h#OiAe zl=dLf~y$J1`Q=f9uvhc?rQC*5Ilum;&e(DApsuaQSHgOs~g@_rUR`Hgq zj%&<-MgyGKw{TBp8|dE}$f) zH}UAQ7}`X9Qi&hh@Qv`l)Qc)l10PeY4IOEfEEO~X7LNZgi9gyt#Du(ktF)D2Iq#}s z+oox|YL{t~)_2T>tV^Fx%_RdNyyjAgS(eNIQdViNp~}^8>U%D^;8L4e&0CFbJ<3(} zgi~Bl!63Bw8VJI3U{ueG`o-iG1;+)cbPMV@UQh9?D5e*vVa%}E14zEgwI2j-2gM;A z%td4zp2bOI@pX+2O3FMaYj?`nO14hLClMd}N==gqngt>OWm{F_0WS_U0a7diH3tl3 zOD-TAdmEf&ZJ^iB_=B;7@H;=qs07{QrUh4Z9h|TEnrAb#OF*jr2y%r(jHBdTZN^B6 zkLe}C+|i@oN3><$Gu{}xU@J<6Yb*556c0UVft+cB?}kEr9mA~i5`du6Wj0FZ!9BO( zd*p)dk@@i)$|g5b*`bRaVX-|Hsd564>{yuMWuNCJ8qIOEn7*jhmM>0u_^y32#ek7i z5t#{*S{D+K8QVp8q@lCHb0NvMJkz|U{R|3Kg)OM=*abXJx7B_CDsCni!n{rn0pG+% z*%5TWfpd>;x*RA{hvI#hO+@zUNDh{0K^T3z;2=ig?1Dora@PNMq+Hc7KqanwX3UaZ$` z3*6hq;C2J_)jEL&HJ4(%qZ>|Y)S!S1tr=d>8~@8eIDrW$m9F$cn(0g)`(>i6+z z#-3B1DXIFdhkRc!Qz8==UU1#^T=*$`;|u!nEc;uJ_VHkbw_*?|^ zi3S8gfe?OVjxgPz0)8I^Q+vzag3|UU^=|aJola7DPMRy!kYc{}5Dk}4V$x4y7 z?zQlinn`r}dWGBQMI+?;n5DhQXQWH`Q3}}+(6En&NA=L_=Wd{RfTykCMo)!~kc>{2 z_|ulZl?S~ANHr}kg|n2GylP0Ax|8>T+ntA#ETie z_H(>a$XtlaxdT%>G(W_X3X%jkEfY}{h!OGVd&>t&{FI4oQ1Q^E@oK@*%Ff%O28hpO zUm2XC?AMfx%Wj)-3g*uT*z>}+vl`q70QC*JE={{*cSvO_Rw6!|9=U8+JZtJ`0@@M4 zu!w|Yo?3MnMol#FZu=VzUx>fmiy~myMopO`M6fYp&5-TKbdqZky1}U9`xuNFmUxTs z$~qj3^m!9xUNm!?zN+>0V;D`)ZM5`a=rJ|+_J%j2=lr>fb|v8UTnt5s2~&a2yOF}ab3hj+H-z+vweoEE9A2jf>QuA=VQx<>6b+i_Kew-h4^>U4Gq;&7psX8D zWw|g=@=hKU^+E2`W#_125ly;ON6vOJs&li%eqA?lGCrxQ2--q*Rpk*mwjQY-vn1{@ zBdm?&NMiBTqMB|C{>VmB<>upY-vU>+?PloEpe`~a1Ep;BOp}J36PykSLMw6mTtqSXbz%X zDX z&83(XQnBpdbYBFoMhA?V&ljC;+i)Veh;UZsAI$b3uKU>!6&0Ao>_42 z+~gd~WmD8EegJqbZRu4a_hM3wE2!Pb4P0NY`a?lVOjC^oc=q3BVKTqdR`SLSn?J|1$c&Dg8-$Dov;?pD`KJNn-q;f)EpCo z?;n*2{*V1=YaIVyz)?zV(EZ`Ne^v1Pse%Qln#aJWWRYc%B$n4M1S}MSbj!Y2g$)S~ z2uj$h+ycb0C{jDCdn49R{OtUZnbb^DAS0_v377~jZMCnJZftR+>?wa*&HU>zIY(3C zaD6=h=B8#4j0s{8s|6 z1)G0^i-Mn*j4TvK(kk@8<6>1|JID*w25^ndKxWzzZbPl&vlwuz>^TKk4R8~`&{{#I z7f|$Zs3%Djsetxln5+<2nJzlK;GdqI>bH1KvE|J-mL23(lgGF~+;edey^se|yuV^Q}|n)G@6Srm8)kVU`33 zIllwi2=MIKY??J{EPOW=3^WElJSC8ZRR2QB%gRQ4{bXja>+=PXKK{va-ig-RvLJyg z)62Nzf(IUS(zT(%SlFJf7R z;C2-|$XopUwBN3mL*GfkFKzxZpF&GeLhIW)CFo(K?Jjejj`545sT?mR2eF8nWQlFk z4L0?1Hk02rFl-1tg@*IXBlU{Q;HCNx98QL0G~vH|?4v z=L%d|6dZY`*9MZiqvffM?K&cT|FbWrm1t}Fkk1TYJo;lPTCrpvTIoUW2e2CNDKg3+ zrE;f);)}V&HmCe6byO7=JqP8K%A6u+X7OIk&2T!V0DkY0?j~)PrE+zu_+boOhXJK_ z-tC|&$EN-u_ZKi~8&if+{jInT&5*_}t%I24K##N)~y! zGqLlXZXl#P(tXaHY$#In?8qibE}n-b56?rFgXeVqd(O{yWe`i4WgG*!1>X=~z{D%i zlxKDTeRj9G+~AqWF9Zl!m;2ZI8Wv)pl;q8LQ<$cbl?cPg9_pLZE}k4;o3nbl{RG^VjK3`->9Z!Bdtm7Uil2+v(9 zc_F~pns=Be1^XDb>~N`-A$;t;A(QPp70-+XYvwb?#_N0YoLI&d3UA+xSK4eyIp4lC z5udfIbhAT5qchr1%~SOMJdct>C4X95`)sNV%I#E>5$rCHmy=E+uL%^^_maB-<<2}V zA$W8TWPeM42pR?XP!KnI(U6Q38b7>{g%$STr(?jFqTx@39_vs3{fpSDSF``pV4#f~9k z(@YE@gC|auwy7vyMb0v(xuV{LSg9L~%Sx5R(ObV}@qrm!R-ee=gbS(gY>JR_&-&+f zvCN7j=VeBS^n(N}vA%m4J)aRwOiTpl!GKG`YLXoUB1DRZn^?Lhcf@s<@q40e%%!UC zS4g|W&y8(u)-s#gs+vYgOqH@IDjcI%PFZ`AO)g1f5l*@-T|MT*I`6XegmsSGy~;_m zMg;y#tz#CcSPiBR3kvE}hjYhG`dUUedWKi%EO7i&FrN`2#*XhuobfIARH5d}MDiz6 z#a8*9WM_Wk_`JiJZ?9?jb0nT5J@V>Sn4jX(Oi!k`0sI_R+TRI0eALOYm^ z%Qb5;R~t3TFfCme z^bD#P9dt;wBi8uYFHG(*3tzSFU7k+e7U?pB zL%ssHZB!VII51*UT*QM9eH0&@xy&CB|L%VEo=jp?gv4{esPmz^9X`k-p7Dxzd?JfH z%ybo#zES-PN}ZDq$F=^RI$};B#+K<}E)@A5>2nk(EB0wwxMU>a(nNKVi3#Dwm-Zx};C?k%OhC>A|a z#~m1Z5|WstBqt@QNlSVrXG*3fBbmucHeVdeEw#!@y%sBWU0gYtmfTEFUS`CR{1l`x zMJY~6N>i5dRHQOhsZLF5QBU$tbeNJF27PcEeo)}3`e4(}L5Xl5{3cAa zVm6yDU;x5z+`?@vU}y>k!A)1(^kXmxZI~_vKogpSTMu=> zs#Re{bjY#J*VBpi)xJY0LitAi!NmE{Nl}h9EB9H3EIBY>uXAs#R`|v_0QT>;yWQgb zX0Yo~7Y1i6Od${gPNOk|6o4EcUZ8HmDuq05uf{Z?#?8+0rV}j*H)cQza3fo;AL674 zA43@M4S`Am@)!Wpk6W-?ztJJ+6-|>6WRMg<#NP-)^mIB6>%xj^>MD+sNbLg{Nl%TW zDNIi1*wFRFB9(ChsVeN-f~&$91-mlIR^UB0J5&!@?r4&P=t(Dxa~RL{&f!wM?%BQt z#iQZ-AuQa50y`~^PG##J;*TTjyPhV9Y|@1w*eM3sjJ9w|Zx^e;7m8h2Ddnw?U^}-VXyvQ!=W&vxD_d&;of4>3uYOA7+sw zyra192-yeFhcnAft&ybABO<$3mnKOhHu<=A=bITI?F;O@oi~Wk>bvC7UljkwuLpsB z-D`8+dREtTn*rF=yl*XDO1JHc_Nn`@1NA0bY`Wt2VW z_^kJc`-o&j7<)8wFoKO^lGlf{xss{bjQAApT3Vc&}__N^VOe06H7iq_I(ul3xx^*0X7081Bws?AO(YH2aZn+ zfmIvA-WM3B1;el2K-$f0>96ivASWAMZW}6C?l0YV;ZZqr-jwF-{T|x)Dd!{Eh<|1Wll4jYV+@!3iTU_ z4WTbnbuOyQD#J$MGbf!l{Gd+E`)(|4ZzK|m8E0%TItr&(|HJzwhldX`-7!`*?5H3* z#cZ>J*qMIe{I?TMPCU^NGzu+d6hEVoSRsS2IgrQ_eI!X6;wB@Aji3wLU6+Be%b-NG zv69nXo`2rI{`)c4+NbI^;oGkvej}42Gx`x2I((LN^0Ugi*-pn81=hlnD4p6DsfWcr9{Z{WS z-diLaBL{;XFd_x32sPo{}EraPy@ghZM{8vG$1XI_j|&Cb+}I|;680qGzd@=-|18} zJuFkE>6f96SvlKN0H*f)(x{}L3$6SK|73(yAmPcAxscT1VYrAPvBTlni4(3 zwD?M|ht4ypstZ)Q>E-=ErkX0b)J9M)yk+u1*o{o-U$G}f*)r4VTdjS2kMlA-&>1E3 z{k!s~%o#>Z>5^VMH`x<(?u{2EBy*r@Er$0yR||F>yx zd+!^e^^?c}#G;YC5aiRR=r!-X(VLk!q8Z5`Szbq8@LCJ9Z{oD zc)K^H;s$8g93BAivINio6!`!BsjJh?*CQI)G5z)R0?z!`K&G38Mp^yb9wMPg3HojL zS)Ovq-QOjMNEl=gu_7WOgXI3(c29iz*WLF!XQrkqDykwXA|mR&_FBK7Nc!k;Boakm z`z_O2R)c{!CU;HQ2@yn;TaZJO?D5;$V{Ns&7g1s~FyJ6j`aLsq)-A9~cLAcuui%jb z=ShHz0d|EVTn|4dWZ4$Dbiox%`AShQnN?W*Ioc*!lpcFvRphUR>g#j!A9roI5 zyNy;`YQCA;jn~R<02_-Mm5dB>q_Im7B@}YJcOX+I39_b-AV&uvP7I$=XNo*Wq$#%- zPaBQffvJ49S0*BEGKcyu^>;aycPnk`Hlf2-w_SU3q=eRd+j7uxtIAejw#=)_B5sj_>^^0w+G#A^Li|Lq* zv2G*A;L&gKAB{^6YBhQe^C%xhBY$L#lo2;{BiNvXFC@u@!*%cmgG9pr^^gA4Z!GXx zKk7SutuNpdj$l7_VsmM0dwDPH**$f|TQTs7rbPVc;o8HxrJDgO>d+&3X&1J>Gdihb zI=r>5FvvkbU^@Ggb8s4t;WX?|eX9@ks=AQ)LEWk=-BRc3M0K#Ux3G5>bOf40%6?}4PYxJoDcimPcF*kW7Spup#18lBeB5uaau@ikZxzv-c=cbPmaKqfS&AiK5!3x5(fiL9+jT(j(Se9wf`pL`<4XeN@Ty>oA{@F#I@ z;GLZ7Z6M>Dc~yivfCGFpF3UUMi zXPl;+xXBx~X!mV+^etxL{|c_tbN@{sV<96TgCYGOjgX$e)4-#UB1k?Y3z7nfgXo|c zsx8p;S)>|t0LFV@+OY}2#l_t~#SHucXI|Phti;-)zTJfiNtp=$yi_2rt&%7}>w@*?&{Dc>r8QQ%b9ec86(U^r$!ii*V2GsLACmS6Lb*Q-_@?ZI>^=?>C37o+u-y(j?Xr8~(tQrlLpuI0 z9dp7-r(Jf%Ro7g1!%er`_P|%){O~tUFgb8^Bn%8>ENp&Ux$@)5lYoqZ9~Bip8X6w7 zv?zjv@fR)}RfGrubaaFwMWKlnjV?wqPpNXL>FKfM$)jXcf>5Q3hDk4KR#s|_8acAD zan_{2AOj5GYM_DKv}nOM$PljV?A#4COfXo%Miu25P36W=7h@^cILa}eYE7U{CULQN z5JIdF+d&m}P==ipvzy~(rN}`GIRxsUBT(wFBQ%au+%YP1g8DeanIeRT$Q=uF-KokA z>g6U?xkbI)4n*#_PvZeaI;mP0_3)IkyydydgWJL+D7zn3yQQ&X`!(01FPV2MlO!?gX2Pb{sRsRByLk+*}C4=Pg~|!?&af+WqtWiJ@Ymk#6^yAj!WFdse*Nm6x2DUU{&@lje2O|zyYiZ5-)!bH7@>Cq_`gq<*YcDjwbM%`x4F-HRLH(1hk!AXF20E zHW`yAm{C%TIJe^Ga18@#c+AyTItCe+nXOqW9#>tw>v%13kz)4l$K#x7b%YX+yX z4I}L&e&Zh^^^0T-XtYe`cZ;t&bC4qC7J7~hPfl|5c7g-uLh_-OUvI2Dx7K#*9q-3ozweIw$ znZcQrn;eIW7Ffv7k2SW~^HXF^Ey3`Xjnwkttr#V%sy$KElBgpqQBGz?nIT_1qKk*K zbhWhVT#xTn-+UM&JUePd4O%s0O(g*e2e0q5@6Ix)+==lD6Vu3PWhE1cRd@ZU7N(9-jje_gOv^~;TEi9ZncA7x2ZNQcO&prdEJW8 zY}OtdpT&4kXP)K0u{Jn6G#rH-_RC`mAR*kRU>htr@d*2Dr~+vNk+XP@np(=iCMYt^4Gb$Ua0a5lT@8)^TtS4Z-rmX{|ctuPRchsz5y?keUCHtpM~ruzfeu+I}Xoe#sl zW}IhEk~pn)($ex+$TGRF+j{Au;`y|@TgjGu4Mx;jLQ=8rGy5Ta`t6Uu5$zQ02RD`+ zBK*?xyqavs2#|tMBvyQz^ue|RDz^T9aS5%|?lQ6}GMwc8taxipPC2RWCriT``&s`@ ze*2382EsLByE@!AaO4{~K}%ECYbFr7hl@JwVRIzL!+?xJCfQQ*ylU@6cy7e3Mwsc( zioU%es|U4CpEV@b$RUp|NORjcNOjm5AE_@KZUE=ia2wyRbT(XHZ1??q{jD|CbggX8 zT*+smLZ?oSI{uXt5x_}%2TEnoxwWSh(b;aIp+hS~TfuPvEhnlA(>#6cs(e+rtDfQi z=5YUiee?I-h~MTXbL!B#J^hBE(ttl=YephDOoQurWlQNA`j|z1bXH$!_GI0!4ouE= zljwWMSj4Fi5)$2CClG1PrZL08Pl;H^W0*qo`m7SQ6IsAW5`K7*Lo- z+gj?-)3s)i25o-;53)1wI;0rKQfLsk*$<%uXPS>B?dCfJEIgim)7!8rol0x?Ta-Ngtn0rUU^^FV;J z51aCi?ooo&2etx|Z4ic?qvLjjsW6 z0qEVaIObAcilI~N$VxFc8|lsRr1Zna)Iv*Yt~Y3KqB?{ugByz6VpMq(UCqU-zn|*Gkf}_x$<*MT5RY*uWrc{rBPHh;ttD032EFbRq9H( zwT`7rzFcbI9y`6>T4TE{FZQI<*SnW2c6XLa*It*KL~8GNC5#oUBW7_AtQ(U>ycU;h zY_4_@tJ2l`WZfAqc1F8K|18mgxQmuxhPMane5-+-YvNgMyK~yi=4MrF+U#(4O8cR{0g^z;9bZ^aobkU2-0|IReX?nY+rkLJ42*@{vU34Tca|>YLd<#xmP`1gj;q z2M%Q*+>FY4%jICngQSb`_^YW3>t!N%@~rC3CE(4>zx4Z&BKC*lMrq%Hq)VYt@g%ez zD1Ih_38zfIipzI9wE~d-!)Ko-!x?F_xAAg{xRtAp{) zPWlwLDQ0?&o}aS@8Y^yDh0HT9SxzK35n<(rJc;Q14v(h^^HOHJ61a~0fFBZfnySr> zP{y^|vKlraRW;I==_s*@wdwKedfAs2odxW_0opk@E2D?TqsOpHRmLgm zFtq55o8P1h>k7d*R3L*j<&an3_JFukZq)ou0TK$N3)JXQP2h+JUj@&HyrKPZvK5 zoyetfG#J}Q`wz*!(>tqZf|N#Sc>E%@S427AY`vEL>s-oY;|>&C$zBMowI>0vh6AO- zGk2nkF#&U5X`N;=7?J2uL0v#xdR#1U&pD0O|m&krx#}m^Kh0Gl>WGBG0 z=PA#mufI*U_jDWf5}lfxpc9!a0T&g*@c_I4A{L`MN&pN1HUNitAi&CneK;Q7!x*U{ z@asaaq1oPBkfO%JmlF#I-&Vdd_QeJxyrN1`WWZVjnGSx9%cYdZ{T7Q@teJ?MIND6l z_uAZ0RHnK%G>xTg`yvxVq!__u<1s6eAH5 zo{swj#vMgcwVCqXO^MU)CdBxs;(X3NKSBHw>PE)s-3eTlb5+i5bo^pE#=Qj$2#)QR zQ)EMP9^bL(^5|tWCBNBeyA00Q7SN)EvgapEW8zE{7_h`A9`Bo~_%Ke48(&Z0s+)fSZ(?x)wIl5|b7KBI3Jtl5>5ab_t4d_COv^+ZhvEFl`0M@l>#>XURprQ2E2W3N2}c^JPQ3^OVY3i>b4z(dosSU&}R|h4yi(L z9{>K}J#KCnSh)fRwOx>oA4{<`x!E^oxlROyVwga5sWO6@@2*5>043iKBuD!uGqkTL z9D&>~nYqGxJG#$mzkBum zYuG!akz5Z3SN1V?GXspol9O~TU8_K`W%Dpu${>xr82)cx05RU>K)O1_Xc~_Rw6w+G z<-*%fSd71GRX=yBSm%doCOlU|2*Zqv;ik1!-uS%F>Kov6g02??&v*%J^w( zLvQTZ%J`YKDigMMW&Qm6+A3`Ov>}rP+Ze0WmYQ#-cH^Js))#j6wqf?yFaG_?*Z|Bg zf5NugfZ$-GK>!XzK}JGN2jp7)Q~~Bgda~|rCl?+Et_L1HjDv|Sx3+L_@Xo%_JKNeA z)>@?%l@n2VWj`g9&Uj1`FT;&MuR#g_D`%Tyu6gELV4+18Tk;gkCutL8#UB5W5HC2H z7zK<>mRe@H6;@hhwKdjS_w=ojCc0-|CS#6iPanH@5sWhigrpp1r{gDH7vrT21xVrD zZ#yDOS_+!nZ{KZ%IC`gI@c70bJWsVQ+C-r6OdhQA5jb4L1Ge;AxRU*jOqyVXuX-5Y2_9_ByYF|tqrA-v5UC1~YbS#2r zRod+Wueq3%03Fzy8LZlz2kKgcPCy?A)E?Lt;7GY8oJ;${&%gYnnhjhn4jG0`C4$}m zXi`x7>qOnDdyQ}sPRFI~cO;Y8mkjL>imbyJ5AL8VFf0_grSN1vVfUW@A1CE3fZeM$k zs}4G5x1)Z?+y5!#P&j~NV&UL%;mQr4ClN1V5;B2Q)HJk$go~gPDcWf}oC)8FM2nFk zRk}=idGZx7DpjUJB@+v)290c*3@}iOLF`V()hT~Hv|p!Zo_HI#I3y~LhP&>cYjH|k zT>P=Y#%TNx&(7$qH^L2DZLv)UDiSg}3K|ABXAT@W5ppNsflJDdHy;6fedjMsun?i5 zDD{ybR-7d95+zHMD@(Q<#kwifU4|a&nAPa1)(`diYt~mkgY`CqLa(Tk7-3|txa^L* zZmWzZ2-3?92Juj?nEAEs>S9=S)@s94AcMwAUF`udPoWt)F#jwM;TSia{&%Kb0vycy zdV#-jJVCR-hq<{+AMU|kN2|m+%oBW(oZD-}fsfx(?m+m)_Z4{i5B%3#8gHLGueaR1 zhaJ*4o>=35%e7p-mX)!V@FT*b^g2L}!Bs?HpX@4PU<3YZL=rxA8}G2c?$e0gQd6CL z_ExM(--Dlz>RlIJ)jT}+1Mc4ynIS)JxWNpJ?D3p}Cu;JqDD04ahi7OIHnGoEIPo}B8FjNL_pwz zNSy76>LSlU)QekT9%Ib}?QQRRyl#_rpg@md~xp!`-8of1Q^|p;M9x|>( z{@j^g(Z^~4@+jX7q1?ja)TLtZCA^_41^}5^V(^c+Jc)GHU^3DwYq^Vv8^ha~&!p(- z)v<=9{4luLXYAijn~<@q5Ty-~A>iBy)F?!$V_>ROAy${^0bUHzLO@NAU^ZY5N!?CA zU~KDQWwi5SmZ2e75$zPMq#V)%rLhL?S}RU0Hv{Y=Jt7ibbjbVTl^tO(1IL+XAP#-H z;^+v?#32x+zxj9{2JY$7k8{{q_^V=jMJvY05ET^@?Ir|4N-$(ZgPag3hz=z&pdu#J z#Da#{{TC41uSz3%JM)5?=zEdGm)0#oF!lY#F2Tw7|2^Gek7LsjJ8ZG1Z5RlKk!T%z)X{0~!ZmY%L$_6bJia4G07J}VS>lmo z#pbC@V*xm6zt=_!9v@lv^S-~UO3Jf!nj;y!1Rlw3TzOBxI8u?w1emewA|d?+fbC~; zlrMdv;CJL2XfPDIhw#X8-%sfV^@XP5EqR8hsg5+>A!E0=hB_4pVrdM$PCpE#3`h8t z$*zs!x?7LtXK#m*_aLNXkR|%XNSCM0Vw(;EH0i#tlZPB?ei;&zQWwA_5&(L^&OGf%djDBuetK?d>2 z2rUkX^*fvBgaObLU`W#pj_B1jiYH-#Bxog75LH>DbUAH0U9Z#=TNr5M^#FRLIeHI1 zb!gG(1E3?*8B9IvW(sLmZiKIWjYh07MY9Oh-H?G4Y`3Mr$JWRo(18I0FfqU_QpaCb3I9I)0W~-*#X@#`;pBRQN)r6+0FKpz< z*dWPUl@s3Shx@`7#=Ay*&s#y7HbQZH&q@}#-9bF-XIi1_$Hu%r^g)>cRkFN^`iDN_ z?mK+69;AIijX@Hrwd{{eKhE-_`-o4<4g-MgggFF3ZW{vB69jqf0M}wZK~T_!01X6< z>_*!L;3~pG1wr=+0xVJx6h9syXjBlCL=a%9g3PjM@fuQ2E2wBgfRzM6RXe~A>_HHi z+7O_bAXzONUai#79n?k;V4Z?wJ)i)4DhPT-5THdtdwbKifX<21ipg${S$qu`Yc?95 zRT!uDc}*fZu=$bFW6%|h!oj{M9O8>Y zyDtidY5<1$5e)YuV*~`FailLATYb?u$`_5JH2`D$2*&!+m~o12bP~2<)f2X{wCc~{ zvfBr&#dmukAZWfZ1!NmgZv{CP?Da3efgb>t*Mt5EIQ1VO*#*~~x4$7c1Sww(LmkFF zz=4AJfXfuE-MyNzhg{vm0U$j=%|t;JOur7UI|>?|_0cqqm7Y~>-zd1mxmMa5-PJ-7 z$}v`@sFPB0Y?s+^3)m~=DOtLj6I<(iZ!=uST&pHTW|dn{`Ve3OshZsaio$PXLM^p4 zrunvA9c{<+snb&862st(Ik{z3)U`c3b$okkMW#n>r?D?g%4m7uUgxD|_TWZ@62tFf zzs%9fO{+C6=E{37HeIJ|k-#Yw*OpM5)Rda#Hs}i1tUNz;DRpb!CQm72&3p>V)G-st zjonkkBmn{DOAe{YXgJgmPC&ZOvKR|PlBsF>F>Ouv)7Ty)C(HbV$Q*5&nL(&qw8q`@ zZk?Vw{)sbIq(aZKQbrtQHtrRtS$T{{X+>h1kmk%rJ|S-^i6^~yz?<|JOJITrVBTQ* zjyxhDwlaVj5^!8}8kG99TN zNT8u=BoVmKN`gRtmN&cq!?X%Uevet-_eK>{AvjX2(L*y1eCPvXM(j=Ve|u)FA&DDR zV}mm0;HgQ5L3D{bjZ7KOhq958P2*~a5&L=E`!TG~Tgde>!ICKSnIIh%J7*}#VjZ3x z-}WqY$?|P-LI+)Cs!VQaH!1|8@TtS zZ1?!Jb;Ca^TY*|gJ68Y~n!&#-TGRsdH#jG+^8W;1CZ)qxC8ON>Beb0POjg2jH-g>9 zfYHgPg>HR{zAq&y>GNk?Cu@!ly2$PzqLz@>{HeEb<5jFvEsPUy)OA8s!g7F>vI&RB z0}Jiy(lw0v++*5fhg53Dp6{BWAxbRC?>3Xd4*}$yofiSdM=!U~LZ(?}eIN0OroQPT zrGBO~*}jaHYtv5=_S7kL>aImsSxswE!d`eY*B)Hm`&wFaI)*aNG(F)83tR!c`VMLb zW!Q6)DUv;3n6}@_H$sY(sIKaB;)=Jb-;Pvqsyg_5jU-)qfhqm`L)vl{q1vP+F96+* zRy|gqF3~jy&&5(~X7Caa-NyXmVQ{pzgFsR1j z9q`HHXc0Y(SA%%{9@Z-BbF?FEx4-!f)4hZIC6r7f^1i*gcZosP$(`;gR3jG7Ngwf) zau)B1QVGVl>hkGpu7w~}%Hgfg!cKHFhQJ>JXJpaUF<&p9-t=ULodHN=250Qvd9He&JkeBt9yaF$~k#pYW*RZ8T|eYJxwmnun{Or7|qHubW9AiL4|J@G1iki_Ly zw&NL5svop8{qt7#H|Y={jK?Y>AVr`(_?>2b1Fw!wtpjNL$G8gbC|vIS%o}*_QG-6= z`N32}RfZlrmKu)Xzvb)|P8vlpCF!QmBYz4jwO?q?pWXaRM#(Ta(8{arGrTFnuNkw{ z3=w#tW?@2<-33}dM7}pU(8v$E7jXZc`E;=L@ZHCx_JYc6>=m0w#2$% z{H?&~T8n@M{5{T*tH`?g7CtN`g3O*TC(S@W=kSIflrq0nF$N;xPm2&fcC*Egcx+{o zs7KrC%=3G`rbT4k4LL+32xJA>Aqou!a+iYq9aa;df_oW-t4fhLR=DI;KBd z-{1d8a%uHWKOg?Tq$HNsa$`}i=u0ws zN1Q=z*dnCCi z!Fl zWKlf#N$ubHcy50#uAH6D7#>t~#W|5mzQ#Fx2^mEy4OG}hkf6Uz*uh1+WTAlFR?-kP zpW8X{SL^v1#-p3snU`>S9yRpG0bo+u7c+w5a)Wg1j_rtU`3t63yjOikl6~1H{-)Wb z>fzr)o>SP{k6mS);yq&1DY&+NxIt~to&GADUko<zB$Zx37sN*Jj_CTA=UxDM4R=;&EnhRL5uDsQmH`So11ynT6qr2 zgdOr$-9_CUihAy#ZpnL<>=WSt^vj_^E&2!eAUovV{`-gNPHU59uF=1LRh_5(G{-2z zf6;iySm#m(g&>6D;gbmCkymrfbc^&G8>}}P>6TwjJ;0&2w|UR-XrK6U@*$m z@S&&)&Lgu5i`3{&w}Y0rxV_ymJehre@a(P6pj-20nqDcPM8KZ4ftzKQ8c|=n6}#w3 zl#h|59Rn=mlW--&cfMn3?$a=iq3+Vo5OMp_!A-A-;+%I0gi07 zX#bams-uMV!-@ zc`HjVp2D~`wb2{q{QBG9^x~-LAkHSdRJ2Zfg}x58?0z-{Kg_(n`dv=RpY#QPqNk7t z?7GsLxxy)Ap0Ms2lgq!9L7)CCKK{*gr`k#`SXr3c&>l1WTzu+IT#S*Mn8Zs=3{Fbq zCeFOd-4_#o$|~+gdhSH#zx=A9mX=|90<(zwW&rytlOtE+O?=^_H~kGscF)luxn1rt zSwBoZJF#=_5?8UzXz|^A`AwY+7V~9Ry1hEPm<+2r%PV8aXW6)hUcg0BU z0yj;SYyA1w09ECjW7ltMYcp+|ZL{*;^xH{V#vj*lEFD*n^ZKW`4+=7Oq^GZ9#(Q8? zha1??NW5W+0WX+xG%`8%;kn683wKY9u}o;BqPufrv%I66prUPjJ)Xi3`sri+HR#3) zKH3a!{sWPH9f>zhfAjg2K2e^J%U6ww??)!e&%RY2EUxk8WNB}G zgJB`%DIIQKMoTg~I}<}O0M)velwsoSp$Tly6^H+YR1CwXlLn@lE|7Jx-A*DH>FvXbz%xW$-573kQkydI$7Qy|qv=UEjp zNl6PA9`zNA$6Yu+;84hLo1RS6V=KJ~PhhK}D;cjMan^Gc=3Z!>+qPivt93Gg} z@Ok+)D`YVkA+zmT1qL6v6A9jn1os*C845Tl6H6m~vw$I>dugP!rF33t&BD_5Qld6| zE8Mh&wT%_L-ZH6bS~7L%)F3uLa&K>3MeMz|>-ReMIt%Yc5NC=j-g*S~r17lG3%)Xs zWnSu0p1IEK^+3)ZZ^%Xzm5U?}OoqC$&{9aQ`d`K;QqqFS1Syhmx zK4hu86!-g`JfdMZ4(z(9uaVxoFwU9Q6mx%D4Xh28!YN$t9M?KxxsB$8RT4 zbxytwPg7BlL3^*O3P;un9r+!fiX9+{jPK+)G+GfA{ov476p+j3Is6RqO-FoHTT!bB z;0wfZ_ZSg(wr$*kwz^Dx{$|mBGWm_?@INkzBgma)^iv6mrHR=mu!cg9R&WQcu3TXj z{^d_O_56kZ$&$}5{O}dNa~VY|3kEKk>T>CMT=zEg|shjiw4{zC1&j+^cmC1v#jDl z7ZyhJzU&64Q7+GZ-QO`aWxS{LZE?&`tO9UxBVoofho)oT@Fqq*ie1zH}#xybZ3&cGlMOKl1y}eq9wM$ z2uWErg=kl9bG-maFQW7E^QZmlNq3vn<{q1;$E0ci zo0`wJoUg;Or{Xq8VAlAu9XNQUs&lyzt%3zhV@H@4klsxg@1tEd;7GC0VDVt*i!pE*86PS`X6m zojX$9QdJ&oEAiKaD$8rNdqBHvSs<`X&(g3b8_x?HIrg0;+v1x3&H`mrFDRrIe*9`_ zKcm4H|E)jlwOCo@P5u)4{5`Fax8H7^2!%w!QX?TiuNWE|Qw*yBJ5MeMwapHP>GAMV!~7+oVP?6IcZx&4ML0Jnz*gAu_7u|@2ty8< z_p4(Z4!uNJTFcYQYiRzeC@q$(gg}{E!&h=?$b$>lKcy@bt z=czBAgRw`}oqg-D^$2IDGv*_*$X(kSP>X|gBAvXPve@~CA}XM_7z`?v2z_d)-qz3@ zJnmq!%XN^bsX`*{Y}~iLS+=XqXNJF)Jrn62i>HOt$boqR5#lHEd49YY7I1{nre&`_;;^;@ zX)%|2Da^eBS&?4JFN%ELz9^Ha7YHGl!rio|c}eeL!=ANOv+-%#`S_99(TxFw%H}zE ztO}J@9H`()wT*mxREwknkSY;9CSxp>@ljqcH@eTw2L+&o3GWmP-Pz}^rQRyOE#-$ryZyY0Et z95PeUo8@7#w78zF)z&e^9&z71v5#XGNW|7s5}#j65St}jp>h8x>Y|YMEtuZ+!xB3G zvOq2|sQIMB0AZVl$TW&1dWC}5GZ|VwYt*=ZLttLKN*3eC=1psDM`#?ri_Z>d^pao| zU#9C7IHS5`)oQ8IiWsGOK0kFY(o$cKgkTs6>F5^Nhl5;h`CpAdD1_YZLXbd7-nJdF zSBlb>+6$)cHEMXc1cL~t*zsO?U`YHTR4FCDb=7oU&9QaO-vL>BvPKEaSQGz@x%I zBop$Kamf)Ib^7u7gC2c+9<|l)b!u0CWgHyQJ+~S#8?t7j2%0uLN%QdF$V2Va%5r z9g?=g9QcNo8=x~{zEpw6)U{^d8$eidG^cKCz~Fo1WpaIOW|Jq~6e>g}?y>#7X^c!S z;ZU!HQN_Z1vY%;{Ko1>N15@QJ+m$^CU~>JE0iHBzPupKhM~LJS2IXXXj7R?~N@{#J zA;$DoWB0i9R3eg`5FRwApr)TPk2ut` zIeD;2Rtr(`G#1h`y$8Orig6)x z>XmuuYV=yT#c&GQ9?9ay8=99L{v3Va$8qbpcY4jTa5%WiJ7bk)6%gzH2&pmS=R}>! z7(`4Kjhcg)K?LDxRCw58rm;k6bS$%r3D$sX7Ahc>N*tL~p$GJT7f2g^YA&yJ&Rl67 z>x;2je2}hMX_bo$mfjiP%5o_Ub64^n^OmN!lGJ-PeoywBIIEd=7> z-3D6Db!w+trVcp*L9ft55})b!;@NtB>rL6suBtnFUk(3tRn~iEY_P8FM_J5ds|&|h z+7wdUvd81K*m4gHRg_ucR#{i!k)r%e#E78?G+)=%JbeFm2c2tH2=1@2*kBE2s2d(i z8EDbHU{*!*LEO7jB+Gl8+E^jlL2D5w9Ln+sU9aCME->*%}!#`V*YjHoWZ={gnE%#)yPtYx@~KgG>Ni`(WH;KtvlC;dQtlP_wLHca}AY;8|MV}R*If4 zqJkoU)!$t`t9wBe#gIIInj!_)@Tk%>y3*X(va8B-AQW=GyR)plyrLir3|FNn7hG#; zzqV*j`>h*2^GPlFu748bb3ZUK5r!`?X(!NiRH@OaA{^XJw5EDoS-3FY8md$AD@qSE zGC*}TUE~xgbbc)r%P_IDWo{=)^ClD(FJQ>5&rfuoTe6bR2ul? z=s!sG6l@klns3MGReYU^^Q0}%wqMEiq-Nz^yg~a9=S_A0{PT#_KH~G)M@B4e_o&73 zl*N72>V~-ODpfZOt2#qS47Ui2wjnNzM$*3*^l^&S? zyhE$*1VMF2hX&GxHK0I^I>TC>__~kBDV0h&Wj?+{K`tmaP~d8H8vDDb+m1G!;W`0`ZY^BjYg4^Lf12@4>j$Homo`ps2tgMC~;#Q zjHnDkVo--#6c;uD#Ah_%-~kRD@#3!SIH<{55(L?@57a3%*4#o2OW*3sHUN^M5&X_M zc(B1@7rHQBa?PSfFX*e0tRZ2$!LO@wD{^SAG)XZNILF@AXAr{nag?AW9?kn^YT z-FJ1|UvWOxEjYSx1{Z_j_8Bz#Om^0_*R^o-=yTdnhUrP2pY#($h3WTc1=PP{xy@hpllyV9 z+zrXPW5MQEgYz|RumuD6eLY{0vxz47dCw05KJWfN0k8Rf?VTQAJFjx2*N|UW{syIYLNybkY>LKcAfJanEr-Due z-35wxo$S%^>H)JZap^zyaQl;LF_#6vk-s%=)1xQ`BhH*2`UrU7HUEDAtUz7RZAzTF zLG~;0NcvW0kU#1Wr)Jv$4`UZd^O

BF$fM9vsYs(%;pVL{QgttFZl2LrhoVLUHN_ z*%fVNWKol@#Hpe^eH${Uql`fG&AS#uT(fl1rDTGmh(PBumv-*=`QmzoV2uh@4i$WL|O10-|QK2;QTuYN0 z!*eFj;7D_=`hy%(wj=5__}szvH$W=f{jWun@{!Nq~kq%F;I z;VWL6eoxPydKkk(rnake;~rI)``-n_kL;I&EZrK47Q&Z0dA$(BmZSOKq zleJVg+7-VhW>qKr&1JoCaIwY#I_@DIyRITnrh}>=BhNWE@_}W&3z73H5^_noqd+L? zi0}q?3=IGqN4VL{eYyk8&d0vogBNKz!9(5!%w!mLEa!akmz;8|hDS6U&W}4=?M5UV9-yRO$x_Tu=_6TG(qkq98x(hc!G*P$IL~4LH;! z%m%mHox&~xvYak190p*)X@qRbrw8$&0k;;M#GfU3K_k|AlhW4WflaFgL3-@k3l{1P$@%> z0LthDuZS4#EtHdDD{)mP02pkp8RjAaGhq*K$=a(Mn}b1BVt`l0$!P#$ zIJGwN7y$TPnrI;I50abZ4SE0noz&Z`${*Zltf9e(UkPU1YbGAYOqX;@<%l5G7YmV$ z-SdQzd~m)=tK47iz0JDPSX$%1-&;PoK?_@C+J|~-+sD?!_s}Bk0P(s+-tH2gs zlyBnrXx#OA-p~D%cX_*2MsAjmUdI!^UkA{Ua-=TfuGS&lbc>wP%BgENW}V!aK-(tV zOkmJrKbaI`ZcW$q%vz$VU>aZ=U_X=s8^@1U|79E_UWWNJFlYIO_C^+v`VKQS-jLii z_g_t5xO6u>C<9b;Y362G&jtn$^DYtq10DT%JnUY3yNJgEv986XCc@q$g9*RF-Igr? z*8-1KMFt5Z)BXpnM;AD25knCs5Ht#wUC-;tKLm$#;Ov42fB2GTnz+C`(j}RI|3^SY zxmQ(hi*b@Bp+O#`M51@+T8_}<%xpzro&_!S_@z!1BYg?UlWSJ#HZ#xsY;R`u0Klk( z7Mv~SFJ0T!EPVATOAfwlZyIg17Zj95xa{W?!jjhuv#b8h(e{OI*G@%uIDkf&!_Z1J|=jHoDj ztz9s*M$enP1%d&5&{F}d&?O>L8%gO0ou-n$<3OLZuGc-%u#eAfVK{_^v8Mlv*5yu5 z?yipqH3}i~?vZ=>*wS2v=b5K&g-FqQkw+aAAD}gQn0Z`~mKr7G?ikQwUF+A>+8T`n z7RMUpm?u`ObQWp>vGtBjJDGL%gPw;VkCp=1gzMo|2ispiWLoC4nITb&*ASR&Sk0HN4&^;m78^HrM7Eq*8s;)K!tENgO#G%HPqw zq)YuaPguI`tR|&fr0-{n`XXU9?2p z%?-6^1mGOG&dDld=&sL?NIiv$)j&@n|A6NjsUf9PhX^IUL!Ilo-uC|i2+5VYVO*zyv4#(M^~Z;|Hp{h$ z)Qt??Y+c+kx6JOho@EEf;7Q~3Qnvsei70Sb`QG699CtV?7nCdyLD}!%kj@=l>E2qU zwV~04NLcpA0f4O~wU);iy)XeQ;ADM`eUpWbiOhY@OkL0rZ5onAFc2-^>=JO40+XSC zZ*f?8tPB88Ks)kiEW7P|Wch<3IAeowq;~Fe`DM=oOX_T8erwALzB* zM)2_h7gQ@IkhDx7Ta7WAcUP@Sw5duF3s2+0IB%p>dnh?1ny|znyY`;%01!mi&@z3| zxjzGwr~HSeuF5P4xrsv?+r6Rb@B_v)y!Lk?qnFQBJ&zfRPk&a_)xi*U{6Xlp8|bD^ zrCi>Csq15ohBPi(tYDZSQ^6A^KE{dMtv~1LomvD}BNgSy{dW@2QmSq_@qR&W!am0W zcZtIo#RY-g9_tCdxEMRjO-_H z-%v4rAhE# zsYziiuzl%yBrF=lIaV!b$*r^kCi`$O(OBZ;ePwu)bl2v zJ3kj|%6{_?8fE=j5^4vW5 zAY^>)G$pvyHMnaqIZ=ETH8WF>9RV@7Ood`r{^C;5ihmr$L`}bzSsxK7KRF2|sLY;} zdrgkMm3BuBe@$`gViPdY@Hlc`vOpDH_t*40f9q_0)`a_9Q400>99Z=)V^YcuIsYS; z7ClgE_(VkC*WKf=`TXZ%Xmb>a2~7j=(q^9C%vT#asG(Yfa29cjbd4S`;6fi)3=Hs> zvU@a}=&pZ+${1}^?b|L|&*VjU=sw5U494VcER%#zz&bDYW0uk#-7>!nF?iNqte170 z>mrUQNOfaav3HP{We%=trZL};aoxsqOI8e(qwo=%U*yDni}p0eT48=rrS- ze~i--$jF#S|H{MCXKiTcAW3Jbo7yhw9+JF<%L>mj{e1HN1nbo`w#Ps)^$kzT+&V4& zC(JxsnavYcPn69WZfOlC+t?1HDLazm^mRtXp9^l`J@HZGDe3#YgM(DNu#S1uk0$kS z*$=@{u?U*&Jsm&xOfZ?pfgo^gr`?$f1@f^9bT<$CmFMUHCa`tX*-3o3v>-JSfF!C2 zLQ307>rg5+GE}1hFtI!N(2|hT%;P8LlC=2uHIPVq5ybE6k}UM z4w+Dsg^p>kmLDbM6B7km_kJOU0Iwdl5Etjl>b&;s?E*jx|*wLCoQicJv#cziPc=fvk^1y1q^3{Mjm~fJYn*jBz4_FkKr=>`NA{> z*z{>v6_7x@GYrY#7IvOeVgxXIqn(0gU(7!K2otx1PpWsEGZGK>weICXEQ8<{KA9%$ z7{O|w z#4c@%LP`k4&NHBj3kWYbZmQT3h~c`wn1?Y*#{IZUhNQm`hhOk4L8<{^IyQ?57qg22 zR&CrA8AK2Q;s?Hg+&A;r@9^6tqON1imXR$2PYZq_%kGVMC4yB#+7mIy)AK3jca-$^ z;{NHzJj)t5w4UW%i)kJG4PiK^2hL_IvuY1Tc}4yS*o58szZLlAvIg^bP?djvoE)t` zq2I%0-Q|w{76rc?zpYHJt5`K~lxx!BC6(2XmdzL8VVO4bQ)e{CCMpOaMR%xj@@qps%Dw0s&n7$lQU8AY;4GuR)gPHY@$kTor=@nDADJ#!o9M*F!diY zZJqUwwzf@GruMp{FzHG7q7-9lxfr593|Ux~rqT)j6=V=YxnY36I=8N0Hvo@qnpq4` zL$$3Q2k$3^mw&HlDEcc~E(Cum*&B7K)*o?V5_7hjBD|!@Y^{Pka_cz_-{QHe(M-U*f8b~n?wj##tQPVZD_K0%@q>X82#2^ zTf_!UL>4=I{v-Y+iE+b58n%DRzu~7vzb|Y-I7a-jh4&L%)^O1&XfUWT1+?*&vYEIr zKTUj$C-$XsuoBCLoSX*3ckpS-qd>_84|y6gB77)Fx@l0JrkAsiJotyoaUwq9GLHb~ z2R8VuX-l8PNE|ZsChwZ-Y1!prF6OGtu-W5{HMm?h(RyD2;tv!qi;zc*DzA;;(WM#2 zPtX1k@*IQ`33n7~E-a#=;d6;y!G;t}9XY4gkva;<^nP>(1MtMTuO^78m%EITVjOxd zN1jK8YM}X;v-&O?i8)j<*TJ@T#I%xgdiGKTVIG3m?Y{m_yX!~^p7PMjNBQRe7~`jQ zRpr?1iI$q=6OMS-Y9{z$+%^OT>$fEUTps$z`T3+MT?U#h86LzmjH)7WUszDU6=Y35C* zy!rwVb4qQqh3Y?Rs@{t%_h8R5=YyW5QIgz}_S63UY1c zxfp=APyNzwp@TN!X@-I@+_RXvhu|MjaLgacd^*dB<)Ns%FnxA?>@%~{5Ic#g#lr^j~}c3GPbo8oVlQ0!1p7v{JOyIZ=f2$p@Df~A;TkkzZD3? zL?y3lzy9hAmv=p508ifccbBK#c9N`PZJzFUO1ef`q8-P}W}90a7H+>P5Xw|fMpbgv zQxIOFtE**9rL7FVdwJY15$VNBiU&U({a+*sy*Z)!Jpg3zP|qP5Hx?N$H%+i6{D$)x zs{#D|yk8nfslAWUdFQQ~Flir3wMN>d9r`_Mv^OE08O;Iab3b=PNh*B?%Mv-EBf~s% z!gtK=j1B+1xtYfPg6eQgl;CbWysU=-f&OJEj=8nEP+{STdw^d~sK(Y^e8??O%?*R&X*f&Y zo~rO|oQe|F7ffvNFK7(sh9orGqd2#UsrlpT50dja2cfh^xeg)MO6xf*8XRkpY(T1u zX@N-3$NCmaMe@P3**iXS#7PJjd%Rc!F=s4+m|Ipr%*+A^KKC0v!#xI_8EbG8yd45@ z&F6;#o~+4(IoWQX`y~;}!_5K&z!?e7`TzglkA7B&`fq~cF91I|Mda&i`nXg2H~a77 zi+<>VH4GrHM`?ZpEMF45|GnFXm=nl$%{3@=fO7%WWhf=KdVZ-&=BkBlto1&k?VRhz zj8I;~-(Of)a~}{7X}%#J3OPhWgmp9L6WSUE#B?3=yxuO%JHwkbnVD@1ls(*H?j-}a zW-`K2ptMdIC`2wfRwxFDN(l5$UK`Cy}exgsm$)XIF|%TGLDu zm8P-68d@&~I+Jfu0k19v9^am!gV94SXlw&Ck^?+!0ksEk1JY!(@t# zw4W2JqR(RT1tcvK&XGV{POE$f&+H;OVes|*&~qcgmF@i3KK5f1mGPfU6CMQOAQk+4orCSaJJf)LC&#{tjQT>eHns^U#dZ0aZ098{_4nzB%8 zU{gyaSBfkt>e*B&P{pcApnTP8^<`1TrcgCoxZS`SHB0%vyE22b3Ed$glm3_!DUm^v z1d&lE_N-YXmNc^3MzhnRn)wYgZzi^F(xA~mHq>z<4W=P8&?z2DfnX3&&9Ya#r99li zf|PE3S$Q*a=T%-cFnu+PYBjK$rt~bO_|CW#h1bU18*g`tBJ=P!`!U+?C^H)Io* zCJYJZ9k|n>JlD8|ANL625n((jz?Dxf2->}6xY79?Y>yRu%;Xq<3 zG6oUHC?qIXDMp-t4JE5Fv23#yFPg9Q4?gIStIPem$Il^!w0oa)r1HgzVYK0VVbmh_G_4QceiEt4gtPi*eE z?{=C-*3%8moZKf&eVeP5mIjkWpOs0k*CaONXHxrq*|CwDZohhG9vKtPW`{S!zb-g< z(y5p32j5Aq8e%O!Fc$ymdI0}Pj;3(%%P39T<~F;NMoV)(T`*^pHKbsZ%XDmfF%+bT z*WrHzm5{(NfeaBeAUG8QKvaWhTL>VD=o$j31ONd7paB2?P6+{l3jm;qo|L|;+|>H| zo0_x@#*J+>E_sphiMJE3Ylx)@y<(2P+F?WiO3}@{P}!HMwhLa1qd0zz5P|hLt3;bjOa>A~W^-Z(o@2=I#O)!WB9q+3p8Avc@eYxao+j9{*zHX#~k zoomWt9!gGN`96cy03A;{v3Q>5uu4Z)vNzLg<;GUNYwmFdDP>U_}_geE@_LEj86|Lqo_UVSBf+G`rSCu)Go->7ol zXqs)Sd@ExseC@x829;)3PCI4rs%~Xi#V?wc)vA`9tFNMqzb@=>>u~Jg#O>U%?m$In zxNHvMo;uudNct>8WA7;59Ji>*AZCv|YAs7#7K>m2gmws634&x12nvFhY=QVf3xiGo5~*MTHUcCAhZqDP1%rGCg&_=r zEgQ|IN5q{SMJ3Q31W{Glb(xU}8#P*CqY;hU0VRs`NcR8#f6CG^L=$8WpsL&2?vN!C zhXSIE5_(}23KLan^n{{TVG9*uj7e*uddqb0O{3vBrCYY8-QPZGSF;)iZ+x&xacFT_ zU#O)Zr)8}RvhF|N-m)J1r|}~H{8Qsm<86p!$mt4&9JcH!s~}5|t@9x1Is>0`BRN^D zFV*b5^ZN*0)cq2dwZaq+ORprJEPjH*5)P+5{bHJGnO^cc1KUQvCMPcs(b}VLc4zN? zN+^+i!mfnmm{cnfRBb@E>`_G);m-hVGi*>%^k@M=5D^puF|cR_3&lw60?e3mF3LGK zH+xaKIcF_?F6y^gn@iW>qWx0sm0>|F!rcdX_r$M%9L#-=1W^%64mnh68mFSN%hI)r za;M*__po>Se~`goxOP=K?b&(GjqdmN`2xWIoUX!Qx$FA5>S^qUP0RD&Sw3(iRUx`J<`0UNj5wG*>x}Ses(ZQgE zVcS9p=!+qyHyD^_sQttsUFKoVOn@U|JIMmTtG^y#Mdu+FsDM1#*S$u5`_>>Kf$f!^m&-t#JN8@O{=TbKFo9u+ zQp8yIBI+n-IwKwKN(Yp-&;H8az&o!3?e5stHM%qB90JMnu`WM5{T+qC5CS$7{@&EI zeTxN8OWbJ&5EW==-YM+yn!BQN4t;K#|KEOa|Ng%?EEb>$EI=Iy@&W)#2A4dGq$v4t zA@LM4Er*;K96(TsR3sHihmfiqs$4WK-Fn>A?#i5svUBasAcutD|NqTdpYB5;=9Tod z7B$926NT-v@3Tz22cqCs(R3AR18vcGja7diQ7}eO?bJQaWwfdd~EHaKldUaakQY%wvE~M zQzg*IiN6wm}J%rDjmTlBSyd zjHPF$lB!==6@IG;BRci#d;;B8zmgEzHX^+u6fniAAlvyG`AU1dW#l3n=!AUHvO* zp2j~<)7(DYtgU@7&_O`1V{Ofo&k2!(h=}_lz@7iM09juP-W#Ox!f9Qu9ulCa{e=e3 zzYKk!|3M3o`U66r=`*MS!}`q-6qHeo!0H!cCSXjN0BQA>T4sfg#)dW9(lP5Z20J$F zYs;ZNVRB@L#hz0gu!5Xmt`ojRpt6L1-c?bsitzT zrNUONqjn{wF0CP>*{s&(oVL793woD|`bq}MhOHP~tQxDCv~GH#VWw%WWzn|f`Hq#Y zb$hnw`gR8P9XgyHIT|~eICtuDX69<{)`k1&rH7TLwRbl@r?$R!e%6TZ$?RA}U#~XLOb=^WAel`ohmDFa7e$@4oh@(i?xh_0PKi^?hj6gb#WjQ9m&? z?z6!%>kIBzuEu=heHZ#etYd!K`DO37i~cdzsJ|xvARzt{RNjjn$Zn7tn}~M1^qqS& zB5g3${y~S3x2bln-EMdHt`MYj1-nzwyg|x|4 zCJ{}<-G4`-+YBlUw0!@s{-6A_+PB8{C%B*Ma%)_7*bZIgS$Ru&mC6}4d1!F)Dm?=1YI)Z>&n^Mq#j$W>t0O&ct_?Urb3m8n*v z)=7^PsZ*|AgGLpaH0x4og-R_}YBlA7RjRaEZH*neUGcwABV>j=Rwzh-Fo8xL6VA_O zM~xXbVbWE{J#@rj5&Q+)DZ~>?wrCemAx@$MN$C32Nz$g&urQm&JL6f{8IShBhi2^C z#&{VC3p@OSDd}(4Ga!2`1CYyo40APP=0gq%&%GZ*MPYU(y0aJ5eBJSNO%Jw@@8lzad%Ml9-H&%~$EFMX255C#+&sFa z>XWsLlf2dl7ZXSNn(PXeF;>_#YonwqXzJL(q6Y9rMtnNKLfd1a?X%I^=URNZX|?C@ z^rVAq4ZhiZgV?;^Y1G;Dw*zRT)rZhcf*lf`RjZb8+uGzEY|#@Ys^+(>SCQ_g`=>`^hA`Us1iaqQ(N*mGPBXb=3&q{pDg9249MZ!HUmlaJlAZ3}6Ss|`WjmJQ4&I3Rc z4IFiqPq7~ZkXrQ^&yl>GY09|3DX=qVN(GXj{p7T$S5ik$$m(+pTD@D*Q(eSaJv?W_ zyNf;2)0PXxmc-H(%AJ9ti3fiJTPoZ^wpU()xuyJ3x(JUotNc*;=g72Km1k#&|u z-c6LtZl^S{Rx*SViI}U+q^%+32}c=w7=m%m@xey+0gnC@UDC0ko{RDe@J8dxh%;lY zL7O;d4_G$0tw#i84G+TE<(5wtO1_3ivResX*X*HY_wg1C+66kZyDD*rY$$uXmiwHd z=uunx);B#T9|W#BO1gF*pISemiw69C6a=$}q1I_Qze?}~=FSG5EtFQJ)~T!r*CVBU zqDdTRW{V;&-4#DS#^9y{cI)a1Gwsu|S7~C!q)nB;Rgl^OotXv!Fgb+AY`ia9Vz)aC z#|GXSq2Wp6t)#M4#Zb>E$N2ZXN;qKuHYtUjb15XIR!f_Vm0H$XYuE# zGrxDMP_k)Rlrdw+*`J$wMIcO$A!>NM>OMGQNM4<0EB3L7i4IJ|Wb&6vk^EN*RqTkC zq)*w)){y0l=&BPFDtQo$N0dDhsVQ$`@RE13Fw?6e?#UAy*k7K>*?Em~>&xrT7Hd9` zh0e8uVqw@RqF!NA5^R3DOy#4itBp~*Bz_u7bCr#C5?M-6r7~ikxx*6YI72>I|l@s0`@m(!67xOBnSFPbv9m-OcUe_$1%kACWGUh~~N#Dz1zy zPM8x5J>m!wg(xOT!n8~^qoh4$$^+S(hP27$3DKQzw<+kj&9XlxcWwewzQzA|ZR}N*=ljooJ|w~l zqYQdl*-b`;AH3T1oHX@$ENyS@irxF`wCki$k%ojsCP{P_QD;tEc+lCvXkS&{U4_{r zZRG&%yxj^gq^|UcbrFu|AMY4dz2aB8H_>tIoopYT^oAVgl(Ao-XRT?g(ef@y=k9gL z`EaLnK0em<_4O1#soSHC`vKa9GU&^#i=?gR(qnNQRNxUuzGapW6R&~XsUe@ADn7^9 zkC^Vh8M#njTrTn=^=sTb59s5c5PuK`I35Oio6B$b#*TRRRc=v|#FMmaIV_spV!BnU%Cc8yOjU%k_TKBciVI6quUT_H;sb|(<73RvZssNQ zIpf0D9B@9(2eEj?rj>tH~IUy3f6z%po;&zZ=87ley#Y6^v+nZ}fFA@Op21YuvzS4hc z|KCloSS~o0upM-5Zy1KUCm+iUh=g;uNp_Rj&>$DKu@p>m+1fbk zrqVO~G&H9P0sW3%B(Bc-Rv5fQP42H|~X&##6S~lVXhp zE|zRoD1*ovVcp5(-4;qs3u*@Xh|O&+L5_3Co~L*1h9!DF_BxNpERy>&ZxZD;)GN^0 zY3F9)8~cMah_fhnoI5_x=`R}IbDW>@$Jkd4M-yBimfx4Xknk-^t2nN8eK#*gDwDRp*Ah=Idob z$K+&MqJ$8}ad_&d%v^2nq^dNgzQE%8{x*nqL9JQToispQ^db&~)zi34IeNXQeYpFj zrKRwtQa~#0K3#vl`=a($K!3Ex;_YZSr<*U|PIkEcUUyyDyM#-33D-IqKBPSvH*19) zl8%YQnV5OOggk*LqnESJhnV7MMOLo^bG+ezA7z~q7`GD}Q{QijCkbi>V3ik7`*D|( z&r64&yX7j^y1!njaV@x_t}y+zv}5QPgX2L$fT>;a7qb{E5(xG1%g^wyzKm$*WYtZQ zW*=sUq{AA)h{V{&@!Xwf0E4ac&&=@r4w$CCZ&(Y~Cv%ZT5YuEoyS@JDn<*e@LoDO` z%bXsue@MZ-R{(6Bgd~0YGF#!Rj(?1WKeaVF^svR57DRGUG&q^^j1Kveds^fl&K6A7 zz6I(%cFU&W4x*R<()A>MHb*3z&r31vqZy+I6N0s3_0j~YH6-X75}*o1xOK&a9}%bQ z9X_xt?Jj`^@>4|=`=UPqRDZXXfkF{}N6aRIu61|r?h+oc;-Zzll&7qcxBr%~oM_Gi9ZoEMt5@y#f!?Sk ztUDCcnm`W)f?QO0#612?wOP-|Ly_D+yfb-vPho)f&}!J-I+Sf6hWLmSVaJn8x>p}e zcMM0&M4F9cdm5^8*lYml)N}qr6y)4+!p%UO$u-{d_w4@^p7#7vwg7>CWOMEF_s-7! zXRY$x2XfGwHJe zzH#K8d0?YQ`&~H8G$|oNg5MLRgUoiLMy2Hl$gOA%WQO}1m-@VeVS7`Yt3sT4J%;g6 zs&guW^o1}Tf9`;TYDoi!0^?7eeDFvCg>yc#Y~mIE32IO;r15wB#>OMUg#F{U=jBLq z+1tcrVg&)Db9Xxe(DmtD8jRc>;#wQATKz%66RtGAVJT<%`VK0y@_AX>Wt&J-p{-AW8_LJB2;wRZy^|9unc5~v~iKZ4kRU06^7)M?My^w<*Z;7eHqOo~Ic;?P2aEEBfy zoocOotWeL_po&!X;{M5v49=S9NwMI3j46D2#2WtjNDL71(`w%3rk@sI?-$BU0aZ?0 z0dPLb)D#$@EKb1YCMdx4NUY-1YT8QE+lOIBpFKVslRaQ(57!KZyaVC}PM3aeEbPaT zORYX@$tP%grNsSqZn4fH8+3m{e*4U)>c*&&O*rkW&9NqEP!jaNzZd>0py1i6Z@h_P z6K^mn3l~>Ug#K?lYn(81{w0Tmde-r^`t06#OF$Nr{4>cax#h;#m_Vr0Fes{eR+BKR zzeuo8+_975^g~WRnO z=;i}kY6rlM(gjWq8D2|S_J@u1sKCsp-2qWdMZgNbm=kyz4o>Psgr55uYryntXYkN5 zq|bFt*U#KI9d^Pc)UGqK=LeU`U|9v<*( zw%TS+(`ag%IsJ0Gtd#+VODUjo&%FqyqbV$?URW#W{HgRpDJYF&M*2HDqQypKrD>G} z@2vG@?6!FaVH+>N z)Z`;0hMkw0?{2S`=1a^>;JoFp1z9*7Xhl`Vt`nqR#)X-|sU<&iCr#hMf0H$rj8PCj zw2yH4(w%PH(X+`u%qBxa4K-PoC*PJ3=owl_QX1w8nV!L!_qf*>+pv7(pKBH0&%eJ` zNHjOM`FGu0(rb2S+nYBdw|A8u)x0+!Pktja?kq)kltR{AfT`RISCkj0d+!UjQ9$?4 z13B#6oS2GMj4Ij841P=xt2~xu*70|0NP}7M`?K=*4TqC8Z9^suJcn%&FroL?uSbTC zgBPzII5zi+rAu^C*Yh|9u%G9Qa#^K~#kCFVL3R(nj2$g4+?$y)nlSD2j1~$8g=m8!q=xc0H8jl2DOpf%Eo(? zIP{C$n7e7UFN=5CN$UpNXLSe9tUg3O`A4}xlH%aVLA3nL$|QY9cBb*FVYi2T?1Opy_)-(p>Utq?MlQwETiwHB6(^$rYOm<6_hW zNf9ZLWQjiA1*q=kY6O0(_VMj#W>jFa8|eR&de zHTz49#64l>X$m7v|8~o?T-*BaSIfDLmue}YhhAOl#h)^I{P^o%gTE8`C91Xr>p08> z|Kr(LGQ$3j|@i)fW)E9gT!;qLJ{K6zB(g7)W2!lfY z?ErONyje~6Fez{@PN@v>367_Wq}F^i1}!;v$k(09;6NUndUC9F<@DF#gG&qC8!FOz7{bs&-f62ll)1U;r~^edM;mj}5BJ8Pl!lb3+6$3Ji+Fk|nY;}e2QoS%J4 zAgN|G<<;44N?N8vG>u@9<=F!9Ey-`rVwKX09g=ByN|Q$|#KG%H+(EnM)Zm?k1(IEj zxuecG<$$V(DS)Baj%NL7s4M`vN48>Ter9uiA9BKKZ5?>0rx+q_)#U54OOp!}%s_yD$mq1C(O1XByATEYUkYJ;P6U zbUEnm8c6t_@_(T&zCg4HA;T|PhDVegpf83Q3;GP~pIkeMHqgRjM_u!`?q~FBxb2BK z1gaf95&mS8zYdEPpxeJ3j$vTwCK$6IhdQr#MjX90JSNU2lWULn_x5FNI>1R5x-nA< zB$M>Em{$1j>J2E=7Su%8kz$dqt(8c(@AGCF9pi3_9_3l*J2Q1orMZmVgpe&af6j6b zvZhBd)w|V1l0Y8gns4!<^M?zX?MLnL+3{`=Gze$O_La( zexXQ^XvL)aLeA-qD|@}(L;`Lh1FTTHXuAijhN@|c6+S-s0Z0+MG%}?q_~fu#xP{b+ zPXI)`%BuKdE+vWUEfa7+?|Ip6ee!eb1G+Vcq1gHiPkNi9GJQAc+ zQ?WVMVHi6SG`T(nu60Zt6ySy4`UH7%ZHR0Q!649DnV7~)DG}C|aCvyOQ@xmuV9HO^7m^6Q=|A1w-2n^Oa8Wz#HEG0m z6rd1l*YS)5OHAbCR8ecc$M@FLNJcMQhwNfN8YyJ&4Awq3A}LpkPRVJ46q$kK^i3Tr z^p ze#R+LO_<^Th4KH)5 z*zkMF7QXcmb`JIYhY<1wpgzbZ3GWfpYOlz&8!S;Yi*Gk?`!BS@HcD?0csXkBm$)Tj z%xzCVRoY6pc$%%;hRd!t?Xk{;xsk4v>|S+XOAWM9w!&a;;G*eMa4R?7y`wy9(ycDC zi=_4wl}8Dzi^WMXa?-(%I|U3zOlUYqfzRTGc-G`cblS%HUiAoBy%G73`?V;+lX?(&@zcWpDqB^EQ|&U69;_d!(|Pal!M(Jcpvt zup$ROuhE5tITZ2uPFN^wJiZnhT6>Bo7l_<3*U4^lx*PdA#=Uzi)5x+OQ+8Dnt@M_3clWVuPC#PID<2Wgzp{kAw7fvztnzfV3KP01aIVxCAOV+13dacn zI1u|wix?mcmrjbs`2YYseE~tJg;?djX0~n1Ej?iNcgOeo$#CP+ zJYr;h;PoJc99fPpE?4z*$HOsbUTkg7PJ^r#vlQHHz1~RrT3b$L6Ukde%~tAYF_=pYL~H;8 zn>NQTK;s?lp&?Zp_j`q$T8lt?uibcitwycJt|{+d|4%EKzeaa`t^GR1ga4-fSrx2t zvEks(lT6DzZw@KzcjwsF+RkGQQE*55D0suxW1aO|NB>x4a=fhynB6C~*7Q#YSVY@~ zn#lUkbPKQlfu^ zV;z}6z+Mu+Gr)C%Y{V<9D>8%Osp#FT3``RXgQLAY#W>9y7946A*EQVi+61P@Y;8O# z;orhB%|O%L_)b68(Pa@!z*!)fp~0T+0zA++`~HJYtX*rY_qOrf{pnmkod8ER2aq{_ z#ZiUOj+fgNL%2&a6Gx$v7UpN4BP!#>2zIE|I|MP&9r2oA2isi{9W&lgR87Ltz`#;` zO$`y!;+I5x^NpKO6SkePA}BvUXa!??xYqR1F6U+_bfEX_nN=bfn9Ea^%N2b40J^T< z=?O6Rj6&P}sK^M+<$$>&qm$FaSPRFVLWZYVfC*)Y-KnpI-}dIL!wpPzJw7Y+n;#6q zC5_xYaM#Y0O=w&T`@2c!uUIN?SltlAw7Ku)-j4fjIh_{oqi=YaZ*bU=)lK{IIB8;n|zI8mmw6k9);6MpvfMeZd3nbGsmRp{RL$ z%8UDBlO&Cl{pLT$Or$pco-&SiwSQfKnf&~Mw|J*CdU|;Afx-mK{g9>QkZJ+au?;$Z zlEED5*d4Sz-n}w}#p|)og|X=|Cw=R1_&q}V+*Q{Gh`jJ#j z{8y0p+IP63Yu!G#iKjzh`{UwJd)?B-wvl)j3q|U#^v(8nNC=Qlp1Z1dN{-33<-W3X zlu^$c^bN6ZzqYR;nlv}HrNZV4eUG{-MJX^yV74dHne9lWz^U`gH_UPs+Jo;aurVgi zP7&~zOopvZykBxsnh3s$mKme3Kl3w0Bq}M5NVks^7%e-{{0(lp{yG$^gUP(1H7A18 zN1RATmn%`u3RilgBl9N3Wd88n5lm*R&cPo(Uu6ci>eA2vN(yx)cndbI*uvR5$e*2o z@z-x`D~9=j4SZ2UU8bEyIU_mY20@81NjwY^sLUYFZH}4$mvBoT<6F9T?vQ0*Jl{K| zC;c!E)u9MBGw$gbUXL$M(jFZ}oRNVYI0}HrAd6WCo2^?YVb7^FF2?dI29f*=uMukU zm@ZBu2;E4*j!cPlo>ZDf_4G=^N}Oq796L{oEOB6#jU~^9qqzoQG|)Fa5aQw#MRB)s z(W*s4H}@SmD|2Q=SkhfSOS;B(l)R6hEJu{JSeF zA0%)4w-j}>tZICbIDRxeYI9S#j|>j(PAmT=sTxJtZQ#vL!^MyK+5NvS22BN+?>zlE zc@XEg-f7P?oHNzsvh&Bez~h1D-KW1K=?fot#KM0oPD2fS4x02SnhMx`3jlCE<%wvb z*tWX?AYUtGxW~W^6?1YURDnc!LFwOz+pFs8Pf9eP zYICed3GDb6yw<;E#@SW{_@@$GowI;R+eb>wtZY3tT38CtV915{wMCw(u5~p3tzC`P z(LU=sQ$Dfx`L)JZCz?B1$W3AMW6bMy)LK}Wdc=M=kKMycP<6R0N@+*S>RqotGv$Rz z!b?rE?p~{nkgp`u-F3RrjuF;;r!K*^-t8*m98G?7gi#eaxSdYPwuff4OwBVI&$egOQLYBGV-dAE!Kg<)WKycm8W1~+UxCb7wS_&%2RD}rBHwm zMz)7IIs$d1fvgS(&7-cz%%Ltdn5z$Lmc@gkmyKLKt6pq6q$wu)BvofsbQh8hA@NUA zTM-f4+}1Qn3Z?qG!fn`wlm?ECL8_`=DkLPoCB9!;4WMWJ zUO##ORLZK2KLaDvlozOdFlhtVtNaud?qT5R;cZey45hkyvvkRfC}P@@y-q_&SIa={ zHCBsa-IUJm8533;tRqKl=|65b5CTnmP9GQO#&*+R#Ep3!2pijPJe(6l00jg}rb*2W zX34Tm3@c_$lGAE7(VimsjqPiBv*xn@7_XQ$51u}*Kh+ll0RzeD>Jm_XX^xdyj;*p7 z|0gm@U@SOe1Bv>sSr0N=vR-7%E4P0c8rH>j*T$ml)M%?^YHFCc_k0yt0i-mV zreSY>d~2;UBf&VeIA~Jz$ON@XgdH>*{ZP z6F7g_vAVn6RfEysqugCL>o`14!v~B&X#04Di~PV~JnS5wvW`VXi8YiM#UNYpmh?_tlc$1bVN@yHjKq|ff+R4)*tytpE|Wp5>7045M@z)w+cjzUnS|?I^P@??{kBvitL-Ae;t+JO)le$h$Fw1lPA zIp9c$Gs655YB%dF-r|~PPwyBK;l=uNOn@{Xo24aJ#cBqz6AkluJcqwF(wbR*jFb#l zv61tE3$J5w;5-Q`AyGAp>f%qp4+@d-Mhfa6;LQ!=83(r|Zl%&>%@aLL_iZQnLt|4rXBUI%-ZGTtLs|bhbSP5^g_+uDN^c98NlZM6ocAfcq-N6At8Y2# z;Uw9SJ<&eeE7eAg_SuL5&y4$XaSS#y&A^wFcnlp>Wvbd}mm;yS6Au#`QJ6Eb(xLPr z=PuL{ymKG}wHA8UQClD=!9arvRYU?~@cS!HPyH%=nxZ8moBsqMCy|+eX_@E{rRQ+g z?;M8(YD2d&G7CDq;w*wACdx}<_DpR+GJ$|)W*WRQ{sYsU(G##i#ZIxJPs^cA?1%|z zmuR3?$;>U2T+csT>@1z_72R0fA&SYW^O0YIL+K25+wQ78PK96uCt8~q)FqAWih8Qm za)heYZEUOB81B1B3}0OdrWPJvSP|5)!y~5^mL0|!TxMh{*_M@P3GoI`5NB{l7$J!f zn57;w-hWU5<()#)Z(($MK8v$y9q9;#8~JHCTIXLXDqmNW*IZW>*=+KCLNXi3jA*U# z8U-$bP?0X->U&e#CXD4*FP~V(CP9f91}2V{0_0=~&D5y3F@iU-8EC=*v>XNE6ql{* zC)hbGLax8HcIcSY1~oyIsaxEBSjU5unMMF{A!J2Rl^*#;7O3Bvz`bjiLB&?laqBp= zTbjV}b9LU|oVPSNJag-w{oDBQE;r6ECHP6;{_siqRmVO5-{GN}1O1E4F6MzhSN)yI zUVBJ3*mf%(x8@9EcoDq%Q@g46kz!R3L>n}@G_%00Fewr0j?7hb(+-GAEq#~Vz6C|r z9Mt)V!6~L`iM~&^;LJ5i9Qsi?+kp_!q7@giaos&S$=VlvstTjDF)<&n>&m0m>RTpa z)&~(iB@Ev8w6j6SdPodw@dgQ2+XPcM6&4KShmu4N2tw7}t-nPMVg*$i2w7Op% zVn6X|syOPbK_?-N%P}$2SRbAS{7`*0UpXbWu5jEJ0+Q#KRd|&<(^0OlXmnMw;csy< zK%UTo8~>&OBj947O#GNP6?I{#-V4|tRakc%Nv^_%Ms*{OlzRUXUJ`cFX3CyBp-5;WgF=NvN9m>P^|_k(-0ML*f+~X%!}O3*d4b4M7tE zZv+NYNWraW!bKa<_HE@^#mg@yo&~2pao$hKKRJyM_$MXkOrh3v+5>l$m^0HZP$JW5 zx5j0%L-ci6VXNuf(uJ=EVf%r0lMUpM=ppq00)Zbcbrs7;E%g=TRG zcH8Oh8mit*c|YYSo)#U4*BaoJ$c05c(t#kuOe(q&f`8L?(E>8H{-f@~y!v+A8_AFc zfdp3CU1_wLL>S*7U`^*<6*$0&cQadWdyP_Un`D(%Q7Ix#hJP+(5(Hy+a~)#sjB$pv z(N#kjZJ5tAU%1Y%ABm)HpyBQbn{pCpQ{hGDditfdN_erG*cCoj=}wI9;@z7T!z@GZ zDzYAjO}a;%YA-=kNN9g%Ut2h`7>65yFxfe3A9aX1%42`OT_NhU+PbGL)Q|s_`b>9v zQC+6pc9l5DAS%(lPsipl zgfdp2umxomTDY`}qps9?RD5-$g1XFp{?Mg98XsC^&=Mgsi|Zb2)z<-XGgI@CsDH$S zp1<+ncqY#e-=Hak4h9HgSW6f8CL$@)Beg1=5Gu98OAk6k*ATR3N{DUKL~PFin6`{%QWYc}!525o+x0E+vk~Z8|^g=g@4ZhvKztflf=dv!es{GmR zr?!G}mlXh97F6j#Fr;$t(j3G7{C;kx8=QUh36+-iK-7EnByiEnId8f2!gs}a;YwNR z$1|%6`JMKE*!=+fm*9(D1gZLBl5Xs)j_^||YNOu1mTswZbL8c3T*nGVMeweJ_*In< z@jR_RT|M7|V^a5(Zbt7){P~m>#(G+))7B}T#$+L~QYE1&#DYbj)Uk$je!*QUXOI9z zWc8DqL{Mt^&O?ZVxKM`O&*`y)uEQjOsr|jx$E@Smz~4 zkIAR!s29~+9O9}}cy2#HU+RxZ@@o@(vkAauvYel;f0<{110z~eoU&sQcYI+-!LzC;+83Ba=172+U=kqp|9YcQ>!3sVsF4)x_7S-q+1q-$ zg}Yn)Ub?eUQVg^;E_mFjNh?uxV|8ax-5Z9$MLyuB zz*&&E)KeW4k!yLxa>=)zJnu;mjWZR&lN|viS+`lp_TfZFh)$_Ng#*`Jsy4WBhV4US z*nr(DB_P=|0$CV`I*XxE;2hBAM8xw0Ww#K;TVt0*Go_N=0mXm#Uk8Pmb;@#t6 zc=#tmWF~o|9OIaVRR;|dx=1$Gk<(-hTSFOD`^LmXB2?N~%xXsO7mm3V{y1u*M>?L1_TG?gr8 zFs);>B4EDp64<)|p{4#}hOa;oJBU#WG+Z(vR**{81|`|ksI?*B`RHJ@W$cy^lOuUe zGYt93q14+*BLy92+Z3~w>jC9i%Kl!}2P}!+GK3R|F*MLFdSS~R(78Oq+-zc^PRf|a zHJF%0FtZ5nG?62Pn6~|@Am&MI zkpb1Niqfj#gsfd_QTRxhi<<~b-!zJlTuxY4(AVT8KFwBmm&?_2^v2#~*t3@wA)Kzg z9>3N;-rw5vO0O0)d{Hq}-GE%%!^Zc>@ycH7=CHD^o$r@oMriDWsZ_}gXc%gn-AzCC zN-Gv47WV6(1l?EOgc7wHn_A8!UyUA0$Lhzh&P=Fp`gAc)c0 zB=kXfh>i;>gCfuQ{X}ym*#| zc8~k1`hr*A+TA3nT`+)MeJBd0m44Nw%cVJI$9B&pNgXIA4_zp-zn2as0{#XlV$Ft+ zYg=qy#)?B*qz9J`DXY&VhkHuY%vKdOSj&lb9#&f!>+vD%MH8u70?J3>^qXZ0Ej7-b z-qD5NQ#)p>S$U#>LFMj^Qth5NF*-zIwvj_L_8qyv5f8FeDUoYTF1Iwk$fng)C$_!7 z#VZvKSaHbq8hKt+{M0~vOqSVxZrz)$v<%R!zJK|M1)Cn)lbE6&%E^2ihB#@`;S|LQ z#VkJHEhQ=K#{Z`N-74=U4x)dY13u?nGdkRJKQx`4c%=e212G-fZ<1wIcP_dok;}T-4H^moNiF3eX2NM~_a|Bvz%| z7O9@@Icb^zn`7(Z)RJ1#r)y_52auI}mRWI+JbbaVhUSoStV5fo6M4azs4pJVt1&e! zt)G-L3~+0;OES23?Afj|SNY$!!9-;69CmLD75j^BAcc86s-p=%jD|PHYm=*unuL+D zH@T7<(xK8DeY%xM35IE7E=F7}Wceb$3V`|{3 z>V5z$WwUaT)su130q^fal)E(DuhO2f6JyUs&hO1T3uckX1CM5QxjnwrTk(?*pLpxD z`7hdG6Yr(wR|zh)gBy0|_3gXT6GRWTAL%bV)x)kD%%*a=PB_tXo_{P;+8cQ8E_UbI zjc-kk>%rZEyVu*@Ub!wF%iB#)7bWgK`6KjVqiIP!qLB{Adn{%^!wVlWblEhlsNA|! zSD4S(?|J=CIzQlO+a1SjLK_Svn2qZ|Q^H~iuYMhjc-bKv)}L4J1aVs@xSQX@MiYy{ zg46|#NU7i1BQ(7_)IChx7YC)@1XiQ$(mmE>TW2|PDu7xoT3LQk-x()3)IES@18d4Y z95KKvp|h8>*+Gn)lokX!-${4_zRd>>dy47M*W^`)SOf$@6cx2J+r}jfVBw_Ac$#jY7CpgOyP+vPKn=Nwfs|+ zRz=oED_EUAk8|X0mEHY6NCg==+|v!ZqRz>kDxIVZtch(L9fp!6gx)>K1p*rrA75~U z53lw^^Y!xwouh9(XIs3N`|{tz*K~KfYF)p+q@rK=o&fra?g-iYaLcBc=c*zE0Impl zI&SUw8p^Zsy<+!L_x|_+Tv!6sKzs{GDuJcDjJ4%OSJhI9D%IE*ODtknxGi%J%bi)J zESVDtPzZ2Ihwd_lJ$}UbgmEpd8J7w4vkRSvT&S_2&=hiS9*o(OF^`-7Wq!U;VqqmR za!4!$Jh_xf@P#&EAWI^`jkT(%)*-*^yF~0`zxCOOMVp zuyiB205Mp=Mq2b2c9E$Z1A!PJ8Uy2sP=iGxL@FSRdv6sH)!RWqhMimvL@ME8Z4=-} zJBV=KA;}d88xx4_#mov#XdOycPYthT1%o9&@sOh7I>5YoL98Mt@!qr?!ZP%ynnA=Z z5&fbnk0gT)d;=S*i7IH$W+)OXmKSfMLN(0I422nS+rAB1(zwMM zl!m}1?OOn5AiAm;r9crDVY%nF z($_@6c5&d!G$Uh!qZEa&hsXS&5w)*wZOVsOCEQP!)}M&kH$A8uc`JT zBNKQnd5pR!_RtSR3Z*uPL`^J*$A(4(P}?vi8oBhUN$j(8OLj%24L2e|3J~GgL!n(~ zuhHcN+O(-mmh-@EpL6f~lRh~=8aUNvd7!vz_K~+olNfFDa=$9X9|Q;`9Tvttv?|4l zk9?&CO^yK8a(i;N`rXD%Gh`1+x>2)#G{fwXJ5Q;k8A7@)(W!Zow%J9aux{fv(JO-; z39W!XwE8{oqXvt-|9Z3OX_*5~zi!igdi(Y{`^@yr@9FyMMO3Ju?J?Wu$=cycmbryb zmbriJ@`F0h)Kx$Om6zpK!GEWD_UMVpXB`dOYO*Yw{Lj0p`*;RVsiZfOJt<_RAiK$7 zuq)Yjjo<0TDAS$XG1v0Z3g`H9=Y2$q;|J%zIUM$8GIXQ%{Py&*>zUir;Ct@gv-ck? z*ZF2wyP+E9%2X-LQ%%QI)@JxWWP`AI{T_)NQg}-qwEAZc@7+uq`yy}l=xhy5BF)_1 zn{TO{xd*e4TZ41vki&R$wg-Iud#Wbr%9C}HH$PgbxwjHf%pzv3%Lh=)w854z$CQ7T zfO5$>Z3!4S3os!A0%GMHIuJnctd&W*VRrIm*h1Q5mhj?j*u>d4Rf-V8wvGM6P4J*84;zixfRf#%6R9ALjd3exLJmra=rl-V+!!CK1o_gBjOAZ zZz3om5YG{b8AS*hhk%q3=@zB3AplXr9J_F>y&q@!PMt<}45FcV-1 zK})juU>ZKjQerk@*;_apLE2aZF!83!76Q|>#44mJI5b9Pz?NIoZyUnL*59QwG zyg%v(`GY-56jP*RAt@iM6iJ&pckxG$)UCofP?xm>5C@8WP z8c!6*F4Y1Q~RL$BpwwaQE54(h3Isn{LtF^3NtO`jz)ZH zHef;_IFS-k0hmToU&^sOm}>yaDhIU*NLz+ktk^z4fxcZXAdtm}Gxo0Gf0TFWJw7v{3NSWWL%G;3Mj^(cL`?p|tr z8AflVm5L&&_Dc(Krkt@A&!oATS=o@a@Tz*lsB>K>N~xqo;Q*2n+BFaN+`B^#_H^+A zDqD;<>qMn=Ej3+MtXc_PD=U`JTIo3#sxWVEO|7ku22hHWQh>h2S&cWsS?a^&(d~Xd zJ^%c5edyztFKFPssnN(Z{H3-6-mZT5y&cCo`>135SXF-2*#;N$;$F?Q07RK}fE1YS z-fQ*lFn^Y^%`v=ieeWUwEoVs&5^HgxzmE>bF`xqkk8m56%I5v6E|J#G+D3k^tq!lT zk8UnK&e@MLrB9LC=csFSf18NCS??{<+EYw9%{hq>-&T8let-Y_-_wV={;7gnDM>0ge?*LA=I4qoALbSj(IfBjM&eE zQ+b|8KhM>EoXm6ioFmB|g;^JHc|mQ9MKkn`>CFWH>T)KGDRt|zjh$QKS{&A@|Y zQ5vhPM1go1-kqR@Y=(i2jB)-90fn?m$hsSA#TZlB0k#ggjpGAd5mBGXuB&UPs_xl4 zX?yv!)xRUu#v%aJiUFGx=z}@Iotw4=uuNh#alw%Zr6=rJ3s3I~OkD#_%cVlDwPZyR z0ZAB^573v$OmfCkf&{X@hV-=zZ9Mz0gc1hXwn+k067&ZDG!qh!3M3-=;vMz zFVUjv*eEy%fGb_8X?iOS={d3DM^oS^u@+u%{%C^WoJd@+?+L-W9>l^!Jm0*_7m9CXY&1oy8E-A=9NthvBTY6@7Lz8QtX0mwj%s|XgEj*& zDWycL>Z)$r!7JO0(0D1OMno+e{~F-2);6y%%{Wr32^p)>4#HHezF5w zOy=BPy!iV4xJdctN*6ktg2ZuZ$JxDc!SpuX;%e`-fHiMv^3(jKc=#4dNL-^e);gPU z#~lVS`>6xd&5mSjcqc0x^VAzv>YD`6b)jv6-bbM#!TS3Y`*oclLLXdA?1s(sE7Kia#MdYaM~F9~Y&@F%N@o-w1TMS?J$vg`ejJ1$gjW%)Cu04MYAv zol50=Ph}fEq@1=iH)Y*yz@^#u(>%G=PM&7xP!{$AQQ1;L`#G!p9#7ItaukJKOL6qx^qpo0df<4G@|@2%vJ0 z#?9Gg%ZavBVXON2gstPAdT8yyS&W+r7fix*#vMsq+t}{b>v*+}d880E@3P3XxP1#@ zKaJnM;NuV>E+awvU*b%#-?$f_CI0LF}q{H)4_6QdS1vu}}p6^6kAJj`- zNCWMgTi0du#hiQn#1;*BJQq@ws4lQPr}+oDX{mchZI&W#~%TkOuVd8b? zxYAxsj21#0)SmIkj*{8c+uK&y&}-0|hqlQUx_#04qh06^czKs^R5aGAN#oI2yQQhl{yKbbFM)%Pf`F(+(&M#2=oznj`vEq!mR=aYrmo5ytz8!2PQ{t83Dg9>>^xBrFN zQC_aAz2itS@AJ%#()Jkok&NHN)i=`C@!Cctc$|P~BDh9@ZXUqx9{TM#++?goQ(&uT zZP|rGo=YjrR9sK7&UKu=r)e|sTqb<3QAh*GR%_`gp!1uBZTdBuJJCwLg|tl~SKJ)- zrgukaK)Z32Ca|kVY4Nh|C~X$p&Il@$I z|XzyHsCAiKOD6=QiZD)vRioLDNC9(hY#2X`9%#h;j2~zBVR2s=9%B^=`7USz@fl1TzL#+-h|0UfD z6pbb=!DM{-@fRY9lw7DV;Us(nh!7}Bv{*6X*s$Y*fyR|J2UL!n&{?rW!NTUo9+NX$ z9G={H0Kg$(A)uH+!@x0N43EHoq17VY(&8q8HA>VeP^?gnHzq8~Rz$59nT1~ZbewU_ zsG~-l1=GxwH!oa#+WJ6EgIM9dd?}$786&2crMW2871zx>@1P`?U2w@Y|GR3=j6>4h zupq;02k6;juXr!Ka>QY}6cU&tdFicpR%!rdgor0mqox3BcRV1mjoa?Y3j@_^L(_vlyB~9e0dbwE<-1~xw$ek zCuO*vDlgOCo@cLpUNF%;R|q*aP4m5OM@I*CJj|ZuXtPuvpA9_+?6$)SHH1z_KA$QD zdWl6v`6UG@qX#@R%ZUNpX9y2ds|Fe`>;JcR_E*M&xvT%JJF>}xrqllPZ?AG5&Q7;w z_uN()T6w{9EZ)k0d2O~yRtugi%PJnm{=<*iD>M0nuk@?$(Nc+4=(p4ln?+gpj=wk0 zW&A?AzX^xDD-QLUBmON3oy@MHUwZA2$FjfJkzR+|wc<~fWf^ytOFyKt{MOE5Ppy=t r$|JW&-Ntr0t+WSoy$Iv_6k8c%9JrR={P%z54?Fn?h9Ntv01n9wT-eOF literal 0 HcmV?d00001 diff --git a/docs/odoc.support/fonts/noticia-text-v15-latin-italic.woff2 b/docs/odoc.support/fonts/noticia-text-v15-latin-italic.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..9b83b0712894271751c61c2129c16baa44222e3a GIT binary patch literal 17356 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 P&>NsQ4M7L++xr0k%F9lN literal 0 HcmV?d00001 diff --git a/docs/odoc.support/highlight.pack.js b/docs/odoc.support/highlight.pack.js new file mode 100644 index 00000000..7d1bcd04 --- /dev/null +++ b/docs/odoc.support/highlight.pack.js @@ -0,0 +1,634 @@ +/*! + Highlight.js v11.7.0 (git: 82688fad18) + (c) 2006-2022 undefined and other contributors + License: BSD-3-Clause + */ +var hljs=function(){"use strict";var e={exports:{}};function t(e){ +return e instanceof Map?e.clear=e.delete=e.set=()=>{ +throw Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=()=>{ +throw Error("set is read-only") +}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((n=>{var i=e[n] +;"object"!=typeof i||Object.isFrozen(i)||t(i)})),e} +e.exports=t,e.exports.default=t;class n{constructor(e){ +void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1} +ignoreMatch(){this.isMatchIgnored=!0}}function i(e){ +return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'") +}function r(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t] +;return t.forEach((e=>{for(const t in e)n[t]=e[t]})),n} +const s=e=>!!e.scope||e.sublanguage&&e.language;class o{constructor(e,t){ +this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){ +this.buffer+=i(e)}openNode(e){if(!s(e))return;let t="" +;t=e.sublanguage?"language-"+e.language:((e,{prefix:t})=>{if(e.includes(".")){ +const n=e.split(".") +;return[`${t}${n.shift()}`,...n.map(((e,t)=>`${e}${"_".repeat(t+1)}`))].join(" ") +}return`${t}${e}`})(e.scope,{prefix:this.classPrefix}),this.span(t)} +closeNode(e){s(e)&&(this.buffer+="")}value(){return this.buffer}span(e){ +this.buffer+=``}}const a=(e={})=>{const t={children:[]} +;return Object.assign(t,e),t};class c{constructor(){ +this.rootNode=a(),this.stack=[this.rootNode]}get top(){ +return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){ +this.top.children.push(e)}openNode(e){const t=a({scope:e}) +;this.add(t),this.stack.push(t)}closeNode(){ +if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){ +for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)} +walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){ +return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t), +t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){ +"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{ +c._collapse(e)})))}}class l extends c{constructor(e){super(),this.options=e} +addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())} +addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root +;n.sublanguage=!0,n.language=t,this.add(n)}toHTML(){ +return new o(this,this.options).value()}finalize(){return!0}}function g(e){ +return e?"string"==typeof e?e:e.source:null}function d(e){return p("(?=",e,")")} +function u(e){return p("(?:",e,")*")}function h(e){return p("(?:",e,")?")} +function p(...e){return e.map((e=>g(e))).join("")}function f(...e){const t=(e=>{ +const t=e[e.length-1] +;return"object"==typeof t&&t.constructor===Object?(e.splice(e.length-1,1),t):{} +})(e);return"("+(t.capture?"":"?:")+e.map((e=>g(e))).join("|")+")"} +function b(e){return RegExp(e.toString()+"|").exec("").length-1} +const m=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./ +;function E(e,{joinWith:t}){let n=0;return e.map((e=>{n+=1;const t=n +;let i=g(e),r="";for(;i.length>0;){const e=m.exec(i);if(!e){r+=i;break} +r+=i.substring(0,e.index), +i=i.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?r+="\\"+(Number(e[1])+t):(r+=e[0], +"("===e[0]&&n++)}return r})).map((e=>`(${e})`)).join(t)} +const x="[a-zA-Z]\\w*",w="[a-zA-Z_]\\w*",y="\\b\\d+(\\.\\d+)?",_="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",O="\\b(0b[01]+)",v={ +begin:"\\\\[\\s\\S]",relevance:0},N={scope:"string",begin:"'",end:"'", +illegal:"\\n",contains:[v]},k={scope:"string",begin:'"',end:'"',illegal:"\\n", +contains:[v]},M=(e,t,n={})=>{const i=r({scope:"comment",begin:e,end:t, +contains:[]},n);i.contains.push({scope:"doctag", +begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)", +end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0}) +;const s=f("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/) +;return i.contains.push({begin:p(/[ ]+/,"(",s,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),i +},S=M("//","$"),R=M("/\\*","\\*/"),j=M("#","$");var A=Object.freeze({ +__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:x,UNDERSCORE_IDENT_RE:w, +NUMBER_RE:y,C_NUMBER_RE:_,BINARY_NUMBER_RE:O, +RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", +SHEBANG:(e={})=>{const t=/^#![ ]*\// +;return e.binary&&(e.begin=p(t,/.*\b/,e.binary,/\b.*/)),r({scope:"meta",begin:t, +end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)}, +BACKSLASH_ESCAPE:v,APOS_STRING_MODE:N,QUOTE_STRING_MODE:k,PHRASAL_WORDS_MODE:{ +begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/ +},COMMENT:M,C_LINE_COMMENT_MODE:S,C_BLOCK_COMMENT_MODE:R,HASH_COMMENT_MODE:j, +NUMBER_MODE:{scope:"number",begin:y,relevance:0},C_NUMBER_MODE:{scope:"number", +begin:_,relevance:0},BINARY_NUMBER_MODE:{scope:"number",begin:O,relevance:0}, +REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{scope:"regexp",begin:/\//, +end:/\/[gimuy]*/,illegal:/\n/,contains:[v,{begin:/\[/,end:/\]/,relevance:0, +contains:[v]}]}]},TITLE_MODE:{scope:"title",begin:x,relevance:0}, +UNDERSCORE_TITLE_MODE:{scope:"title",begin:w,relevance:0},METHOD_GUARD:{ +begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:e=>Object.assign(e,{ +"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{ +t.data._beginMatch!==e[1]&&t.ignoreMatch()}})});function I(e,t){ +"."===e.input[e.index-1]&&t.ignoreMatch()}function T(e,t){ +void 0!==e.className&&(e.scope=e.className,delete e.className)}function L(e,t){ +t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)", +e.__beforeBegin=I,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords, +void 0===e.relevance&&(e.relevance=0))}function B(e,t){ +Array.isArray(e.illegal)&&(e.illegal=f(...e.illegal))}function D(e,t){ +if(e.match){ +if(e.begin||e.end)throw Error("begin & end are not supported with match") +;e.begin=e.match,delete e.match}}function H(e,t){ +void 0===e.relevance&&(e.relevance=1)}const P=(e,t)=>{if(!e.beforeMatch)return +;if(e.starts)throw Error("beforeMatch cannot be used with starts") +;const n=Object.assign({},e);Object.keys(e).forEach((t=>{delete e[t] +})),e.keywords=n.keywords,e.begin=p(n.beforeMatch,d(n.begin)),e.starts={ +relevance:0,contains:[Object.assign(n,{endsParent:!0})] +},e.relevance=0,delete n.beforeMatch +},C=["of","and","for","in","not","or","if","then","parent","list","value"] +;function $(e,t,n="keyword"){const i=Object.create(null) +;return"string"==typeof e?r(n,e.split(" ")):Array.isArray(e)?r(n,e):Object.keys(e).forEach((n=>{ +Object.assign(i,$(e[n],t,n))})),i;function r(e,n){ +t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((t=>{const n=t.split("|") +;i[n[0]]=[e,U(n[0],n[1])]}))}}function U(e,t){ +return t?Number(t):(e=>C.includes(e.toLowerCase()))(e)?0:1}const z={},K=e=>{ +console.error(e)},W=(e,...t)=>{console.log("WARN: "+e,...t)},X=(e,t)=>{ +z[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),z[`${e}/${t}`]=!0) +},G=Error();function Z(e,t,{key:n}){let i=0;const r=e[n],s={},o={} +;for(let e=1;e<=t.length;e++)o[e+i]=r[e],s[e+i]=!0,i+=b(t[e-1]) +;e[n]=o,e[n]._emit=s,e[n]._multi=!0}function F(e){(e=>{ +e.scope&&"object"==typeof e.scope&&null!==e.scope&&(e.beginScope=e.scope, +delete e.scope)})(e),"string"==typeof e.beginScope&&(e.beginScope={ +_wrap:e.beginScope}),"string"==typeof e.endScope&&(e.endScope={_wrap:e.endScope +}),(e=>{if(Array.isArray(e.begin)){ +if(e.skip||e.excludeBegin||e.returnBegin)throw K("skip, excludeBegin, returnBegin not compatible with beginScope: {}"), +G +;if("object"!=typeof e.beginScope||null===e.beginScope)throw K("beginScope must be object"), +G;Z(e,e.begin,{key:"beginScope"}),e.begin=E(e.begin,{joinWith:""})}})(e),(e=>{ +if(Array.isArray(e.end)){ +if(e.skip||e.excludeEnd||e.returnEnd)throw K("skip, excludeEnd, returnEnd not compatible with endScope: {}"), +G +;if("object"!=typeof e.endScope||null===e.endScope)throw K("endScope must be object"), +G;Z(e,e.end,{key:"endScope"}),e.end=E(e.end,{joinWith:""})}})(e)}function V(e){ +function t(t,n){ +return RegExp(g(t),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(n?"g":"")) +}class n{constructor(){ +this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0} +addRule(e,t){ +t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]), +this.matchAt+=b(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null) +;const e=this.regexes.map((e=>e[1]));this.matcherRe=t(E(e,{joinWith:"|" +}),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex +;const t=this.matcherRe.exec(e);if(!t)return null +;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),i=this.matchIndexes[n] +;return t.splice(0,n),Object.assign(t,i)}}class i{constructor(){ +this.rules=[],this.multiRegexes=[], +this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){ +if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n +;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))), +t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){ +return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){ +this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){ +const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex +;let n=t.exec(e) +;if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{ +const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)} +return n&&(this.regexIndex+=n.position+1, +this.regexIndex===this.count&&this.considerAll()),n}} +if(e.compilerExtensions||(e.compilerExtensions=[]), +e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.") +;return e.classNameAliases=r(e.classNameAliases||{}),function n(s,o){const a=s +;if(s.isCompiled)return a +;[T,D,F,P].forEach((e=>e(s,o))),e.compilerExtensions.forEach((e=>e(s,o))), +s.__beforeBegin=null,[L,B,H].forEach((e=>e(s,o))),s.isCompiled=!0;let c=null +;return"object"==typeof s.keywords&&s.keywords.$pattern&&(s.keywords=Object.assign({},s.keywords), +c=s.keywords.$pattern, +delete s.keywords.$pattern),c=c||/\w+/,s.keywords&&(s.keywords=$(s.keywords,e.case_insensitive)), +a.keywordPatternRe=t(c,!0), +o&&(s.begin||(s.begin=/\B|\b/),a.beginRe=t(a.begin),s.end||s.endsWithParent||(s.end=/\B|\b/), +s.end&&(a.endRe=t(a.end)), +a.terminatorEnd=g(a.end)||"",s.endsWithParent&&o.terminatorEnd&&(a.terminatorEnd+=(s.end?"|":"")+o.terminatorEnd)), +s.illegal&&(a.illegalRe=t(s.illegal)), +s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((e=>(e=>(e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((t=>r(e,{ +variants:null},t)))),e.cachedVariants?e.cachedVariants:q(e)?r(e,{ +starts:e.starts?r(e.starts):null +}):Object.isFrozen(e)?r(e):e))("self"===e?s:e)))),s.contains.forEach((e=>{n(e,a) +})),s.starts&&n(s.starts,o),a.matcher=(e=>{const t=new i +;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin" +}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end" +}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t})(a),a}(e)}function q(e){ +return!!e&&(e.endsWithParent||q(e.starts))}class J extends Error{ +constructor(e,t){super(e),this.name="HTMLInjectionError",this.html=t}} +const Y=i,Q=r,ee=Symbol("nomatch");var te=(t=>{ +const i=Object.create(null),r=Object.create(null),s=[];let o=!0 +;const a="Could not find the language '{}', did you forget to load/include a language module?",c={ +disableAutodetect:!0,name:"Plain text",contains:[]};let g={ +ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i, +languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-", +cssSelector:"pre code",languages:null,__emitter:l};function b(e){ +return g.noHighlightRe.test(e)}function m(e,t,n){let i="",r="" +;"object"==typeof t?(i=e, +n=t.ignoreIllegals,r=t.language):(X("10.7.0","highlight(lang, code, ...args) has been deprecated."), +X("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"), +r=e,i=t),void 0===n&&(n=!0);const s={code:i,language:r};k("before:highlight",s) +;const o=s.result?s.result:E(s.language,s.code,n) +;return o.code=s.code,k("after:highlight",o),o}function E(e,t,r,s){ +const c=Object.create(null);function l(){if(!N.keywords)return void M.addText(S) +;let e=0;N.keywordPatternRe.lastIndex=0;let t=N.keywordPatternRe.exec(S),n="" +;for(;t;){n+=S.substring(e,t.index) +;const r=y.case_insensitive?t[0].toLowerCase():t[0],s=(i=r,N.keywords[i]);if(s){ +const[e,i]=s +;if(M.addText(n),n="",c[r]=(c[r]||0)+1,c[r]<=7&&(R+=i),e.startsWith("_"))n+=t[0];else{ +const n=y.classNameAliases[e]||e;M.addKeyword(t[0],n)}}else n+=t[0] +;e=N.keywordPatternRe.lastIndex,t=N.keywordPatternRe.exec(S)}var i +;n+=S.substring(e),M.addText(n)}function d(){null!=N.subLanguage?(()=>{ +if(""===S)return;let e=null;if("string"==typeof N.subLanguage){ +if(!i[N.subLanguage])return void M.addText(S) +;e=E(N.subLanguage,S,!0,k[N.subLanguage]),k[N.subLanguage]=e._top +}else e=x(S,N.subLanguage.length?N.subLanguage:null) +;N.relevance>0&&(R+=e.relevance),M.addSublanguage(e._emitter,e.language) +})():l(),S=""}function u(e,t){let n=1;const i=t.length-1;for(;n<=i;){ +if(!e._emit[n]){n++;continue}const i=y.classNameAliases[e[n]]||e[n],r=t[n] +;i?M.addKeyword(r,i):(S=r,l(),S=""),n++}}function h(e,t){ +return e.scope&&"string"==typeof e.scope&&M.openNode(y.classNameAliases[e.scope]||e.scope), +e.beginScope&&(e.beginScope._wrap?(M.addKeyword(S,y.classNameAliases[e.beginScope._wrap]||e.beginScope._wrap), +S=""):e.beginScope._multi&&(u(e.beginScope,t),S="")),N=Object.create(e,{parent:{ +value:N}}),N}function p(e,t,i){let r=((e,t)=>{const n=e&&e.exec(t) +;return n&&0===n.index})(e.endRe,i);if(r){if(e["on:end"]){const i=new n(e) +;e["on:end"](t,i),i.isMatchIgnored&&(r=!1)}if(r){ +for(;e.endsParent&&e.parent;)e=e.parent;return e}} +if(e.endsWithParent)return p(e.parent,t,i)}function f(e){ +return 0===N.matcher.regexIndex?(S+=e[0],1):(I=!0,0)}function b(e){ +const n=e[0],i=t.substring(e.index),r=p(N,e,i);if(!r)return ee;const s=N +;N.endScope&&N.endScope._wrap?(d(), +M.addKeyword(n,N.endScope._wrap)):N.endScope&&N.endScope._multi?(d(), +u(N.endScope,e)):s.skip?S+=n:(s.returnEnd||s.excludeEnd||(S+=n), +d(),s.excludeEnd&&(S=n));do{ +N.scope&&M.closeNode(),N.skip||N.subLanguage||(R+=N.relevance),N=N.parent +}while(N!==r.parent);return r.starts&&h(r.starts,e),s.returnEnd?0:n.length} +let m={};function w(i,s){const a=s&&s[0];if(S+=i,null==a)return d(),0 +;if("begin"===m.type&&"end"===s.type&&m.index===s.index&&""===a){ +if(S+=t.slice(s.index,s.index+1),!o){const t=Error(`0 width match regex (${e})`) +;throw t.languageName=e,t.badRule=m.rule,t}return 1} +if(m=s,"begin"===s.type)return(e=>{ +const t=e[0],i=e.rule,r=new n(i),s=[i.__beforeBegin,i["on:begin"]] +;for(const n of s)if(n&&(n(e,r),r.isMatchIgnored))return f(t) +;return i.skip?S+=t:(i.excludeBegin&&(S+=t), +d(),i.returnBegin||i.excludeBegin||(S=t)),h(i,e),i.returnBegin?0:t.length})(s) +;if("illegal"===s.type&&!r){ +const e=Error('Illegal lexeme "'+a+'" for mode "'+(N.scope||"")+'"') +;throw e.mode=N,e}if("end"===s.type){const e=b(s);if(e!==ee)return e} +if("illegal"===s.type&&""===a)return 1 +;if(A>1e5&&A>3*s.index)throw Error("potential infinite loop, way more iterations than matches") +;return S+=a,a.length}const y=O(e) +;if(!y)throw K(a.replace("{}",e)),Error('Unknown language: "'+e+'"') +;const _=V(y);let v="",N=s||_;const k={},M=new g.__emitter(g);(()=>{const e=[] +;for(let t=N;t!==y;t=t.parent)t.scope&&e.unshift(t.scope) +;e.forEach((e=>M.openNode(e)))})();let S="",R=0,j=0,A=0,I=!1;try{ +for(N.matcher.considerAll();;){ +A++,I?I=!1:N.matcher.considerAll(),N.matcher.lastIndex=j +;const e=N.matcher.exec(t);if(!e)break;const n=w(t.substring(j,e.index),e) +;j=e.index+n} +return w(t.substring(j)),M.closeAllNodes(),M.finalize(),v=M.toHTML(),{ +language:e,value:v,relevance:R,illegal:!1,_emitter:M,_top:N}}catch(n){ +if(n.message&&n.message.includes("Illegal"))return{language:e,value:Y(t), +illegal:!0,relevance:0,_illegalBy:{message:n.message,index:j, +context:t.slice(j-100,j+100),mode:n.mode,resultSoFar:v},_emitter:M};if(o)return{ +language:e,value:Y(t),illegal:!1,relevance:0,errorRaised:n,_emitter:M,_top:N} +;throw n}}function x(e,t){t=t||g.languages||Object.keys(i);const n=(e=>{ +const t={value:Y(e),illegal:!1,relevance:0,_top:c,_emitter:new g.__emitter(g)} +;return t._emitter.addText(e),t})(e),r=t.filter(O).filter(N).map((t=>E(t,e,!1))) +;r.unshift(n);const s=r.sort(((e,t)=>{ +if(e.relevance!==t.relevance)return t.relevance-e.relevance +;if(e.language&&t.language){if(O(e.language).supersetOf===t.language)return 1 +;if(O(t.language).supersetOf===e.language)return-1}return 0})),[o,a]=s,l=o +;return l.secondBest=a,l}function w(e){let t=null;const n=(e=>{ +let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"" +;const n=g.languageDetectRe.exec(t);if(n){const t=O(n[1]) +;return t||(W(a.replace("{}",n[1])), +W("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"} +return t.split(/\s+/).find((e=>b(e)||O(e)))})(e);if(b(n))return +;if(k("before:highlightElement",{el:e,language:n +}),e.children.length>0&&(g.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."), +console.warn("https://github.com/highlightjs/highlight.js/wiki/security"), +console.warn("The element with unescaped HTML:"), +console.warn(e)),g.throwUnescapedHTML))throw new J("One of your code blocks includes unescaped HTML.",e.innerHTML) +;t=e;const i=t.textContent,s=n?m(i,{language:n,ignoreIllegals:!0}):x(i) +;e.innerHTML=s.value,((e,t,n)=>{const i=t&&r[t]||n +;e.classList.add("hljs"),e.classList.add("language-"+i) +})(e,n,s.language),e.result={language:s.language,re:s.relevance, +relevance:s.relevance},s.secondBest&&(e.secondBest={ +language:s.secondBest.language,relevance:s.secondBest.relevance +}),k("after:highlightElement",{el:e,result:s,text:i})}let y=!1;function _(){ +"loading"!==document.readyState?document.querySelectorAll(g.cssSelector).forEach(w):y=!0 +}function O(e){return e=(e||"").toLowerCase(),i[e]||i[r[e]]} +function v(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{ +r[e.toLowerCase()]=t}))}function N(e){const t=O(e) +;return t&&!t.disableAutodetect}function k(e,t){const n=e;s.forEach((e=>{ +e[n]&&e[n](t)}))} +"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(()=>{ +y&&_()}),!1),Object.assign(t,{highlight:m,highlightAuto:x,highlightAll:_, +highlightElement:w, +highlightBlock:e=>(X("10.7.0","highlightBlock will be removed entirely in v12.0"), +X("10.7.0","Please use highlightElement now."),w(e)),configure:e=>{g=Q(g,e)}, +initHighlighting:()=>{ +_(),X("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")}, +initHighlightingOnLoad:()=>{ +_(),X("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.") +},registerLanguage:(e,n)=>{let r=null;try{r=n(t)}catch(t){ +if(K("Language definition for '{}' could not be registered.".replace("{}",e)), +!o)throw t;K(t),r=c} +r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&v(r.aliases,{ +languageName:e})},unregisterLanguage:e=>{delete i[e] +;for(const t of Object.keys(r))r[t]===e&&delete r[t]}, +listLanguages:()=>Object.keys(i),getLanguage:O,registerAliases:v, +autoDetection:N,inherit:Q,addPlugin:e=>{(e=>{ +e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{ +e["before:highlightBlock"](Object.assign({block:t.el},t)) +}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{ +e["after:highlightBlock"](Object.assign({block:t.el},t))})})(e),s.push(e)} +}),t.debugMode=()=>{o=!1},t.safeMode=()=>{o=!0 +},t.versionString="11.7.0",t.regex={concat:p,lookahead:d,either:f,optional:h, +anyNumberOfTimes:u};for(const t in A)"object"==typeof A[t]&&e.exports(A[t]) +;return Object.assign(t,A),t})({});return te}() +;"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);/*! `reasonml` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n="~?[a-z$_][0-9a-zA-Z$_]*",a="`?[A-Z$_][0-9a-zA-Z$_]*",s="("+["||","++","**","+.","*","/","*.","/.","..."].map((e=>e.split("").map((e=>"\\"+e)).join(""))).join("|")+"|\\|>|&&|==|===)",i="\\s+"+s+"\\s+",r={ +keyword:"and as asr assert begin class constraint do done downto else end exception external for fun function functor if in include inherit initializer land lazy let lor lsl lsr lxor match method mod module mutable new nonrec object of open or private rec sig struct then to try type val virtual when while with", +built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 ref string unit ", +literal:"true false" +},l="\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",t={ +className:"number",relevance:0,variants:[{begin:l},{begin:"\\(-"+l+"\\)"}]},c={ +className:"operator",relevance:0,begin:s},o=[{className:"identifier", +relevance:0,begin:n},c,t],g=[e.QUOTE_STRING_MODE,c,{className:"module", +begin:"\\b"+a,returnBegin:!0,relevance:0,end:".",contains:[{ +className:"identifier",begin:a,relevance:0}]}],b=[{className:"module", +begin:"\\b"+a,returnBegin:!0,end:".",relevance:0,contains:[{ +className:"identifier",begin:a,relevance:0}]}],m={className:"function", +relevance:0,keywords:r,variants:[{begin:"\\s(\\(\\.?.*?\\)|"+n+")\\s*=>", +end:"\\s*=>",returnBegin:!0,relevance:0,contains:[{className:"params", +variants:[{begin:n},{ +begin:"~?[a-z$_][0-9a-zA-Z$_]*(\\s*:\\s*[a-z$_][0-9a-z$_]*(\\(\\s*('?[a-z$_][0-9a-z$_]*\\s*(,'?[a-z$_][0-9a-z$_]*\\s*)*)?\\))?){0,2}" +},{begin:/\(\s*\)/}]}]},{begin:"\\s\\(\\.?[^;\\|]*\\)\\s*=>",end:"\\s=>", +returnBegin:!0,relevance:0,contains:[{className:"params",relevance:0,variants:[{ +begin:n,end:"(,|\\n|\\))",relevance:0,contains:[c,{className:"typing",begin:":", +end:"(,|\\n)",returnBegin:!0,relevance:0,contains:b}]}]}]},{ +begin:"\\(\\.\\s"+n+"\\)\\s*=>"}]};g.push(m);const d={className:"constructor", +begin:a+"\\(",end:"\\)",illegal:"\\n",keywords:r, +contains:[e.QUOTE_STRING_MODE,c,{className:"params",begin:"\\b"+n}]},u={ +className:"pattern-match",begin:"\\|",returnBegin:!0,keywords:r,end:"=>", +relevance:0,contains:[d,c,{relevance:0,className:"constructor",begin:a}]},v={ +className:"module-access",keywords:r,returnBegin:!0,variants:[{ +begin:"\\b("+a+"\\.)+"+n},{begin:"\\b("+a+"\\.)+\\(",end:"\\)",returnBegin:!0, +contains:[m,{begin:"\\(",end:"\\)",relevance:0,skip:!0}].concat(g)},{ +begin:"\\b("+a+"\\.)+\\{",end:/\}/}],contains:g};return b.push(v),{ +name:"ReasonML",aliases:["re"],keywords:r,illegal:"(:-|:=|\\$\\{|\\+=)", +contains:[e.COMMENT("/\\*","\\*/",{illegal:"^(#,\\/\\/)"}),{ +className:"character",begin:"'(\\\\[^']+|[^'])'",illegal:"\\n",relevance:0 +},e.QUOTE_STRING_MODE,{className:"literal",begin:"\\(\\)",relevance:0},{ +className:"literal",begin:"\\[\\|",end:"\\|\\]",relevance:0,contains:o},{ +className:"literal",begin:"\\[",end:"\\]",relevance:0,contains:o},d,{ +className:"operator",begin:i,illegal:"--\x3e",relevance:0 +},t,e.C_LINE_COMMENT_MODE,u,m,{className:"module-def", +begin:"\\bmodule\\s+"+n+"\\s+"+a+"\\s+=\\s+\\{",end:/\}/,returnBegin:!0, +keywords:r,relevance:0,contains:[{className:"module",relevance:0,begin:a},{ +begin:/\{/,end:/\}/,relevance:0,skip:!0}].concat(g)},v]}}})() +;hljs.registerLanguage("reasonml",e)})();/*! `javascript` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict" +;const e="[A-Za-z$_][0-9A-Za-z$_]*",n=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],a=["true","false","null","undefined","NaN","Infinity"],t=["Object","Function","Boolean","Symbol","Math","Date","Number","BigInt","String","RegExp","Array","Float32Array","Float64Array","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Int32Array","Uint16Array","Uint32Array","BigInt64Array","BigUint64Array","Set","Map","WeakSet","WeakMap","ArrayBuffer","SharedArrayBuffer","Atomics","DataView","JSON","Promise","Generator","GeneratorFunction","AsyncFunction","Reflect","Proxy","Intl","WebAssembly"],s=["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"],r=["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],c=["arguments","this","super","console","window","document","localStorage","module","global"],i=[].concat(r,t,s) +;return o=>{const l=o.regex,b=e,d={begin:/<[A-Za-z0-9\\._:-]+/, +end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,n)=>{ +const a=e[0].length+e.index,t=e.input[a] +;if("<"===t||","===t)return void n.ignoreMatch();let s +;">"===t&&(((e,{after:n})=>{const a="",M={ +match:[/const|var|let/,/\s+/,b,/\s*/,/=\s*/,/(async\s*)?/,l.lookahead(C)], +keywords:"async",className:{1:"keyword",3:"title.function"},contains:[S]} +;return{name:"Javascript",aliases:["js","jsx","mjs","cjs"],keywords:g,exports:{ +PARAMS_CONTAINS:p,CLASS_REFERENCE:R},illegal:/#(?![$_A-z])/, +contains:[o.SHEBANG({label:"shebang",binary:"node",relevance:5}),{ +label:"use_strict",className:"meta",relevance:10, +begin:/^\s*['"]use (strict|asm)['"]/ +},o.APOS_STRING_MODE,o.QUOTE_STRING_MODE,y,N,_,h,{match:/\$\d+/},E,R,{ +className:"attr",begin:b+l.lookahead(":"),relevance:0},M,{ +begin:"("+o.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*", +keywords:"return throw case",relevance:0,contains:[h,o.REGEXP_MODE,{ +className:"function",begin:C,returnBegin:!0,end:"\\s*=>",contains:[{ +className:"params",variants:[{begin:o.UNDERSCORE_IDENT_RE,relevance:0},{ +className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0, +excludeEnd:!0,keywords:g,contains:p}]}]},{begin:/,/,relevance:0},{match:/\s+/, +relevance:0},{variants:[{begin:"<>",end:""},{ +match:/<[A-Za-z0-9\\._:-]+\s*\/>/},{begin:d.begin, +"on:begin":d.isTrulyOpeningTag,end:d.end}],subLanguage:"xml",contains:[{ +begin:d.begin,end:d.end,skip:!0,contains:["self"]}]}]},O,{ +beginKeywords:"while if switch catch for"},{ +begin:"\\b(?!function)"+o.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{", +returnBegin:!0,label:"func.def",contains:[S,o.inherit(o.TITLE_MODE,{begin:b, +className:"title.function"})]},{match:/\.\.\./,relevance:0},x,{match:"\\$"+b, +relevance:0},{match:[/\bconstructor(?=\s*\()/],className:{1:"title.function"}, +contains:[S]},k,{relevance:0,match:/\b[A-Z][A-Z_0-9]+\b/, +className:"variable.constant"},w,T,{match:/\$[(.]/}]}}})() +;hljs.registerLanguage("javascript",e)})();/*! `sql` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const r=e.regex,t=e.COMMENT("--","$"),n=["true","false","unknown"],a=["bigint","binary","blob","boolean","char","character","clob","date","dec","decfloat","decimal","float","int","integer","interval","nchar","nclob","national","numeric","real","row","smallint","time","timestamp","varchar","varying","varbinary"],i=["abs","acos","array_agg","asin","atan","avg","cast","ceil","ceiling","coalesce","corr","cos","cosh","count","covar_pop","covar_samp","cume_dist","dense_rank","deref","element","exp","extract","first_value","floor","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","last_value","lead","listagg","ln","log","log10","lower","max","min","mod","nth_value","ntile","nullif","percent_rank","percentile_cont","percentile_disc","position","position_regex","power","rank","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","row_number","sin","sinh","sqrt","stddev_pop","stddev_samp","substring","substring_regex","sum","tan","tanh","translate","translate_regex","treat","trim","trim_array","unnest","upper","value_of","var_pop","var_samp","width_bucket"],s=["create table","insert into","primary key","foreign key","not null","alter table","add constraint","grouping sets","on overflow","character set","respect nulls","ignore nulls","nulls first","nulls last","depth first","breadth first"],o=i,c=["abs","acos","all","allocate","alter","and","any","are","array","array_agg","array_max_cardinality","as","asensitive","asin","asymmetric","at","atan","atomic","authorization","avg","begin","begin_frame","begin_partition","between","bigint","binary","blob","boolean","both","by","call","called","cardinality","cascaded","case","cast","ceil","ceiling","char","char_length","character","character_length","check","classifier","clob","close","coalesce","collate","collect","column","commit","condition","connect","constraint","contains","convert","copy","corr","corresponding","cos","cosh","count","covar_pop","covar_samp","create","cross","cube","cume_dist","current","current_catalog","current_date","current_default_transform_group","current_path","current_role","current_row","current_schema","current_time","current_timestamp","current_path","current_role","current_transform_group_for_type","current_user","cursor","cycle","date","day","deallocate","dec","decimal","decfloat","declare","default","define","delete","dense_rank","deref","describe","deterministic","disconnect","distinct","double","drop","dynamic","each","element","else","empty","end","end_frame","end_partition","end-exec","equals","escape","every","except","exec","execute","exists","exp","external","extract","false","fetch","filter","first_value","float","floor","for","foreign","frame_row","free","from","full","function","fusion","get","global","grant","group","grouping","groups","having","hold","hour","identity","in","indicator","initial","inner","inout","insensitive","insert","int","integer","intersect","intersection","interval","into","is","join","json_array","json_arrayagg","json_exists","json_object","json_objectagg","json_query","json_table","json_table_primitive","json_value","lag","language","large","last_value","lateral","lead","leading","left","like","like_regex","listagg","ln","local","localtime","localtimestamp","log","log10","lower","match","match_number","match_recognize","matches","max","member","merge","method","min","minute","mod","modifies","module","month","multiset","national","natural","nchar","nclob","new","no","none","normalize","not","nth_value","ntile","null","nullif","numeric","octet_length","occurrences_regex","of","offset","old","omit","on","one","only","open","or","order","out","outer","over","overlaps","overlay","parameter","partition","pattern","per","percent","percent_rank","percentile_cont","percentile_disc","period","portion","position","position_regex","power","precedes","precision","prepare","primary","procedure","ptf","range","rank","reads","real","recursive","ref","references","referencing","regr_avgx","regr_avgy","regr_count","regr_intercept","regr_r2","regr_slope","regr_sxx","regr_sxy","regr_syy","release","result","return","returns","revoke","right","rollback","rollup","row","row_number","rows","running","savepoint","scope","scroll","search","second","seek","select","sensitive","session_user","set","show","similar","sin","sinh","skip","smallint","some","specific","specifictype","sql","sqlexception","sqlstate","sqlwarning","sqrt","start","static","stddev_pop","stddev_samp","submultiset","subset","substring","substring_regex","succeeds","sum","symmetric","system","system_time","system_user","table","tablesample","tan","tanh","then","time","timestamp","timezone_hour","timezone_minute","to","trailing","translate","translate_regex","translation","treat","trigger","trim","trim_array","true","truncate","uescape","union","unique","unknown","unnest","update","upper","user","using","value","values","value_of","var_pop","var_samp","varbinary","varchar","varying","versioning","when","whenever","where","width_bucket","window","with","within","without","year","add","asc","collation","desc","final","first","last","view"].filter((e=>!i.includes(e))),l={ +begin:r.concat(/\b/,r.either(...o),/\s*\(/),relevance:0,keywords:{built_in:o}} +;return{name:"SQL",case_insensitive:!0,illegal:/[{}]|<\//,keywords:{ +$pattern:/\b[\w\.]+/,keyword:((e,{exceptions:r,when:t}={})=>{const n=t +;return r=r||[],e.map((e=>e.match(/\|\d+$/)||r.includes(e)?e:n(e)?e+"|0":e)) +})(c,{when:e=>e.length<3}),literal:n,type:a, +built_in:["current_catalog","current_date","current_default_transform_group","current_path","current_role","current_schema","current_transform_group_for_type","current_user","session_user","system_time","system_user","current_time","localtime","current_timestamp","localtimestamp"] +},contains:[{begin:r.either(...s),relevance:0,keywords:{$pattern:/[\w\.]+/, +keyword:c.concat(s),literal:n,type:a}},{className:"type", +begin:r.either("double precision","large object","with timezone","without timezone") +},l,{className:"variable",begin:/@[a-z0-9]+/},{className:"string",variants:[{ +begin:/'/,end:/'/,contains:[{begin:/''/}]}]},{begin:/"/,end:/"/,contains:[{ +begin:/""/}]},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,{className:"operator", +begin:/[-+*/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,relevance:0}]}}})() +;hljs.registerLanguage("sql",e)})();/*! `bash` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const s=e.regex,t={},n={begin:/\$\{/, +end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{ +className:"variable",variants:[{ +begin:s.concat(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},n]});const a={ +className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},i={ +begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/, +end:/(\w+)/,className:"string"})]}},c={className:"string",begin:/"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,t,a]};a.contains.push(c);const o={begin:/\$?\(\(/, +end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t] +},r=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10 +}),l={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0, +contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{ +name:"Bash",aliases:["sh"],keywords:{$pattern:/\b[a-z][a-z0-9._-]+\b/, +keyword:["if","then","else","elif","fi","for","while","in","do","done","case","esac","function"], +literal:["true","false"], +built_in:["break","cd","continue","eval","exec","exit","export","getopts","hash","pwd","readonly","return","shift","test","times","trap","umask","unset","alias","bind","builtin","caller","command","declare","echo","enable","help","let","local","logout","mapfile","printf","read","readarray","source","type","typeset","ulimit","unalias","set","shopt","autoload","bg","bindkey","bye","cap","chdir","clone","comparguments","compcall","compctl","compdescribe","compfiles","compgroups","compquote","comptags","comptry","compvalues","dirs","disable","disown","echotc","echoti","emulate","fc","fg","float","functions","getcap","getln","history","integer","jobs","kill","limit","log","noglob","popd","print","pushd","pushln","rehash","sched","setcap","setopt","stat","suspend","ttyctl","unfunction","unhash","unlimit","unsetopt","vared","wait","whence","where","which","zcompile","zformat","zftp","zle","zmodload","zparseopts","zprof","zpty","zregexparse","zsocket","zstyle","ztcp","chcon","chgrp","chown","chmod","cp","dd","df","dir","dircolors","ln","ls","mkdir","mkfifo","mknod","mktemp","mv","realpath","rm","rmdir","shred","sync","touch","truncate","vdir","b2sum","base32","base64","cat","cksum","comm","csplit","cut","expand","fmt","fold","head","join","md5sum","nl","numfmt","od","paste","ptx","pr","sha1sum","sha224sum","sha256sum","sha384sum","sha512sum","shuf","sort","split","sum","tac","tail","tr","tsort","unexpand","uniq","wc","arch","basename","chroot","date","dirname","du","echo","env","expr","factor","groups","hostid","id","link","logname","nice","nohup","nproc","pathchk","pinky","printenv","printf","pwd","readlink","runcon","seq","sleep","stat","stdbuf","stty","tee","test","timeout","tty","uname","unlink","uptime","users","who","whoami","yes"] +},contains:[r,e.SHEBANG(),l,o,e.HASH_COMMENT_MODE,i,{match:/(\/[a-z._-]+)+/},c,{ +className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}}})() +;hljs.registerLanguage("bash",e)})();/*! `shell` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var s=(()=>{"use strict";return s=>({name:"Shell Session", +aliases:["console","shellsession"],contains:[{className:"meta.prompt", +begin:/^\s{0,3}[/~\w\d[\]()@-]*[>%$#][ ]?/,starts:{end:/[^\\](?=\s*$)/, +subLanguage:"bash"}}]})})();hljs.registerLanguage("shell",s)})();/*! `plaintext` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var t=(()=>{"use strict";return t=>({name:"Plain text", +aliases:["text","txt"],disableAutodetect:!0})})() +;hljs.registerLanguage("plaintext",t)})();/*! `graphql` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const a=e.regex;return{name:"GraphQL", +aliases:["gql"],case_insensitive:!0,disableAutodetect:!1,keywords:{ +keyword:["query","mutation","subscription","type","input","schema","directive","interface","union","scalar","fragment","enum","on"], +literal:["true","false","null"]}, +contains:[e.HASH_COMMENT_MODE,e.QUOTE_STRING_MODE,e.NUMBER_MODE,{ +scope:"punctuation",match:/[.]{3}/,relevance:0},{scope:"punctuation", +begin:/[\!\(\)\:\=\[\]\{\|\}]{1}/,relevance:0},{scope:"variable",begin:/\$/, +end:/\W/,excludeEnd:!0,relevance:0},{scope:"meta",match:/@\w+/,excludeEnd:!0},{ +scope:"symbol",begin:a.concat(/[_A-Za-z][_0-9A-Za-z]*/,a.lookahead(/\s*:/)), +relevance:0}],illegal:[/[;<']/,/BEGIN/]}}})();hljs.registerLanguage("graphql",e) +})();/*! `ocaml` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>({name:"OCaml",aliases:["ml"], +keywords:{$pattern:"[a-z_]\\w*!?", +keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value", +built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref", +literal:"true false"},illegal:/\/\/|>>/,contains:[{className:"literal", +begin:"\\[(\\|\\|)?\\]|\\(\\)",relevance:0},e.COMMENT("\\(\\*","\\*\\)",{ +contains:["self"]}),{className:"symbol",begin:"'[A-Za-z_](?!')[\\w']*"},{ +className:"type",begin:"`[A-Z][\\w']*"},{className:"type", +begin:"\\b[A-Z][\\w']*",relevance:0},{begin:"[a-z_]\\w*'[\\w']*",relevance:0 +},e.inherit(e.APOS_STRING_MODE,{className:"string",relevance:0 +}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null}),{className:"number", +begin:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)", +relevance:0},{begin:/->/}]})})();hljs.registerLanguage("ocaml",e)})();/*! `json` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const a=["true","false","null"],n={ +scope:"literal",beginKeywords:a.join(" ")};return{name:"JSON",keywords:{ +literal:a},contains:[{className:"attr",begin:/"(\\.|[^\\"\r\n])*"(?=\s*:)/, +relevance:1.01},{match:/[{}[\],:]/,className:"punctuation",relevance:0 +},e.QUOTE_STRING_MODE,n,e.C_NUMBER_MODE,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE], +illegal:"\\S"}}})();hljs.registerLanguage("json",e)})();/*! `python` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const n=e.regex,a=/[\p{XID_Start}_]\p{XID_Continue}*/u,i=["and","as","assert","async","await","break","case","class","continue","def","del","elif","else","except","finally","for","from","global","if","import","in","is","lambda","match","nonlocal|10","not","or","pass","raise","return","try","while","with","yield"],s={ +$pattern:/[A-Za-z]\w+|__\w+__/,keyword:i, +built_in:["__import__","abs","all","any","ascii","bin","bool","breakpoint","bytearray","bytes","callable","chr","classmethod","compile","complex","delattr","dict","dir","divmod","enumerate","eval","exec","filter","float","format","frozenset","getattr","globals","hasattr","hash","help","hex","id","input","int","isinstance","issubclass","iter","len","list","locals","map","max","memoryview","min","next","object","oct","open","ord","pow","print","property","range","repr","reversed","round","set","setattr","slice","sorted","staticmethod","str","sum","super","tuple","type","vars","zip"], +literal:["__debug__","Ellipsis","False","None","NotImplemented","True"], +type:["Any","Callable","Coroutine","Dict","List","Literal","Generic","Optional","Sequence","Set","Tuple","Type","Union"] +},t={className:"meta",begin:/^(>>>|\.\.\.) /},r={className:"subst",begin:/\{/, +end:/\}/,keywords:s,illegal:/#/},l={begin:/\{\{/,relevance:0},b={ +className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,t],relevance:10},{ +begin:/([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,end:/"""/, +contains:[e.BACKSLASH_ESCAPE,t],relevance:10},{ +begin:/([fF][rR]|[rR][fF]|[fF])'''/,end:/'''/, +contains:[e.BACKSLASH_ESCAPE,t,l,r]},{begin:/([fF][rR]|[rR][fF]|[fF])"""/, +end:/"""/,contains:[e.BACKSLASH_ESCAPE,t,l,r]},{begin:/([uU]|[rR])'/,end:/'/, +relevance:10},{begin:/([uU]|[rR])"/,end:/"/,relevance:10},{ +begin:/([bB]|[bB][rR]|[rR][bB])'/,end:/'/},{begin:/([bB]|[bB][rR]|[rR][bB])"/, +end:/"/},{begin:/([fF][rR]|[rR][fF]|[fF])'/,end:/'/, +contains:[e.BACKSLASH_ESCAPE,l,r]},{begin:/([fF][rR]|[rR][fF]|[fF])"/,end:/"/, +contains:[e.BACKSLASH_ESCAPE,l,r]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE] +},o="[0-9](_?[0-9])*",c=`(\\b(${o}))?\\.(${o})|\\b(${o})\\.`,d="\\b|"+i.join("|"),g={ +className:"number",relevance:0,variants:[{ +begin:`(\\b(${o})|(${c}))[eE][+-]?(${o})[jJ]?(?=${d})`},{begin:`(${c})[jJ]?`},{ +begin:`\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${d})`},{ +begin:`\\b0[bB](_?[01])+[lL]?(?=${d})`},{begin:`\\b0[oO](_?[0-7])+[lL]?(?=${d})` +},{begin:`\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${d})`},{begin:`\\b(${o})[jJ](?=${d})` +}]},p={className:"comment",begin:n.lookahead(/# type:/),end:/$/,keywords:s, +contains:[{begin:/# type:/},{begin:/#/,end:/\b\B/,endsWithParent:!0}]},m={ +className:"params",variants:[{className:"",begin:/\(\s*\)/,skip:!0},{begin:/\(/, +end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s, +contains:["self",t,g,b,e.HASH_COMMENT_MODE]}]};return r.contains=[b,g,t],{ +name:"Python",aliases:["py","gyp","ipython"],unicodeRegex:!0,keywords:s, +illegal:/(<\/|->|\?)|=>/,contains:[t,g,{begin:/\bself\b/},{beginKeywords:"if", +relevance:0},b,p,e.HASH_COMMENT_MODE,{match:[/\bdef/,/\s+/,a],scope:{ +1:"keyword",3:"title.function"},contains:[m]},{variants:[{ +match:[/\bclass/,/\s+/,a,/\s*/,/\(\s*/,a,/\s*\)/]},{match:[/\bclass/,/\s+/,a]}], +scope:{1:"keyword",3:"title.class",6:"title.class.inherited"}},{ +className:"meta",begin:/^[\t ]*@/,end:/(?=#)|$/,contains:[g,m,b]}]}}})() +;hljs.registerLanguage("python",e)})();/*! `xml` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{ +const a=e.regex,n=a.concat(/[\p{L}_]/u,a.optional(/[\p{L}0-9_.-]*:/u),/[\p{L}0-9_.-]*/u),s={ +className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},t={begin:/\s/, +contains:[{className:"keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}] +},i=e.inherit(t,{begin:/\(/,end:/\)/}),c=e.inherit(e.APOS_STRING_MODE,{ +className:"string"}),l=e.inherit(e.QUOTE_STRING_MODE,{className:"string"}),r={ +endsWithParent:!0,illegal:/`]+/}]}]}]};return{ +name:"HTML, XML", +aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"], +case_insensitive:!0,unicodeRegex:!0,contains:[{className:"meta",begin://,relevance:10,contains:[t,l,c,i,{begin:/\[/,end:/\]/,contains:[{ +className:"meta",begin://,contains:[t,i,l,c]}]}] +},e.COMMENT(//,{relevance:10}),{begin://, +relevance:10},s,{className:"meta",end:/\?>/,variants:[{begin:/<\?xml/, +relevance:10,contains:[l]},{begin:/<\?[a-z][a-z0-9]+/}]},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"style"},contains:[r],starts:{ +end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag", +begin:/)/,end:/>/,keywords:{name:"script"},contains:[r],starts:{ +end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{ +className:"tag",begin:/<>|<\/>/},{className:"tag", +begin:a.concat(//,/>/,/\s/)))), +end:/\/?>/,contains:[{className:"name",begin:n,relevance:0,starts:r}]},{ +className:"tag",begin:a.concat(/<\//,a.lookahead(a.concat(n,/>/))),contains:[{ +className:"name",begin:n,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}} +})();hljs.registerLanguage("xml",e)})();/*! `markdown` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n={begin:/<\/?[A-Za-z_]/, +end:">",subLanguage:"xml",relevance:0},a={variants:[{begin:/\[.+?\]\[.*?\]/, +relevance:0},{ +begin:/\[.+?\]\(((data|javascript|mailto):|(?:http|ftp)s?:\/\/).*?\)/, +relevance:2},{ +begin:e.regex.concat(/\[.+?\]\(/,/[A-Za-z][A-Za-z0-9+.-]*/,/:\/\/.*?\)/), +relevance:2},{begin:/\[.+?\]\([./?&#].*?\)/,relevance:1},{ +begin:/\[.*?\]\(.*?\)/,relevance:0}],returnBegin:!0,contains:[{match:/\[(?=\])/ +},{className:"string",relevance:0,begin:"\\[",end:"\\]",excludeBegin:!0, +returnEnd:!0},{className:"link",relevance:0,begin:"\\]\\(",end:"\\)", +excludeBegin:!0,excludeEnd:!0},{className:"symbol",relevance:0,begin:"\\]\\[", +end:"\\]",excludeBegin:!0,excludeEnd:!0}]},i={className:"strong",contains:[], +variants:[{begin:/_{2}(?!\s)/,end:/_{2}/},{begin:/\*{2}(?!\s)/,end:/\*{2}/}] +},s={className:"emphasis",contains:[],variants:[{begin:/\*(?![*\s])/,end:/\*/},{ +begin:/_(?![_\s])/,end:/_/,relevance:0}]},c=e.inherit(i,{contains:[] +}),t=e.inherit(s,{contains:[]});i.contains.push(t),s.contains.push(c) +;let g=[n,a];return[i,s,c,t].forEach((e=>{e.contains=e.contains.concat(g) +})),g=g.concat(i,s),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{ +className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:g},{ +begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n", +contains:g}]}]},n,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", +end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:g, +end:"$"},{className:"code",variants:[{begin:"(`{3,})[^`](.|\\n)*?\\1`*[ ]*"},{ +begin:"(~{3,})[^~](.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{ +begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))", +contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{ +begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{ +className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{ +className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}})() +;hljs.registerLanguage("markdown",e)})();/*! `c` grammar compiled for Highlight.js 11.7.0 */ +(()=>{var e=(()=>{"use strict";return e=>{const n=e.regex,t=e.COMMENT("//","$",{ +contains:[{begin:/\\\n/}] +}),s="[a-zA-Z_]\\w*::",a="(decltype\\(auto\\)|"+n.optional(s)+"[a-zA-Z_]\\w*"+n.optional("<[^<>]+>")+")",r={ +className:"type",variants:[{begin:"\\b[a-z\\d_]*_t\\b"},{ +match:/\batomic_[a-z]{3,6}\b/}]},i={className:"string",variants:[{ +begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{ +begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)", +end:"'",illegal:"."},e.END_SAME_AS_BEGIN({ +begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},l={ +className:"number",variants:[{begin:"\\b(0b[01']+)"},{ +begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)" +},{ +begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)" +}],relevance:0},o={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{ +keyword:"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include" +},contains:[{begin:/\\\n/,relevance:0},e.inherit(i,{className:"string"}),{ +className:"string",begin:/<.*?>/},t,e.C_BLOCK_COMMENT_MODE]},c={ +className:"title",begin:n.optional(s)+e.IDENT_RE,relevance:0 +},d=n.optional(s)+e.IDENT_RE+"\\s*\\(",u={ +keyword:["asm","auto","break","case","continue","default","do","else","enum","extern","for","fortran","goto","if","inline","register","restrict","return","sizeof","struct","switch","typedef","union","volatile","while","_Alignas","_Alignof","_Atomic","_Generic","_Noreturn","_Static_assert","_Thread_local","alignas","alignof","noreturn","static_assert","thread_local","_Pragma"], +type:["float","double","signed","unsigned","int","short","long","char","void","_Bool","_Complex","_Imaginary","_Decimal32","_Decimal64","_Decimal128","const","static","complex","bool","imaginary"], +literal:"true false NULL", +built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr" +},g=[o,r,t,e.C_BLOCK_COMMENT_MODE,l,i],m={variants:[{begin:/=/,end:/;/},{ +begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}], +keywords:u,contains:g.concat([{begin:/\(/,end:/\)/,keywords:u, +contains:g.concat(["self"]),relevance:0}]),relevance:0},p={ +begin:"("+a+"[\\*&\\s]+)+"+d,returnBegin:!0,end:/[{;=]/,excludeEnd:!0, +keywords:u,illegal:/[^\w\s\*&:<>.]/,contains:[{begin:"decltype\\(auto\\)", +keywords:u,relevance:0},{begin:d,returnBegin:!0,contains:[e.inherit(c,{ +className:"title.function"})],relevance:0},{relevance:0,match:/,/},{ +className:"params",begin:/\(/,end:/\)/,keywords:u,relevance:0, +contains:[t,e.C_BLOCK_COMMENT_MODE,i,l,r,{begin:/\(/,end:/\)/,keywords:u, +relevance:0,contains:["self",t,e.C_BLOCK_COMMENT_MODE,i,l,r]}] +},r,t,e.C_BLOCK_COMMENT_MODE,o]};return{name:"C",aliases:["h"],keywords:u, +disableAutodetect:!0,illegal:"=]/,contains:[{ +beginKeywords:"final class struct"},e.TITLE_MODE]}]),exports:{preprocessor:o, +strings:i,keywords:u}}}})();hljs.registerLanguage("c",e)})(); diff --git a/docs/odoc.support/katex.min.css b/docs/odoc.support/katex.min.css new file mode 100644 index 00000000..5f1f8576 --- /dev/null +++ b/docs/odoc.support/katex.min.css @@ -0,0 +1 @@ +@font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.15.2"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} diff --git a/docs/odoc.support/katex.min.js b/docs/odoc.support/katex.min.js new file mode 100644 index 00000000..e4d78f24 --- /dev/null +++ b/docs/odoc.support/katex.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.katex=t():e.katex=t()}("undefined"!=typeof self?self:this,(function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return Zn}});var r=function e(t,r){this.position=void 0;var n,a="KaTeX parse error: "+t,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;n=i.start;var s=i.end;n===o.length?a+=" at end of input: ":a+=" at position "+(n+1)+": ";var l=o.slice(n,s).replace(/[^]/g,"$&\u0332");a+=(n>15?"\u2026"+o.slice(n-15,n):o.slice(0,n))+l+(s+15":">","<":"<",'"':""","'":"'"},o=/[&><"']/g;var s=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},l={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(o,(function(e){return i[e]}))},hyphenate:function(e){return e.replace(a,"-$1").toLowerCase()},getBaseElem:s,isCharacterBox:function(e){var t=s(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(e);return null!=t?t[1]:"_relative"}},h={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:function(e){return"#"+e}},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:function(e,t){return t.push(e),t}},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:function(e){return Math.max(0,e)},cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:function(e){return Math.max(0,e)},cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:function(e){return Math.max(0,e)},cli:"-e, --max-expand ",cliProcessor:function(e){return"Infinity"===e?1/0:parseInt(e)}},globalGroup:{type:"boolean",cli:!1}};function m(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}var c=function(){function e(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},h)if(h.hasOwnProperty(t)){var r=h[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:m(r)}}var t=e.prototype;return t.reportNonstrict=function(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new n("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}},t.useStrictBehavior=function(e,t,r){var n=this.strict;if("function"==typeof n)try{n=n(e,t,r)}catch(e){n="error"}return!(!n||"ignore"===n)&&(!0===n||"error"===n||("warn"===n?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+n+"': "+t+" ["+e+"]"),!1)))},t.isTrusted=function(e){e.url&&!e.protocol&&(e.protocol=l.protocolFromUrl(e.url));var t="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(t)},e}(),u=function(){function e(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}var t=e.prototype;return t.sup=function(){return p[d[this.id]]},t.sub=function(){return p[f[this.id]]},t.fracNum=function(){return p[g[this.id]]},t.fracDen=function(){return p[v[this.id]]},t.cramp=function(){return p[b[this.id]]},t.text=function(){return p[y[this.id]]},t.isTight=function(){return this.size>=2},e}(),p=[new u(0,0,!1),new u(1,0,!0),new u(2,1,!1),new u(3,1,!0),new u(4,2,!1),new u(5,2,!0),new u(6,3,!1),new u(7,3,!0)],d=[4,5,4,5,6,7,6,7],f=[5,5,5,5,7,7,7,7],g=[2,3,4,5,6,7,6,7],v=[3,3,5,5,7,7,7,7],b=[1,1,3,3,5,5,7,7],y=[0,1,2,3,2,3,2,3],x={DISPLAY:p[0],TEXT:p[2],SCRIPT:p[4],SCRIPTSCRIPT:p[6]},w=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var k=[];function S(e){for(var t=0;t=k[t]&&e<=k[t+1])return!0;return!1}w.forEach((function(e){return e.blocks.forEach((function(e){return k.push.apply(k,e)}))}));var M=80,z={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},A=function(){function e(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){for(var e=document.createDocumentFragment(),t=0;t=5?0:e>=3?1:2]){var r=N[t]={cssEmPerMu:B.quad[t]/18};for(var n in B)B.hasOwnProperty(n)&&(r[n]=B[n][t])}return N[t]}(this.size)),this._fontMetrics},t.getColor=function(){return this.phantom?"transparent":this.color},e}();H.BASESIZE=6;var E=H,L={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},D={ex:!0,em:!0,mu:!0},P=function(e){return"string"!=typeof e&&(e=e.unit),e in L||e in D||"ex"===e},F=function(e,t){var r;if(e.unit in L)r=L[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new n("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},V=function(e){return+e.toFixed(4)+"em"},G=function(e){return e.filter((function(e){return e})).join(" ")},U=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var n=t.getColor();n&&(this.style.color=n)}},Y=function(e){var t=document.createElement(e);for(var r in t.className=G(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var n in this.attributes)this.attributes.hasOwnProperty(n)&&t.setAttribute(n,this.attributes[n]);for(var a=0;a"},W=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,e,r,n),this.children=t||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return Y.call(this,"span")},t.toMarkup=function(){return X.call(this,"span")},e}(),_=function(){function e(e,t,r,n){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,U.call(this,t,n),this.children=r||[],this.setAttribute("href",e)}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){return Y.call(this,"a")},t.toMarkup=function(){return X.call(this,"a")},e}(),j=function(){function e(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e},t.toMarkup=function(){var e=""+this.alt+"=a[0]&&e<=a[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=$[this.text])}var t=e.prototype;return t.hasClass=function(e){return l.contains(this.classes,e)},t.toNode=function(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=V(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=G(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e},t.toMarkup=function(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(n)&&(r+=l.hyphenate(n)+":"+this.style[n]+";");r&&(e=!0,t+=' style="'+l.escape(r)+'"');var a=l.escape(this.text);return e?(t+=">",t+=a,t+=""):a},e}(),K=function(){function e(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r":""},e}(),Q=function(){function e(e){this.attributes=void 0,this.attributes=e||{}}var t=e.prototype;return t.toNode=function(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e},t.toMarkup=function(){var e="","\\gt",!0),ie(oe,le,be,"\u2208","\\in",!0),ie(oe,le,be,"\ue020","\\@not"),ie(oe,le,be,"\u2282","\\subset",!0),ie(oe,le,be,"\u2283","\\supset",!0),ie(oe,le,be,"\u2286","\\subseteq",!0),ie(oe,le,be,"\u2287","\\supseteq",!0),ie(oe,he,be,"\u2288","\\nsubseteq",!0),ie(oe,he,be,"\u2289","\\nsupseteq",!0),ie(oe,le,be,"\u22a8","\\models"),ie(oe,le,be,"\u2190","\\leftarrow",!0),ie(oe,le,be,"\u2264","\\le"),ie(oe,le,be,"\u2264","\\leq",!0),ie(oe,le,be,"<","\\lt",!0),ie(oe,le,be,"\u2192","\\rightarrow",!0),ie(oe,le,be,"\u2192","\\to"),ie(oe,he,be,"\u2271","\\ngeq",!0),ie(oe,he,be,"\u2270","\\nleq",!0),ie(oe,le,ye,"\xa0","\\ "),ie(oe,le,ye,"\xa0","\\space"),ie(oe,le,ye,"\xa0","\\nobreakspace"),ie(se,le,ye,"\xa0","\\ "),ie(se,le,ye,"\xa0"," "),ie(se,le,ye,"\xa0","\\space"),ie(se,le,ye,"\xa0","\\nobreakspace"),ie(oe,le,ye,null,"\\nobreak"),ie(oe,le,ye,null,"\\allowbreak"),ie(oe,le,ve,",",","),ie(oe,le,ve,";",";"),ie(oe,he,ce,"\u22bc","\\barwedge",!0),ie(oe,he,ce,"\u22bb","\\veebar",!0),ie(oe,le,ce,"\u2299","\\odot",!0),ie(oe,le,ce,"\u2295","\\oplus",!0),ie(oe,le,ce,"\u2297","\\otimes",!0),ie(oe,le,xe,"\u2202","\\partial",!0),ie(oe,le,ce,"\u2298","\\oslash",!0),ie(oe,he,ce,"\u229a","\\circledcirc",!0),ie(oe,he,ce,"\u22a1","\\boxdot",!0),ie(oe,le,ce,"\u25b3","\\bigtriangleup"),ie(oe,le,ce,"\u25bd","\\bigtriangledown"),ie(oe,le,ce,"\u2020","\\dagger"),ie(oe,le,ce,"\u22c4","\\diamond"),ie(oe,le,ce,"\u22c6","\\star"),ie(oe,le,ce,"\u25c3","\\triangleleft"),ie(oe,le,ce,"\u25b9","\\triangleright"),ie(oe,le,ge,"{","\\{"),ie(se,le,xe,"{","\\{"),ie(se,le,xe,"{","\\textbraceleft"),ie(oe,le,ue,"}","\\}"),ie(se,le,xe,"}","\\}"),ie(se,le,xe,"}","\\textbraceright"),ie(oe,le,ge,"{","\\lbrace"),ie(oe,le,ue,"}","\\rbrace"),ie(oe,le,ge,"[","\\lbrack",!0),ie(se,le,xe,"[","\\lbrack",!0),ie(oe,le,ue,"]","\\rbrack",!0),ie(se,le,xe,"]","\\rbrack",!0),ie(oe,le,ge,"(","\\lparen",!0),ie(oe,le,ue,")","\\rparen",!0),ie(se,le,xe,"<","\\textless",!0),ie(se,le,xe,">","\\textgreater",!0),ie(oe,le,ge,"\u230a","\\lfloor",!0),ie(oe,le,ue,"\u230b","\\rfloor",!0),ie(oe,le,ge,"\u2308","\\lceil",!0),ie(oe,le,ue,"\u2309","\\rceil",!0),ie(oe,le,xe,"\\","\\backslash"),ie(oe,le,xe,"\u2223","|"),ie(oe,le,xe,"\u2223","\\vert"),ie(se,le,xe,"|","\\textbar",!0),ie(oe,le,xe,"\u2225","\\|"),ie(oe,le,xe,"\u2225","\\Vert"),ie(se,le,xe,"\u2225","\\textbardbl"),ie(se,le,xe,"~","\\textasciitilde"),ie(se,le,xe,"\\","\\textbackslash"),ie(se,le,xe,"^","\\textasciicircum"),ie(oe,le,be,"\u2191","\\uparrow",!0),ie(oe,le,be,"\u21d1","\\Uparrow",!0),ie(oe,le,be,"\u2193","\\downarrow",!0),ie(oe,le,be,"\u21d3","\\Downarrow",!0),ie(oe,le,be,"\u2195","\\updownarrow",!0),ie(oe,le,be,"\u21d5","\\Updownarrow",!0),ie(oe,le,fe,"\u2210","\\coprod"),ie(oe,le,fe,"\u22c1","\\bigvee"),ie(oe,le,fe,"\u22c0","\\bigwedge"),ie(oe,le,fe,"\u2a04","\\biguplus"),ie(oe,le,fe,"\u22c2","\\bigcap"),ie(oe,le,fe,"\u22c3","\\bigcup"),ie(oe,le,fe,"\u222b","\\int"),ie(oe,le,fe,"\u222b","\\intop"),ie(oe,le,fe,"\u222c","\\iint"),ie(oe,le,fe,"\u222d","\\iiint"),ie(oe,le,fe,"\u220f","\\prod"),ie(oe,le,fe,"\u2211","\\sum"),ie(oe,le,fe,"\u2a02","\\bigotimes"),ie(oe,le,fe,"\u2a01","\\bigoplus"),ie(oe,le,fe,"\u2a00","\\bigodot"),ie(oe,le,fe,"\u222e","\\oint"),ie(oe,le,fe,"\u222f","\\oiint"),ie(oe,le,fe,"\u2230","\\oiiint"),ie(oe,le,fe,"\u2a06","\\bigsqcup"),ie(oe,le,fe,"\u222b","\\smallint"),ie(se,le,pe,"\u2026","\\textellipsis"),ie(oe,le,pe,"\u2026","\\mathellipsis"),ie(se,le,pe,"\u2026","\\ldots",!0),ie(oe,le,pe,"\u2026","\\ldots",!0),ie(oe,le,pe,"\u22ef","\\@cdots",!0),ie(oe,le,pe,"\u22f1","\\ddots",!0),ie(oe,le,xe,"\u22ee","\\varvdots"),ie(oe,le,me,"\u02ca","\\acute"),ie(oe,le,me,"\u02cb","\\grave"),ie(oe,le,me,"\xa8","\\ddot"),ie(oe,le,me,"~","\\tilde"),ie(oe,le,me,"\u02c9","\\bar"),ie(oe,le,me,"\u02d8","\\breve"),ie(oe,le,me,"\u02c7","\\check"),ie(oe,le,me,"^","\\hat"),ie(oe,le,me,"\u20d7","\\vec"),ie(oe,le,me,"\u02d9","\\dot"),ie(oe,le,me,"\u02da","\\mathring"),ie(oe,le,de,"\ue131","\\@imath"),ie(oe,le,de,"\ue237","\\@jmath"),ie(oe,le,xe,"\u0131","\u0131"),ie(oe,le,xe,"\u0237","\u0237"),ie(se,le,xe,"\u0131","\\i",!0),ie(se,le,xe,"\u0237","\\j",!0),ie(se,le,xe,"\xdf","\\ss",!0),ie(se,le,xe,"\xe6","\\ae",!0),ie(se,le,xe,"\u0153","\\oe",!0),ie(se,le,xe,"\xf8","\\o",!0),ie(se,le,xe,"\xc6","\\AE",!0),ie(se,le,xe,"\u0152","\\OE",!0),ie(se,le,xe,"\xd8","\\O",!0),ie(se,le,me,"\u02ca","\\'"),ie(se,le,me,"\u02cb","\\`"),ie(se,le,me,"\u02c6","\\^"),ie(se,le,me,"\u02dc","\\~"),ie(se,le,me,"\u02c9","\\="),ie(se,le,me,"\u02d8","\\u"),ie(se,le,me,"\u02d9","\\."),ie(se,le,me,"\xb8","\\c"),ie(se,le,me,"\u02da","\\r"),ie(se,le,me,"\u02c7","\\v"),ie(se,le,me,"\xa8",'\\"'),ie(se,le,me,"\u02dd","\\H"),ie(se,le,me,"\u25ef","\\textcircled");var we={"--":!0,"---":!0,"``":!0,"''":!0};ie(se,le,xe,"\u2013","--",!0),ie(se,le,xe,"\u2013","\\textendash"),ie(se,le,xe,"\u2014","---",!0),ie(se,le,xe,"\u2014","\\textemdash"),ie(se,le,xe,"\u2018","`",!0),ie(se,le,xe,"\u2018","\\textquoteleft"),ie(se,le,xe,"\u2019","'",!0),ie(se,le,xe,"\u2019","\\textquoteright"),ie(se,le,xe,"\u201c","``",!0),ie(se,le,xe,"\u201c","\\textquotedblleft"),ie(se,le,xe,"\u201d","''",!0),ie(se,le,xe,"\u201d","\\textquotedblright"),ie(oe,le,xe,"\xb0","\\degree",!0),ie(se,le,xe,"\xb0","\\degree"),ie(se,le,xe,"\xb0","\\textdegree",!0),ie(oe,le,xe,"\xa3","\\pounds"),ie(oe,le,xe,"\xa3","\\mathsterling",!0),ie(se,le,xe,"\xa3","\\pounds"),ie(se,le,xe,"\xa3","\\textsterling",!0),ie(oe,he,xe,"\u2720","\\maltese"),ie(se,he,xe,"\u2720","\\maltese");for(var ke='0123456789/@."',Se=0;Set&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>n&&(n=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=n},Xe=function(e,t,r,n){var a=new W(e,t,r,n);return Ye(a),a},We=function(e,t,r,n){return new W(e,t,r,n)},_e=function(e){var t=new A(e);return Ye(t),t},je=function(e,t,r){var n="";switch(e){case"amsrm":n="AMS";break;case"textrm":n="Main";break;case"textsf":n="SansSerif";break;case"texttt":n="Typewriter";break;default:n=e}return n+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},$e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ze={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Ke={fontMap:$e,makeSymbol:Ge,mathsym:function(e,t,r,n){return void 0===n&&(n=[]),"boldsymbol"===r.font&&Ve(e,"Main-Bold",t).metrics?Ge(e,"Main-Bold",t,r,n.concat(["mathbf"])):"\\"===e||"main"===ae[t][e].font?Ge(e,"Main-Regular",t,r,n):Ge(e,"AMS-Regular",t,r,n.concat(["amsrm"]))},makeSpan:Xe,makeSvgSpan:We,makeLineSpan:function(e,t,r){var n=Xe([e],[],t);return n.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),n.style.borderBottomWidth=V(n.height),n.maxFontSize=1,n},makeAnchor:function(e,t,r,n){var a=new _(e,t,r,n);return Ye(a),a},makeFragment:_e,wrapFragment:function(e,t){return e instanceof A?Xe([],[e],t):e},makeVList:function(e,t){for(var r=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],n=-t[0].shift-t[0].elem.depth,a=n,i=1;i0&&(o.push(kt(s,t)),s=[]),o.push(a[l]));s.length>0&&o.push(kt(s,t)),r?((i=kt(ft(r,t,!0))).classes=["tag"],o.push(i)):n&&o.push(n);var m=mt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=V(m.height+m.depth),m.depth&&(c.style.verticalAlign=V(-m.depth))}return m}function Mt(e){return new A(e)}var zt=function(){function e(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}var t=e.prototype;return t.setAttribute=function(e,t){this.attributes[e]=t},t.getAttribute=function(e){return this.attributes[e]},t.toNode=function(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=G(this.classes));for(var r=0;r0&&(e+=' class ="'+l.escape(G(this.classes))+'"'),e+=">";for(var r=0;r"},t.toText=function(){return this.children.map((function(e){return e.toText()})).join("")},e}(),At=function(){function e(e){this.text=void 0,this.text=e}var t=e.prototype;return t.toNode=function(){return document.createTextNode(this.text)},t.toMarkup=function(){return l.escape(this.toText())},t.toText=function(){return this.text},e}(),Tt={MathNode:zt,TextNode:At,SpaceNode:function(){function e(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}var t=e.prototype;return t.toNode=function(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",V(this.width)),e},t.toMarkup=function(){return this.character?""+this.character+"":''},t.toText=function(){return this.character?this.character:" "},e}(),newDocumentFragment:Mt},Bt=function(e,t,r){return!ae[t][e]||!ae[t][e].replace||55349===e.charCodeAt(0)||we.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(e=ae[t][e].replace),new Tt.TextNode(e)},Ct=function(e){return 1===e.length?e[0]:new Tt.MathNode("mrow",e)},qt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var n=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var a=e.text;return l.contains(["\\imath","\\jmath"],a)?null:(ae[n][a]&&ae[n][a].replace&&(a=ae[n][a].replace),q(a,Ke.fontMap[r].fontName,n)?Ke.fontMap[r].variant:null)},Nt=function(e,t,r){if(1===e.length){var n=Rt(e[0],t);return r&&n instanceof zt&&"mo"===n.type&&(n.setAttribute("lspace","0em"),n.setAttribute("rspace","0em")),[n]}for(var a,i=[],o=0;o0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),a=s}return i},It=function(e,t,r){return Ct(Nt(e,t,r))},Rt=function(e,t){if(!e)return new Tt.MathNode("mrow");if(it[e.type])return it[e.type](e,t);throw new n("Got group of unknown type: '"+e.type+"'")};function Ot(e,t,r,n,a){var i,o=Nt(e,r);i=1===o.length&&o[0]instanceof zt&&l.contains(["mrow","mtable"],o[0].type)?o[0]:new Tt.MathNode("mrow",o);var s=new Tt.MathNode("annotation",[new Tt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var h=new Tt.MathNode("semantics",[i,s]),m=new Tt.MathNode("math",[h]);m.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),n&&m.setAttribute("display","block");var c=a?"katex":"katex-mathml";return Ke.makeSpan([c],[m])}var Ht=function(e){return new E({style:e.displayMode?x.DISPLAY:x.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Et=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Ke.makeSpan(r,[e])}return e},Lt=function(e,t,r){var n,a=Ht(r);if("mathml"===r.output)return Ot(e,t,a,r.displayMode,!0);if("html"===r.output){var i=St(e,a);n=Ke.makeSpan(["katex"],[i])}else{var o=Ot(e,t,a,r.displayMode,!1),s=St(e,a);n=Ke.makeSpan(["katex"],[o,s])}return Et(n,r)},Dt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Pt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Ft=function(e,t,r,n,a){var i,o=e.height+e.depth+r+n;if(/fbox|color|angl/.test(t)){if(i=Ke.makeSpan(["stretchy",t],[],a),"fbox"===t){var s=a.color&&a.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new Q({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new Q({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new K(l,{width:"100%",height:V(o)});i=Ke.makeSvgSpan([],[h],a)}return i.height=o,i.style.height=V(o),i},Vt=function(e){var t=new Tt.MathNode("mo",[new Tt.TextNode(Dt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Gt=function(e,t){var r=function(){var r=4e5,n=e.label.substr(1);if(l.contains(["widehat","widecheck","widetilde","utilde"],n)){var a,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===n||"widecheck"===n?(a=420,r=2364,o=.42,i=n+"4"):(a=312,r=2340,o=.34,i="tilde4");else{var h=[1,1,2,2,3,3][s];"widehat"===n||"widecheck"===n?(r=[0,1062,2364,2364,2364][h],a=[0,239,300,360,420][h],o=[0,.24,.3,.3,.36,.42][h],i=n+h):(r=[0,600,1033,2339,2340][h],a=[0,260,286,306,312][h],o=[0,.26,.286,.3,.306,.34][h],i="tilde"+h)}var m=new J(i),c=new K([m],{width:"100%",height:V(o),viewBox:"0 0 "+r+" "+a,preserveAspectRatio:"none"});return{span:Ke.makeSvgSpan([],[c],t),minWidth:0,height:o}}var u,p,d,f=[],g=Pt[n],v=g[0],b=g[1],y=g[2],x=y/1e3,w=v.length;if(1===w)u=["hide-tail"],p=[g[3]];else if(2===w)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(n.style.minWidth=V(a)),n};function Ut(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Yt(e){var t=Xt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Xt(e){return e&&("atom"===e.type||re.hasOwnProperty(e.type))?e:null}var Wt=function(e,t){var r,n,a;e&&"supsub"===e.type?(r=(n=Ut(e.base,"accent")).base,e.base=r,a=function(e){if(e instanceof W)return e;throw new Error("Expected span but got "+String(e)+".")}(wt(e,t)),e.base=n):r=(n=Ut(e,"accent")).base;var i=wt(r,t.havingCrampedStyle()),o=0;if(n.isShifty&&l.isCharacterBox(r)){var s=l.getBaseElem(r);o=ee(wt(s,t.havingCrampedStyle())).skew}var h,m="\\c"===n.label,c=m?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(n.isStretchy)h=Gt(n,t),h=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:h,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+V(2*o)+")",marginLeft:V(2*o)}:void 0}]},t);else{var u,p;"\\vec"===n.label?(u=Ke.staticSvg("vec",t),p=Ke.svgData.vec[1]):((u=ee(u=Ke.makeOrd({mode:n.mode,text:n.label},t,"textord"))).italic=0,p=u.width,m&&(c+=u.depth)),h=Ke.makeSpan(["accent-body"],[u]);var d="\\textcircled"===n.label;d&&(h.classes.push("accent-full"),c=i.height);var f=o;d||(f-=p/2),h.style.left=V(f),"\\textcircled"===n.label&&(h.style.top=".2em"),h=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:h}]},t)}var g=Ke.makeSpan(["mord","accent"],[h],t);return a?(a.children[0]=g,a.height=Math.max(g.height,a.height),a.classes[0]="mord",a):g},_t=function(e,t){var r=e.isStretchy?Vt(e.label):new Tt.MathNode("mo",[Bt(e.label,e.mode)]),n=new Tt.MathNode("mover",[Rt(e.base,t),r]);return n.setAttribute("accent","true"),n},jt=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((function(e){return"\\"+e})).join("|"));ot({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(e,t){var r=lt(t[0]),n=!jt.test(e.funcName),a=!n||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:n,isShifty:a,base:r}},htmlBuilder:Wt,mathmlBuilder:_t}),ot({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:function(e,t){var r=t[0],n=e.parser.mode;return"math"===n&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),n="text"),{type:"accent",mode:n,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Wt,mathmlBuilder:_t}),ot({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"accentUnder",mode:r.mode,label:n,base:a}},htmlBuilder:function(e,t){var r=wt(e.base,t),n=Gt(e,t),a="\\utilde"===e.label?.12:0,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:n,wrapperClasses:["svg-align"]},{type:"kern",size:a},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:function(e,t){var r=Vt(e.label),n=new Tt.MathNode("munder",[Rt(e.base,t),r]);return n.setAttribute("accentunder","true"),n}});var $t=function(e){var t=new Tt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};ot({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler:function(e,t,r){var n=e.parser,a=e.funcName;return{type:"xArrow",mode:n.mode,label:a,body:t[0],below:r[0]}},htmlBuilder:function(e,t){var r,n=t.style,a=t.havingStyle(n.sup()),i=Ke.wrapFragment(wt(e.body,a,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(a=t.havingStyle(n.sub()),(r=Ke.wrapFragment(wt(e.below,a,t),t)).classes.push(o+"-arrow-pad"));var s,l=Gt(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Ke.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder:function(e,t){var r,n=Vt(e.label);if(n.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var a=$t(Rt(e.body,t));if(e.below){var i=$t(Rt(e.below,t));r=new Tt.MathNode("munderover",[n,i,a])}else r=new Tt.MathNode("mover",[n,a])}else if(e.below){var o=$t(Rt(e.below,t));r=new Tt.MathNode("munder",[n,o])}else r=$t(),r=new Tt.MathNode("mover",[n,r]);return r}});var Zt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},Kt=function(e){return"textord"===e.type&&"@"===e.text};function Jt(e,t,r){var n=Zt[e];switch(n){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(n,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var a={type:"atom",text:n,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[a],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}ot({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"cdlabel",mode:r.mode,side:n.slice(4),label:t[0]}},htmlBuilder:function(e,t){var r=t.havingStyle(t.style.sup()),n=Ke.wrapFragment(wt(e.label,r,t),t);return n.classes.push("cd-label-"+e.side),n.style.bottom=V(.8-n.depth),n.height=0,n.depth=0,n},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mrow",[Rt(e.label,t)]);return(r=new Tt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Tt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),ot({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler:function(e,t){return{type:"cdlabelparent",mode:e.parser.mode,fragment:t[0]}},htmlBuilder:function(e,t){var r=Ke.wrapFragment(wt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:function(e,t){return new Tt.MathNode("mrow",[Rt(e.fragment,t)])}}),ot({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){for(var r=e.parser,a=Ut(t[0],"ordgroup").body,i="",o=0;o=1114111)throw new n("\\@char with invalid code point "+i);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var Qt=function(e,t){var r=ft(e.body,t.withColor(e.color),!1);return Ke.makeFragment(r)},er=function(e,t){var r=Nt(e.body,t.withColor(e.color)),n=new Tt.MathNode("mstyle",r);return n.setAttribute("mathcolor",e.color),n};ot({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler:function(e,t){var r=e.parser,n=Ut(t[0],"color-token").color,a=t[1];return{type:"color",mode:r.mode,color:n,body:ht(a)}},htmlBuilder:Qt,mathmlBuilder:er}),ot({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler:function(e,t){var r=e.parser,n=e.breakOnTokenText,a=Ut(t[0],"color-token").color;r.gullet.macros.set("\\current@color",a);var i=r.parseExpression(!0,n);return{type:"color",mode:r.mode,color:a,body:i}},htmlBuilder:Qt,mathmlBuilder:er}),ot({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=r[0],i=!n.settings.displayMode||!n.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:n.mode,newLine:i,size:a&&Ut(a,"size").value}},htmlBuilder:function(e,t){var r=Ke.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=V(F(e.size,t)))),r},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",V(F(e.size,t)))),r}});var tr={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},rr=function(e){var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new n("Expected a control sequence",e);return t},nr=function(e,t,r,n){var a=e.gullet.macros.get(r.text);null==a&&(r.noexpand=!0,a={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,a,n)};ot({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(e){var t=e.parser,r=e.funcName;t.consumeSpaces();var a=t.fetch();if(tr[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=tr[a.text]),Ut(t.parseFunction(),"internal");throw new n("Invalid token after macro prefix",a)}}),ot({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,a=t.gullet.popToken(),i=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(i))throw new n("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new n('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new n('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new n("Expected a macro definition");l[s].push(a.text)}var h=t.gullet.consumeArg().tokens;return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(i,{tokens:h,numArgs:s,delimiters:l},r===tr[r]),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=rr(t.gullet.popToken());t.gullet.consumeSpaces();var a=function(e){var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t}(t);return nr(t,n,a,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e){var t=e.parser,r=e.funcName,n=rr(t.gullet.popToken()),a=t.gullet.popToken(),i=t.gullet.popToken();return nr(t,n,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(a),{type:"internal",mode:t.mode}}});var ar=function(e,t,r){var n=q(ae.math[e]&&ae.math[e].replace||e,t,r);if(!n)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return n},ir=function(e,t,r,n){var a=r.havingBaseStyle(t),i=Ke.makeSpan(n.concat(a.sizingClasses(r)),[e],r),o=a.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=a.sizeMultiplier,i},or=function(e,t,r){var n=t.havingBaseStyle(r),a=(1-t.sizeMultiplier/n.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=V(a),e.height-=a,e.depth+=a},sr=function(e,t,r,n,a,i){var o=function(e,t,r,n){return Ke.makeSymbol(e,"Size"+t+"-Regular",r,n)}(e,t,a,n),s=ir(Ke.makeSpan(["delimsizing","size"+t],[o],n),x.TEXT,n,i);return r&&or(s,n,x.TEXT),s},lr=function(e,t,r){var n;return n="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:Ke.makeSpan(["delimsizinginner",n],[Ke.makeSpan([],[Ke.makeSymbol(e,t,r)])])}},hr=function(e,t,r){var n=T["Size4-Regular"][e.charCodeAt(0)]?T["Size4-Regular"][e.charCodeAt(0)][4]:T["Size1-Regular"][e.charCodeAt(0)][4],a=new J("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new K([a],{width:V(n),height:V(t),style:"width:"+V(n),viewBox:"0 0 "+1e3*n+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Ke.makeSvgSpan([],[i],r);return o.height=t,o.style.height=V(t),o.style.width=V(n),{type:"elem",elem:o}},mr={type:"kern",size:-.008},cr=["|","\\lvert","\\rvert","\\vert"],ur=["\\|","\\lVert","\\rVert","\\Vert"],pr=function(e,t,r,n,a,i){var o,s,h,m;o=h=m=e,s=null;var c="Size1-Regular";"\\uparrow"===e?h=m="\u23d0":"\\Uparrow"===e?h=m="\u2016":"\\downarrow"===e?o=h="\u23d0":"\\Downarrow"===e?o=h="\u2016":"\\updownarrow"===e?(o="\\uparrow",h="\u23d0",m="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",h="\u2016",m="\\Downarrow"):l.contains(cr,e)?h="\u2223":l.contains(ur,e)?h="\u2225":"["===e||"\\lbrack"===e?(o="\u23a1",h="\u23a2",m="\u23a3",c="Size4-Regular"):"]"===e||"\\rbrack"===e?(o="\u23a4",h="\u23a5",m="\u23a6",c="Size4-Regular"):"\\lfloor"===e||"\u230a"===e?(h=o="\u23a2",m="\u23a3",c="Size4-Regular"):"\\lceil"===e||"\u2308"===e?(o="\u23a1",h=m="\u23a2",c="Size4-Regular"):"\\rfloor"===e||"\u230b"===e?(h=o="\u23a5",m="\u23a6",c="Size4-Regular"):"\\rceil"===e||"\u2309"===e?(o="\u23a4",h=m="\u23a5",c="Size4-Regular"):"("===e||"\\lparen"===e?(o="\u239b",h="\u239c",m="\u239d",c="Size4-Regular"):")"===e||"\\rparen"===e?(o="\u239e",h="\u239f",m="\u23a0",c="Size4-Regular"):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",m="\u23a9",h="\u23aa",c="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",m="\u23ad",h="\u23aa",c="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",m="\u23a9",h="\u23aa",c="Size4-Regular");var u=ar(o,c,a),p=u.height+u.depth,d=ar(h,c,a),f=d.height+d.depth,g=ar(m,c,a),v=g.height+g.depth,b=0,y=1;if(null!==s){var w=ar(s,c,a);b=w.height+w.depth,y=2}var k=p+v+b,S=k+Math.max(0,Math.ceil((t-k)/(y*f)))*y*f,M=n.fontMetrics().axisHeight;r&&(M*=n.sizeMultiplier);var z=S/2-M,A=[];if(A.push(lr(m,c,a)),A.push(mr),null===s){var T=S-p-v+.016;A.push(hr(h,T,n))}else{var B=(S-p-v-b)/2+.016;A.push(hr(h,B,n)),A.push(mr),A.push(lr(s,c,a)),A.push(mr),A.push(hr(h,B,n))}A.push(mr),A.push(lr(o,c,a));var C=n.havingBaseStyle(x.TEXT),q=Ke.makeVList({positionType:"bottom",positionData:z,children:A},C);return ir(Ke.makeSpan(["delimsizing","mult"],[q],C),x.TEXT,n,i)},dr=.08,fr=function(e,t,r,n,a){var i=function(e,t,r){t*=1e3;var n="";switch(e){case"sqrtMain":n=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize1":n=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize2":n=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize3":n=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,M);break;case"sqrtSize4":n=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,M);break;case"sqrtTall":n=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,M,r)}return n}(e,n,r),o=new J(e,i),s=new K([o],{width:"400em",height:V(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Ke.makeSvgSpan(["hide-tail"],[s],a)},gr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],vr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],br=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],yr=[0,1.2,1.8,2.4,3],xr=[{type:"small",style:x.SCRIPTSCRIPT},{type:"small",style:x.SCRIPT},{type:"small",style:x.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],wr=[{type:"small",style:x.SCRIPTSCRIPT},{type:"small",style:x.SCRIPT},{type:"small",style:x.TEXT},{type:"stack"}],kr=[{type:"small",style:x.SCRIPTSCRIPT},{type:"small",style:x.SCRIPT},{type:"small",style:x.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Sr=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},Mr=function(e,t,r,n){for(var a=Math.min(2,3-n.style.size);at)return r[a]}return r[r.length-1]},zr=function(e,t,r,n,a,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=l.contains(br,e)?xr:l.contains(gr,e)?kr:wr;var s=Mr(e,t,o,n);return"small"===s.type?function(e,t,r,n,a,i){var o=Ke.makeSymbol(e,"Main-Regular",a,n),s=ir(o,t,n,i);return r&&or(s,n,t),s}(e,s.style,r,n,a,i):"large"===s.type?sr(e,s.size,r,n,a,i):pr(e,t,r,n,a,i)},Ar={sqrtImage:function(e,t){var r,n,a=t.havingBaseSizing(),i=Mr("\\surd",e*a.sizeMultiplier,kr,a),o=a.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=fr("sqrtMain",l=(1+s+dr)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",n=.833/o):"large"===i.type?(m=1080*yr[i.size],h=(yr[i.size]+s)/o,l=(yr[i.size]+s+dr)/o,(r=fr("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",n=1/o):(l=e+s+dr,h=e+s,m=Math.floor(1e3*e+s)+80,(r=fr("sqrtTall",l,m,s,t)).style.minWidth="0.742em",n=1.056),r.height=h,r.style.height=V(l),{span:r,advanceWidth:n,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,i){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),l.contains(gr,e)||l.contains(br,e))return sr(e,t,!1,r,a,i);if(l.contains(vr,e))return pr(e,yr[t],!1,r,a,i);throw new n("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:yr,customSizedDelim:zr,leftRightDelim:function(e,t,r,n,a,i){var o=n.fontMetrics().axisHeight*n.sizeMultiplier,s=5/n.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return zr(e,h,!0,n,a,i)}},Tr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},Br=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Cr(e,t){var r=Xt(e);if(r&&l.contains(Br,r.text))return r;throw new n(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function qr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}ot({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:function(e,t){var r=Cr(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:Tr[e.funcName].size,mclass:Tr[e.funcName].mclass,delim:r.text}},htmlBuilder:function(e,t){return"."===e.delim?Ke.makeSpan([e.mclass]):Ar.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass])},mathmlBuilder:function(e){var t=[];"."!==e.delim&&t.push(Bt(e.delim,e.mode));var r=new Tt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var n=V(Ar.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",n),r.setAttribute("maxsize",n),r}}),ot({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new n("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Cr(t[0],e).text,color:r}}}),ot({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:function(e,t){var r=Cr(t[0],e),n=e.parser;++n.leftrightDepth;var a=n.parseExpression(!1);--n.leftrightDepth,n.expect("\\right",!1);var i=Ut(n.parseFunction(),"leftright-right");return{type:"leftright",mode:n.mode,body:a,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(e,t){qr(e);for(var r,n,a=ft(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l-1?"mpadded":"menclose",[Rt(e.body,t)]);switch(e.label){case"\\cancel":n.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":n.setAttribute("notation","downdiagonalstrike");break;case"\\phase":n.setAttribute("notation","phasorangle");break;case"\\sout":n.setAttribute("notation","horizontalstrike");break;case"\\fbox":n.setAttribute("notation","box");break;case"\\angl":n.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,n.setAttribute("width","+"+2*r+"pt"),n.setAttribute("height","+"+2*r+"pt"),n.setAttribute("lspace",r+"pt"),n.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var a=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);n.setAttribute("style","border: "+a+"em solid "+String(e.borderColor))}break;case"\\xcancel":n.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&n.setAttribute("mathbackground",e.backgroundColor),n};ot({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Ut(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:n.mode,label:a,backgroundColor:i,body:o}},htmlBuilder:Nr,mathmlBuilder:Ir}),ot({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler:function(e,t,r){var n=e.parser,a=e.funcName,i=Ut(t[0],"color-token").color,o=Ut(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:n.mode,label:a,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Nr,mathmlBuilder:Ir}),ot({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\fbox",body:t[0]}}}),ot({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"enclose",mode:r.mode,label:n,body:a}},htmlBuilder:Nr,mathmlBuilder:Ir}),ot({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler:function(e,t){return{type:"enclose",mode:e.parser.mode,label:"\\angl",body:t[0]}}});var Rr={};function Or(e){for(var t=e.type,r=e.names,n=e.props,a=e.handler,i=e.htmlBuilder,o=e.mathmlBuilder,s={type:t,numArgs:n.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:a},l=0;l1||!c)&&g.pop(),b.length0&&(y+=.25),m.push({pos:y,isDashed:e[t]})}for(w(o[0]),r=0;r0&&(M<(B+=b)&&(M=B),B=0),e.addJot&&(M+=f),z.height=S,z.depth=M,y+=S,z.pos=y,y+=M+B,h[r]=z,w(o[r+1])}var C,q,N=y/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],O=[];if(e.tags&&e.tags.some((function(e){return e})))for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=l.deflt(P.pregap,p))&&((C=Ke.makeSpan(["arraycolsep"],[])).style.width=V(W),R.push(C));var _=[];for(r=0;r0){for(var K=Ke.makeLineSpan("hline",t,c),J=Ke.makeLineSpan("hdashline",t,c),Q=[{type:"elem",elem:h,shift:0}];m.length>0;){var ee=m.pop(),te=ee.pos-N;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}h=Ke.makeVList({positionType:"individualShift",children:Q},t)}if(0===O.length)return Ke.makeSpan(["mord"],[h],t);var re=Ke.makeVList({positionType:"individualShift",children:O},t);return re=Ke.makeSpan(["tag"],[re],t),Ke.makeFragment([h,re])},Xr={c:"center ",l:"left ",r:"right "},Wr=function(e,t){for(var r=[],n=new Tt.MathNode("mtd",[],["mtr-glue"]),a=new Tt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var p=e.cols,d="",f=!1,g=0,v=p.length;"separator"===p[0].type&&(c+="top ",g=1),"separator"===p[p.length-1].type&&(c+="bottom ",v-=1);for(var b=g;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o="split"===e.envName,s=Gr(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Vr(e.envName),emptySingleRow:!0,colSeparationType:i,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var m="",c=0;c0&&u&&(f=1),a[p]={type:"align",align:d,pregap:f,postgap:0}}return s.colSeparationType=u?"align":"alignat",s};Or({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(e,t){var r=(Xt(t[0])?[t[0]]:Ut(t[0],"ordgroup").body).map((function(e){var t=Yt(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new n("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Gr(e.parser,a,Ur(e.envName))},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler:function(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var i=e.parser;if(i.consumeSpaces(),"["===i.fetch().text){if(i.consume(),i.consumeSpaces(),r=i.fetch().text,-1==="lcr".indexOf(r))throw new n("Expected l or c or r",i.nextToken);i.consume(),i.consumeSpaces(),i.expect("]"),i.consume(),a.cols=[{type:"align",align:r}]}}var o=Gr(e.parser,a,Ur(e.envName)),s=Math.max.apply(Math,[0].concat(o.body.map((function(e){return e.length}))));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(e){var t=Gr(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["subarray"],props:{numArgs:1},handler:function(e,t){var r=(Xt(t[0])?[t[0]]:Ut(t[0],"ordgroup").body).map((function(e){var t=Yt(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new n("Unknown column alignment: "+t,e)}));if(r.length>1)throw new n("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Gr(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new n("{subarray} can contain only one column");return a},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(e){var t=Gr(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Ur(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:_r,htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler:function(e){l.contains(["gather","gather*"],e.envName)&&Fr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Vr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Gr(e.parser,t,"display")},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:_r,htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["equation","equation*"],props:{numArgs:0},handler:function(e){Fr(e);var t={autoTag:Vr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Gr(e.parser,t,"display")},htmlBuilder:Yr,mathmlBuilder:Wr}),Or({type:"array",names:["CD"],props:{numArgs:0},handler:function(e){return Fr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new n("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,i,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(u)>-1))throw new n('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var f=!0,g=c+1;g=x.SCRIPT.id?r.text():x.DISPLAY:"text"===e&&r.size===x.DISPLAY.size?r=x.TEXT:"script"===e?r=x.SCRIPT:"scriptscript"===e&&(r=x.SCRIPTSCRIPT),r},nn=function(e,t){var r,n=rn(e.size,t.style),a=n.fracNum(),i=n.fracDen();r=t.havingStyle(a);var o=wt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(u=t.fontMetrics().num2,p=c):(u=t.fontMetrics().num3,p=3*c),d=t.fontMetrics().denom2),h){var w=t.fontMetrics().axisHeight;u-o.depth-(w+.5*m)0&&(t="."===(t=e)?null:t),t};ot({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler:function(e,t){var r,n=e.parser,a=t[4],i=t[5],o=lt(t[0]),s="atom"===o.type&&"open"===o.family?sn(o.text):null,l=lt(t[1]),h="atom"===l.type&&"close"===l.family?sn(l.text):null,m=Ut(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var u="auto",p=t[3];if("ordgroup"===p.type){if(p.body.length>0){var d=Ut(p.body[0],"textord");u=on[Number(d.text)]}}else p=Ut(p,"textord"),u=on[Number(p.text)];return{type:"genfrac",mode:n.mode,numer:a,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:u}},htmlBuilder:nn,mathmlBuilder:an}),ot({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(e,t){var r=e.parser,n=(e.funcName,e.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Ut(t[0],"size").value,token:n}}}),ot({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(e,t){var r=e.parser,n=(e.funcName,t[0]),a=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Ut(t[1],"infix").size),i=t[2],o=a.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:i,continued:!1,hasBarLine:o,barSize:a,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:nn,mathmlBuilder:an});var ln=function(e,t){var r,n,a=t.style;"supsub"===e.type?(r=e.sup?wt(e.sup,t.havingStyle(a.sup()),t):wt(e.sub,t.havingStyle(a.sub()),t),n=Ut(e.base,"horizBrace")):n=Ut(e,"horizBrace");var i,o=wt(n.base,t.havingBaseStyle(x.DISPLAY)),s=Gt(n,t);if(n.isOver?(i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Ke.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Ke.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t);i=n.isOver?Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Ke.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Ke.makeSpan(["mord",n.isOver?"mover":"munder"],[i],t)};ot({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(e,t){var r=e.parser,n=e.funcName;return{type:"horizBrace",mode:r.mode,label:n,isOver:/^\\over/.test(n),base:t[0]}},htmlBuilder:ln,mathmlBuilder:function(e,t){var r=Vt(e.label);return new Tt.MathNode(e.isOver?"mover":"munder",[Rt(e.base,t),r])}}),ot({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=t[1],a=Ut(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:a})?{type:"href",mode:r.mode,href:a,body:ht(n)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(e,t){var r=ft(e.body,t,!1);return Ke.makeAnchor(e.href,[],r,t)},mathmlBuilder:function(e,t){var r=It(e.body,t);return r instanceof zt||(r=new zt("mrow",[r])),r.setAttribute("href",e.href),r}}),ot({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(e,t){var r=e.parser,n=Ut(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:n}))return r.formatUnsupportedCmd("\\url");for(var a=[],i=0;i0&&(n=F(e.totalheight,t)-r);var a=0;e.width.number>0&&(a=F(e.width,t));var i={height:V(r+n)};a>0&&(i.width=V(a)),n>0&&(i.verticalAlign=V(-n));var o=new j(e.src,e.alt,i);return o.height=r,o.depth=n,o},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var n=F(e.height,t),a=0;if(e.totalheight.number>0&&(a=F(e.totalheight,t)-n,r.setAttribute("valign",V(-a))),r.setAttribute("height",V(n+a)),e.width.number>0){var i=F(e.width,t);r.setAttribute("width",V(i))}return r.setAttribute("src",e.src),r}}),ot({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=Ut(t[0],"size");if(r.settings.strict){var i="m"===n[1],o="mu"===a.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" supports only mu units, not "+a.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+n+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:a.value}},htmlBuilder:function(e,t){return Ke.makeGlue(e.dimension,t)},mathmlBuilder:function(e,t){var r=F(e.dimension,t);return new Tt.SpaceNode(r)}}),ot({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"lap",mode:r.mode,alignment:n.slice(5),body:a}},htmlBuilder:function(e,t){var r;"clap"===e.alignment?(r=Ke.makeSpan([],[wt(e.body,t)]),r=Ke.makeSpan(["inner"],[r],t)):r=Ke.makeSpan(["inner"],[wt(e.body,t)]);var n=Ke.makeSpan(["fix"],[]),a=Ke.makeSpan([e.alignment],[r,n],t),i=Ke.makeSpan(["strut"]);return i.style.height=V(a.height+a.depth),a.depth&&(i.style.verticalAlign=V(-a.depth)),a.children.unshift(i),a=Ke.makeSpan(["thinbox"],[a],t),Ke.makeSpan(["mord","vbox"],[a],t)},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);if("rlap"!==e.alignment){var n="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",n+"width")}return r.setAttribute("width","0px"),r}}),ot({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){var r=e.funcName,n=e.parser,a=n.mode;n.switchMode("math");var i="\\("===r?"\\)":"$",o=n.parseExpression(!1,i);return n.expect(i),n.switchMode(a),{type:"styling",mode:n.mode,style:"text",body:o}}}),ot({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(e,t){throw new n("Mismatched "+e.funcName)}});var mn=function(e,t){switch(t.style.size){case x.DISPLAY.size:return e.display;case x.TEXT.size:return e.text;case x.SCRIPT.size:return e.script;case x.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};ot({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:function(e,t){return{type:"mathchoice",mode:e.parser.mode,display:ht(t[0]),text:ht(t[1]),script:ht(t[2]),scriptscript:ht(t[3])}},htmlBuilder:function(e,t){var r=mn(e,t),n=ft(r,t,!1);return Ke.makeFragment(n)},mathmlBuilder:function(e,t){var r=mn(e,t);return It(r,t)}});var cn=function(e,t,r,n,a,i,o){e=Ke.makeSpan([],[e]);var s,h,m,c=r&&l.isCharacterBox(r);if(t){var u=wt(t,n.havingStyle(a.sup()),n);h={elem:u,kern:Math.max(n.fontMetrics().bigOpSpacing1,n.fontMetrics().bigOpSpacing3-u.depth)}}if(r){var p=wt(r,n.havingStyle(a.sub()),n);s={elem:p,kern:Math.max(n.fontMetrics().bigOpSpacing2,n.fontMetrics().bigOpSpacing4-p.height)}}if(h&&s){var d=n.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;m=Ke.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:V(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}else if(s){var f=e.height-o;m=Ke.makeVList({positionType:"top",positionData:f,children:[{type:"kern",size:n.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:V(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},n)}else{if(!h)return e;var g=e.depth+o;m=Ke.makeVList({positionType:"bottom",positionData:g,children:[{type:"elem",elem:e},{type:"kern",size:h.kern},{type:"elem",elem:h.elem,marginLeft:V(i)},{type:"kern",size:n.fontMetrics().bigOpSpacing5}]},n)}var v=[m];if(s&&0!==i&&!c){var b=Ke.makeSpan(["mspace"],[],n);b.style.marginRight=V(i),v.unshift(b)}return Ke.makeSpan(["mop","op-limits"],v,n)},un=["\\smallint"],pn=function(e,t){var r,n,a,i=!1;"supsub"===e.type?(r=e.sup,n=e.sub,a=Ut(e.base,"op"),i=!0):a=Ut(e,"op");var o,s=t.style,h=!1;if(s.size===x.DISPLAY.size&&a.symbol&&!l.contains(un,a.name)&&(h=!0),a.symbol){var m=h?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==a.name&&"\\oiiint"!==a.name||(c=a.name.substr(1),a.name="oiint"===c?"\\iint":"\\iiint"),o=Ke.makeSymbol(a.name,m,"math",t,["mop","op-symbol",h?"large-op":"small-op"]),c.length>0){var u=o.italic,p=Ke.staticSvg(c+"Size"+(h?"2":"1"),t);o=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:h?.08:0}]},t),a.name="\\"+c,o.classes.unshift("mop"),o.italic=u}}else if(a.body){var d=ft(a.body,t,!0);1===d.length&&d[0]instanceof Z?(o=d[0]).classes[0]="mop":o=Ke.makeSpan(["mop"],d,t)}else{for(var f=[],g=1;g0){for(var s=a.body.map((function(e){var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=ft(s,t.withFont("mathrm"),!0),h=0;h=0?s.setAttribute("height",V(a)):(s.setAttribute("height",V(a)),s.setAttribute("depth",V(-a))),s.setAttribute("voffset",V(a)),s}});var yn=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];ot({type:"sizing",names:yn,props:{numArgs:0,allowedInText:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!1,r);return{type:"sizing",mode:a.mode,size:yn.indexOf(n)+1,body:i}},htmlBuilder:function(e,t){var r=t.havingSize(e.size);return bn(e.body,r,t)},mathmlBuilder:function(e,t){var r=t.havingSize(e.size),n=Nt(e.body,r),a=new Tt.MathNode("mstyle",n);return a.setAttribute("mathsize",V(r.sizeMultiplier)),a}}),ot({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(e,t,r){var n=e.parser,a=!1,i=!1,o=r[0]&&Ut(r[0],"ordgroup");if(o)for(var s="",l=0;lr.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=V(m);var p=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},t);if(e.index){var d=t.havingStyle(x.SCRIPTSCRIPT),f=wt(e.index,d,t),g=.6*(p.height-p.depth),v=Ke.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},t),b=Ke.makeSpan(["root"],[v]);return Ke.makeSpan(["mord","sqrt"],[b,p],t)}return Ke.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder:function(e,t){var r=e.body,n=e.index;return n?new Tt.MathNode("mroot",[Rt(r,t),Rt(n,t)]):new Tt.MathNode("msqrt",[Rt(r,t)])}});var xn={display:x.DISPLAY,text:x.TEXT,script:x.SCRIPT,scriptscript:x.SCRIPTSCRIPT};ot({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler:function(e,t){var r=e.breakOnTokenText,n=e.funcName,a=e.parser,i=a.parseExpression(!0,r),o=n.slice(1,n.length-5);return{type:"styling",mode:a.mode,style:o,body:i}},htmlBuilder:function(e,t){var r=xn[e.style],n=t.havingStyle(r).withFont("");return bn(e.body,n,t)},mathmlBuilder:function(e,t){var r=xn[e.style],n=t.havingStyle(r),a=Nt(e.body,n),i=new Tt.MathNode("mstyle",a),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});var wn=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===x.DISPLAY.size||r.alwaysHandleSupSub)?pn:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===x.DISPLAY.size||r.limits)?vn:null:"accent"===r.type?l.isCharacterBox(r.base)?Wt:null:"horizBrace"===r.type&&!e.sub===r.isOver?ln:null:null};st({type:"supsub",htmlBuilder:function(e,t){var r=wn(e,t);if(r)return r(e,t);var n,a,i,o=e.base,s=e.sup,h=e.sub,m=wt(o,t),c=t.fontMetrics(),u=0,p=0,d=o&&l.isCharacterBox(o);if(s){var f=t.havingStyle(t.style.sup());n=wt(s,f,t),d||(u=m.height-f.fontMetrics().supDrop*f.sizeMultiplier/t.sizeMultiplier)}if(h){var g=t.havingStyle(t.style.sub());a=wt(h,g,t),d||(p=m.depth+g.fontMetrics().subDrop*g.sizeMultiplier/t.sizeMultiplier)}i=t.style===x.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,b=t.sizeMultiplier,y=V(.5/c.ptPerEm/b),w=null;if(a){var k=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(m instanceof Z||k)&&(w=V(-m.italic))}if(n&&a){u=Math.max(u,i,n.depth+.25*c.xHeight),p=Math.max(p,c.sub2);var S=4*c.defaultRuleThickness;if(u-n.depth-(a.height-p)0&&(u+=M,p-=M)}var z=[{type:"elem",elem:a,shift:p,marginRight:y,marginLeft:w},{type:"elem",elem:n,shift:-u,marginRight:y}];v=Ke.makeVList({positionType:"individualShift",children:z},t)}else if(a){p=Math.max(p,c.sub1,a.height-.8*c.xHeight);var A=[{type:"elem",elem:a,marginLeft:w,marginRight:y}];v=Ke.makeVList({positionType:"shift",positionData:p,children:A},t)}else{if(!n)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,n.depth+.25*c.xHeight),v=Ke.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:n,marginRight:y}]},t)}var T=yt(m,"right")||"mord";return Ke.makeSpan([T],[m,Ke.makeSpan(["msupsub"],[v])],t)},mathmlBuilder:function(e,t){var r,n=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(n=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var a,i=[Rt(e.base,t)];if(e.sub&&i.push(Rt(e.sub,t)),e.sup&&i.push(Rt(e.sup,t)),n)a=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;a=o&&"op"===o.type&&o.limits&&t.style===x.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===x.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;a=s&&"op"===s.type&&s.limits&&(t.style===x.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===x.DISPLAY)?"munder":"msub"}else{var l=e.base;a=l&&"op"===l.type&&l.limits&&(t.style===x.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===x.DISPLAY)?"mover":"msup"}return new Tt.MathNode(a,i)}}),st({type:"atom",htmlBuilder:function(e,t){return Ke.mathsym(e.text,e.mode,t,["m"+e.family])},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mo",[Bt(e.text,e.mode)]);if("bin"===e.family){var n=qt(e,t);"bold-italic"===n&&r.setAttribute("mathvariant",n)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var kn={mi:"italic",mn:"normal",mtext:"normal"};st({type:"mathord",htmlBuilder:function(e,t){return Ke.makeOrd(e,t,"mathord")},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mi",[Bt(e.text,e.mode,t)]),n=qt(e,t)||"italic";return n!==kn[r.type]&&r.setAttribute("mathvariant",n),r}}),st({type:"textord",htmlBuilder:function(e,t){return Ke.makeOrd(e,t,"textord")},mathmlBuilder:function(e,t){var r,n=Bt(e.text,e.mode,t),a=qt(e,t)||"normal";return r="text"===e.mode?new Tt.MathNode("mtext",[n]):/[0-9]/.test(e.text)?new Tt.MathNode("mn",[n]):"\\prime"===e.text?new Tt.MathNode("mo",[n]):new Tt.MathNode("mi",[n]),a!==kn[r.type]&&r.setAttribute("mathvariant",a),r}});var Sn={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Mn={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};st({type:"spacing",htmlBuilder:function(e,t){if(Mn.hasOwnProperty(e.text)){var r=Mn[e.text].className||"";if("text"===e.mode){var a=Ke.makeOrd(e,t,"textord");return a.classes.push(r),a}return Ke.makeSpan(["mspace",r],[Ke.mathsym(e.text,e.mode,t)],t)}if(Sn.hasOwnProperty(e.text))return Ke.makeSpan(["mspace",Sn[e.text]],[],t);throw new n('Unknown type of space "'+e.text+'"')},mathmlBuilder:function(e,t){if(!Mn.hasOwnProperty(e.text)){if(Sn.hasOwnProperty(e.text))return new Tt.MathNode("mspace");throw new n('Unknown type of space "'+e.text+'"')}return new Tt.MathNode("mtext",[new Tt.TextNode("\xa0")])}});var zn=function(){var e=new Tt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};st({type:"tag",mathmlBuilder:function(e,t){var r=new Tt.MathNode("mtable",[new Tt.MathNode("mtr",[zn(),new Tt.MathNode("mtd",[It(e.body,t)]),zn(),new Tt.MathNode("mtd",[It(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var An={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},Tn={"\\textbf":"textbf","\\textmd":"textmd"},Bn={"\\textit":"textit","\\textup":"textup"},Cn=function(e,t){var r=e.font;return r?An[r]?t.withTextFontFamily(An[r]):Tn[r]?t.withTextFontWeight(Tn[r]):t.withTextFontShape(Bn[r]):t};ot({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler:function(e,t){var r=e.parser,n=e.funcName,a=t[0];return{type:"text",mode:r.mode,body:ht(a),font:n}},htmlBuilder:function(e,t){var r=Cn(e,t),n=ft(e.body,r,!0);return Ke.makeSpan(["mord","text"],n,r)},mathmlBuilder:function(e,t){var r=Cn(e,t);return It(e.body,r)}}),ot({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(e,t){return{type:"underline",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=wt(e.body,t),n=Ke.makeLineSpan("underline-line",t),a=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:a},{type:"elem",elem:n},{type:"kern",size:3*a},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","underline"],[i],t)},mathmlBuilder:function(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var n=new Tt.MathNode("munder",[Rt(e.body,t),r]);return n.setAttribute("accentunder","true"),n}}),ot({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler:function(e,t){return{type:"vcenter",mode:e.parser.mode,body:t[0]}},htmlBuilder:function(e,t){var r=wt(e.body,t),n=t.fontMetrics().axisHeight,a=.5*(r.height-n-(r.depth+n));return Ke.makeVList({positionType:"shift",positionData:a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:function(e,t){return new Tt.MathNode("mpadded",[Rt(e.body,t)],["vcenter"])}}),ot({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(e,t,r){throw new n("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(e,t){for(var r=qn(e),n=[],a=t.havingStyle(t.style.text()),i=0;i0;)this.endGroup()},t.has=function(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)},t.get=function(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]},t.set=function(e,t,r){if(void 0===r&&(r=!1),r){for(var n=0;n0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var a=this.undefStack[this.undefStack.length-1];a&&!a.hasOwnProperty(e)&&(a[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t},e}(),Hn=Hr;Er("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Er("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Er("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Er("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Er("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Er("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Er("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var En={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Er("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new n("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=En[r.text])||a>=t)throw new n("Invalid base-"+t+" digit "+r.text);for(var i;null!=(i=En[e.future().text])&&i":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Er("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in Dn?t=Dn[r]:("\\not"===r.substr(0,4)||r in ae.math&&l.contains(["bin","rel"],ae.math[r].group))&&(t="\\dotsb"),t}));var Pn={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Er("\\dotso",(function(e){return e.future().text in Pn?"\\ldots\\,":"\\ldots"})),Er("\\dotsc",(function(e){var t=e.future().text;return t in Pn&&","!==t?"\\ldots\\,":"\\ldots"})),Er("\\cdots",(function(e){return e.future().text in Pn?"\\@cdots\\,":"\\@cdots"})),Er("\\dotsb","\\cdots"),Er("\\dotsm","\\cdots"),Er("\\dotsi","\\!\\cdots"),Er("\\dotsx","\\ldots\\,"),Er("\\DOTSI","\\relax"),Er("\\DOTSB","\\relax"),Er("\\DOTSX","\\relax"),Er("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Er("\\,","\\tmspace+{3mu}{.1667em}"),Er("\\thinspace","\\,"),Er("\\>","\\mskip{4mu}"),Er("\\:","\\tmspace+{4mu}{.2222em}"),Er("\\medspace","\\:"),Er("\\;","\\tmspace+{5mu}{.2777em}"),Er("\\thickspace","\\;"),Er("\\!","\\tmspace-{3mu}{.1667em}"),Er("\\negthinspace","\\!"),Er("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Er("\\negthickspace","\\tmspace-{5mu}{.277em}"),Er("\\enspace","\\kern.5em "),Er("\\enskip","\\hskip.5em\\relax"),Er("\\quad","\\hskip1em\\relax"),Er("\\qquad","\\hskip2em\\relax"),Er("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Er("\\tag@paren","\\tag@literal{({#1})}"),Er("\\tag@literal",(function(e){if(e.macros.get("\\df@tag"))throw new n("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Er("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Er("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Er("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Er("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Er("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),Er("\\newline","\\\\\\relax"),Er("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Fn=V(T["Main-Regular"]["T".charCodeAt(0)][1]-.7*T["Main-Regular"]["A".charCodeAt(0)][1]);Er("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Fn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Er("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Fn+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Er("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Er("\\@hspace","\\hskip #1\\relax"),Er("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Er("\\ordinarycolon",":"),Er("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Er("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Er("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Er("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Er("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Er("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Er("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Er("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Er("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Er("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Er("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Er("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Er("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Er("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Er("\u2237","\\dblcolon"),Er("\u2239","\\eqcolon"),Er("\u2254","\\coloneqq"),Er("\u2255","\\eqqcolon"),Er("\u2a74","\\Coloneqq"),Er("\\ratio","\\vcentcolon"),Er("\\coloncolon","\\dblcolon"),Er("\\colonequals","\\coloneqq"),Er("\\coloncolonequals","\\Coloneqq"),Er("\\equalscolon","\\eqqcolon"),Er("\\equalscoloncolon","\\Eqqcolon"),Er("\\colonminus","\\coloneq"),Er("\\coloncolonminus","\\Coloneq"),Er("\\minuscolon","\\eqcolon"),Er("\\minuscoloncolon","\\Eqcolon"),Er("\\coloncolonapprox","\\Colonapprox"),Er("\\coloncolonsim","\\Colonsim"),Er("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Er("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Er("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Er("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Er("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Er("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Er("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Er("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Er("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Er("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Er("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Er("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Er("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Er("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Er("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Er("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Er("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Er("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Er("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Er("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Er("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Er("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Er("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Er("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Er("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Er("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Er("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Er("\\imath","\\html@mathml{\\@imath}{\u0131}"),Er("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Er("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Er("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Er("\u27e6","\\llbracket"),Er("\u27e7","\\rrbracket"),Er("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Er("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Er("\u2983","\\lBrace"),Er("\u2984","\\rBrace"),Er("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Er("\u29b5","\\minuso"),Er("\\darr","\\downarrow"),Er("\\dArr","\\Downarrow"),Er("\\Darr","\\Downarrow"),Er("\\lang","\\langle"),Er("\\rang","\\rangle"),Er("\\uarr","\\uparrow"),Er("\\uArr","\\Uparrow"),Er("\\Uarr","\\Uparrow"),Er("\\N","\\mathbb{N}"),Er("\\R","\\mathbb{R}"),Er("\\Z","\\mathbb{Z}"),Er("\\alef","\\aleph"),Er("\\alefsym","\\aleph"),Er("\\Alpha","\\mathrm{A}"),Er("\\Beta","\\mathrm{B}"),Er("\\bull","\\bullet"),Er("\\Chi","\\mathrm{X}"),Er("\\clubs","\\clubsuit"),Er("\\cnums","\\mathbb{C}"),Er("\\Complex","\\mathbb{C}"),Er("\\Dagger","\\ddagger"),Er("\\diamonds","\\diamondsuit"),Er("\\empty","\\emptyset"),Er("\\Epsilon","\\mathrm{E}"),Er("\\Eta","\\mathrm{H}"),Er("\\exist","\\exists"),Er("\\harr","\\leftrightarrow"),Er("\\hArr","\\Leftrightarrow"),Er("\\Harr","\\Leftrightarrow"),Er("\\hearts","\\heartsuit"),Er("\\image","\\Im"),Er("\\infin","\\infty"),Er("\\Iota","\\mathrm{I}"),Er("\\isin","\\in"),Er("\\Kappa","\\mathrm{K}"),Er("\\larr","\\leftarrow"),Er("\\lArr","\\Leftarrow"),Er("\\Larr","\\Leftarrow"),Er("\\lrarr","\\leftrightarrow"),Er("\\lrArr","\\Leftrightarrow"),Er("\\Lrarr","\\Leftrightarrow"),Er("\\Mu","\\mathrm{M}"),Er("\\natnums","\\mathbb{N}"),Er("\\Nu","\\mathrm{N}"),Er("\\Omicron","\\mathrm{O}"),Er("\\plusmn","\\pm"),Er("\\rarr","\\rightarrow"),Er("\\rArr","\\Rightarrow"),Er("\\Rarr","\\Rightarrow"),Er("\\real","\\Re"),Er("\\reals","\\mathbb{R}"),Er("\\Reals","\\mathbb{R}"),Er("\\Rho","\\mathrm{P}"),Er("\\sdot","\\cdot"),Er("\\sect","\\S"),Er("\\spades","\\spadesuit"),Er("\\sub","\\subset"),Er("\\sube","\\subseteq"),Er("\\supe","\\supseteq"),Er("\\Tau","\\mathrm{T}"),Er("\\thetasym","\\vartheta"),Er("\\weierp","\\wp"),Er("\\Zeta","\\mathrm{Z}"),Er("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Er("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Er("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Er("\\bra","\\mathinner{\\langle{#1}|}"),Er("\\ket","\\mathinner{|{#1}\\rangle}"),Er("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Er("\\Bra","\\left\\langle#1\\right|"),Er("\\Ket","\\left|#1\\right\\rangle"),Er("\\angln","{\\angl n}"),Er("\\blue","\\textcolor{##6495ed}{#1}"),Er("\\orange","\\textcolor{##ffa500}{#1}"),Er("\\pink","\\textcolor{##ff00af}{#1}"),Er("\\red","\\textcolor{##df0030}{#1}"),Er("\\green","\\textcolor{##28ae7b}{#1}"),Er("\\gray","\\textcolor{gray}{#1}"),Er("\\purple","\\textcolor{##9d38bd}{#1}"),Er("\\blueA","\\textcolor{##ccfaff}{#1}"),Er("\\blueB","\\textcolor{##80f6ff}{#1}"),Er("\\blueC","\\textcolor{##63d9ea}{#1}"),Er("\\blueD","\\textcolor{##11accd}{#1}"),Er("\\blueE","\\textcolor{##0c7f99}{#1}"),Er("\\tealA","\\textcolor{##94fff5}{#1}"),Er("\\tealB","\\textcolor{##26edd5}{#1}"),Er("\\tealC","\\textcolor{##01d1c1}{#1}"),Er("\\tealD","\\textcolor{##01a995}{#1}"),Er("\\tealE","\\textcolor{##208170}{#1}"),Er("\\greenA","\\textcolor{##b6ffb0}{#1}"),Er("\\greenB","\\textcolor{##8af281}{#1}"),Er("\\greenC","\\textcolor{##74cf70}{#1}"),Er("\\greenD","\\textcolor{##1fab54}{#1}"),Er("\\greenE","\\textcolor{##0d923f}{#1}"),Er("\\goldA","\\textcolor{##ffd0a9}{#1}"),Er("\\goldB","\\textcolor{##ffbb71}{#1}"),Er("\\goldC","\\textcolor{##ff9c39}{#1}"),Er("\\goldD","\\textcolor{##e07d10}{#1}"),Er("\\goldE","\\textcolor{##a75a05}{#1}"),Er("\\redA","\\textcolor{##fca9a9}{#1}"),Er("\\redB","\\textcolor{##ff8482}{#1}"),Er("\\redC","\\textcolor{##f9685d}{#1}"),Er("\\redD","\\textcolor{##e84d39}{#1}"),Er("\\redE","\\textcolor{##bc2612}{#1}"),Er("\\maroonA","\\textcolor{##ffbde0}{#1}"),Er("\\maroonB","\\textcolor{##ff92c6}{#1}"),Er("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Er("\\maroonD","\\textcolor{##ca337c}{#1}"),Er("\\maroonE","\\textcolor{##9e034e}{#1}"),Er("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Er("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Er("\\purpleC","\\textcolor{##aa87ff}{#1}"),Er("\\purpleD","\\textcolor{##7854ab}{#1}"),Er("\\purpleE","\\textcolor{##543b78}{#1}"),Er("\\mintA","\\textcolor{##f5f9e8}{#1}"),Er("\\mintB","\\textcolor{##edf2df}{#1}"),Er("\\mintC","\\textcolor{##e0e5cc}{#1}"),Er("\\grayA","\\textcolor{##f6f7f7}{#1}"),Er("\\grayB","\\textcolor{##f0f1f2}{#1}"),Er("\\grayC","\\textcolor{##e3e5e6}{#1}"),Er("\\grayD","\\textcolor{##d6d8da}{#1}"),Er("\\grayE","\\textcolor{##babec2}{#1}"),Er("\\grayF","\\textcolor{##888d93}{#1}"),Er("\\grayG","\\textcolor{##626569}{#1}"),Er("\\grayH","\\textcolor{##3b3e40}{#1}"),Er("\\grayI","\\textcolor{##21242c}{#1}"),Er("\\kaBlue","\\textcolor{##314453}{#1}"),Er("\\kaGreen","\\textcolor{##71B307}{#1}");var Vn={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},Gn=function(){function e(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new On(Hn,t.macros),this.mode=r,this.stack=[]}var t=e.prototype;return t.feed=function(e){this.lexer=new Rn(e,this.settings)},t.switchMode=function(e){this.mode=e},t.beginGroup=function(){this.macros.beginGroup()},t.endGroup=function(){this.macros.endGroup()},t.endGroups=function(){this.macros.endGroups()},t.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},t.popToken=function(){return this.future(),this.stack.pop()},t.pushToken=function(e){this.stack.push(e)},t.pushTokens=function(e){var t;(t=this.stack).push.apply(t,e)},t.scanArgument=function(e){var t,r,n;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken();var a=this.consumeArg(["]"]);n=a.tokens,r=a.end}else{var i=this.consumeArg();n=i.tokens,t=i.start,r=i.end}return this.pushToken(new Dr("EOF",r.loc)),this.pushTokens(n),t.range(r,"")},t.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},t.consumeArg=function(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,i=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new n("Extra }",a)}else if("EOF"===a.text)throw new n("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===i.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:i,end:a}},t.consumeArgs=function(e,t){if(t){if(t.length!==e+1)throw new n("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new n("Too many expansions: infinite loop or need to increase maxExpand setting");var i=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(i=i.slice()).length-1;s>=0;--s){var l=i[s];if("#"===l.text){if(0===s)throw new n("Incomplete placeholder at end of macro body",l);if("#"===(l=i[--s]).text)i.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new n("Not a valid argument number",l);var h;(h=i).splice.apply(h,[s,2].concat(o[+l.text-1]))}}}return this.pushTokens(i),i},t.expandAfterFuture=function(){return this.expandOnce(),this.future()},t.expandNextToken=function(){for(;;){var e=this.expandOnce();if(e instanceof Dr)return e.treatAsRelax&&(e.text="\\relax"),this.stack.pop()}throw new Error},t.expandMacro=function(e){return this.macros.has(e)?this.expandTokens([new Dr(e)]):void 0},t.expandTokens=function(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;){var n=this.expandOnce(!0);n instanceof Dr&&(n.treatAsRelax&&(n.noexpand=!1,n.treatAsRelax=!1),t.push(this.stack.pop()))}return t},t.expandMacroAsText=function(e){var t=this.expandMacro(e);return t?t.map((function(e){return e.text})).join(""):t},t._getExpansion=function(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var n="function"==typeof t?t(this):t;if("string"==typeof n){var a=0;if(-1!==n.indexOf("#"))for(var i=n.replace(/##/g,"");-1!==i.indexOf("#"+(a+1));)++a;for(var o=new Rn(n,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:a}}return n},t.isDefined=function(e){return this.macros.has(e)||Nn.hasOwnProperty(e)||ae.math.hasOwnProperty(e)||ae.text.hasOwnProperty(e)||Vn.hasOwnProperty(e)},t.isExpandable=function(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Nn.hasOwnProperty(e)&&!Nn[e].primitive},e}(),Un={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Yn={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Xn=function(){function e(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Gn(e,t,this.mode),this.settings=t,this.leftrightDepth=0}var t=e.prototype;return t.expect=function(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new n("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()},t.consume=function(){this.nextToken=null},t.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},t.switchMode=function(e){this.mode=e,this.gullet.switchMode(e)},t.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}},t.subparse=function(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new Dr("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r},t.parseExpression=function(t,r){for(var n=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==e.endOfExpression.indexOf(a.text))break;if(r&&a.text===r)break;if(t&&Nn[a.text]&&Nn[a.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&n.push(i)}return"text"===this.mode&&this.formLigatures(n),this.handleInfixNodes(n)},t.handleInfixNodes=function(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var s,l=ae[this.mode][t].group,h=Lr.range(e);if(te.hasOwnProperty(l)){var m=l;s={type:"atom",mode:this.mode,family:m,loc:h,text:t}}else s={type:l,mode:this.mode,loc:h,text:t};i=s}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(S(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),i={type:"textord",mode:"text",loc:Lr.range(e),text:t}}if(this.consume(),o)for(var c=0;c *:first-child { + /* This make the first thing in the preamble align with the sidebar */ + padding-top: 0; + margin-top: 0; +} + +header { + margin-bottom: 30px; +} + +header.odoc-preamble { + grid-column: 2; + grid-row: 3; +} + +nav { + font-family: "Fira Sans", sans-serif; +} + +nav.odoc-nav { + grid-column: 2; + grid-row: 2; +} + +/* Basic markup elements */ + +b, strong { + font-weight: bold; +} + +i { + font-style: italic; +} + +em, i em.odd{ + font-style: italic; +} + +em.odd, i em { + font-style: normal; +} + +sup { + vertical-align: super; +} + +sub { + vertical-align: sub; +} + +sup, sub { + font-size: 12px; + line-height: 0; + margin-left: 0.2ex; +} + +ul, ol { + list-style-position: outside +} + +ul>li { + margin-left: 22px; +} + +ol>li { + margin-left: 27.2px; +} + +li>*:first-child { + margin-top: 0 +} + +/* Text alignements, this should be forbidden. */ + +.left { + text-align: left; +} + +.right { + text-align: right; +} + +.center { + text-align: center; +} + +/* Links and anchors */ + +a { + text-decoration: none; + color: var(--link-color); +} + +.odoc-src pre a { + color: inherit; +} + +a:hover { + box-shadow: 0 1px 0 0 var(--link-color); +} + +/* Linked highlight */ +*:target { + background-color: var(--target-background) !important; + box-shadow: 0 0px 0 1px var(--target-shadow) !important; + border-radius: 1px; +} + +*:hover > a.anchor { + visibility: visible; +} + +a.anchor:before { + content: "#"; +} + +a.anchor:hover { + box-shadow: none; + text-decoration: none; + color: var(--anchor-hover); +} + +a.anchor { + visibility: hidden; + position: absolute; + /* top: 0px; */ + /* margin-left: -3ex; */ + margin-left: -1.3em; + font-weight: normal; + font-style: normal; + padding-right: 0.4em; + padding-left: 0.4em; + /* To remain selectable */ + color: var(--anchor-color); +} + +.spec > a.anchor { + margin-left: -2.3em; + padding-right: 0.9em; +} + +.xref-unresolved { + color: #2C94BD; +} +.xref-unresolved:hover { + box-shadow: 0 1px 0 0 var(--xref-shadow); +} + +/* Source links float inside preformated text or headings. */ +a.source_link { + float: right; + color: var(--source-color); + font-family: "Fira Sans", sans-serif; + font-size: initial; +} + +/* Section and document divisions. + Until at least 4.03 many of the modules of the stdlib start at .h7, + we restart the sequence there like h2 */ + +h1, h2, h3, h4, h5, h6, .h7, .h8, .h9, .h10 { + font-family: "Fira Sans", sans-serif; + font-weight: 400; + padding-top: 0.1em; + line-height: 1.2; + overflow-wrap: break-word; +} + +.odoc-preamble h1 { + margin-top: 10px; +} + +h1 { + font-weight: 500; + font-size: 2.441em; +} + +h1 { + font-weight: 500; + font-size: 1.953em; + box-shadow: 0 1px 0 0 var(--header-shadow); +} + +h2 { + font-size: 1.563em; +} + +h3 { + font-size: 1.25em; +} + +small, .font_small { + font-size: 0.8em; +} + +h1 code, h1 tt { + font-size: inherit; + font-weight: inherit; +} + +h2 code, h2 tt { + font-size: inherit; + font-weight: inherit; +} + +h3 code, h3 tt { + font-size: inherit; + font-weight: inherit; +} + +h3 code, h3 tt { + font-size: inherit; + font-weight: inherit; +} + +h4 { + font-size: 1.12em; +} + +/* Comment delimiters, hidden but accessible to screen readers and + selected for copy/pasting */ + +/* Taken from bootstrap */ +/* See also https://stackoverflow.com/a/27769435/4220738 */ +.comment-delim { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +/* Preformatted and code */ + +tt, code, pre { + font-family: "Fira Mono", monospace; + font-weight: 400; +} + +.odoc pre { + padding: 0.1em; + border: 1px solid var(--pre-border-color); + border-radius: 5px; + overflow-x: auto; +} + +.odoc p code, +.odoc li code { + background-color: var(--li-code-background); + color: var(--li-code-color); + border-radius: 3px; + padding: 0 0.3ex; +} + +p a > code, li a > code { + color: var(--link-color); +} + +.odoc code { + white-space: pre-wrap; +} + +/* Code blocks (e.g. Examples) */ + +.odoc pre code { + font-size: 0.893rem; +} + +/* Code lexemes */ + +.keyword { + font-weight: 500; +} + +.arrow { white-space: nowrap } + +/* Module member specification */ + +.spec { + background-color: var(--spec-summary-background); + border-radius: 3px; + border-left: 4px solid var(--spec-summary-border-color); + border-right: 5px solid transparent; + padding: 0.35em 0.5em; +} + +.spec .label, .spec .optlabel { + color: var(--spec-label-color); +} + +li:not(:last-child) > .def-doc { + margin-bottom: 15px; +} + +/* Spacing between items */ +div.odoc-spec,.odoc-include { + margin-bottom: 2em; +} + +.spec.type .variant p, .spec.type .record p { + margin: 5px; +} + +.spec.type .variant, .spec.type .record { + margin-left: 2ch; +} + +.spec.type li.variant, .spec.type li.record { + list-style: none; +} + +.spec.type .record > code, .spec.type .variant > code { + min-width: 40%; +} + +.spec.type > ol { + margin-top: 0; + margin-bottom: 0; +} + +.spec.type .record > .def-doc, .spec.type .variant > .def-doc { + min-width:50%; + padding: 0.25em 0.5em; + margin-left: 10%; + border-radius: 3px; + background: var(--main-background); + box-shadow: 1px 1px 2px lightgrey; +} + +div.def { + margin-top: 0; + text-indent: -2ex; + padding-left: 2ex; +} + +div.def-doc>*:first-child { + margin-top: 0; +} + +/* Collapsible inlined include and module */ + +.odoc-include details { + position: relative; +} + +.odoc-include.shadowed-include { + display: none; +} + +.odoc-include details:after { + z-index: -100; + display: block; + content: " "; + position: absolute; + border-radius: 0 1ex 1ex 0; + right: -20px; + top: 1px; + bottom: 1px; + width: 15px; + background: var(--spec-details-after-background, rgba(0, 4, 15, 0.05)); + box-shadow: 0 0px 0 1px var(--spec-details-after-shadow, rgba(204, 204, 204, 0.53)); +} + +.odoc-include summary { + position: relative; + margin-bottom: 1em; + cursor: pointer; + outline: none; +} + +.odoc-include summary:hover { + background-color: var(--spec-summary-hover-background); +} + +/* FIXME: Does not work in Firefox. */ +.odoc-include summary::-webkit-details-marker { + color: #888; + transform: scaleX(-1); + position: absolute; + top: calc(50% - 5px); + height: 11px; + right: -29px; +} + +/* Records and variants FIXME */ + +div.def table { + text-indent: 0em; + padding: 0; + margin-left: -2ex; +} + +td.def { + padding-left: 2ex; +} + +td.def-doc *:first-child { + margin-top: 0em; +} + +/* Lists of @tags */ + +.at-tags { list-style-type: none; margin-left: -3ex; } +.at-tags li { padding-left: 3ex; text-indent: -3ex; } +.at-tags .at-tag { text-transform: capitalize } + +/* Alert emoji */ + +.alert::before, .deprecated::before { + content: '⚠️ '; +} + +/* Lists of modules */ + +.modules { list-style-type: none; margin-left: -3ex; } +.modules li { padding-left: 3ex; text-indent: -3ex; margin-top: 5px } +.modules .synopsis { padding-left: 1ch; } + +/* Odig package index */ + +.packages { list-style-type: none; margin-left: -3ex; } +.packages li { padding-left: 3ex; text-indent: -3ex } +.packages li a.anchor { padding-right: 0.5ch; padding-left: 3ch; } +.packages .version { font-size: 10px; color: var(--by-name-version-color); } +.packages .synopsis { padding-left: 1ch } + +.by-name nav a { + text-transform: uppercase; + font-size: 18px; + margin-right: 1ex; + color: var(--by-name-nav-link-color,); + display: inline-block; +} + +.by-tag nav a { + margin-right: 1ex; + color: var(--by-name-nav-link-color); + display: inline-block; +} + +.by-tag ol { list-style-type: none; } +.by-tag ol.tags li { margin-left: 1ch; display: inline-block } +.by-tag td:first-child { text-transform: uppercase; } + +/* Odig package page */ + +.package nav { + display: inline; + font-size: 14px; + font-weight: normal; +} + +.package .version { + font-size: 14px; +} + +.package.info { + margin: 0; +} + +.package.info td:first-child { + font-style: italic; + padding-right: 2ex; +} + +.package.info ul { + list-style-type: none; + display: inline; + margin: 0; +} + +.package.info li { + display: inline-block; + margin: 0; + margin-right: 1ex; +} + +#info-authors li, #info-maintainers li { + display: block; +} + +/* Sidebar and TOC */ + +.odoc-toc:before { + display: block; + content: "Contents"; + text-transform: uppercase; + font-size: 1em; + margin: 1.414em 0 0.5em; + font-weight: 500; + color: var(--toc-before-color); + line-height: 1.2; +} + +/* When a search bar is present, we need the sticky sidebar to be a bit lower, + so `top` is higher */ + +.odoc-search + * + .odoc-toc { + --toc-top: calc(var(--search-bar-height) + var(--search-padding-top) + 20px); + max-height: calc(100vh - 2 * var(--toc-top)); + top: var(--toc-top) +} + +.odoc-toc { + --toc-top: 20px; + width: 28ex; + background: var(--toc-background); + overflow: auto; + color: var(--toc-color); + padding-left: 2ex; + padding-right: 2ex; + grid-row-start: 3; + grid-row-end: 5; + grid-column: 1; + height: fit-content; + border: solid 1px var(--border); + border-radius: 5px; + position:sticky; + max-height: calc(100vh - 2 * var(--toc-top)); + top: var(--toc-top) +} + +.odoc-toc ul li a { + font-family: "Fira Sans", sans-serif; + font-size: 0.95em; + color: var(--color); + font-weight: 400; + line-height: 1.2em; + display: block; +} + +.odoc-sidebar ul li a:hover { + box-shadow: none; + text-decoration: underline; +} + +:root { + --search-bar-height: 25px; + --search-padding-top: 1rem; +} + +.odoc-search { + position: sticky; + top: 0; + background: var(--main-background); + /* This amounts to fit-content when the search is not active, but when you + have the search results displayed, you do not want the height of the search + container to change. */ + height: calc(var(--search-bar-height) + var(--search-padding-top)); + width: 100%; + padding-top: var(--search-padding-top); + z-index: 1; + grid-row: 1; + grid-column-start: 1; + grid-column-end: 3; +} + + +.odoc-search .search-inner { + width: 100%; + position: relative; + left: 0; + display: grid; + /* The second column is for the search snake, which has 0 width */ + grid-template-columns: 1fr 0fr; + grid-row-gap: 1rem; + /* The second row is for the search results. It has a width, but only */ + grid-template-rows: min-content 0px; + background: transparent; +} + +.odoc-search .search-bar { + position: relative; + z-index: 2; + font-size: 1em; + transition: font-size 0.3s; + box-shadow: 0px 0px 0.2rem 0.3em var(--main-background); + height: var(--search-bar-height); +} + +.odoc-search:focus-within .search-bar { + font-size: 1.1em; +} + +.odoc-search:not(:focus-within) .search-result { + display: none; +} + +.odoc-search .search-result:empty { + display: none; +} + +.odoc-search .search-result { + grid-row: 2; + background: var(--toc-background); + position: absolute; + left: 0; + right: 0; + border: solid; + border-color: var(--search-results-border); + border-width: 1px; + border-radius: 6px; + box-shadow: 0 3px 10px 2px var(--search-results-shadow), 0 0 3px 4px var(--main-background), 0px -1rem 0px 0px var(--main-background); + /* Works better on smallish screens with this */ + max-height: calc(min(40rem, 50vh)); + overflow-y: auto; +} + +.search-bar { + /* inputs are of fixed size by default, even if you display:block them */ + width: 100%; +} + + +.odoc-search .search-no-result { + color: var(--color); + border-bottom: var(--search-results-border) solid 1px; + background-color: inherit; + outline: 0; + padding: 10px; + padding-right: 0.5rem; +} + +.search-bar-container { + display: flex; + align-items: stretch; + border-bottom: 1rem solid var(--main-background); +} + +.search-snake { + grid-row: 1; + grid-column: 2; + display: flex; + align-items: center; + width: 0; + z-index: 2; + position: relative; + left: 0; + margin-top: 4px; + margin-bottom: 4px; + /* Otherwise the search snake flickers for very fast searches. */ + transition: opacity 0.2s; + opacity: 0; +} + +.search-snake.search-busy { + opacity: 1; +} + +.search-snake:before { + content: " "; + display: block; + aspect-ratio: 1 / 1; + height: 100%; + margin-right: 4px; + border-radius: 50%; + border: 3px solid #aaa; + border-color: var(--search-snake) transparent var(--search-snake) transparent; + animation: search-snake 1.2s linear infinite; + position: absolute; + right: 0; +} + +@keyframes search-snake { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +:root { + --kind-font-size-factor: 0.8; +} + +.odoc-search .search-entry { + color: var(--color); + display: grid; + /* Possible kinds are the following : + "doc" "type" "mod" "exn" "class" "meth" "cons" "sig" "cons" "field" "val" + and "ext". + As the longest is 5 characters (and the font monospace), we give 5 + character size to the column. However the font used for kind is a little + smaller, so we adjust by this factor. + */ + grid-template-columns: [kinds] calc(var(--kind-font-size-factor) * 5ch) [titles] 1fr; + column-gap: 0.5rem; + border-bottom: var(--search-results-border) solid 1px; + background-color: inherit; + outline: 0; + padding: 0.4rem 0.4rem 0.7rem 0.7rem; +} +.odoc-search .search-entry p { + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.odoc-search .search-entry:focus-visible { + box-shadow: none; + background-color: var(--target-background); +} + +.odoc-search .search-entry:hover { + box-shadow: none; + background-color: var(--toc-background-emph); +} + +.odoc-search .search-entry .entry-kind { + grid-row: 1/2; + grid-column: 1/2; + line-height: 1.4rem; + font-size: calc(var(--kind-font-size-factor) * 1em); + font-weight: bold; + text-align: right; + position: relative; + bottom: 0; +} + +.odoc-search .search-entry pre { + border: none; + margin: 0; +} + +.odoc-search .search-entry pre code { + font-size: 1em; + background-color: var(--li-code-background); + color: var(--li-code-color); + border-radius: 3px; + padding: 0 0.3ex; +} + +.odoc-search .search-entry .entry-title { + width: 100%; + display: block; + grid-column: 2/2; + grid-row: 1/2; + align-self: end; + line-height: 1.4rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.odoc-search .entry-name { + font-weight: bold; +} + +.odoc-search .prefix-name { + font-weight: bold; +} + +.odoc-search .search-entry .prefix-name { + opacity: 0.7; +} + +.odoc-search .entry-rhs { + white-space: nowrap; +} + +.odoc-search .search-entry .entry-content { + flex-grow: 1; + flex-shrink: 1; + min-width: 0; +} + +.odoc-search .search-entry .entry-comment { + max-height: 1.5em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 0.95em; + grid-row: 2/2; + grid-column: 2/2; +} + +.odoc-search .search-entry .entry-comment ul { + white-space: nowrap; + display: inline; +} + +.odoc-search .search-entry .entry-comment li { + display: inline; + white-space: nowrap; +} + +.odoc-search .search-entry .entry-comment ul>li::before { + content: '•'; +} + +.odoc-search .search-entry .entry-comment div { + display: inline; + white-space: nowrap; +} + +.odoc-search .search-entry .entry-comment p { + display: inline; + white-space: nowrap; +} + +.odoc-search .search-entry .entry-comment code { + display: inline; + white-space: nowrap; +} + +/* First level titles */ + +.odoc-toc>ul>li>a { + font-weight: 500; +} + +.odoc-toc li ul { + margin: 0px; + padding-top: 0.25em; +} + +.odoc-toc ul { + list-style-type: none; +} + +.odoc-toc ul li { + padding: 0.25em 0; +} + +.odoc-toc>ul>li { + margin-bottom: 0.3em; +} + +.odoc-toc ul li li { + border-left: 1px solid var(--toc-list-border); + margin-left: 5px; + padding-left: 12px; +} + +/* Tables */ + +.odoc-table { + margin: 1em; +} + +.odoc-table td, +.odoc-table th { + padding-left: 0.5em; + padding-right: 0.5em; + border: 1px solid black; +} + +.odoc-table th { + font-weight: bold; +} + +/* Mobile adjustements. */ + +@media only screen and (max-width: 110ex) { + body { + margin: 2em; + padding: 0; + } + + body.odoc { + display: block; + } + + .odoc-toc { + position: static; + width: auto; + min-width: unset; + max-width: unset; + border: none; + padding: 0.2em 1em; + border-radius: 5px; + margin-bottom: 2em; + } +} + +/* Print adjustements. */ + +@media print { + body { + color: black; + background: white; + } + + body nav:first-child { + visibility: hidden; + } +} + +/* Source code. */ + +.source_container { + display: flex; +} + +.source_line_column { + padding-right: 0.5em; + text-align: right; + background: #eee8d5; +} + +.source_line { + padding: 0 1em; +} + +.source_code { + flex-grow: 1; + background: #fdf6e3; + padding: 0 0.3em; + color: #657b83; +} + +/* Source directories */ + +.odoc-directory::before { + content: "📁"; + margin: 0.3em; + font-size: 1.3em; +} + +.odoc-file::before { + content: "📄"; + margin: 0.3em; + font-size: 1.3em; +} + +.odoc-folder-list { + list-style: none; +} + +/* Syntax highlighting (based on github-gist) */ + +.hljs { + display: block; + background: var(--code-background); + padding: 0.5em; + color: var(--color); + overflow-x: auto; +} + +.hljs-comment, +.hljs-meta { + color: #969896; +} + +.hljs-string, +.hljs-variable, +.hljs-template-variable, +.hljs-strong, +.hljs-emphasis, +.hljs-quote { + color: #df5000; +} + +.hljs-keyword, +.hljs-selector-tag { + color: #a71d5d; +} + +.hljs-type, +.hljs-class .hljs-title { + color: #458; + font-weight: 500; +} + +.hljs-literal, +.hljs-symbol, +.hljs-bullet, +.hljs-attribute { + color: #0086b3; +} + +.hljs-section, +.hljs-name { + color: #63a35c; +} + +.hljs-tag { + color: #333333; +} + +.hljs-attr, +.hljs-selector-id, +.hljs-selector-class, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #795da3; +} + +.hljs-addition { + color: #55a532; + background-color: #eaffea; +} + +.hljs-deletion { + color: #bd2c00; + background-color: #ffecec; +} + +.hljs-link { + text-decoration: underline; +} + +.VAL, +.TYPE, +.LET, +.REC, +.IN, +.OPEN, +.NONREC, +.MODULE, +.METHOD, +.LETOP, +.INHERIT, +.INCLUDE, +.FUNCTOR, +.EXTERNAL, +.CONSTRAINT, +.ASSERT, +.AND, +.END, +.CLASS, +.STRUCT, +.SIG { + color: #859900; + ; +} + +.WITH, +.WHILE, +.WHEN, +.VIRTUAL, +.TRY, +.TO, +.THEN, +.PRIVATE, +.OF, +.NEW, +.MUTABLE, +.MATCH, +.LAZY, +.IF, +.FUNCTION, +.FUN, +.FOR, +.EXCEPTION, +.ELSE, +.TO, +.DOWNTO, +.DO, +.DONE, +.BEGIN, +.AS { + color: #cb4b16; +} + +.TRUE, +.FALSE { + color: #b58900; +} + +.failwith, +.INT, +.SEMISEMI, +.LIDENT { + color: #2aa198; +} + +.STRING, +.CHAR, +.UIDENT { + color: #b58900; +} + +.DOCSTRING { + color: #268bd2; +} + +.COMMENT { + color: #93a1a1; +} + +/*--------------------------------------------------------------------------- + Copyright (c) 2016 The odoc contributors + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ---------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/docs/odoc.support/odoc_search.js b/docs/odoc.support/odoc_search.js new file mode 100644 index 00000000..0dc659d2 --- /dev/null +++ b/docs/odoc.support/odoc_search.js @@ -0,0 +1,66 @@ +/* The browsers interpretation of the CORS origin policy prevents to run + webworkers from javascript files fetched from the file:// protocol. This hack + is to workaround this restriction. */ +function createWebWorker() { + var searchs = search_urls.map((search_url) => { + let parts = document.location.href.split("/"); + parts[parts.length - 1] = search_url; + return '"' + parts.join("/") + '"'; + }); + blobContents = ["importScripts(" + searchs.join(",") + ");"]; + var blob = new Blob(blobContents, { type: "application/javascript" }); + var blobUrl = URL.createObjectURL(blob); + + var worker = new Worker(blobUrl); + URL.revokeObjectURL(blobUrl); + + return worker; +} + +var worker; +var waiting = 0; + +function wait() { + waiting = waiting + 1; + document.querySelector(".search-snake").classList.add("search-busy"); +} + +function stop_waiting() { + if (waiting > 0) waiting = waiting - 1; + else waiting = 0; + if (waiting == 0) { + document.querySelector(".search-snake").classList.remove("search-busy"); + } +} + +document.querySelector(".search-bar").addEventListener("focus", (ev) => { + if (typeof worker == "undefined") { + worker = createWebWorker(); + worker.onmessage = (e) => { + stop_waiting(); + let results = e.data; + let search_results = document.querySelector(".search-result"); + search_results.innerHTML = ""; + let f = (entry) => { + let search_result = document.createElement("a"); + search_result.classList.add("search-entry"); + search_result.href = base_url + entry.url; + search_result.innerHTML = entry.html; + search_results.appendChild(search_result); + }; + results.forEach(f); + let search_request = document.querySelector(".search-bar").value; + if (results.length == 0 && search_request != "") { + let no_result = document.createElement("div"); + no_result.classList.add("search-no-result"); + no_result.innerText = "No result..."; + search_results.appendChild(no_result); + } + }; + } +}); + +document.querySelector(".search-bar").addEventListener("input", (ev) => { + wait(); + worker.postMessage(ev.target.value); +}); diff --git a/docs/stdlib/CamlinternalFormat/index.html b/docs/stdlib/CamlinternalFormat/index.html new file mode 100644 index 00000000..819e280d --- /dev/null +++ b/docs/stdlib/CamlinternalFormat/index.html @@ -0,0 +1,53 @@ + +CamlinternalFormat (docs.stdlib.CamlinternalFormat)

Module CamlinternalFormat

val is_in_char_set : CamlinternalFormatBasics.char_set -> char -> bool
type mutable_char_set = bytes
val create_char_set : unit -> mutable_char_set
val add_in_char_set : mutable_char_set -> char -> unit
type ('a, 'b, 'c, 'd, 'e, 'f) param_format_ebb =
  1. | Param_format_EBB : ('x -> 'a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmt -> + ('a, 'b, 'c, 'd, 'e, 'f) + param_format_ebb
val param_format_of_ignored_format : + ('a, 'b, 'c, 'd, 'y, 'x) CamlinternalFormatBasics.ignored -> + ('x, 'b, 'c, 'y, 'e, 'f) CamlinternalFormatBasics.fmt -> + ('a, 'b, 'c, 'd, 'e, 'f) param_format_ebb
type ('b, 'c) acc_formatting_gen =
  1. | Acc_open_tag of ('b, 'c) acc
  2. | Acc_open_box of ('b, 'c) acc
and ('b, 'c) acc =
  1. | Acc_formatting_lit of ('b, 'c) acc * CamlinternalFormatBasics.formatting_lit
  2. | Acc_formatting_gen of ('b, 'c) acc * ('b, 'c) acc_formatting_gen
  3. | Acc_string_literal of ('b, 'c) acc * string
  4. | Acc_char_literal of ('b, 'c) acc * char
  5. | Acc_data_string of ('b, 'c) acc * string
  6. | Acc_data_char of ('b, 'c) acc * char
  7. | Acc_delay of ('b, 'c) acc * 'b -> 'c
  8. | Acc_flush of ('b, 'c) acc
  9. | Acc_invalid_arg of ('b, 'c) acc * string
  10. | End_of_acc
type ('a, 'b) heter_list =
  1. | Cons : 'c * ('a, 'b) heter_list -> ('c -> 'a, 'b) heter_list
  2. | Nil : ('b, 'b) heter_list
type ('b, 'c, 'e, 'f) fmt_ebb =
  1. | Fmt_EBB : ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmt -> ('b, + 'c, + 'e, + 'f) + fmt_ebb
val make_printf : + (('b, 'c) acc -> 'd) -> + ('b, 'c) acc -> + ('a, 'b, 'c, 'c, 'c, 'd) CamlinternalFormatBasics.fmt -> + 'a
val make_iprintf : + ('s -> 'f) -> + 's -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmt -> + 'a
val output_acc : out_channel -> (out_channel, unit) acc -> unit
val bufput_acc : Buffer.t -> (Buffer.t, unit) acc -> unit
val strput_acc : Buffer.t -> (unit, string) acc -> unit
val type_format : + ('x, 'b, 'c, 't, 'u, 'v) CamlinternalFormatBasics.fmt -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmtty -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmt
val fmt_ebb_of_string : + ?legacy_behavior:bool -> + string -> + ('b, 'c, 'e, 'f) fmt_ebb
val format_of_string_fmtty : + string -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmtty -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.format6
val format_of_string_format : + string -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.format6 -> + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.format6
val char_of_iconv : CamlinternalFormatBasics.int_conv -> char
val string_of_formatting_lit : + CamlinternalFormatBasics.formatting_lit -> + string
val string_of_fmtty : + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmtty -> + string
val string_of_fmt : + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.fmt -> + string
val open_box_of_string : string -> int * CamlinternalFormatBasics.block_type
val symm : + ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + CamlinternalFormatBasics.fmtty_rel -> + ('a2, 'b2, 'c2, 'd2, 'e2, 'f2, 'a1, 'b1, 'c1, 'd1, 'e1, 'f1) + CamlinternalFormatBasics.fmtty_rel
val trans : + ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + CamlinternalFormatBasics.fmtty_rel -> + ('a2, 'b2, 'c2, 'd2, 'e2, 'f2, 'a3, 'b3, 'c3, 'd3, 'e3, 'f3) + CamlinternalFormatBasics.fmtty_rel -> + ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a3, 'b3, 'c3, 'd3, 'e3, 'f3) + CamlinternalFormatBasics.fmtty_rel
val recast : + ('a1, 'b1, 'c1, 'd1, 'e1, 'f1) CamlinternalFormatBasics.fmt -> + ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + CamlinternalFormatBasics.fmtty_rel -> + ('a2, 'b2, 'c2, 'd2, 'e2, 'f2) CamlinternalFormatBasics.fmt
diff --git a/docs/stdlib/CamlinternalFormatBasics/index.html b/docs/stdlib/CamlinternalFormatBasics/index.html new file mode 100644 index 00000000..5d134d65 --- /dev/null +++ b/docs/stdlib/CamlinternalFormatBasics/index.html @@ -0,0 +1,308 @@ + +CamlinternalFormatBasics (docs.stdlib.CamlinternalFormatBasics)

Module CamlinternalFormatBasics

type padty =
  1. | Left
  2. | Right
  3. | Zeros
type int_conv =
  1. | Int_d
  2. | Int_pd
  3. | Int_sd
  4. | Int_i
  5. | Int_pi
  6. | Int_si
  7. | Int_x
  8. | Int_Cx
  9. | Int_X
  10. | Int_CX
  11. | Int_o
  12. | Int_Co
  13. | Int_u
  14. | Int_Cd
  15. | Int_Ci
  16. | Int_Cu
type float_flag_conv =
  1. | Float_flag_
  2. | Float_flag_p
  3. | Float_flag_s
type float_kind_conv =
  1. | Float_f
  2. | Float_e
  3. | Float_E
  4. | Float_g
  5. | Float_G
  6. | Float_F
  7. | Float_h
  8. | Float_H
  9. | Float_CF
type float_conv = float_flag_conv * float_kind_conv
type char_set = string
type counter =
  1. | Line_counter
  2. | Char_counter
  3. | Token_counter
type ('a, 'b) padding =
  1. | No_padding : ('a, 'a) padding
  2. | Lit_padding : padty * int -> ('a, 'a) padding
  3. | Arg_padding : padty -> (int -> 'a, 'a) padding
type pad_option = int option
type ('a, 'b) precision =
  1. | No_precision : ('a, 'a) precision
  2. | Lit_precision : int -> ('a, 'a) precision
  3. | Arg_precision : (int -> 'a, 'a) precision
type prec_option = int option
type ('a, 'b, 'c) custom_arity =
  1. | Custom_zero : ('a, string, 'a) custom_arity
  2. | Custom_succ : ('a, 'b, 'c) custom_arity -> ('a, 'x -> 'b, 'x -> 'c) + custom_arity
type block_type =
  1. | Pp_hbox
  2. | Pp_vbox
  3. | Pp_hvbox
  4. | Pp_hovbox
  5. | Pp_box
  6. | Pp_fits
type formatting_lit =
  1. | Close_box
  2. | Close_tag
  3. | Break of string * int * int
  4. | FFlush
  5. | Force_newline
  6. | Flush_newline
  7. | Magic_size of string * int
  8. | Escaped_at
  9. | Escaped_percent
  10. | Scan_indic of char
type ('a, 'b, 'c, 'd, 'e, 'f) formatting_gen =
  1. | Open_tag : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) + formatting_gen
  2. | Open_box : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> ('a, 'b, 'c, 'd, 'e, 'f) + formatting_gen
and ('a, 'b, 'c, 'd, 'e, 'f) fmtty = + ('a, 'b, 'c, 'd, 'e, 'f, 'a, 'b, 'c, 'd, 'e, 'f) fmtty_rel
and ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) fmtty_rel =
  1. | Char_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (char -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + char -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  2. | String_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (string -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + string -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  3. | Int_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) fmtty_rel -> + (int -> 'a1, 'b1, 'c1, 'd1, 'e1, 'f1, int -> 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel
  4. | Int32_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (int32 -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + int32 -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  5. | Nativeint_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (nativeint -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + nativeint -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  6. | Int64_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (int64 -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + int64 -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  7. | Float_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (float -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + float -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  8. | Bool_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (bool -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + bool -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  9. | Format_arg_ty : ('g, 'h, 'i, 'j, 'k, 'l) fmtty + * ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) fmtty_rel -> + (('g, 'h, 'i, 'j, 'k, 'l) format6 -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + ('g, 'h, 'i, 'j, 'k, 'l) format6 -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  10. | Format_subst_ty : ('g, 'h, 'i, 'j, 'k, 'l, 'g1, 'b1, 'c1, 'j1, 'd1, 'a1) + fmtty_rel + * ('g, 'h, 'i, 'j, 'k, 'l, 'g2, 'b2, 'c2, 'j2, 'd2, 'a2) fmtty_rel + * ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) fmtty_rel -> + (('g, 'h, 'i, 'j, 'k, 'l) format6 -> + 'g1, + 'b1, + 'c1, + 'j1, + 'e1, + 'f1, + ('g, 'h, 'i, 'j, 'k, 'l) format6 -> + 'g2, + 'b2, + 'c2, + 'j2, + 'e2, + 'f2) + fmtty_rel
  11. | Alpha_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (('b1 -> 'x -> 'c1) -> + 'x -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + ('b2 -> 'x -> 'c2) -> + 'x -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  12. | Theta_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> (('b1 -> 'c1) -> + 'a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + ('b2 -> 'c2) -> + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel
  13. | Any_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) fmtty_rel -> + ('x -> 'a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'x -> 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel
  14. | Reader_ty : ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) + fmtty_rel -> ('x -> + 'a1, + 'b1, + 'c1, + ('b1 -> 'x) -> + 'd1, + 'e1, + 'f1, + 'x -> + 'a2, + 'b2, + 'c2, + ('b2 -> 'x) -> + 'd2, + 'e2, + 'f2) + fmtty_rel
  15. | Ignored_reader_ty : ('a1, + 'b1, + 'c1, + 'd1, + 'e1, + 'f1, + 'a2, + 'b2, + 'c2, + 'd2, + 'e2, + 'f2) + fmtty_rel -> ('a1, + 'b1, + 'c1, + ('b1 -> 'x) -> + 'd1, + 'e1, + 'f1, + 'a2, + 'b2, + 'c2, + ('b2 -> 'x) -> + 'd2, + 'e2, + 'f2) + fmtty_rel
  16. | End_of_fmtty : ('f1, 'b1, 'c1, 'd1, 'd1, 'f1, 'f2, 'b2, 'c2, 'd2, 'd2, 'f2) + fmtty_rel
and ('a, 'b, 'c, 'd, 'e, 'f) fmt =
  1. | Char : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (char -> 'a, 'b, 'c, 'd, 'e, 'f) fmt
  2. | Caml_char : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (char -> 'a, 'b, 'c, 'd, 'e, 'f) + fmt
  3. | String : ('x, string -> 'a) padding + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  4. | Caml_string : ('x, string -> 'a) padding + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  5. | Int : int_conv + * ('x, 'y) padding + * ('y, int -> 'a) precision + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  6. | Int32 : int_conv + * ('x, 'y) padding + * ('y, int32 -> 'a) precision + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  7. | Nativeint : int_conv + * ('x, 'y) padding + * ('y, nativeint -> 'a) precision + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  8. | Int64 : int_conv + * ('x, 'y) padding + * ('y, int64 -> 'a) precision + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  9. | Float : float_conv + * ('x, 'y) padding + * ('y, float -> 'a) precision + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  10. | Bool : ('x, bool -> 'a) padding + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x, 'b, 'c, 'd, 'e, 'f) fmt
  11. | Flush : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt
  12. | String_literal : string + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt
  13. | Char_literal : char + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt
  14. | Format_arg : pad_option + * ('g, 'h, 'i, 'j, 'k, 'l) fmtty + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (('g, 'h, 'i, 'j, 'k, 'l) format6 -> + 'a, + 'b, + 'c, + 'd, + 'e, + 'f) + fmt
  15. | Format_subst : pad_option + * ('g, 'h, 'i, 'j, 'k, 'l, 'g2, 'b, 'c, 'j2, 'd, 'a) fmtty_rel + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (('g, 'h, 'i, 'j, 'k, 'l) format6 -> + 'g2, + 'b, + 'c, + 'j2, + 'e, + 'f) + fmt
  16. | Alpha : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (('b -> 'x -> 'c) -> + 'x -> + 'a, + 'b, + 'c, + 'd, + 'e, + 'f) + fmt
  17. | Theta : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (('b -> 'c) -> 'a, 'b, 'c, 'd, 'e, 'f) + fmt
  18. | Formatting_lit : formatting_lit + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt
  19. | Formatting_gen : ('a1, 'b, 'c, 'd1, 'e1, 'f1) formatting_gen + * ('f1, 'b, 'c, 'e1, 'e2, 'f2) fmt -> ('a1, 'b, 'c, 'd1, 'e2, 'f2) fmt
  20. | Reader : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('x -> + 'a, + 'b, + 'c, + ('b -> 'x) -> + 'd, + 'e, + 'f) + fmt
  21. | Scan_char_set : pad_option + * char_set + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (string -> 'a, 'b, 'c, 'd, 'e, 'f) fmt
  22. | Scan_get_counter : counter + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (int -> 'a, 'b, 'c, 'd, 'e, 'f) fmt
  23. | Scan_next_char : ('a, 'b, 'c, 'd, 'e, 'f) fmt -> (char -> + 'a, + 'b, + 'c, + 'd, + 'e, + 'f) + fmt
  24. | Ignored_param : ('a, 'b, 'c, 'd, 'y, 'x) ignored + * ('x, 'b, 'c, 'y, 'e, 'f) fmt -> ('a, 'b, 'c, 'd, 'e, 'f) fmt
  25. | Custom : ('a, 'x, 'y) custom_arity + * (unit -> + 'x) + * ('a, 'b, 'c, 'd, 'e, 'f) fmt -> ('y, 'b, 'c, 'd, 'e, 'f) fmt
  26. | End_of_format : ('f, 'b, 'c, 'e, 'e, 'f) fmt

List of format elements.

and ('a, 'b, 'c, 'd, 'e, 'f) ignored =
  1. | Ignored_char : ('a, 'b, 'c, 'd, 'd, 'a) ignored
  2. | Ignored_caml_char : ('a, 'b, 'c, 'd, 'd, 'a) ignored
  3. | Ignored_string : pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  4. | Ignored_caml_string : pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  5. | Ignored_int : int_conv * pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  6. | Ignored_int32 : int_conv * pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  7. | Ignored_nativeint : int_conv * pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  8. | Ignored_int64 : int_conv * pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  9. | Ignored_float : pad_option * prec_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  10. | Ignored_bool : pad_option -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  11. | Ignored_format_arg : pad_option + * ('g, 'h, 'i, 'j, 'k, 'l) fmtty -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  12. | Ignored_format_subst : pad_option + * ('a, 'b, 'c, 'd, 'e, 'f) fmtty -> ('a, 'b, 'c, 'd, 'e, 'f) ignored
  13. | Ignored_reader : ('a, 'b, 'c, ('b -> 'x) -> 'd, 'd, 'a) ignored
  14. | Ignored_scan_char_set : pad_option + * char_set -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  15. | Ignored_scan_get_counter : counter -> ('a, 'b, 'c, 'd, 'd, 'a) ignored
  16. | Ignored_scan_next_char : ('a, 'b, 'c, 'd, 'd, 'a) ignored
and ('a, 'b, 'c, 'd, 'e, 'f) format6 =
  1. | Format of ('a, 'b, 'c, 'd, 'e, 'f) fmt * string
val concat_fmtty : + ('g1, 'b1, 'c1, 'j1, 'd1, 'a1, 'g2, 'b2, 'c2, 'j2, 'd2, 'a2) fmtty_rel -> + ('a1, 'b1, 'c1, 'd1, 'e1, 'f1, 'a2, 'b2, 'c2, 'd2, 'e2, 'f2) fmtty_rel -> + ('g1, 'b1, 'c1, 'j1, 'e1, 'f1, 'g2, 'b2, 'c2, 'j2, 'e2, 'f2) fmtty_rel
val erase_rel : + ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l) fmtty_rel -> + ('a, 'b, 'c, 'd, 'e, 'f) fmtty
val concat_fmt : + ('a, 'b, 'c, 'd, 'e, 'f) fmt -> + ('f, 'b, 'c, 'e, 'g, 'h) fmt -> + ('a, 'b, 'c, 'd, 'g, 'h) fmt
diff --git a/docs/stdlib/CamlinternalLazy/index.html b/docs/stdlib/CamlinternalLazy/index.html new file mode 100644 index 00000000..48cf69cf --- /dev/null +++ b/docs/stdlib/CamlinternalLazy/index.html @@ -0,0 +1,2 @@ + +CamlinternalLazy (docs.stdlib.CamlinternalLazy)

Module CamlinternalLazy

Run-time support for lazy values. All functions in this module are for system use only, not for the casual user.

type 'a t = 'a lazy_t
exception Undefined
val force_lazy_block : 'a lazy_t -> 'a
val force_gen : only_val:bool -> 'a lazy_t -> 'a
diff --git a/docs/stdlib/CamlinternalMod/index.html b/docs/stdlib/CamlinternalMod/index.html new file mode 100644 index 00000000..8c420068 --- /dev/null +++ b/docs/stdlib/CamlinternalMod/index.html @@ -0,0 +1,2 @@ + +CamlinternalMod (docs.stdlib.CamlinternalMod)

Module CamlinternalMod

Run-time support for recursive modules. All functions in this module are for system use only, not for the casual user.

type shape =
  1. | Function
  2. | Lazy
  3. | Class
  4. | Module of shape array
  5. | Value of Obj.t
val init_mod : (string * int * int) -> shape -> Obj.t
val update_mod : shape -> Obj.t -> Obj.t -> unit
diff --git a/docs/stdlib/CamlinternalOO/index.html b/docs/stdlib/CamlinternalOO/index.html new file mode 100644 index 00000000..c6fe9daf --- /dev/null +++ b/docs/stdlib/CamlinternalOO/index.html @@ -0,0 +1,18 @@ + +CamlinternalOO (docs.stdlib.CamlinternalOO)

Module CamlinternalOO

Run-time support for objects and classes. All functions in this module are for system use only, not for the casual user.

Classes

type tag
type label
type table
type meth
type t
type obj
type closure
val public_method_label : string -> tag
val new_method : table -> label
val new_variable : table -> string -> int
val new_methods_variables : + table -> + string array -> + string array -> + label array
val get_variable : table -> string -> int
val get_variables : table -> string array -> int array
val get_method_label : table -> string -> label
val get_method_labels : table -> string array -> label array
val get_method : table -> label -> meth
val set_method : table -> label -> meth -> unit
val set_methods : table -> label array -> unit
val narrow : table -> string array -> string array -> string array -> unit
val widen : table -> unit
val add_initializer : table -> (obj -> unit) -> unit
val dummy_table : table
val create_table : string array -> table
val init_class : table -> unit
val inherits : + table -> + string array -> + string array -> + string array -> + (t * (table -> obj -> Obj.t) * t * obj) -> + bool -> + Obj.t array
val make_class : + string array -> + (table -> Obj.t -> t) -> + t * (table -> Obj.t -> t) * (Obj.t -> t) * Obj.t
type init_table
val make_class_store : string array -> (table -> t) -> init_table -> unit
val dummy_class : + (string * int * int) -> + t * (table -> Obj.t -> t) * (Obj.t -> t) * Obj.t

Objects

val copy : < .. > as 'a -> 'a
val create_object : table -> obj
val create_object_opt : obj -> table -> obj
val run_initializers : obj -> table -> unit
val run_initializers_opt : obj -> obj -> table -> obj
val create_object_and_run_initializers : obj -> table -> obj
val send : obj -> tag -> t
val sendcache : obj -> tag -> t -> int -> t
val sendself : obj -> label -> t
val get_public_method : obj -> tag -> closure

Table cache

type tables
val lookup_tables : tables -> closure array -> tables

Builtins to reduce code size

type impl =
  1. | GetConst
  2. | GetVar
  3. | GetEnv
  4. | GetMeth
  5. | SetVar
  6. | AppConst
  7. | AppVar
  8. | AppEnv
  9. | AppMeth
  10. | AppConstConst
  11. | AppConstVar
  12. | AppConstEnv
  13. | AppConstMeth
  14. | AppVarConst
  15. | AppEnvConst
  16. | AppMethConst
  17. | MethAppConst
  18. | MethAppVar
  19. | MethAppEnv
  20. | MethAppMeth
  21. | SendConst
  22. | SendVar
  23. | SendEnv
  24. | SendMeth
  25. | Closure of closure

Parameters

type params = {
  1. mutable compact_table : bool;
  2. mutable copy_parent : bool;
  3. mutable clean_when_copying : bool;
  4. mutable retry_count : int;
  5. mutable bucket_small_size : int;
}
val params : params

Statistics

type stats = {
  1. classes : int;
  2. methods : int;
  3. inst_vars : int;
}
val stats : unit -> stats
diff --git a/docs/stdlib/Std_exit/index.html b/docs/stdlib/Std_exit/index.html new file mode 100644 index 00000000..6180cdc7 --- /dev/null +++ b/docs/stdlib/Std_exit/index.html @@ -0,0 +1,2 @@ + +Std_exit (docs.stdlib.Std_exit)

Module Std_exit

diff --git a/docs/stdlib/Stdlib/Arg/index.html b/docs/stdlib/Stdlib/Arg/index.html new file mode 100644 index 00000000..ccfa92b8 --- /dev/null +++ b/docs/stdlib/Stdlib/Arg/index.html @@ -0,0 +1,38 @@ + +Arg (docs.stdlib.Stdlib.Arg)

Module Stdlib.Arg

Parsing of command line arguments.

This module provides a general mechanism for extracting options and arguments from the command line to the program. For example:

let usage_msg = "append [-verbose] <file1> [<file2>] ... -o <output>"
+let verbose = ref false
+let input_files = ref []
+let output_file = ref ""
+
+let anon_fun filename =
+  input_files := filename::!input_files
+
+let speclist =
+  [("-verbose", Arg.Set verbose, "Output debug information");
+   ("-o", Arg.Set_string output_file, "Set output file name")]
+
+let () =
+  Arg.parse speclist anon_fun usage_msg;
+  (* Main functionality here *)

Syntax of command lines: A keyword is a character string starting with a -. An option is a keyword alone or followed by an argument. The types of keywords are: Unit, Bool, Set, Clear, String, Set_string, Int, Set_int, Float, Set_float, Tuple, Symbol, Rest, Rest_all and Expand.

Unit, Set and Clear keywords take no argument.

A Rest or Rest_all keyword takes the remainder of the command line as arguments. (More explanations below.)

Every other keyword takes the following word on the command line as argument. For compatibility with GNU getopt_long, keyword=arg is also allowed. Arguments not preceded by a keyword are called anonymous arguments.

Examples (cmd is assumed to be the command name):

  • cmd -flag (a unit option)
  • cmd -int 1 (an int option with argument 1)
  • cmd -string foobar (a string option with argument "foobar")
  • cmd -float 12.34 (a float option with argument 12.34)
  • cmd a b c (three anonymous arguments: "a", "b", and "c")
  • cmd a b -- c d (two anonymous arguments and a rest option with two arguments)

Rest takes a function that is called repeatedly for each remaining command line argument. Rest_all takes a function that is called once, with the list of all remaining arguments.

Note that if no arguments follow a Rest keyword then the function is not called at all whereas the function for a Rest_all keyword is called with an empty list.

  • alert unsynchronized_access The Arg module relies on a mutable global state, parsing functions should only be called from a single domain.
type spec =
  1. | Unit of unit -> unit
    (*

    Call the function with unit argument

    *)
  2. | Bool of bool -> unit
    (*

    Call the function with a bool argument

    *)
  3. | Set of bool ref
    (*

    Set the reference to true

    *)
  4. | Clear of bool ref
    (*

    Set the reference to false

    *)
  5. | String of string -> unit
    (*

    Call the function with a string argument

    *)
  6. | Set_string of string ref
    (*

    Set the reference to the string argument

    *)
  7. | Int of int -> unit
    (*

    Call the function with an int argument

    *)
  8. | Set_int of int ref
    (*

    Set the reference to the int argument

    *)
  9. | Float of float -> unit
    (*

    Call the function with a float argument

    *)
  10. | Set_float of float ref
    (*

    Set the reference to the float argument

    *)
  11. | Tuple of spec list
    (*

    Take several arguments according to the spec list

    *)
  12. | Symbol of string list * string -> unit
    (*

    Take one of the symbols as argument and call the function with the symbol

    *)
  13. | Rest of string -> unit
    (*

    Stop interpreting keywords and call the function with each remaining argument

    *)
  14. | Rest_all of string list -> unit
    (*

    Stop interpreting keywords and call the function with all remaining arguments

    *)
  15. | Expand of string -> string array
    (*

    If the remaining arguments to process are of the form ["-foo"; "arg"] @ rest where "foo" is registered as Expand f, then the arguments f "arg" @ rest are processed. Only allowed in parse_and_expand_argv_dynamic.

    *)

The concrete type describing the behavior associated with a keyword.

type key = string
type doc = string
type usage_msg = string
type anon_fun = string -> unit
val parse : (key * spec * doc) list -> anon_fun -> usage_msg -> unit

Arg.parse speclist anon_fun usage_msg parses the command line. speclist is a list of triples (key, spec, doc). key is the option keyword, it must start with a '-' character. spec gives the option type and the function to call when this option is found on the command line. doc is a one-line description of this option. anon_fun is called on anonymous arguments. The functions in spec and anon_fun are called in the same order as their arguments appear on the command line.

If an error occurs, Arg.parse exits the program, after printing to standard error an error message as follows:

  • The reason for the error: unknown option, invalid or missing argument, etc.
  • usage_msg
  • The list of options, each followed by the corresponding doc string. Beware: options that have an empty doc string will not be included in the list.

For the user to be able to specify anonymous arguments starting with a -, include for example ("-", String anon_fun, doc) in speclist.

By default, parse recognizes two unit options, -help and --help, which will print to standard output usage_msg and the list of options, and exit the program. You can override this behaviour by specifying your own -help and --help options in speclist.

val parse_dynamic : + (key * spec * doc) list ref -> + anon_fun -> + usage_msg -> + unit

Same as Arg.parse, except that the speclist argument is a reference and may be updated during the parsing. A typical use for this feature is to parse command lines of the form:

  • command subcommand options where the list of options depends on the value of the subcommand argument.
  • since 4.01
val parse_argv : + ?current:int ref -> + string array -> + (key * spec * doc) list -> + anon_fun -> + usage_msg -> + unit

Arg.parse_argv ~current args speclist anon_fun usage_msg parses the array args as if it were the command line. It uses and updates the value of ~current (if given), or Arg.current. You must set it before calling parse_argv. The initial value of current is the index of the program name (argument 0) in the array. If an error occurs, Arg.parse_argv raises Arg.Bad with the error message as argument. If option -help or --help is given, Arg.parse_argv raises Arg.Help with the help message as argument.

val parse_argv_dynamic : + ?current:int ref -> + string array -> + (key * spec * doc) list ref -> + anon_fun -> + string -> + unit

Same as Arg.parse_argv, except that the speclist argument is a reference and may be updated during the parsing. See Arg.parse_dynamic.

  • since 4.01
val parse_and_expand_argv_dynamic : + int ref -> + string array ref -> + (key * spec * doc) list ref -> + anon_fun -> + string -> + unit

Same as Arg.parse_argv_dynamic, except that the argv argument is a reference and may be updated during the parsing of Expand arguments. See Arg.parse_argv_dynamic.

  • since 4.05
val parse_expand : (key * spec * doc) list -> anon_fun -> usage_msg -> unit

Same as Arg.parse, except that the Expand arguments are allowed and the current reference is not updated.

  • since 4.05
exception Help of string

Raised by Arg.parse_argv when the user asks for help.

exception Bad of string

Functions in spec or anon_fun can raise Arg.Bad with an error message to reject invalid arguments. Arg.Bad is also raised by Arg.parse_argv in case of an error.

val usage : (key * spec * doc) list -> usage_msg -> unit

Arg.usage speclist usage_msg prints to standard error an error message that includes the list of valid options. This is the same message that Arg.parse prints in case of error. speclist and usage_msg are the same as for Arg.parse.

val usage_string : (key * spec * doc) list -> usage_msg -> string

Returns the message that would have been printed by Arg.usage, if provided with the same parameters.

val align : ?limit:int -> (key * spec * doc) list -> (key * spec * doc) list

Align the documentation strings by inserting spaces at the first alignment separator (tab or, if tab is not found, space), according to the length of the keyword. Use a alignment separator as the first character in a doc string if you want to align the whole string. The doc strings corresponding to Symbol arguments are aligned on the next line.

  • parameter limit

    options with keyword and message longer than limit will not be used to compute the alignment.

val current : int ref

Position (in Sys.argv) of the argument being processed. You can change this value, e.g. to force Arg.parse to skip some arguments. Arg.parse uses the initial value of Arg.current as the index of argument 0 (the program name) and starts parsing arguments at the next element.

val read_arg : string -> string array

Arg.read_arg file reads newline-terminated command line arguments from file file.

  • since 4.05
val read_arg0 : string -> string array

Identical to Arg.read_arg but assumes null character terminated command line arguments.

  • since 4.05
val write_arg : string -> string array -> unit

Arg.write_arg file args writes the arguments args newline-terminated into the file file. If any of the arguments in args contains a newline, use Arg.write_arg0 instead.

  • since 4.05
val write_arg0 : string -> string array -> unit

Identical to Arg.write_arg but uses the null character for terminator instead of newline.

  • since 4.05
diff --git a/docs/stdlib/Stdlib/Array/index.html b/docs/stdlib/Stdlib/Array/index.html new file mode 100644 index 00000000..98f916a2 --- /dev/null +++ b/docs/stdlib/Stdlib/Array/index.html @@ -0,0 +1,19 @@ + +Array (docs.stdlib.Stdlib.Array)

Module Stdlib.Array

Array operations.

The labeled version of this module can be used as described in the StdLabels module.

type 'a t = 'a array

An alias for the type of arrays.

val length : 'a array -> int

Return the length (number of elements) of the given array.

val get : 'a array -> int -> 'a

get a n returns the element number n of array a. The first element has number 0. The last element has number length a - 1. You can also write a.(n) instead of get a n.

val set : 'a array -> int -> 'a -> unit

set a n x modifies array a in place, replacing element number n with x. You can also write a.(n) <- x instead of set a n x.

val make : int -> 'a -> 'a array

make n x returns a fresh array of length n, initialized with x. All the elements of this new array are initially physically equal to x (in the sense of the == predicate). Consequently, if x is mutable, it is shared among all elements of the array, and modifying x through one of the array entries will modify all other entries at the same time.

  • raises Invalid_argument

    if n < 0 or n > Sys.max_array_length. If the value of x is a floating-point number, then the maximum size is only Sys.max_array_length / 2.

val create_float : int -> float array

create_float n returns a fresh float array of length n, with uninitialized data.

  • since 4.03
val init : int -> (int -> 'a) -> 'a array

init n f returns a fresh array of length n, with element number i initialized to the result of f i. In other terms, init n f tabulates the results of f applied in order to the integers 0 to n-1.

  • raises Invalid_argument

    if n < 0 or n > Sys.max_array_length. If the return type of f is float, then the maximum size is only Sys.max_array_length / 2.

val make_matrix : int -> int -> 'a -> 'a array array

make_matrix dimx dimy e returns a two-dimensional array (an array of arrays) with first dimension dimx and second dimension dimy. All the elements of this new matrix are initially physically equal to e. The element (x,y) of a matrix m is accessed with the notation m.(x).(y).

  • raises Invalid_argument

    if dimx or dimy is negative or greater than Sys.max_array_length. If the value of e is a floating-point number, then the maximum size is only Sys.max_array_length / 2.

val append : 'a array -> 'a array -> 'a array

append v1 v2 returns a fresh array containing the concatenation of the arrays v1 and v2.

val concat : 'a array list -> 'a array

Same as append, but concatenates a list of arrays.

val sub : 'a array -> int -> int -> 'a array

sub a pos len returns a fresh array of length len, containing the elements number pos to pos + len - 1 of array a.

  • raises Invalid_argument

    if pos and len do not designate a valid subarray of a; that is, if pos < 0, or len < 0, or pos + len > length a.

val copy : 'a array -> 'a array

copy a returns a copy of a, that is, a fresh array containing the same elements as a.

val fill : 'a array -> int -> int -> 'a -> unit

fill a pos len x modifies the array a in place, storing x in elements number pos to pos + len - 1.

val blit : 'a array -> int -> 'a array -> int -> int -> unit

blit src src_pos dst dst_pos len copies len elements from array src, starting at element number src_pos, to array dst, starting at element number dst_pos. It works correctly even if src and dst are the same array, and the source and destination chunks overlap.

  • raises Invalid_argument

    if src_pos and len do not designate a valid subarray of src, or if dst_pos and len do not designate a valid subarray of dst.

val to_list : 'a array -> 'a list

to_list a returns the list of all the elements of a.

val of_list : 'a list -> 'a array

of_list l returns a fresh array containing the elements of l.

  • raises Invalid_argument

    if the length of l is greater than Sys.max_array_length.

Iterators

val iter : ('a -> unit) -> 'a array -> unit

iter f a applies function f in turn to all the elements of a. It is equivalent to f a.(0); f a.(1); ...; f a.(length a - 1); ().

val iteri : (int -> 'a -> unit) -> 'a array -> unit

Same as iter, but the function is applied to the index of the element as first argument, and the element itself as second argument.

val map : ('a -> 'b) -> 'a array -> 'b array

map f a applies function f to all the elements of a, and builds an array with the results returned by f: [| f a.(0); f a.(1); ...; f a.(length a - 1) |].

val map_inplace : ('a -> 'a) -> 'a array -> unit

map_inplace f a applies function f to all elements of a, and updates their values in place.

  • since 5.1
val mapi : (int -> 'a -> 'b) -> 'a array -> 'b array

Same as map, but the function is applied to the index of the element as first argument, and the element itself as second argument.

val mapi_inplace : (int -> 'a -> 'a) -> 'a array -> unit

Same as map_inplace, but the function is applied to the index of the element as first argument, and the element itself as second argument.

  • since 5.1
val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a array -> 'acc

fold_left f init a computes f (... (f (f init a.(0)) a.(1)) ...) a.(n-1), where n is the length of the array a.

val fold_left_map : + ('acc -> 'a -> 'acc * 'b) -> + 'acc -> + 'a array -> + 'acc * 'b array

fold_left_map is a combination of fold_left and map that threads an accumulator through calls to f.

  • since 4.13
val fold_right : ('a -> 'acc -> 'acc) -> 'a array -> 'acc -> 'acc

fold_right f a init computes f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...)), where n is the length of the array a.

Iterators on two arrays

val iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit

iter2 f a b applies function f to all the elements of a and b.

  • since 4.03 (4.05 in ArrayLabels)
val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array

map2 f a b applies function f to all the elements of a and b, and builds an array with the results returned by f: [| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|].

  • since 4.03 (4.05 in ArrayLabels)

Array scanning

val for_all : ('a -> bool) -> 'a array -> bool

for_all f [|a1; ...; an|] checks if all elements of the array satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an).

  • since 4.03
val exists : ('a -> bool) -> 'a array -> bool

exists f [|a1; ...; an|] checks if at least one element of the array satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an).

  • since 4.03
val for_all2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool

Same as for_all, but for a two-argument predicate.

  • since 4.11
val exists2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool

Same as exists, but for a two-argument predicate.

  • since 4.11
val mem : 'a -> 'a array -> bool

mem a set is true if and only if a is structurally equal to an element of l (i.e. there is an x in l such that compare a x = 0).

  • since 4.03
val memq : 'a -> 'a array -> bool

Same as mem, but uses physical equality instead of structural equality to compare list elements.

  • since 4.03
val find_opt : ('a -> bool) -> 'a array -> 'a option

find_opt f a returns the first element of the array a that satisfies the predicate f, or None if there is no value that satisfies f in the array a.

  • since 4.13
val find_index : ('a -> bool) -> 'a array -> int option

find_index f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

  • since 5.1
val find_map : ('a -> 'b option) -> 'a array -> 'b option

find_map f a applies f to the elements of a in order, and returns the first result of the form Some v, or None if none exist.

  • since 4.13
val find_mapi : (int -> 'a -> 'b option) -> 'a array -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 5.1

Arrays of pairs

val split : ('a * 'b) array -> 'a array * 'b array

split [|(a1,b1); ...; (an,bn)|] is ([|a1; ...; an|], [|b1; ...; bn|]).

  • since 4.13
val combine : 'a array -> 'b array -> ('a * 'b) array

combine [|a1; ...; an|] [|b1; ...; bn|] is [|(a1,b1); ...; (an,bn)|]. Raise Invalid_argument if the two arrays have different lengths.

  • since 4.13

Sorting

val sort : ('a -> 'a -> int) -> 'a array -> unit

Sort an array in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, Stdlib.compare is a suitable comparison function. After calling sort, the array is sorted in place in increasing order. sort is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses Heap Sort. It runs in constant stack space.

Specification of the comparison function: Let a be the array and cmp the comparison function. The following must be true for all x, y, z in a :

  • cmp x y > 0 if and only if cmp y x < 0
  • if cmp x y >= 0 and cmp y z >= 0 then cmp x z >= 0

When sort returns, a contains the same elements as before, reordered in such a way that for all i and j valid indices of a :

  • cmp a.(i) a.(j) >= 0 if and only if i >= j
val stable_sort : ('a -> 'a -> int) -> 'a array -> unit

Same as sort, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary array of length n/2, where n is the length of the array. It is usually faster than the current implementation of sort.

val fast_sort : ('a -> 'a -> int) -> 'a array -> unit

Same as sort or stable_sort, whichever is faster on typical input.

Arrays and Sequences

val to_seq : 'a array -> 'a Seq.t

Iterate on the array, in increasing order. Modifications of the array during iteration will be reflected in the sequence.

  • since 4.07
val to_seqi : 'a array -> (int * 'a) Seq.t

Iterate on the array, in increasing order, yielding indices along elements. Modifications of the array during iteration will be reflected in the sequence.

  • since 4.07
val of_seq : 'a Seq.t -> 'a array

Create an array from the generator

  • since 4.07

Arrays and concurrency safety

Care must be taken when concurrently accessing arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.

For example, consider the following program:

let size = 100_000_000
+let a = Array.make size 1
+let d1 = Domain.spawn (fun () ->
+   Array.iteri (fun i x -> a.(i) <- x + 1) a
+)
+let d2 = Domain.spawn (fun () ->
+  Array.iteri (fun i x -> a.(i) <- 2 * x + 1) a
+)
+let () = Domain.join d1; Domain.join d2

After executing this code, each field of the array a is either 2, 3, 4 or 5. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location (with a few exceptions for float arrays).

Float arrays

Float arrays have two supplementary caveats in the presence of data races.

First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.

For instance, at the end of

let zeros = Array.make size 0.
+let max_floats = Array.make size Float.max_float
+let res = Array.copy zeros
+let d1 = Domain.spawn (fun () -> Array.blit zeros 0 res 0 size)
+let d2 = Domain.spawn (fun () -> Array.blit max_floats 0 res 0 size)
+let () = Domain.join d1; Domain.join d2

the res array might contain values that are neither 0. nor max_float.

Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.

diff --git a/docs/stdlib/Stdlib/ArrayLabels/index.html b/docs/stdlib/Stdlib/ArrayLabels/index.html new file mode 100644 index 00000000..34ad48d0 --- /dev/null +++ b/docs/stdlib/Stdlib/ArrayLabels/index.html @@ -0,0 +1,25 @@ + +ArrayLabels (docs.stdlib.Stdlib.ArrayLabels)

Module Stdlib.ArrayLabels

Array operations.

The labeled version of this module can be used as described in the StdLabels module.

type 'a t = 'a array

An alias for the type of arrays.

val length : 'a array -> int

Return the length (number of elements) of the given array.

val get : 'a array -> int -> 'a

get a n returns the element number n of array a. The first element has number 0. The last element has number length a - 1. You can also write a.(n) instead of get a n.

val set : 'a array -> int -> 'a -> unit

set a n x modifies array a in place, replacing element number n with x. You can also write a.(n) <- x instead of set a n x.

val make : int -> 'a -> 'a array

make n x returns a fresh array of length n, initialized with x. All the elements of this new array are initially physically equal to x (in the sense of the == predicate). Consequently, if x is mutable, it is shared among all elements of the array, and modifying x through one of the array entries will modify all other entries at the same time.

  • raises Invalid_argument

    if n < 0 or n > Sys.max_array_length. If the value of x is a floating-point number, then the maximum size is only Sys.max_array_length / 2.

val create_float : int -> float array

create_float n returns a fresh float array of length n, with uninitialized data.

  • since 4.03
val init : int -> f:(int -> 'a) -> 'a array

init n ~f returns a fresh array of length n, with element number i initialized to the result of f i. In other terms, init n ~f tabulates the results of f applied in order to the integers 0 to n-1.

  • raises Invalid_argument

    if n < 0 or n > Sys.max_array_length. If the return type of f is float, then the maximum size is only Sys.max_array_length / 2.

val make_matrix : dimx:int -> dimy:int -> 'a -> 'a array array

make_matrix ~dimx ~dimy e returns a two-dimensional array (an array of arrays) with first dimension dimx and second dimension dimy. All the elements of this new matrix are initially physically equal to e. The element (x,y) of a matrix m is accessed with the notation m.(x).(y).

  • raises Invalid_argument

    if dimx or dimy is negative or greater than Sys.max_array_length. If the value of e is a floating-point number, then the maximum size is only Sys.max_array_length / 2.

val append : 'a array -> 'a array -> 'a array

append v1 v2 returns a fresh array containing the concatenation of the arrays v1 and v2.

val concat : 'a array list -> 'a array

Same as append, but concatenates a list of arrays.

val sub : 'a array -> pos:int -> len:int -> 'a array

sub a ~pos ~len returns a fresh array of length len, containing the elements number pos to pos + len - 1 of array a.

  • raises Invalid_argument

    if pos and len do not designate a valid subarray of a; that is, if pos < 0, or len < 0, or pos + len > length a.

val copy : 'a array -> 'a array

copy a returns a copy of a, that is, a fresh array containing the same elements as a.

val fill : 'a array -> pos:int -> len:int -> 'a -> unit

fill a ~pos ~len x modifies the array a in place, storing x in elements number pos to pos + len - 1.

val blit : + src:'a array -> + src_pos:int -> + dst:'a array -> + dst_pos:int -> + len:int -> + unit

blit ~src ~src_pos ~dst ~dst_pos ~len copies len elements from array src, starting at element number src_pos, to array dst, starting at element number dst_pos. It works correctly even if src and dst are the same array, and the source and destination chunks overlap.

  • raises Invalid_argument

    if src_pos and len do not designate a valid subarray of src, or if dst_pos and len do not designate a valid subarray of dst.

val to_list : 'a array -> 'a list

to_list a returns the list of all the elements of a.

val of_list : 'a list -> 'a array

of_list l returns a fresh array containing the elements of l.

  • raises Invalid_argument

    if the length of l is greater than Sys.max_array_length.

Iterators

val iter : f:('a -> unit) -> 'a array -> unit

iter ~f a applies function f in turn to all the elements of a. It is equivalent to f a.(0); f a.(1); ...; f a.(length a - 1); ().

val iteri : f:(int -> 'a -> unit) -> 'a array -> unit

Same as iter, but the function is applied to the index of the element as first argument, and the element itself as second argument.

val map : f:('a -> 'b) -> 'a array -> 'b array

map ~f a applies function f to all the elements of a, and builds an array with the results returned by f: [| f a.(0); f a.(1); ...; f a.(length a - 1) |].

val map_inplace : f:('a -> 'a) -> 'a array -> unit

map_inplace ~f a applies function f to all elements of a, and updates their values in place.

  • since 5.1
val mapi : f:(int -> 'a -> 'b) -> 'a array -> 'b array

Same as map, but the function is applied to the index of the element as first argument, and the element itself as second argument.

val mapi_inplace : f:(int -> 'a -> 'a) -> 'a array -> unit

Same as map_inplace, but the function is applied to the index of the element as first argument, and the element itself as second argument.

  • since 5.1
val fold_left : f:('acc -> 'a -> 'acc) -> init:'acc -> 'a array -> 'acc

fold_left ~f ~init a computes f (... (f (f init a.(0)) a.(1)) ...) a.(n-1), where n is the length of the array a.

val fold_left_map : + f:('acc -> 'a -> 'acc * 'b) -> + init:'acc -> + 'a array -> + 'acc * 'b array

fold_left_map is a combination of fold_left and map that threads an accumulator through calls to f.

  • since 4.13
val fold_right : f:('a -> 'acc -> 'acc) -> 'a array -> init:'acc -> 'acc

fold_right ~f a ~init computes f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...)), where n is the length of the array a.

Iterators on two arrays

val iter2 : f:('a -> 'b -> unit) -> 'a array -> 'b array -> unit

iter2 ~f a b applies function f to all the elements of a and b.

  • since 4.05
val map2 : f:('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array

map2 ~f a b applies function f to all the elements of a and b, and builds an array with the results returned by f: [| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|].

  • since 4.05

Array scanning

val for_all : f:('a -> bool) -> 'a array -> bool

for_all ~f [|a1; ...; an|] checks if all elements of the array satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an).

  • since 4.03
val exists : f:('a -> bool) -> 'a array -> bool

exists ~f [|a1; ...; an|] checks if at least one element of the array satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an).

  • since 4.03
val for_all2 : f:('a -> 'b -> bool) -> 'a array -> 'b array -> bool

Same as for_all, but for a two-argument predicate.

  • since 4.11
val exists2 : f:('a -> 'b -> bool) -> 'a array -> 'b array -> bool

Same as exists, but for a two-argument predicate.

  • since 4.11
val mem : 'a -> set:'a array -> bool

mem a ~set is true if and only if a is structurally equal to an element of l (i.e. there is an x in l such that compare a x = 0).

  • since 4.03
val memq : 'a -> set:'a array -> bool

Same as mem, but uses physical equality instead of structural equality to compare list elements.

  • since 4.03
val find_opt : f:('a -> bool) -> 'a array -> 'a option

find_opt ~f a returns the first element of the array a that satisfies the predicate f, or None if there is no value that satisfies f in the array a.

  • since 4.13
val find_index : f:('a -> bool) -> 'a array -> int option

find_index ~f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

  • since 5.1
val find_map : f:('a -> 'b option) -> 'a array -> 'b option

find_map ~f a applies f to the elements of a in order, and returns the first result of the form Some v, or None if none exist.

  • since 4.13
val find_mapi : f:(int -> 'a -> 'b option) -> 'a array -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 5.1

Arrays of pairs

val split : ('a * 'b) array -> 'a array * 'b array

split [|(a1,b1); ...; (an,bn)|] is ([|a1; ...; an|], [|b1; ...; bn|]).

  • since 4.13
val combine : 'a array -> 'b array -> ('a * 'b) array

combine [|a1; ...; an|] [|b1; ...; bn|] is [|(a1,b1); ...; (an,bn)|]. Raise Invalid_argument if the two arrays have different lengths.

  • since 4.13

Sorting

val sort : cmp:('a -> 'a -> int) -> 'a array -> unit

Sort an array in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, Stdlib.compare is a suitable comparison function. After calling sort, the array is sorted in place in increasing order. sort is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses Heap Sort. It runs in constant stack space.

Specification of the comparison function: Let a be the array and cmp the comparison function. The following must be true for all x, y, z in a :

  • cmp x y > 0 if and only if cmp y x < 0
  • if cmp x y >= 0 and cmp y z >= 0 then cmp x z >= 0

When sort returns, a contains the same elements as before, reordered in such a way that for all i and j valid indices of a :

  • cmp a.(i) a.(j) >= 0 if and only if i >= j
val stable_sort : cmp:('a -> 'a -> int) -> 'a array -> unit

Same as sort, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary array of length n/2, where n is the length of the array. It is usually faster than the current implementation of sort.

val fast_sort : cmp:('a -> 'a -> int) -> 'a array -> unit

Same as sort or stable_sort, whichever is faster on typical input.

Arrays and Sequences

val to_seq : 'a array -> 'a Seq.t

Iterate on the array, in increasing order. Modifications of the array during iteration will be reflected in the sequence.

  • since 4.07
val to_seqi : 'a array -> (int * 'a) Seq.t

Iterate on the array, in increasing order, yielding indices along elements. Modifications of the array during iteration will be reflected in the sequence.

  • since 4.07
val of_seq : 'a Seq.t -> 'a array

Create an array from the generator

  • since 4.07

Arrays and concurrency safety

Care must be taken when concurrently accessing arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.

For example, consider the following program:

let size = 100_000_000
+let a = ArrayLabels.make size 1
+let d1 = Domain.spawn (fun () ->
+   ArrayLabels.iteri ~f:(fun i x -> a.(i) <- x + 1) a
+)
+let d2 = Domain.spawn (fun () ->
+  ArrayLabels.iteri ~f:(fun i x -> a.(i) <- 2 * x + 1) a
+)
+let () = Domain.join d1; Domain.join d2

After executing this code, each field of the array a is either 2, 3, 4 or 5. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location (with a few exceptions for float arrays).

Float arrays

Float arrays have two supplementary caveats in the presence of data races.

First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.

For instance, at the end of

let zeros = Array.make size 0.
+let max_floats = Array.make size Float.max_float
+let res = Array.copy zeros
+let d1 = Domain.spawn (fun () -> Array.blit zeros 0 res 0 size)
+let d2 = Domain.spawn (fun () -> Array.blit max_floats 0 res 0 size)
+let () = Domain.join d1; Domain.join d2

the res array might contain values that are neither 0. nor max_float.

Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.

diff --git a/docs/stdlib/Stdlib/Atomic/index.html b/docs/stdlib/Stdlib/Atomic/index.html new file mode 100644 index 00000000..c2c5e659 --- /dev/null +++ b/docs/stdlib/Stdlib/Atomic/index.html @@ -0,0 +1,64 @@ + +Atomic (docs.stdlib.Stdlib.Atomic)

Module Stdlib.Atomic

Atomic references.

See the examples below. See 'Memory model: The hard bits' chapter in the manual.

  • since 4.12
type !'a t

An atomic (mutable) reference to a value of type 'a.

val make : 'a -> 'a t

Create an atomic reference.

val get : 'a t -> 'a

Get the current value of the atomic reference.

val set : 'a t -> 'a -> unit

Set a new value for the atomic reference.

val exchange : 'a t -> 'a -> 'a

Set a new value for the atomic reference, and return the current value.

val compare_and_set : 'a t -> 'a -> 'a -> bool

compare_and_set r seen v sets the new value of r to v only if its current value is physically equal to seen -- the comparison and the set occur atomically. Returns true if the comparison succeeded (so the set happened) and false otherwise.

val fetch_and_add : int t -> int -> int

fetch_and_add r n atomically increments the value of r by n, and returns the current value (before the increment).

val incr : int t -> unit

incr r atomically increments the value of r by 1.

val decr : int t -> unit

decr r atomically decrements the value of r by 1.

Examples

Basic Thread Coordination

A basic use case is to have global counters that are updated in a thread-safe way, for example to keep some sorts of metrics over IOs performed by the program. Another basic use case is to coordinate the termination of threads in a given program, for example when one thread finds an answer, or when the program is shut down by the user.

Here, for example, we're going to try to find a number whose hash satisfies a basic property. To do that, we'll run multiple threads which will try random numbers until they find one that works.

Of course the output below is a sample run and will change every time the program is run.

(* use for termination *)
+let stop_all_threads = Atomic.make false
+
+(* total number of individual attempts to find a number *)
+let num_attempts = Atomic.make 0
+
+(* find a number that satisfies [p], by... trying random numbers
+   until one fits. *)
+let find_number_where (p:int -> bool) =
+  let rand = Random.State.make_self_init() in
+  while not (Atomic.get stop_all_threads) do
+
+    let n = Random.State.full_int rand max_int in
+    ignore (Atomic.fetch_and_add num_attempts 1 : int);
+
+    if p (Hashtbl.hash n) then (
+      Printf.printf "found %d (hash=%d)\n%!" n (Hashtbl.hash n);
+      Atomic.set stop_all_threads true; (* signal all threads to stop *)
+    )
+  done;;
+
+
+(* run multiple domains to search for a [n] where [hash n <= 100] *)
+let () =
+  let criterion n = n <= 100 in
+  let threads =
+    Array.init 8
+      (fun _ -> Domain.spawn (fun () -> find_number_where criterion))
+  in
+  Array.iter Domain.join threads;
+  Printf.printf "total number of attempts: %d\n%!"
+    (Atomic.get num_attempts) ;;
+
+- : unit = ()
+found 1651745641680046833 (hash=33)
+total number of attempts: 30230350

Treiber Stack

Another example is a basic Treiber stack (a thread-safe stack) that can be safely shared between threads.

Note how both push and pop are recursive, because they attempt to swap the new stack (with one more, or one fewer, element) with the old stack. This is optimistic concurrency: each iteration of, say, push stack x gets the old stack l, and hopes that by the time it tries to replace l with x::l, nobody else has had time to modify the list. If the compare_and_set fails it means we were too optimistic, and must try again.

type 'a stack = 'a list Atomic.t
+
+let rec push (stack: _ stack) elt : unit =
+  let cur = Atomic.get stack in
+  let success = Atomic.compare_and_set stack cur (elt :: cur) in
+  if not success then
+    push stack elt
+
+let rec pop (stack: _ stack) : _ option =
+  let cur = Atomic.get stack in
+  match cur with
+  | [] -> None
+  | x :: tail ->
+    let success = Atomic.compare_and_set stack cur tail in
+    if success then Some x
+    else pop stack
+
+# let st = Atomic.make []
+# push st 1
+- : unit = ()
+# push st 2
+- : unit = ()
+# pop st
+- : int option = Some 2
+# pop st
+- : int option = Some 1
+# pop st
+- : int option = None
diff --git a/docs/stdlib/Stdlib/Bigarray/Array0/index.html b/docs/stdlib/Stdlib/Bigarray/Array0/index.html new file mode 100644 index 00000000..103c1ce6 --- /dev/null +++ b/docs/stdlib/Stdlib/Bigarray/Array0/index.html @@ -0,0 +1,2 @@ + +Array0 (docs.stdlib.Stdlib.Bigarray.Array0)

Module Bigarray.Array0

Zero-dimensional arrays. The Array0 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of zero-dimensional arrays that only contain a single scalar value. Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking.

  • since 4.05
type (!'a, !'b, !'c) t

The type of zero-dimensional Bigarrays whose elements have OCaml type 'a, representation kind 'b, and memory layout 'c.

val create : ('a, 'b) kind -> 'c layout -> ('a, 'b, 'c) t

Array0.create kind layout returns a new Bigarray of zero dimension. kind and layout determine the array element kind and the array layout as described for Genarray.create.

val init : ('a, 'b) kind -> 'c layout -> 'a -> ('a, 'b, 'c) t

Array0.init kind layout v behaves like Array0.create kind layout except that the element is additionally initialized to the value v.

  • since 4.12
val kind : ('a, 'b, 'c) t -> ('a, 'b) kind

Return the kind of the given Bigarray.

val layout : ('a, 'b, 'c) t -> 'c layout

Return the layout of the given Bigarray.

val change_layout : ('a, 'b, 'c) t -> 'd layout -> ('a, 'b, 'd) t

Array0.change_layout a layout returns a Bigarray with the specified layout, sharing the data with a. No copying of elements is involved: the new array and the original array share the same storage space.

  • since 4.06
val size_in_bytes : ('a, 'b, 'c) t -> int

size_in_bytes a is a's kind_size_in_bytes.

val get : ('a, 'b, 'c) t -> 'a

Array0.get a returns the only element in a.

val set : ('a, 'b, 'c) t -> 'a -> unit

Array0.set a x v stores the value v in a.

val blit : ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit

Copy the first Bigarray to the second Bigarray. See Genarray.blit for more details.

val fill : ('a, 'b, 'c) t -> 'a -> unit

Fill the given Bigarray with the given value. See Genarray.fill for more details.

val of_value : ('a, 'b) kind -> 'c layout -> 'a -> ('a, 'b, 'c) t

Build a zero-dimensional Bigarray initialized from the given value.

diff --git a/docs/stdlib/Stdlib/Bigarray/Array1/index.html b/docs/stdlib/Stdlib/Bigarray/Array1/index.html new file mode 100644 index 00000000..3ac651fc --- /dev/null +++ b/docs/stdlib/Stdlib/Bigarray/Array1/index.html @@ -0,0 +1,2 @@ + +Array1 (docs.stdlib.Stdlib.Bigarray.Array1)

Module Bigarray.Array1

One-dimensional arrays. The Array1 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of one-dimensional arrays. (The Array2 and Array3 structures below provide operations specialized for two- and three-dimensional arrays.) Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking.

type (!'a, !'b, !'c) t

The type of one-dimensional Bigarrays whose elements have OCaml type 'a, representation kind 'b, and memory layout 'c.

val create : ('a, 'b) kind -> 'c layout -> int -> ('a, 'b, 'c) t

Array1.create kind layout dim returns a new Bigarray of one dimension, whose size is dim. kind and layout determine the array element kind and the array layout as described for Genarray.create.

val init : ('a, 'b) kind -> 'c layout -> int -> (int -> 'a) -> ('a, 'b, 'c) t

Array1.init kind layout dim f returns a new Bigarray b of one dimension, whose size is dim. kind and layout determine the array element kind and the array layout as described for Genarray.create.

Each element Array1.get b i of the array is initialized to the result of f i.

In other words, Array1.init kind layout dimensions f tabulates the results of f applied to the indices of a new Bigarray whose layout is described by kind, layout and dim.

  • since 4.12
val dim : ('a, 'b, 'c) t -> int

Return the size (dimension) of the given one-dimensional Bigarray.

val kind : ('a, 'b, 'c) t -> ('a, 'b) kind

Return the kind of the given Bigarray.

val layout : ('a, 'b, 'c) t -> 'c layout

Return the layout of the given Bigarray.

val change_layout : ('a, 'b, 'c) t -> 'd layout -> ('a, 'b, 'd) t

Array1.change_layout a layout returns a Bigarray with the specified layout, sharing the data with a (and hence having the same dimension as a). No copying of elements is involved: the new array and the original array share the same storage space.

  • since 4.06
val size_in_bytes : ('a, 'b, 'c) t -> int

size_in_bytes a is the number of elements in a multiplied by a's kind_size_in_bytes.

  • since 4.03
val get : ('a, 'b, 'c) t -> int -> 'a

Array1.get a x, or alternatively a.{x}, returns the element of a at index x. x must be greater or equal than 0 and strictly less than Array1.dim a if a has C layout. If a has Fortran layout, x must be greater or equal than 1 and less or equal than Array1.dim a. Otherwise, Invalid_argument is raised.

val set : ('a, 'b, 'c) t -> int -> 'a -> unit

Array1.set a x v, also written a.{x} <- v, stores the value v at index x in a. x must be inside the bounds of a as described in Bigarray.Array1.get; otherwise, Invalid_argument is raised.

val sub : ('a, 'b, 'c) t -> int -> int -> ('a, 'b, 'c) t

Extract a sub-array of the given one-dimensional Bigarray. See Genarray.sub_left for more details.

val slice : ('a, 'b, 'c) t -> int -> ('a, 'b, 'c) Array0.t

Extract a scalar (zero-dimensional slice) of the given one-dimensional Bigarray. The integer parameter is the index of the scalar to extract. See Bigarray.Genarray.slice_left and Bigarray.Genarray.slice_right for more details.

  • since 4.05
val blit : ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit

Copy the first Bigarray to the second Bigarray. See Genarray.blit for more details.

val fill : ('a, 'b, 'c) t -> 'a -> unit

Fill the given Bigarray with the given value. See Genarray.fill for more details.

val of_array : ('a, 'b) kind -> 'c layout -> 'a array -> ('a, 'b, 'c) t

Build a one-dimensional Bigarray initialized from the given array.

val unsafe_get : ('a, 'b, 'c) t -> int -> 'a

Like Bigarray.Array1.get, but bounds checking is not always performed. Use with caution and only when the program logic guarantees that the access is within bounds.

val unsafe_set : ('a, 'b, 'c) t -> int -> 'a -> unit

Like Bigarray.Array1.set, but bounds checking is not always performed. Use with caution and only when the program logic guarantees that the access is within bounds.

diff --git a/docs/stdlib/Stdlib/Bigarray/Array2/index.html b/docs/stdlib/Stdlib/Bigarray/Array2/index.html new file mode 100644 index 00000000..c44c92b3 --- /dev/null +++ b/docs/stdlib/Stdlib/Bigarray/Array2/index.html @@ -0,0 +1,15 @@ + +Array2 (docs.stdlib.Stdlib.Bigarray.Array2)

Module Bigarray.Array2

Two-dimensional arrays. The Array2 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of two-dimensional arrays.

type (!'a, !'b, !'c) t

The type of two-dimensional Bigarrays whose elements have OCaml type 'a, representation kind 'b, and memory layout 'c.

val create : ('a, 'b) kind -> 'c layout -> int -> int -> ('a, 'b, 'c) t

Array2.create kind layout dim1 dim2 returns a new Bigarray of two dimensions, whose size is dim1 in the first dimension and dim2 in the second dimension. kind and layout determine the array element kind and the array layout as described for Bigarray.Genarray.create.

val init : + ('a, 'b) kind -> + 'c layout -> + int -> + int -> + (int -> int -> 'a) -> + ('a, 'b, 'c) t

Array2.init kind layout dim1 dim2 f returns a new Bigarray b of two dimensions, whose size is dim2 in the first dimension and dim2 in the second dimension. kind and layout determine the array element kind and the array layout as described for Bigarray.Genarray.create.

Each element Array2.get b i j of the array is initialized to the result of f i j.

In other words, Array2.init kind layout dim1 dim2 f tabulates the results of f applied to the indices of a new Bigarray whose layout is described by kind, layout, dim1 and dim2.

  • since 4.12
val dim1 : ('a, 'b, 'c) t -> int

Return the first dimension of the given two-dimensional Bigarray.

val dim2 : ('a, 'b, 'c) t -> int

Return the second dimension of the given two-dimensional Bigarray.

val kind : ('a, 'b, 'c) t -> ('a, 'b) kind

Return the kind of the given Bigarray.

val layout : ('a, 'b, 'c) t -> 'c layout

Return the layout of the given Bigarray.

val change_layout : ('a, 'b, 'c) t -> 'd layout -> ('a, 'b, 'd) t

Array2.change_layout a layout returns a Bigarray with the specified layout, sharing the data with a (and hence having the same dimensions as a). No copying of elements is involved: the new array and the original array share the same storage space. The dimensions are reversed, such that get v [| a; b |] in C layout becomes get v [| b+1; a+1 |] in Fortran layout.

  • since 4.06
val size_in_bytes : ('a, 'b, 'c) t -> int

size_in_bytes a is the number of elements in a multiplied by a's kind_size_in_bytes.

  • since 4.03
val get : ('a, 'b, 'c) t -> int -> int -> 'a

Array2.get a x y, also written a.{x,y}, returns the element of a at coordinates (x, y). x and y must be within the bounds of a, as described for Bigarray.Genarray.get; otherwise, Invalid_argument is raised.

val set : ('a, 'b, 'c) t -> int -> int -> 'a -> unit

Array2.set a x y v, or alternatively a.{x,y} <- v, stores the value v at coordinates (x, y) in a. x and y must be within the bounds of a, as described for Bigarray.Genarray.set; otherwise, Invalid_argument is raised.

val sub_left : ('a, 'b, c_layout) t -> int -> int -> ('a, 'b, c_layout) t

Extract a two-dimensional sub-array of the given two-dimensional Bigarray by restricting the first dimension. See Bigarray.Genarray.sub_left for more details. Array2.sub_left applies only to arrays with C layout.

val sub_right : + ('a, 'b, fortran_layout) t -> + int -> + int -> + ('a, 'b, fortran_layout) t

Extract a two-dimensional sub-array of the given two-dimensional Bigarray by restricting the second dimension. See Bigarray.Genarray.sub_right for more details. Array2.sub_right applies only to arrays with Fortran layout.

val slice_left : ('a, 'b, c_layout) t -> int -> ('a, 'b, c_layout) Array1.t

Extract a row (one-dimensional slice) of the given two-dimensional Bigarray. The integer parameter is the index of the row to extract. See Bigarray.Genarray.slice_left for more details. Array2.slice_left applies only to arrays with C layout.

val slice_right : + ('a, 'b, fortran_layout) t -> + int -> + ('a, 'b, fortran_layout) Array1.t

Extract a column (one-dimensional slice) of the given two-dimensional Bigarray. The integer parameter is the index of the column to extract. See Bigarray.Genarray.slice_right for more details. Array2.slice_right applies only to arrays with Fortran layout.

val blit : ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit

Copy the first Bigarray to the second Bigarray. See Bigarray.Genarray.blit for more details.

val fill : ('a, 'b, 'c) t -> 'a -> unit

Fill the given Bigarray with the given value. See Bigarray.Genarray.fill for more details.

val of_array : ('a, 'b) kind -> 'c layout -> 'a array array -> ('a, 'b, 'c) t

Build a two-dimensional Bigarray initialized from the given array of arrays.

val unsafe_get : ('a, 'b, 'c) t -> int -> int -> 'a

Like Bigarray.Array2.get, but bounds checking is not always performed.

val unsafe_set : ('a, 'b, 'c) t -> int -> int -> 'a -> unit

Like Bigarray.Array2.set, but bounds checking is not always performed.

diff --git a/docs/stdlib/Stdlib/Bigarray/Array3/index.html b/docs/stdlib/Stdlib/Bigarray/Array3/index.html new file mode 100644 index 00000000..1adea30c --- /dev/null +++ b/docs/stdlib/Stdlib/Bigarray/Array3/index.html @@ -0,0 +1,28 @@ + +Array3 (docs.stdlib.Stdlib.Bigarray.Array3)

Module Bigarray.Array3

Three-dimensional arrays. The Array3 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of three-dimensional arrays.

type (!'a, !'b, !'c) t

The type of three-dimensional Bigarrays whose elements have OCaml type 'a, representation kind 'b, and memory layout 'c.

val create : ('a, 'b) kind -> 'c layout -> int -> int -> int -> ('a, 'b, 'c) t

Array3.create kind layout dim1 dim2 dim3 returns a new Bigarray of three dimensions, whose size is dim1 in the first dimension, dim2 in the second dimension, and dim3 in the third. kind and layout determine the array element kind and the array layout as described for Bigarray.Genarray.create.

val init : + ('a, 'b) kind -> + 'c layout -> + int -> + int -> + int -> + (int -> int -> int -> 'a) -> + ('a, 'b, 'c) t

Array3.init kind layout dim1 dim2 dim3 f returns a new Bigarray b of three dimensions, whose size is dim1 in the first dimension, dim2 in the second dimension, and dim3 in the third. kind and layout determine the array element kind and the array layout as described for Bigarray.Genarray.create.

Each element Array3.get b i j k of the array is initialized to the result of f i j k.

In other words, Array3.init kind layout dim1 dim2 dim3 f tabulates the results of f applied to the indices of a new Bigarray whose layout is described by kind, layout, dim1, dim2 and dim3.

  • since 4.12
val dim1 : ('a, 'b, 'c) t -> int

Return the first dimension of the given three-dimensional Bigarray.

val dim2 : ('a, 'b, 'c) t -> int

Return the second dimension of the given three-dimensional Bigarray.

val dim3 : ('a, 'b, 'c) t -> int

Return the third dimension of the given three-dimensional Bigarray.

val kind : ('a, 'b, 'c) t -> ('a, 'b) kind

Return the kind of the given Bigarray.

val layout : ('a, 'b, 'c) t -> 'c layout

Return the layout of the given Bigarray.

val change_layout : ('a, 'b, 'c) t -> 'd layout -> ('a, 'b, 'd) t

Array3.change_layout a layout returns a Bigarray with the specified layout, sharing the data with a (and hence having the same dimensions as a). No copying of elements is involved: the new array and the original array share the same storage space. The dimensions are reversed, such that get v [| a; b; c |] in C layout becomes get v [| c+1; b+1; a+1 |] in Fortran layout.

  • since 4.06
val size_in_bytes : ('a, 'b, 'c) t -> int

size_in_bytes a is the number of elements in a multiplied by a's kind_size_in_bytes.

  • since 4.03
val get : ('a, 'b, 'c) t -> int -> int -> int -> 'a

Array3.get a x y z, also written a.{x,y,z}, returns the element of a at coordinates (x, y, z). x, y and z must be within the bounds of a, as described for Bigarray.Genarray.get; otherwise, Invalid_argument is raised.

val set : ('a, 'b, 'c) t -> int -> int -> int -> 'a -> unit

Array3.set a x y v, or alternatively a.{x,y,z} <- v, stores the value v at coordinates (x, y, z) in a. x, y and z must be within the bounds of a, as described for Bigarray.Genarray.set; otherwise, Invalid_argument is raised.

val sub_left : ('a, 'b, c_layout) t -> int -> int -> ('a, 'b, c_layout) t

Extract a three-dimensional sub-array of the given three-dimensional Bigarray by restricting the first dimension. See Bigarray.Genarray.sub_left for more details. Array3.sub_left applies only to arrays with C layout.

val sub_right : + ('a, 'b, fortran_layout) t -> + int -> + int -> + ('a, 'b, fortran_layout) t

Extract a three-dimensional sub-array of the given three-dimensional Bigarray by restricting the second dimension. See Bigarray.Genarray.sub_right for more details. Array3.sub_right applies only to arrays with Fortran layout.

val slice_left_1 : + ('a, 'b, c_layout) t -> + int -> + int -> + ('a, 'b, c_layout) Array1.t

Extract a one-dimensional slice of the given three-dimensional Bigarray by fixing the first two coordinates. The integer parameters are the coordinates of the slice to extract. See Bigarray.Genarray.slice_left for more details. Array3.slice_left_1 applies only to arrays with C layout.

val slice_right_1 : + ('a, 'b, fortran_layout) t -> + int -> + int -> + ('a, 'b, fortran_layout) Array1.t

Extract a one-dimensional slice of the given three-dimensional Bigarray by fixing the last two coordinates. The integer parameters are the coordinates of the slice to extract. See Bigarray.Genarray.slice_right for more details. Array3.slice_right_1 applies only to arrays with Fortran layout.

val slice_left_2 : ('a, 'b, c_layout) t -> int -> ('a, 'b, c_layout) Array2.t

Extract a two-dimensional slice of the given three-dimensional Bigarray by fixing the first coordinate. The integer parameter is the first coordinate of the slice to extract. See Bigarray.Genarray.slice_left for more details. Array3.slice_left_2 applies only to arrays with C layout.

val slice_right_2 : + ('a, 'b, fortran_layout) t -> + int -> + ('a, 'b, fortran_layout) Array2.t

Extract a two-dimensional slice of the given three-dimensional Bigarray by fixing the last coordinate. The integer parameter is the coordinate of the slice to extract. See Bigarray.Genarray.slice_right for more details. Array3.slice_right_2 applies only to arrays with Fortran layout.

val blit : ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit

Copy the first Bigarray to the second Bigarray. See Bigarray.Genarray.blit for more details.

val fill : ('a, 'b, 'c) t -> 'a -> unit

Fill the given Bigarray with the given value. See Bigarray.Genarray.fill for more details.

val of_array : + ('a, 'b) kind -> + 'c layout -> + 'a array array array -> + ('a, 'b, 'c) t

Build a three-dimensional Bigarray initialized from the given array of arrays of arrays.

val unsafe_get : ('a, 'b, 'c) t -> int -> int -> int -> 'a

Like Bigarray.Array3.get, but bounds checking is not always performed.

val unsafe_set : ('a, 'b, 'c) t -> int -> int -> int -> 'a -> unit

Like Bigarray.Array3.set, but bounds checking is not always performed.

diff --git a/docs/stdlib/Stdlib/Bigarray/Genarray/index.html b/docs/stdlib/Stdlib/Bigarray/Genarray/index.html new file mode 100644 index 00000000..71f7f453 --- /dev/null +++ b/docs/stdlib/Stdlib/Bigarray/Genarray/index.html @@ -0,0 +1,15 @@ + +Genarray (docs.stdlib.Stdlib.Bigarray.Genarray)

Module Bigarray.Genarray

type (!'a, !'b, !'c) t

The type Genarray.t is the type of Bigarrays with variable numbers of dimensions. Any number of dimensions between 0 and 16 is supported.

The three type parameters to Genarray.t identify the array element kind and layout, as follows:

  • the first parameter, 'a, is the OCaml type for accessing array elements (float, int, int32, int64, nativeint);
  • the second parameter, 'b, is the actual kind of array elements (float32_elt, float64_elt, int8_signed_elt, int8_unsigned_elt, etc);
  • the third parameter, 'c, identifies the array layout (c_layout or fortran_layout).

For instance, (float, float32_elt, fortran_layout) Genarray.t is the type of generic Bigarrays containing 32-bit floats in Fortran layout; reads and writes in this array use the OCaml type float.

val create : ('a, 'b) kind -> 'c layout -> int array -> ('a, 'b, 'c) t

Genarray.create kind layout dimensions returns a new Bigarray whose element kind is determined by the parameter kind (one of float32, float64, int8_signed, etc) and whose layout is determined by the parameter layout (one of c_layout or fortran_layout). The dimensions parameter is an array of integers that indicate the size of the Bigarray in each dimension. The length of dimensions determines the number of dimensions of the Bigarray.

For instance, Genarray.create int32 c_layout [|4;6;8|] returns a fresh Bigarray of 32-bit integers, in C layout, having three dimensions, the three dimensions being 4, 6 and 8 respectively.

Bigarrays returned by Genarray.create are not initialized: the initial values of array elements is unspecified.

Genarray.create raises Invalid_argument if the number of dimensions is not in the range 0 to 16 inclusive, or if one of the dimensions is negative.

val init : + ('a, 'b) kind -> + 'c layout -> + int array -> + (int array -> 'a) -> + ('a, 'b, 'c) t

Genarray.init kind layout dimensions f returns a new Bigarray b whose element kind is determined by the parameter kind (one of float32, float64, int8_signed, etc) and whose layout is determined by the parameter layout (one of c_layout or fortran_layout). The dimensions parameter is an array of integers that indicate the size of the Bigarray in each dimension. The length of dimensions determines the number of dimensions of the Bigarray.

Each element Genarray.get b i is initialized to the result of f i. In other words, Genarray.init kind layout dimensions f tabulates the results of f applied to the indices of a new Bigarray whose layout is described by kind, layout and dimensions. The index array i may be shared and mutated between calls to f.

For instance, Genarray.init int c_layout [|2; 1; 3|] + (Array.fold_left (+) 0) returns a fresh Bigarray of integers, in C layout, having three dimensions (2, 1, 3, respectively), with the element values 0, 1, 2, 1, 2, 3.

Genarray.init raises Invalid_argument if the number of dimensions is not in the range 0 to 16 inclusive, or if one of the dimensions is negative.

  • since 4.12
val num_dims : ('a, 'b, 'c) t -> int

Return the number of dimensions of the given Bigarray.

val dims : ('a, 'b, 'c) t -> int array

Genarray.dims a returns all dimensions of the Bigarray a, as an array of integers of length Genarray.num_dims a.

val nth_dim : ('a, 'b, 'c) t -> int -> int

Genarray.nth_dim a n returns the n-th dimension of the Bigarray a. The first dimension corresponds to n = 0; the second dimension corresponds to n = 1; the last dimension, to n = Genarray.num_dims a - 1.

  • raises Invalid_argument

    if n is less than 0 or greater or equal than Genarray.num_dims a.

val kind : ('a, 'b, 'c) t -> ('a, 'b) kind

Return the kind of the given Bigarray.

val layout : ('a, 'b, 'c) t -> 'c layout

Return the layout of the given Bigarray.

val change_layout : ('a, 'b, 'c) t -> 'd layout -> ('a, 'b, 'd) t

Genarray.change_layout a layout returns a Bigarray with the specified layout, sharing the data with a (and hence having the same dimensions as a). No copying of elements is involved: the new array and the original array share the same storage space. The dimensions are reversed, such that get v [| a; b |] in C layout becomes get v [| b+1; a+1 |] in Fortran layout.

  • since 4.04
val size_in_bytes : ('a, 'b, 'c) t -> int

size_in_bytes a is the number of elements in a multiplied by a's kind_size_in_bytes.

  • since 4.03
val get : ('a, 'b, 'c) t -> int array -> 'a

Read an element of a generic Bigarray. Genarray.get a [|i1; ...; iN|] returns the element of a whose coordinates are i1 in the first dimension, i2 in the second dimension, ..., iN in the N-th dimension.

If a has C layout, the coordinates must be greater or equal than 0 and strictly less than the corresponding dimensions of a. If a has Fortran layout, the coordinates must be greater or equal than 1 and less or equal than the corresponding dimensions of a.

If N > 3, alternate syntax is provided: you can write a.{i1, i2, ..., iN} instead of Genarray.get a [|i1; ...; iN|]. (The syntax a.{...} with one, two or three coordinates is reserved for accessing one-, two- and three-dimensional arrays as described below.)

  • raises Invalid_argument

    if the array a does not have exactly N dimensions, or if the coordinates are outside the array bounds.

val set : ('a, 'b, 'c) t -> int array -> 'a -> unit

Assign an element of a generic Bigarray. Genarray.set a [|i1; ...; iN|] v stores the value v in the element of a whose coordinates are i1 in the first dimension, i2 in the second dimension, ..., iN in the N-th dimension.

The array a must have exactly N dimensions, and all coordinates must lie inside the array bounds, as described for Genarray.get; otherwise, Invalid_argument is raised.

If N > 3, alternate syntax is provided: you can write a.{i1, i2, ..., iN} <- v instead of Genarray.set a [|i1; ...; iN|] v. (The syntax a.{...} <- v with one, two or three coordinates is reserved for updating one-, two- and three-dimensional arrays as described below.)

val sub_left : ('a, 'b, c_layout) t -> int -> int -> ('a, 'b, c_layout) t

Extract a sub-array of the given Bigarray by restricting the first (left-most) dimension. Genarray.sub_left a ofs len returns a Bigarray with the same number of dimensions as a, and the same dimensions as a, except the first dimension, which corresponds to the interval [ofs ... ofs + len - 1] of the first dimension of a. No copying of elements is involved: the sub-array and the original array share the same storage space. In other terms, the element at coordinates [|i1; ...; iN|] of the sub-array is identical to the element at coordinates [|i1+ofs; ...; iN|] of the original array a.

Genarray.sub_left applies only to Bigarrays in C layout.

  • raises Invalid_argument

    if ofs and len do not designate a valid sub-array of a, that is, if ofs < 0, or len < 0, or ofs + len > Genarray.nth_dim a 0.

val sub_right : + ('a, 'b, fortran_layout) t -> + int -> + int -> + ('a, 'b, fortran_layout) t

Extract a sub-array of the given Bigarray by restricting the last (right-most) dimension. Genarray.sub_right a ofs len returns a Bigarray with the same number of dimensions as a, and the same dimensions as a, except the last dimension, which corresponds to the interval [ofs ... ofs + len - 1] of the last dimension of a. No copying of elements is involved: the sub-array and the original array share the same storage space. In other terms, the element at coordinates [|i1; ...; iN|] of the sub-array is identical to the element at coordinates [|i1; ...; iN+ofs|] of the original array a.

Genarray.sub_right applies only to Bigarrays in Fortran layout.

  • raises Invalid_argument

    if ofs and len do not designate a valid sub-array of a, that is, if ofs < 1, or len < 0, or ofs + len > Genarray.nth_dim a (Genarray.num_dims a - 1).

val slice_left : ('a, 'b, c_layout) t -> int array -> ('a, 'b, c_layout) t

Extract a sub-array of lower dimension from the given Bigarray by fixing one or several of the first (left-most) coordinates. Genarray.slice_left a [|i1; ... ; iM|] returns the 'slice' of a obtained by setting the first M coordinates to i1, ..., iM. If a has N dimensions, the slice has dimension N - M, and the element at coordinates [|j1; ...; j(N-M)|] in the slice is identical to the element at coordinates [|i1; ...; iM; j1; ...; j(N-M)|] in the original array a. No copying of elements is involved: the slice and the original array share the same storage space.

Genarray.slice_left applies only to Bigarrays in C layout.

  • raises Invalid_argument

    if M >= N, or if [|i1; ... ; iM|] is outside the bounds of a.

val slice_right : + ('a, 'b, fortran_layout) t -> + int array -> + ('a, 'b, fortran_layout) t

Extract a sub-array of lower dimension from the given Bigarray by fixing one or several of the last (right-most) coordinates. Genarray.slice_right a [|i1; ... ; iM|] returns the 'slice' of a obtained by setting the last M coordinates to i1, ..., iM. If a has N dimensions, the slice has dimension N - M, and the element at coordinates [|j1; ...; j(N-M)|] in the slice is identical to the element at coordinates [|j1; ...; j(N-M); i1; ...; iM|] in the original array a. No copying of elements is involved: the slice and the original array share the same storage space.

Genarray.slice_right applies only to Bigarrays in Fortran layout.

  • raises Invalid_argument

    if M >= N, or if [|i1; ... ; iM|] is outside the bounds of a.

val blit : ('a, 'b, 'c) t -> ('a, 'b, 'c) t -> unit

Copy all elements of a Bigarray in another Bigarray. Genarray.blit src dst copies all elements of src into dst. Both arrays src and dst must have the same number of dimensions and equal dimensions. Copying a sub-array of src to a sub-array of dst can be achieved by applying Genarray.blit to sub-array or slices of src and dst.

val fill : ('a, 'b, 'c) t -> 'a -> unit

Set all elements of a Bigarray to a given value. Genarray.fill a v stores the value v in all elements of the Bigarray a. Setting only some elements of a to v can be achieved by applying Genarray.fill to a sub-array or a slice of a.

diff --git a/docs/stdlib/Stdlib/Bigarray/index.html b/docs/stdlib/Stdlib/Bigarray/index.html new file mode 100644 index 00000000..c8bcbb6c --- /dev/null +++ b/docs/stdlib/Stdlib/Bigarray/index.html @@ -0,0 +1,24 @@ + +Bigarray (docs.stdlib.Stdlib.Bigarray)

Module Stdlib.Bigarray

Large, multi-dimensional, numerical arrays.

This module implements multi-dimensional arrays of integers and floating-point numbers, thereafter referred to as 'Bigarrays', to distinguish them from the standard OCaml arrays described in Array.

The implementation allows efficient sharing of large numerical arrays between OCaml code and C or Fortran numerical libraries.

The main differences between 'Bigarrays' and standard OCaml arrays are as follows:

  • Bigarrays are not limited in size, unlike OCaml arrays. (Normal float arrays are limited to 2,097,151 elements on a 32-bit platform, and normal arrays of other types to 4,194,303 elements.)
  • Bigarrays are multi-dimensional. Any number of dimensions between 0 and 16 is supported. In contrast, OCaml arrays are mono-dimensional and require encoding multi-dimensional arrays as arrays of arrays.
  • Bigarrays can only contain integers and floating-point numbers, while OCaml arrays can contain arbitrary OCaml data types.
  • Bigarrays provide more space-efficient storage of integer and floating-point elements than normal OCaml arrays, in particular because they support 'small' types such as single-precision floats and 8 and 16-bit integers, in addition to the standard OCaml types of double-precision floats and 32 and 64-bit integers.
  • The memory layout of Bigarrays is entirely compatible with that of arrays in C and Fortran, allowing large arrays to be passed back and forth between OCaml code and C / Fortran code with no data copying at all.
  • Bigarrays support interesting high-level operations that normal arrays do not provide efficiently, such as extracting sub-arrays and 'slicing' a multi-dimensional array along certain dimensions, all without any copying.

Users of this module are encouraged to do open Bigarray in their source, then refer to array types and operations via short dot notation, e.g. Array1.t or Array2.sub.

Bigarrays support all the OCaml ad-hoc polymorphic operations:

Element kinds

Bigarrays can contain elements of the following kinds:

Each element kind is represented at the type level by one of the *_elt types defined below (defined with a single constructor instead of abstract types for technical injectivity reasons).

  • since 4.07 Moved from otherlibs to stdlib.
type float32_elt =
  1. | Float32_elt
type float64_elt =
  1. | Float64_elt
type int8_signed_elt =
  1. | Int8_signed_elt
type int8_unsigned_elt =
  1. | Int8_unsigned_elt
type int16_signed_elt =
  1. | Int16_signed_elt
type int16_unsigned_elt =
  1. | Int16_unsigned_elt
type int32_elt =
  1. | Int32_elt
type int64_elt =
  1. | Int64_elt
type int_elt =
  1. | Int_elt
type nativeint_elt =
  1. | Nativeint_elt
type complex32_elt =
  1. | Complex32_elt
type complex64_elt =
  1. | Complex64_elt
type ('a, 'b) kind =
  1. | Float32 : (float, float32_elt) kind
  2. | Float64 : (float, float64_elt) kind
  3. | Int8_signed : (int, int8_signed_elt) kind
  4. | Int8_unsigned : (int, int8_unsigned_elt) kind
  5. | Int16_signed : (int, int16_signed_elt) kind
  6. | Int16_unsigned : (int, int16_unsigned_elt) kind
  7. | Int32 : (int32, int32_elt) kind
  8. | Int64 : (int64, int64_elt) kind
  9. | Int : (int, int_elt) kind
  10. | Nativeint : (nativeint, nativeint_elt) kind
  11. | Complex32 : (Complex.t, complex32_elt) kind
  12. | Complex64 : (Complex.t, complex64_elt) kind
  13. | Char : (char, int8_unsigned_elt) kind

To each element kind is associated an OCaml type, which is the type of OCaml values that can be stored in the Bigarray or read back from it. This type is not necessarily the same as the type of the array elements proper: for instance, a Bigarray whose elements are of kind float32_elt contains 32-bit single precision floats, but reading or writing one of its elements from OCaml uses the OCaml type float, which is 64-bit double precision floats.

The GADT type ('a, 'b) kind captures this association of an OCaml type 'a for values read or written in the Bigarray, and of an element kind 'b which represents the actual contents of the Bigarray. Its constructors list all possible associations of OCaml types with element kinds, and are re-exported below for backward-compatibility reasons.

Using a generalized algebraic datatype (GADT) here allows writing well-typed polymorphic functions whose return type depend on the argument type, such as:

let zero : type a b. (a, b) kind -> a = function
+  | Float32 -> 0.0 | Complex32 -> Complex.zero
+  | Float64 -> 0.0 | Complex64 -> Complex.zero
+  | Int8_signed -> 0 | Int8_unsigned -> 0
+  | Int16_signed -> 0 | Int16_unsigned -> 0
+  | Int32 -> 0l | Int64 -> 0L
+  | Int -> 0 | Nativeint -> 0n
+  | Char -> '\000'
val float32 : (float, float32_elt) kind
val float64 : (float, float64_elt) kind
val complex32 : (Complex.t, complex32_elt) kind
val complex64 : (Complex.t, complex64_elt) kind
val int8_signed : (int, int8_signed_elt) kind
val int8_unsigned : (int, int8_unsigned_elt) kind
val int16_signed : (int, int16_signed_elt) kind
val int16_unsigned : (int, int16_unsigned_elt) kind
val int : (int, int_elt) kind
val int32 : (int32, int32_elt) kind
val int64 : (int64, int64_elt) kind
val nativeint : (nativeint, nativeint_elt) kind
val char : (char, int8_unsigned_elt) kind

As shown by the types of the values above, Bigarrays of kind float32_elt and float64_elt are accessed using the OCaml type float. Bigarrays of complex kinds complex32_elt, complex64_elt are accessed with the OCaml type Complex.t. Bigarrays of integer kinds are accessed using the smallest OCaml integer type large enough to represent the array elements: int for 8- and 16-bit integer Bigarrays, as well as OCaml-integer Bigarrays; int32 for 32-bit integer Bigarrays; int64 for 64-bit integer Bigarrays; and nativeint for platform-native integer Bigarrays. Finally, Bigarrays of kind int8_unsigned_elt can also be accessed as arrays of characters instead of arrays of small integers, by using the kind value char instead of int8_unsigned.

val kind_size_in_bytes : ('a, 'b) kind -> int

kind_size_in_bytes k is the number of bytes used to store an element of type k.

  • since 4.03

Array layouts

type c_layout =
  1. | C_layout_typ
type fortran_layout =
  1. | Fortran_layout_typ

To facilitate interoperability with existing C and Fortran code, this library supports two different memory layouts for Bigarrays, one compatible with the C conventions, the other compatible with the Fortran conventions.

In the C-style layout, array indices start at 0, and multi-dimensional arrays are laid out in row-major format. That is, for a two-dimensional array, all elements of row 0 are contiguous in memory, followed by all elements of row 1, etc. In other terms, the array elements at (x,y) and (x, y+1) are adjacent in memory.

In the Fortran-style layout, array indices start at 1, and multi-dimensional arrays are laid out in column-major format. That is, for a two-dimensional array, all elements of column 0 are contiguous in memory, followed by all elements of column 1, etc. In other terms, the array elements at (x,y) and (x+1, y) are adjacent in memory.

Each layout style is identified at the type level by the phantom types Bigarray.c_layout and Bigarray.fortran_layout respectively.

Supported layouts

The GADT type 'a layout represents one of the two supported memory layouts: C-style or Fortran-style. Its constructors are re-exported as values below for backward-compatibility reasons.

type 'a layout =
  1. | C_layout : c_layout layout
  2. | Fortran_layout : fortran_layout layout
val c_layout : c_layout layout
val fortran_layout : fortran_layout layout

Generic arrays (of arbitrarily many dimensions)

module Genarray : sig ... end

Zero-dimensional arrays

module Array0 : sig ... end

Zero-dimensional arrays. The Array0 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of zero-dimensional arrays that only contain a single scalar value. Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking.

One-dimensional arrays

module Array1 : sig ... end

One-dimensional arrays. The Array1 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of one-dimensional arrays. (The Array2 and Array3 structures below provide operations specialized for two- and three-dimensional arrays.) Statically knowing the number of dimensions of the array allows faster operations, and more precise static type-checking.

Two-dimensional arrays

module Array2 : sig ... end

Two-dimensional arrays. The Array2 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of two-dimensional arrays.

Three-dimensional arrays

module Array3 : sig ... end

Three-dimensional arrays. The Array3 structure provides operations similar to those of Bigarray.Genarray, but specialized to the case of three-dimensional arrays.

Coercions between generic Bigarrays and fixed-dimension Bigarrays

val genarray_of_array0 : ('a, 'b, 'c) Array0.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given zero-dimensional Bigarray.

  • since 4.05
val genarray_of_array1 : ('a, 'b, 'c) Array1.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given one-dimensional Bigarray.

val genarray_of_array2 : ('a, 'b, 'c) Array2.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given two-dimensional Bigarray.

val genarray_of_array3 : ('a, 'b, 'c) Array3.t -> ('a, 'b, 'c) Genarray.t

Return the generic Bigarray corresponding to the given three-dimensional Bigarray.

val array0_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array0.t

Return the zero-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly zero dimension.

  • since 4.05
val array1_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array1.t

Return the one-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly one dimension.

val array2_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array2.t

Return the two-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly two dimensions.

val array3_of_genarray : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array3.t

Return the three-dimensional Bigarray corresponding to the given generic Bigarray.

  • raises Invalid_argument

    if the generic Bigarray does not have exactly three dimensions.

Re-shaping Bigarrays

val reshape : ('a, 'b, 'c) Genarray.t -> int array -> ('a, 'b, 'c) Genarray.t

reshape b [|d1;...;dN|] converts the Bigarray b to a N-dimensional array of dimensions d1...dN. The returned array and the original array b share their data and have the same layout. For instance, assuming that b is a one-dimensional array of dimension 12, reshape b [|3;4|] returns a two-dimensional array b' of dimensions 3 and 4. If b has C layout, the element (x,y) of b' corresponds to the element x * 3 + y of b. If b has Fortran layout, the element (x,y) of b' corresponds to the element x + (y - 1) * 4 of b. The returned Bigarray must have exactly the same number of elements as the original Bigarray b. That is, the product of the dimensions of b must be equal to i1 * ... * iN. Otherwise, Invalid_argument is raised.

val reshape_0 : ('a, 'b, 'c) Genarray.t -> ('a, 'b, 'c) Array0.t

Specialized version of Bigarray.reshape for reshaping to zero-dimensional arrays.

  • since 4.05
val reshape_1 : ('a, 'b, 'c) Genarray.t -> int -> ('a, 'b, 'c) Array1.t

Specialized version of Bigarray.reshape for reshaping to one-dimensional arrays.

val reshape_2 : ('a, 'b, 'c) Genarray.t -> int -> int -> ('a, 'b, 'c) Array2.t

Specialized version of Bigarray.reshape for reshaping to two-dimensional arrays.

val reshape_3 : + ('a, 'b, 'c) Genarray.t -> + int -> + int -> + int -> + ('a, 'b, 'c) Array3.t

Specialized version of Bigarray.reshape for reshaping to three-dimensional arrays.

Bigarrays and concurrency safety

Care must be taken when concurrently accessing bigarrays from multiple domains: accessing a bigarray will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every bigarray operation that accesses more than one array element is not atomic. This includes slicing, bliting, and filling bigarrays.

For example, consider the following program:

open Bigarray
+let size = 100_000_000
+let a = Array1.init Int C_layout size (fun _ -> 1)
+let update f a () =
+  for i = 0 to size - 1 do a.{i} <- f a.{i} done
+let d1 = Domain.spawn (update (fun x -> x + 1) a)
+let d2 = Domain.spawn (update (fun x -> 2 * x + 1) a)
+let () = Domain.join d1; Domain.join d2

After executing this code, each field of the bigarray a is either 2, 3, 4 or 5. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of the bigarray, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same bigarray element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the bigarray elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains.

Tearing

Bigarrays have a distinct caveat in the presence of data races: concurrent bigarray operations might produce surprising values due to tearing. More precisely, the interleaving of partial writes and reads might create values that would not exist with a sequential execution. For instance, at the end of

let res = Array1.init Complex64 c_layout size (fun _ -> Complex.zero)
+let d1 = Domain.spawn (fun () -> Array1.fill res Complex.one)
+let d2 = Domain.spawn (fun () -> Array1.fill res Complex.i)
+let () = Domain.join d1; Domain.join d2

the res bigarray might contain values that are neither Complex.i nor Complex.one (for instance 1 + i).

diff --git a/docs/stdlib/Stdlib/Bool/index.html b/docs/stdlib/Stdlib/Bool/index.html new file mode 100644 index 00000000..7c99b1b2 --- /dev/null +++ b/docs/stdlib/Stdlib/Bool/index.html @@ -0,0 +1,2 @@ + +Bool (docs.stdlib.Stdlib.Bool)

Module Stdlib.Bool

Boolean values.

  • since 4.08

Booleans

type t = bool =
  1. | false
  2. | true

The type of booleans (truth values).

The constructors false and true are included here so that they have paths, but they are not intended to be used in user-defined data types.

val not : bool -> bool

not b is the boolean negation of b.

val (&&) : bool -> bool -> bool

e0 && e1 is the lazy boolean conjunction of expressions e0 and e1. If e0 evaluates to false, e1 is not evaluated. Right-associative operator at precedence level 3/11.

val (||) : bool -> bool -> bool

e0 || e1 is the lazy boolean disjunction of expressions e0 and e1. If e0 evaluates to true, e1 is not evaluated. Right-associative operator at precedence level 2/11.

Predicates and comparisons

val equal : bool -> bool -> bool

equal b0 b1 is true if and only if b0 and b1 are both true or both false.

val compare : bool -> bool -> int

compare b0 b1 is a total order on boolean values. false is smaller than true.

Converting

val to_int : bool -> int

to_int b is 0 if b is false and 1 if b is true.

val to_float : bool -> float

to_float b is 0. if b is false and 1. if b is true.

val to_string : bool -> string

to_string b is "true" if b is true and "false" if b is false.

val seeded_hash : int -> bool -> int

A seeded hash function for booleans, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : bool -> int

An unseeded hash function for booleans, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Buffer/index.html b/docs/stdlib/Stdlib/Buffer/index.html new file mode 100644 index 00000000..9fe4dd48 --- /dev/null +++ b/docs/stdlib/Stdlib/Buffer/index.html @@ -0,0 +1,5 @@ + +Buffer (docs.stdlib.Stdlib.Buffer)

Module Stdlib.Buffer

Extensible buffers.

This module implements buffers that automatically expand as necessary. It provides accumulative concatenation of strings in linear time (instead of quadratic time when strings are concatenated pairwise). For example:

let concat_strings ss =
+  let b = Buffer.create 16 in
+    List.iter (Buffer.add_string b) ss;
+    Buffer.contents b

Unsynchronized accesses

Unsynchronized accesses to a buffer may lead to an invalid buffer state. Thus, concurrent accesses to a buffer must be synchronized (for instance with a Mutex.t).

type t

The abstract type of buffers.

val create : int -> t

create n returns a fresh buffer, initially empty. The n parameter is the initial size of the internal byte sequence that holds the buffer contents. That byte sequence is automatically reallocated when more than n characters are stored in the buffer, but shrinks back to n characters when reset is called. For best performance, n should be of the same order of magnitude as the number of characters that are expected to be stored in the buffer (for instance, 80 for a buffer that holds one output line). Nothing bad will happen if the buffer grows beyond that limit, however. In doubt, take n = 16 for instance. If n is not between 1 and Sys.max_string_length, it will be clipped to that interval.

val contents : t -> string

Return a copy of the current contents of the buffer. The buffer itself is unchanged.

val to_bytes : t -> bytes

Return a copy of the current contents of the buffer. The buffer itself is unchanged.

  • since 4.02
val sub : t -> int -> int -> string

Buffer.sub b off len returns a copy of len bytes from the current contents of the buffer b, starting at offset off.

val blit : t -> int -> bytes -> int -> int -> unit

Buffer.blit src srcoff dst dstoff len copies len characters from the current contents of the buffer src, starting at offset srcoff to dst, starting at character dstoff.

  • raises Invalid_argument

    if srcoff and len do not designate a valid range of src, or if dstoff and len do not designate a valid range of dst.

  • since 3.11.2
val nth : t -> int -> char

Get the n-th character of the buffer.

val length : t -> int

Return the number of characters currently contained in the buffer.

val clear : t -> unit

Empty the buffer.

val reset : t -> unit

Empty the buffer and deallocate the internal byte sequence holding the buffer contents, replacing it with the initial internal byte sequence of length n that was allocated by Buffer.create n. For long-lived buffers that may have grown a lot, reset allows faster reclamation of the space used by the buffer.

val output_buffer : out_channel -> t -> unit

output_buffer oc b writes the current contents of buffer b on the output channel oc.

val truncate : t -> int -> unit

truncate b len truncates the length of b to len Note: the internal byte sequence is not shortened.

  • since 4.05

Appending

Note: all add_* operations can raise Failure if the internal byte sequence of the buffer would need to grow beyond Sys.max_string_length.

val add_char : t -> char -> unit

add_char b c appends the character c at the end of buffer b.

val add_utf_8_uchar : t -> Uchar.t -> unit

add_utf_8_uchar b u appends the UTF-8 encoding of u at the end of buffer b.

  • since 4.06
val add_utf_16le_uchar : t -> Uchar.t -> unit

add_utf_16le_uchar b u appends the UTF-16LE encoding of u at the end of buffer b.

  • since 4.06
val add_utf_16be_uchar : t -> Uchar.t -> unit

add_utf_16be_uchar b u appends the UTF-16BE encoding of u at the end of buffer b.

  • since 4.06
val add_string : t -> string -> unit

add_string b s appends the string s at the end of buffer b.

val add_bytes : t -> bytes -> unit

add_bytes b s appends the byte sequence s at the end of buffer b.

  • since 4.02
val add_substring : t -> string -> int -> int -> unit

add_substring b s ofs len takes len characters from offset ofs in string s and appends them at the end of buffer b.

val add_subbytes : t -> bytes -> int -> int -> unit

add_subbytes b s ofs len takes len characters from offset ofs in byte sequence s and appends them at the end of buffer b.

  • since 4.02
val add_substitute : t -> (string -> string) -> string -> unit

add_substitute b f s appends the string pattern s at the end of buffer b with substitution. The substitution process looks for variables into the pattern and substitutes each variable name by its value, as obtained by applying the mapping f to the variable name. Inside the string pattern, a variable name immediately follows a non-escaped $ character and is one of the following:

  • a non empty sequence of alphanumeric or _ characters,
  • an arbitrary sequence of characters enclosed by a pair of matching parentheses or curly brackets. An escaped $ character is a $ that immediately follows a backslash character; it then stands for a plain $.
  • raises Not_found

    if the closing character of a parenthesized variable cannot be found.

val add_buffer : t -> t -> unit

add_buffer b1 b2 appends the current contents of buffer b2 at the end of buffer b1. b2 is not modified.

val add_channel : t -> in_channel -> int -> unit

add_channel b ic n reads at most n characters from the input channel ic and stores them at the end of buffer b.

  • raises End_of_file

    if the channel contains fewer than n characters. In this case, the characters are still added to the buffer, so as to avoid loss of data.

Buffers and Sequences

val to_seq : t -> char Seq.t

Iterate on the buffer, in increasing order.

The behavior is not specified if the buffer is modified during iteration.

  • since 4.07
val to_seqi : t -> (int * char) Seq.t

Iterate on the buffer, in increasing order, yielding indices along chars.

The behavior is not specified if the buffer is modified during iteration.

  • since 4.07
val add_seq : t -> char Seq.t -> unit

Add chars to the buffer

  • since 4.07
val of_seq : char Seq.t -> t

Create a buffer from the generator

  • since 4.07

Binary encoding of integers

The functions in this section append binary encodings of integers to buffers.

Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order. Native-endian encoding is either little-endian or big-endian depending on Sys.big_endian.

32-bit and 64-bit integers are represented by the int32 and int64 types, which can be interpreted either as signed or unsigned numbers.

8-bit and 16-bit integers are represented by the int type, which has more bits than the binary encoding. Functions that encode these values truncate their inputs to their least significant bytes.

val add_uint8 : t -> int -> unit

add_uint8 b i appends a binary unsigned 8-bit integer i to b.

  • since 4.08
val add_int8 : t -> int -> unit

add_int8 b i appends a binary signed 8-bit integer i to b.

  • since 4.08
val add_uint16_ne : t -> int -> unit

add_uint16_ne b i appends a binary native-endian unsigned 16-bit integer i to b.

  • since 4.08
val add_uint16_be : t -> int -> unit

add_uint16_be b i appends a binary big-endian unsigned 16-bit integer i to b.

  • since 4.08
val add_uint16_le : t -> int -> unit

add_uint16_le b i appends a binary little-endian unsigned 16-bit integer i to b.

  • since 4.08
val add_int16_ne : t -> int -> unit

add_int16_ne b i appends a binary native-endian signed 16-bit integer i to b.

  • since 4.08
val add_int16_be : t -> int -> unit

add_int16_be b i appends a binary big-endian signed 16-bit integer i to b.

  • since 4.08
val add_int16_le : t -> int -> unit

add_int16_le b i appends a binary little-endian signed 16-bit integer i to b.

  • since 4.08
val add_int32_ne : t -> int32 -> unit

add_int32_ne b i appends a binary native-endian 32-bit integer i to b.

  • since 4.08
val add_int32_be : t -> int32 -> unit

add_int32_be b i appends a binary big-endian 32-bit integer i to b.

  • since 4.08
val add_int32_le : t -> int32 -> unit

add_int32_le b i appends a binary little-endian 32-bit integer i to b.

  • since 4.08
val add_int64_ne : t -> int64 -> unit

add_int64_ne b i appends a binary native-endian 64-bit integer i to b.

  • since 4.08
val add_int64_be : t -> int64 -> unit

add_int64_be b i appends a binary big-endian 64-bit integer i to b.

  • since 4.08
val add_int64_le : t -> int64 -> unit

add_int64_ne b i appends a binary little-endian 64-bit integer i to b.

  • since 4.08
diff --git a/docs/stdlib/Stdlib/Bytes/index.html b/docs/stdlib/Stdlib/Bytes/index.html new file mode 100644 index 00000000..5c4c9c93 --- /dev/null +++ b/docs/stdlib/Stdlib/Bytes/index.html @@ -0,0 +1,17 @@ + +Bytes (docs.stdlib.Stdlib.Bytes)

Module Stdlib.Bytes

Byte sequence operations.

A byte sequence is a mutable data structure that contains a fixed-length sequence of bytes. Each byte can be indexed in constant time for reading or writing.

Given a byte sequence s of length l, we can access each of the l bytes of s via its index in the sequence. Indexes start at 0, and we will call an index valid in s if it falls within the range [0...l-1] (inclusive). A position is the point between two bytes or at the beginning or end of the sequence. We call a position valid in s if it falls within the range [0...l] (inclusive). Note that the byte at index n is between positions n and n+1.

Two parameters start and len are said to designate a valid range of s if len >= 0 and start and start+len are valid positions in s.

Byte sequences can be modified in place, for instance via the set and blit functions described below. See also strings (module String), which are almost the same data structure, but cannot be modified in place.

Bytes are represented by the OCaml type char.

The labeled version of this module can be used as described in the StdLabels module.

  • since 4.02
val length : bytes -> int

Return the length (number of bytes) of the argument.

val get : bytes -> int -> char

get s n returns the byte at index n in argument s.

val set : bytes -> int -> char -> unit

set s n c modifies s in place, replacing the byte at index n with c.

val create : int -> bytes

create n returns a new byte sequence of length n. The sequence is uninitialized and contains arbitrary bytes.

val make : int -> char -> bytes

make n c returns a new byte sequence of length n, filled with the byte c.

val init : int -> (int -> char) -> bytes

init n f returns a fresh byte sequence of length n, with character i initialized to the result of f i (in increasing index order).

val empty : bytes

A byte sequence of size 0.

val copy : bytes -> bytes

Return a new byte sequence that contains the same bytes as the argument.

val of_string : string -> bytes

Return a new byte sequence that contains the same bytes as the given string.

val to_string : bytes -> string

Return a new string that contains the same bytes as the given byte sequence.

val sub : bytes -> int -> int -> bytes

sub s pos len returns a new byte sequence of length len, containing the subsequence of s that starts at position pos and has length len.

val sub_string : bytes -> int -> int -> string

Same as sub but return a string instead of a byte sequence.

val extend : bytes -> int -> int -> bytes

extend s left right returns a new byte sequence that contains the bytes of s, with left uninitialized bytes prepended and right uninitialized bytes appended to it. If left or right is negative, then bytes are removed (instead of appended) from the corresponding side of s.

  • since 4.05 in BytesLabels
val fill : bytes -> int -> int -> char -> unit

fill s pos len c modifies s in place, replacing len characters with c, starting at pos.

val blit : bytes -> int -> bytes -> int -> int -> unit

blit src src_pos dst dst_pos len copies len bytes from byte sequence src, starting at index src_pos, to byte sequence dst, starting at index dst_pos. It works correctly even if src and dst are the same byte sequence, and the source and destination intervals overlap.

  • raises Invalid_argument

    if src_pos and len do not designate a valid range of src, or if dst_pos and len do not designate a valid range of dst.

val blit_string : string -> int -> bytes -> int -> int -> unit

blit_string src src_pos dst dst_pos len copies len bytes from string src, starting at index src_pos, to byte sequence dst, starting at index dst_pos.

  • raises Invalid_argument

    if src_pos and len do not designate a valid range of src, or if dst_pos and len do not designate a valid range of dst.

  • since 4.05 in BytesLabels
val concat : bytes -> bytes list -> bytes

concat sep sl concatenates the list of byte sequences sl, inserting the separator byte sequence sep between each, and returns the result as a new byte sequence.

val cat : bytes -> bytes -> bytes

cat s1 s2 concatenates s1 and s2 and returns the result as a new byte sequence.

  • since 4.05 in BytesLabels
val iter : (char -> unit) -> bytes -> unit

iter f s applies function f in turn to all the bytes of s. It is equivalent to f (get s 0); f (get s 1); ...; f (get s + (length s - 1)); ().

val iteri : (int -> char -> unit) -> bytes -> unit

Same as iter, but the function is applied to the index of the byte as first argument and the byte itself as second argument.

val map : (char -> char) -> bytes -> bytes

map f s applies function f in turn to all the bytes of s (in increasing index order) and stores the resulting bytes in a new sequence that is returned as the result.

val mapi : (int -> char -> char) -> bytes -> bytes

mapi f s calls f with each character of s and its index (in increasing index order) and stores the resulting bytes in a new sequence that is returned as the result.

val fold_left : ('acc -> char -> 'acc) -> 'acc -> bytes -> 'acc

fold_left f x s computes f (... (f (f x (get s 0)) (get s 1)) ...) (get s (n-1)), where n is the length of s.

  • since 4.13
val fold_right : (char -> 'acc -> 'acc) -> bytes -> 'acc -> 'acc

fold_right f s x computes f (get s 0) (f (get s 1) ( ... (f (get s (n-1)) x) ...)), where n is the length of s.

  • since 4.13
val for_all : (char -> bool) -> bytes -> bool

for_all p s checks if all characters in s satisfy the predicate p.

  • since 4.13
val exists : (char -> bool) -> bytes -> bool

exists p s checks if at least one character of s satisfies the predicate p.

  • since 4.13
val trim : bytes -> bytes

Return a copy of the argument, without leading and trailing whitespace. The bytes regarded as whitespace are the ASCII characters ' ', '\012', '\n', '\r', and '\t'.

val escaped : bytes -> bytes

Return a copy of the argument, with special characters represented by escape sequences, following the lexical conventions of OCaml. All characters outside the ASCII printable range (32..126) are escaped, as well as backslash and double-quote.

val index : bytes -> char -> int

index s c returns the index of the first occurrence of byte c in s.

val index_opt : bytes -> char -> int option

index_opt s c returns the index of the first occurrence of byte c in s or None if c does not occur in s.

  • since 4.05
val rindex : bytes -> char -> int

rindex s c returns the index of the last occurrence of byte c in s.

val rindex_opt : bytes -> char -> int option

rindex_opt s c returns the index of the last occurrence of byte c in s or None if c does not occur in s.

  • since 4.05
val index_from : bytes -> int -> char -> int

index_from s i c returns the index of the first occurrence of byte c in s after position i. index s c is equivalent to index_from s 0 c.

  • raises Not_found

    if c does not occur in s after position i.

val index_from_opt : bytes -> int -> char -> int option

index_from_opt s i c returns the index of the first occurrence of byte c in s after position i or None if c does not occur in s after position i. index_opt s c is equivalent to index_from_opt s 0 c.

  • since 4.05
val rindex_from : bytes -> int -> char -> int

rindex_from s i c returns the index of the last occurrence of byte c in s before position i+1. rindex s c is equivalent to rindex_from s (length s - 1) c.

  • raises Not_found

    if c does not occur in s before position i+1.

val rindex_from_opt : bytes -> int -> char -> int option

rindex_from_opt s i c returns the index of the last occurrence of byte c in s before position i+1 or None if c does not occur in s before position i+1. rindex_opt s c is equivalent to rindex_from s (length s - 1) c.

  • since 4.05
val contains : bytes -> char -> bool

contains s c tests if byte c appears in s.

val contains_from : bytes -> int -> char -> bool

contains_from s start c tests if byte c appears in s after position start. contains s c is equivalent to contains_from + s 0 c.

val rcontains_from : bytes -> int -> char -> bool

rcontains_from s stop c tests if byte c appears in s before position stop+1.

val uppercase_ascii : bytes -> bytes

Return a copy of the argument, with all lowercase letters translated to uppercase, using the US-ASCII character set.

  • since 4.03 (4.05 in BytesLabels)
val lowercase_ascii : bytes -> bytes

Return a copy of the argument, with all uppercase letters translated to lowercase, using the US-ASCII character set.

  • since 4.03 (4.05 in BytesLabels)
val capitalize_ascii : bytes -> bytes

Return a copy of the argument, with the first character set to uppercase, using the US-ASCII character set.

  • since 4.03 (4.05 in BytesLabels)
val uncapitalize_ascii : bytes -> bytes

Return a copy of the argument, with the first character set to lowercase, using the US-ASCII character set.

  • since 4.03 (4.05 in BytesLabels)
type t = bytes

An alias for the type of byte sequences.

val compare : t -> t -> int

The comparison function for byte sequences, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Bytes to be passed as argument to the functors Set.Make and Map.Make.

val equal : t -> t -> bool

The equality function for byte sequences.

  • since 4.03 (4.05 in BytesLabels)
val starts_with : prefix:bytes -> bytes -> bool

starts_with ~prefix s is true if and only if s starts with prefix.

  • since 4.13
val ends_with : suffix:bytes -> bytes -> bool

ends_with ~suffix s is true if and only if s ends with suffix.

  • since 4.13

Unsafe conversions (for advanced users)

This section describes unsafe, low-level conversion functions between bytes and string. They do not copy the internal data; used improperly, they can break the immutability invariant on strings provided by the -safe-string option. They are available for expert library authors, but for most purposes you should use the always-correct to_string and of_string instead.

val unsafe_to_string : bytes -> string

Unsafely convert a byte sequence into a string.

To reason about the use of unsafe_to_string, it is convenient to consider an "ownership" discipline. A piece of code that manipulates some data "owns" it; there are several disjoint ownership modes, including:

  • Unique ownership: the data may be accessed and mutated
  • Shared ownership: the data has several owners, that may only access it, not mutate it.

Unique ownership is linear: passing the data to another piece of code means giving up ownership (we cannot write the data again). A unique owner may decide to make the data shared (giving up mutation rights on it), but shared data may not become uniquely-owned again.

unsafe_to_string s can only be used when the caller owns the byte sequence s -- either uniquely or as shared immutable data. The caller gives up ownership of s, and gains ownership of the returned string.

There are two valid use-cases that respect this ownership discipline:

1. Creating a string by initializing and mutating a byte sequence that is never changed after initialization is performed.

let string_init len f : string =
+  let s = Bytes.create len in
+  for i = 0 to len - 1 do Bytes.set s i (f i) done;
+  Bytes.unsafe_to_string s

This function is safe because the byte sequence s will never be accessed or mutated after unsafe_to_string is called. The string_init code gives up ownership of s, and returns the ownership of the resulting string to its caller.

Note that it would be unsafe if s was passed as an additional parameter to the function f as it could escape this way and be mutated in the future -- string_init would give up ownership of s to pass it to f, and could not call unsafe_to_string safely.

We have provided the String.init, String.map and String.mapi functions to cover most cases of building new strings. You should prefer those over to_string or unsafe_to_string whenever applicable.

2. Temporarily giving ownership of a byte sequence to a function that expects a uniquely owned string and returns ownership back, so that we can mutate the sequence again after the call ended.

let bytes_length (s : bytes) =
+  String.length (Bytes.unsafe_to_string s)

In this use-case, we do not promise that s will never be mutated after the call to bytes_length s. The String.length function temporarily borrows unique ownership of the byte sequence (and sees it as a string), but returns this ownership back to the caller, which may assume that s is still a valid byte sequence after the call. Note that this is only correct because we know that String.length does not capture its argument -- it could escape by a side-channel such as a memoization combinator.

The caller may not mutate s while the string is borrowed (it has temporarily given up ownership). This affects concurrent programs, but also higher-order functions: if String.length returned a closure to be called later, s should not be mutated until this closure is fully applied and returns ownership.

val unsafe_of_string : string -> bytes

Unsafely convert a shared string to a byte sequence that should not be mutated.

The same ownership discipline that makes unsafe_to_string correct applies to unsafe_of_string: you may use it if you were the owner of the string value, and you will own the return bytes in the same mode.

In practice, unique ownership of string values is extremely difficult to reason about correctly. You should always assume strings are shared, never uniquely owned.

For example, string literals are implicitly shared by the compiler, so you never uniquely own them.

let incorrect = Bytes.unsafe_of_string "hello"
+let s = Bytes.of_string "hello"

The first declaration is incorrect, because the string literal "hello" could be shared by the compiler with other parts of the program, and mutating incorrect is a bug. You must always use the second version, which performs a copy and is thus correct.

Assuming unique ownership of strings that are not string literals, but are (partly) built from string literals, is also incorrect. For example, mutating unsafe_of_string ("foo" ^ s) could mutate the shared string "foo" -- assuming a rope-like representation of strings. More generally, functions operating on strings will assume shared ownership, they do not preserve unique ownership. It is thus incorrect to assume unique ownership of the result of unsafe_of_string.

The only case we have reasonable confidence is safe is if the produced bytes is shared -- used as an immutable byte sequence. This is possibly useful for incremental migration of low-level programs that manipulate immutable sequences of bytes (for example Marshal.from_bytes) and previously used the string type for this purpose.

val split_on_char : char -> bytes -> bytes list

split_on_char sep s returns the list of all (possibly empty) subsequences of s that are delimited by the sep character.

The function's output is specified by the following invariants:

  • The list is not empty.
  • Concatenating its elements using sep as a separator returns a byte sequence equal to the input (Bytes.concat (Bytes.make 1 sep) + (Bytes.split_on_char sep s) = s).
  • No byte sequence in the result contains the sep character.
  • since 4.13

Iterators

val to_seq : t -> char Seq.t

Iterate on the string, in increasing index order. Modifications of the string during iteration will be reflected in the sequence.

  • since 4.07
val to_seqi : t -> (int * char) Seq.t

Iterate on the string, in increasing order, yielding indices along chars

  • since 4.07
val of_seq : char Seq.t -> t

Create a string from the generator

  • since 4.07

UTF codecs and validations

  • since 4.14

UTF-8

val get_utf_8_uchar : t -> int -> Uchar.utf_decode

get_utf_8_uchar b i decodes an UTF-8 character at index i in b.

val set_utf_8_uchar : t -> int -> Uchar.t -> int

set_utf_8_uchar b i u UTF-8 encodes u at index i in b and returns the number of bytes n that were written starting at i. If n is 0 there was not enough space to encode u at i and b was left untouched. Otherwise a new character can be encoded at i + n.

val is_valid_utf_8 : t -> bool

is_valid_utf_8 b is true if and only if b contains valid UTF-8 data.

UTF-16BE

val get_utf_16be_uchar : t -> int -> Uchar.utf_decode

get_utf_16be_uchar b i decodes an UTF-16BE character at index i in b.

val set_utf_16be_uchar : t -> int -> Uchar.t -> int

set_utf_16be_uchar b i u UTF-16BE encodes u at index i in b and returns the number of bytes n that were written starting at i. If n is 0 there was not enough space to encode u at i and b was left untouched. Otherwise a new character can be encoded at i + n.

val is_valid_utf_16be : t -> bool

is_valid_utf_16be b is true if and only if b contains valid UTF-16BE data.

UTF-16LE

val get_utf_16le_uchar : t -> int -> Uchar.utf_decode

get_utf_16le_uchar b i decodes an UTF-16LE character at index i in b.

val set_utf_16le_uchar : t -> int -> Uchar.t -> int

set_utf_16le_uchar b i u UTF-16LE encodes u at index i in b and returns the number of bytes n that were written starting at i. If n is 0 there was not enough space to encode u at i and b was left untouched. Otherwise a new character can be encoded at i + n.

val is_valid_utf_16le : t -> bool

is_valid_utf_16le b is true if and only if b contains valid UTF-16LE data.

Binary encoding/decoding of integers

The functions in this section binary encode and decode integers to and from byte sequences.

All following functions raise Invalid_argument if the space needed at index i to decode or encode the integer is not available.

Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order. Native-endian encoding is either little-endian or big-endian depending on Sys.big_endian.

32-bit and 64-bit integers are represented by the int32 and int64 types, which can be interpreted either as signed or unsigned numbers.

8-bit and 16-bit integers are represented by the int type, which has more bits than the binary encoding. These extra bits are handled as follows:

  • Functions that decode signed (resp. unsigned) 8-bit or 16-bit integers represented by int values sign-extend (resp. zero-extend) their result.
  • Functions that encode 8-bit or 16-bit integers represented by int values truncate their input to their least significant bytes.
val get_uint8 : bytes -> int -> int

get_uint8 b i is b's unsigned 8-bit integer starting at byte index i.

  • since 4.08
val get_int8 : bytes -> int -> int

get_int8 b i is b's signed 8-bit integer starting at byte index i.

  • since 4.08
val get_uint16_ne : bytes -> int -> int

get_uint16_ne b i is b's native-endian unsigned 16-bit integer starting at byte index i.

  • since 4.08
val get_uint16_be : bytes -> int -> int

get_uint16_be b i is b's big-endian unsigned 16-bit integer starting at byte index i.

  • since 4.08
val get_uint16_le : bytes -> int -> int

get_uint16_le b i is b's little-endian unsigned 16-bit integer starting at byte index i.

  • since 4.08
val get_int16_ne : bytes -> int -> int

get_int16_ne b i is b's native-endian signed 16-bit integer starting at byte index i.

  • since 4.08
val get_int16_be : bytes -> int -> int

get_int16_be b i is b's big-endian signed 16-bit integer starting at byte index i.

  • since 4.08
val get_int16_le : bytes -> int -> int

get_int16_le b i is b's little-endian signed 16-bit integer starting at byte index i.

  • since 4.08
val get_int32_ne : bytes -> int -> int32

get_int32_ne b i is b's native-endian 32-bit integer starting at byte index i.

  • since 4.08
val get_int32_be : bytes -> int -> int32

get_int32_be b i is b's big-endian 32-bit integer starting at byte index i.

  • since 4.08
val get_int32_le : bytes -> int -> int32

get_int32_le b i is b's little-endian 32-bit integer starting at byte index i.

  • since 4.08
val get_int64_ne : bytes -> int -> int64

get_int64_ne b i is b's native-endian 64-bit integer starting at byte index i.

  • since 4.08
val get_int64_be : bytes -> int -> int64

get_int64_be b i is b's big-endian 64-bit integer starting at byte index i.

  • since 4.08
val get_int64_le : bytes -> int -> int64

get_int64_le b i is b's little-endian 64-bit integer starting at byte index i.

  • since 4.08
val set_uint8 : bytes -> int -> int -> unit

set_uint8 b i v sets b's unsigned 8-bit integer starting at byte index i to v.

  • since 4.08
val set_int8 : bytes -> int -> int -> unit

set_int8 b i v sets b's signed 8-bit integer starting at byte index i to v.

  • since 4.08
val set_uint16_ne : bytes -> int -> int -> unit

set_uint16_ne b i v sets b's native-endian unsigned 16-bit integer starting at byte index i to v.

  • since 4.08
val set_uint16_be : bytes -> int -> int -> unit

set_uint16_be b i v sets b's big-endian unsigned 16-bit integer starting at byte index i to v.

  • since 4.08
val set_uint16_le : bytes -> int -> int -> unit

set_uint16_le b i v sets b's little-endian unsigned 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int16_ne : bytes -> int -> int -> unit

set_int16_ne b i v sets b's native-endian signed 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int16_be : bytes -> int -> int -> unit

set_int16_be b i v sets b's big-endian signed 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int16_le : bytes -> int -> int -> unit

set_int16_le b i v sets b's little-endian signed 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int32_ne : bytes -> int -> int32 -> unit

set_int32_ne b i v sets b's native-endian 32-bit integer starting at byte index i to v.

  • since 4.08
val set_int32_be : bytes -> int -> int32 -> unit

set_int32_be b i v sets b's big-endian 32-bit integer starting at byte index i to v.

  • since 4.08
val set_int32_le : bytes -> int -> int32 -> unit

set_int32_le b i v sets b's little-endian 32-bit integer starting at byte index i to v.

  • since 4.08
val set_int64_ne : bytes -> int -> int64 -> unit

set_int64_ne b i v sets b's native-endian 64-bit integer starting at byte index i to v.

  • since 4.08
val set_int64_be : bytes -> int -> int64 -> unit

set_int64_be b i v sets b's big-endian 64-bit integer starting at byte index i to v.

  • since 4.08
val set_int64_le : bytes -> int -> int64 -> unit

set_int64_le b i v sets b's little-endian 64-bit integer starting at byte index i to v.

  • since 4.08

Byte sequences and concurrency safety

Care must be taken when concurrently accessing byte sequences from multiple domains: accessing a byte sequence will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every byte sequence operation that accesses more than one byte is not atomic. This includes iteration and scanning.

For example, consider the following program:

let size = 100_000_000
+let b = Bytes.make size  ' '
+let update b f ()  =
+  Bytes.iteri (fun i x -> Bytes.set b i (Char.chr (f (Char.code x)))) b
+let d1 = Domain.spawn (update b (fun x -> x + 1))
+let d2 = Domain.spawn (update b (fun x -> 2 * x + 1))
+let () = Domain.join d1; Domain.join d2

the bytes sequence b may contain a non-deterministic mixture of '!', 'A', 'B', and 'C' values.

After executing this code, each byte of the sequence b is either '!', 'A', 'B', or 'C'. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of a byte sequence, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same byte without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the elements of the sequence.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location.

Mixed-size accesses

Another subtle point is that if a data race involves mixed-size writes and reads to the same location, the order in which those writes and reads are observed by domains is not specified. For instance, the following code write sequentially a 32-bit integer and a char to the same index

let b = Bytes.make 10 '\000'
+let d1 = Domain.spawn (fun () -> Bytes.set_int32_ne b 0 100; b.[0] <- 'd' )

In this situation, a domain that observes the write of 'd' to b.0 is not guaranteed to also observe the write to indices 1, 2, or 3.

diff --git a/docs/stdlib/Stdlib/BytesLabels/index.html b/docs/stdlib/Stdlib/BytesLabels/index.html new file mode 100644 index 00000000..1ba65765 --- /dev/null +++ b/docs/stdlib/Stdlib/BytesLabels/index.html @@ -0,0 +1,29 @@ + +BytesLabels (docs.stdlib.Stdlib.BytesLabels)

Module Stdlib.BytesLabels

Byte sequence operations.

A byte sequence is a mutable data structure that contains a fixed-length sequence of bytes. Each byte can be indexed in constant time for reading or writing.

Given a byte sequence s of length l, we can access each of the l bytes of s via its index in the sequence. Indexes start at 0, and we will call an index valid in s if it falls within the range [0...l-1] (inclusive). A position is the point between two bytes or at the beginning or end of the sequence. We call a position valid in s if it falls within the range [0...l] (inclusive). Note that the byte at index n is between positions n and n+1.

Two parameters start and len are said to designate a valid range of s if len >= 0 and start and start+len are valid positions in s.

Byte sequences can be modified in place, for instance via the set and blit functions described below. See also strings (module String), which are almost the same data structure, but cannot be modified in place.

Bytes are represented by the OCaml type char.

The labeled version of this module can be used as described in the StdLabels module.

  • since 4.02
val length : bytes -> int

Return the length (number of bytes) of the argument.

val get : bytes -> int -> char

get s n returns the byte at index n in argument s.

val set : bytes -> int -> char -> unit

set s n c modifies s in place, replacing the byte at index n with c.

val create : int -> bytes

create n returns a new byte sequence of length n. The sequence is uninitialized and contains arbitrary bytes.

val make : int -> char -> bytes

make n c returns a new byte sequence of length n, filled with the byte c.

val init : int -> f:(int -> char) -> bytes

init n f returns a fresh byte sequence of length n, with character i initialized to the result of f i (in increasing index order).

val empty : bytes

A byte sequence of size 0.

val copy : bytes -> bytes

Return a new byte sequence that contains the same bytes as the argument.

val of_string : string -> bytes

Return a new byte sequence that contains the same bytes as the given string.

val to_string : bytes -> string

Return a new string that contains the same bytes as the given byte sequence.

val sub : bytes -> pos:int -> len:int -> bytes

sub s ~pos ~len returns a new byte sequence of length len, containing the subsequence of s that starts at position pos and has length len.

val sub_string : bytes -> pos:int -> len:int -> string

Same as sub but return a string instead of a byte sequence.

val extend : bytes -> left:int -> right:int -> bytes

extend s ~left ~right returns a new byte sequence that contains the bytes of s, with left uninitialized bytes prepended and right uninitialized bytes appended to it. If left or right is negative, then bytes are removed (instead of appended) from the corresponding side of s.

  • since 4.05 in BytesLabels
val fill : bytes -> pos:int -> len:int -> char -> unit

fill s ~pos ~len c modifies s in place, replacing len characters with c, starting at pos.

val blit : + src:bytes -> + src_pos:int -> + dst:bytes -> + dst_pos:int -> + len:int -> + unit

blit ~src ~src_pos ~dst ~dst_pos ~len copies len bytes from byte sequence src, starting at index src_pos, to byte sequence dst, starting at index dst_pos. It works correctly even if src and dst are the same byte sequence, and the source and destination intervals overlap.

  • raises Invalid_argument

    if src_pos and len do not designate a valid range of src, or if dst_pos and len do not designate a valid range of dst.

val blit_string : + src:string -> + src_pos:int -> + dst:bytes -> + dst_pos:int -> + len:int -> + unit

blit_string ~src ~src_pos ~dst ~dst_pos ~len copies len bytes from string src, starting at index src_pos, to byte sequence dst, starting at index dst_pos.

  • raises Invalid_argument

    if src_pos and len do not designate a valid range of src, or if dst_pos and len do not designate a valid range of dst.

  • since 4.05 in BytesLabels
val concat : sep:bytes -> bytes list -> bytes

concat ~sep sl concatenates the list of byte sequences sl, inserting the separator byte sequence sep between each, and returns the result as a new byte sequence.

val cat : bytes -> bytes -> bytes

cat s1 s2 concatenates s1 and s2 and returns the result as a new byte sequence.

  • since 4.05 in BytesLabels
val iter : f:(char -> unit) -> bytes -> unit

iter ~f s applies function f in turn to all the bytes of s. It is equivalent to f (get s 0); f (get s 1); ...; f (get s + (length s - 1)); ().

val iteri : f:(int -> char -> unit) -> bytes -> unit

Same as iter, but the function is applied to the index of the byte as first argument and the byte itself as second argument.

val map : f:(char -> char) -> bytes -> bytes

map ~f s applies function f in turn to all the bytes of s (in increasing index order) and stores the resulting bytes in a new sequence that is returned as the result.

val mapi : f:(int -> char -> char) -> bytes -> bytes

mapi ~f s calls f with each character of s and its index (in increasing index order) and stores the resulting bytes in a new sequence that is returned as the result.

val fold_left : f:('acc -> char -> 'acc) -> init:'acc -> bytes -> 'acc

fold_left f x s computes f (... (f (f x (get s 0)) (get s 1)) ...) (get s (n-1)), where n is the length of s.

  • since 4.13
val fold_right : f:(char -> 'acc -> 'acc) -> bytes -> init:'acc -> 'acc

fold_right f s x computes f (get s 0) (f (get s 1) ( ... (f (get s (n-1)) x) ...)), where n is the length of s.

  • since 4.13
val for_all : f:(char -> bool) -> bytes -> bool

for_all p s checks if all characters in s satisfy the predicate p.

  • since 4.13
val exists : f:(char -> bool) -> bytes -> bool

exists p s checks if at least one character of s satisfies the predicate p.

  • since 4.13
val trim : bytes -> bytes

Return a copy of the argument, without leading and trailing whitespace. The bytes regarded as whitespace are the ASCII characters ' ', '\012', '\n', '\r', and '\t'.

val escaped : bytes -> bytes

Return a copy of the argument, with special characters represented by escape sequences, following the lexical conventions of OCaml. All characters outside the ASCII printable range (32..126) are escaped, as well as backslash and double-quote.

val index : bytes -> char -> int

index s c returns the index of the first occurrence of byte c in s.

val index_opt : bytes -> char -> int option

index_opt s c returns the index of the first occurrence of byte c in s or None if c does not occur in s.

  • since 4.05
val rindex : bytes -> char -> int

rindex s c returns the index of the last occurrence of byte c in s.

val rindex_opt : bytes -> char -> int option

rindex_opt s c returns the index of the last occurrence of byte c in s or None if c does not occur in s.

  • since 4.05
val index_from : bytes -> int -> char -> int

index_from s i c returns the index of the first occurrence of byte c in s after position i. index s c is equivalent to index_from s 0 c.

  • raises Not_found

    if c does not occur in s after position i.

val index_from_opt : bytes -> int -> char -> int option

index_from_opt s i c returns the index of the first occurrence of byte c in s after position i or None if c does not occur in s after position i. index_opt s c is equivalent to index_from_opt s 0 c.

  • since 4.05
val rindex_from : bytes -> int -> char -> int

rindex_from s i c returns the index of the last occurrence of byte c in s before position i+1. rindex s c is equivalent to rindex_from s (length s - 1) c.

  • raises Not_found

    if c does not occur in s before position i+1.

val rindex_from_opt : bytes -> int -> char -> int option

rindex_from_opt s i c returns the index of the last occurrence of byte c in s before position i+1 or None if c does not occur in s before position i+1. rindex_opt s c is equivalent to rindex_from s (length s - 1) c.

  • since 4.05
val contains : bytes -> char -> bool

contains s c tests if byte c appears in s.

val contains_from : bytes -> int -> char -> bool

contains_from s start c tests if byte c appears in s after position start. contains s c is equivalent to contains_from + s 0 c.

val rcontains_from : bytes -> int -> char -> bool

rcontains_from s stop c tests if byte c appears in s before position stop+1.

val uppercase_ascii : bytes -> bytes

Return a copy of the argument, with all lowercase letters translated to uppercase, using the US-ASCII character set.

  • since 4.05
val lowercase_ascii : bytes -> bytes

Return a copy of the argument, with all uppercase letters translated to lowercase, using the US-ASCII character set.

  • since 4.05
val capitalize_ascii : bytes -> bytes

Return a copy of the argument, with the first character set to uppercase, using the US-ASCII character set.

  • since 4.05
val uncapitalize_ascii : bytes -> bytes

Return a copy of the argument, with the first character set to lowercase, using the US-ASCII character set.

  • since 4.05
type t = bytes

An alias for the type of byte sequences.

val compare : t -> t -> int

The comparison function for byte sequences, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Bytes to be passed as argument to the functors Set.Make and Map.Make.

val equal : t -> t -> bool

The equality function for byte sequences.

  • since 4.05
val starts_with : prefix:bytes -> bytes -> bool

starts_with ~prefix s is true if and only if s starts with prefix.

  • since 4.13
val ends_with : suffix:bytes -> bytes -> bool

ends_with ~suffix s is true if and only if s ends with suffix.

  • since 4.13

Unsafe conversions (for advanced users)

This section describes unsafe, low-level conversion functions between bytes and string. They do not copy the internal data; used improperly, they can break the immutability invariant on strings provided by the -safe-string option. They are available for expert library authors, but for most purposes you should use the always-correct to_string and of_string instead.

val unsafe_to_string : bytes -> string

Unsafely convert a byte sequence into a string.

To reason about the use of unsafe_to_string, it is convenient to consider an "ownership" discipline. A piece of code that manipulates some data "owns" it; there are several disjoint ownership modes, including:

  • Unique ownership: the data may be accessed and mutated
  • Shared ownership: the data has several owners, that may only access it, not mutate it.

Unique ownership is linear: passing the data to another piece of code means giving up ownership (we cannot write the data again). A unique owner may decide to make the data shared (giving up mutation rights on it), but shared data may not become uniquely-owned again.

unsafe_to_string s can only be used when the caller owns the byte sequence s -- either uniquely or as shared immutable data. The caller gives up ownership of s, and gains ownership of the returned string.

There are two valid use-cases that respect this ownership discipline:

1. Creating a string by initializing and mutating a byte sequence that is never changed after initialization is performed.

let string_init len f : string =
+  let s = Bytes.create len in
+  for i = 0 to len - 1 do Bytes.set s i (f i) done;
+  Bytes.unsafe_to_string s

This function is safe because the byte sequence s will never be accessed or mutated after unsafe_to_string is called. The string_init code gives up ownership of s, and returns the ownership of the resulting string to its caller.

Note that it would be unsafe if s was passed as an additional parameter to the function f as it could escape this way and be mutated in the future -- string_init would give up ownership of s to pass it to f, and could not call unsafe_to_string safely.

We have provided the String.init, String.map and String.mapi functions to cover most cases of building new strings. You should prefer those over to_string or unsafe_to_string whenever applicable.

2. Temporarily giving ownership of a byte sequence to a function that expects a uniquely owned string and returns ownership back, so that we can mutate the sequence again after the call ended.

let bytes_length (s : bytes) =
+  String.length (Bytes.unsafe_to_string s)

In this use-case, we do not promise that s will never be mutated after the call to bytes_length s. The String.length function temporarily borrows unique ownership of the byte sequence (and sees it as a string), but returns this ownership back to the caller, which may assume that s is still a valid byte sequence after the call. Note that this is only correct because we know that String.length does not capture its argument -- it could escape by a side-channel such as a memoization combinator.

The caller may not mutate s while the string is borrowed (it has temporarily given up ownership). This affects concurrent programs, but also higher-order functions: if String.length returned a closure to be called later, s should not be mutated until this closure is fully applied and returns ownership.

val unsafe_of_string : string -> bytes

Unsafely convert a shared string to a byte sequence that should not be mutated.

The same ownership discipline that makes unsafe_to_string correct applies to unsafe_of_string: you may use it if you were the owner of the string value, and you will own the return bytes in the same mode.

In practice, unique ownership of string values is extremely difficult to reason about correctly. You should always assume strings are shared, never uniquely owned.

For example, string literals are implicitly shared by the compiler, so you never uniquely own them.

let incorrect = Bytes.unsafe_of_string "hello"
+let s = Bytes.of_string "hello"

The first declaration is incorrect, because the string literal "hello" could be shared by the compiler with other parts of the program, and mutating incorrect is a bug. You must always use the second version, which performs a copy and is thus correct.

Assuming unique ownership of strings that are not string literals, but are (partly) built from string literals, is also incorrect. For example, mutating unsafe_of_string ("foo" ^ s) could mutate the shared string "foo" -- assuming a rope-like representation of strings. More generally, functions operating on strings will assume shared ownership, they do not preserve unique ownership. It is thus incorrect to assume unique ownership of the result of unsafe_of_string.

The only case we have reasonable confidence is safe is if the produced bytes is shared -- used as an immutable byte sequence. This is possibly useful for incremental migration of low-level programs that manipulate immutable sequences of bytes (for example Marshal.from_bytes) and previously used the string type for this purpose.

val split_on_char : sep:char -> bytes -> bytes list

split_on_char sep s returns the list of all (possibly empty) subsequences of s that are delimited by the sep character.

The function's output is specified by the following invariants:

  • The list is not empty.
  • Concatenating its elements using sep as a separator returns a byte sequence equal to the input (Bytes.concat (Bytes.make 1 sep) + (Bytes.split_on_char sep s) = s).
  • No byte sequence in the result contains the sep character.
  • since 4.13

Iterators

val to_seq : t -> char Seq.t

Iterate on the string, in increasing index order. Modifications of the string during iteration will be reflected in the sequence.

  • since 4.07
val to_seqi : t -> (int * char) Seq.t

Iterate on the string, in increasing order, yielding indices along chars

  • since 4.07
val of_seq : char Seq.t -> t

Create a string from the generator

  • since 4.07

UTF codecs and validations

  • since 4.14

UTF-8

val get_utf_8_uchar : t -> int -> Uchar.utf_decode

get_utf_8_uchar b i decodes an UTF-8 character at index i in b.

val set_utf_8_uchar : t -> int -> Uchar.t -> int

set_utf_8_uchar b i u UTF-8 encodes u at index i in b and returns the number of bytes n that were written starting at i. If n is 0 there was not enough space to encode u at i and b was left untouched. Otherwise a new character can be encoded at i + n.

val is_valid_utf_8 : t -> bool

is_valid_utf_8 b is true if and only if b contains valid UTF-8 data.

UTF-16BE

val get_utf_16be_uchar : t -> int -> Uchar.utf_decode

get_utf_16be_uchar b i decodes an UTF-16BE character at index i in b.

val set_utf_16be_uchar : t -> int -> Uchar.t -> int

set_utf_16be_uchar b i u UTF-16BE encodes u at index i in b and returns the number of bytes n that were written starting at i. If n is 0 there was not enough space to encode u at i and b was left untouched. Otherwise a new character can be encoded at i + n.

val is_valid_utf_16be : t -> bool

is_valid_utf_16be b is true if and only if b contains valid UTF-16BE data.

UTF-16LE

val get_utf_16le_uchar : t -> int -> Uchar.utf_decode

get_utf_16le_uchar b i decodes an UTF-16LE character at index i in b.

val set_utf_16le_uchar : t -> int -> Uchar.t -> int

set_utf_16le_uchar b i u UTF-16LE encodes u at index i in b and returns the number of bytes n that were written starting at i. If n is 0 there was not enough space to encode u at i and b was left untouched. Otherwise a new character can be encoded at i + n.

val is_valid_utf_16le : t -> bool

is_valid_utf_16le b is true if and only if b contains valid UTF-16LE data.

Binary encoding/decoding of integers

The functions in this section binary encode and decode integers to and from byte sequences.

All following functions raise Invalid_argument if the space needed at index i to decode or encode the integer is not available.

Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order. Native-endian encoding is either little-endian or big-endian depending on Sys.big_endian.

32-bit and 64-bit integers are represented by the int32 and int64 types, which can be interpreted either as signed or unsigned numbers.

8-bit and 16-bit integers are represented by the int type, which has more bits than the binary encoding. These extra bits are handled as follows:

  • Functions that decode signed (resp. unsigned) 8-bit or 16-bit integers represented by int values sign-extend (resp. zero-extend) their result.
  • Functions that encode 8-bit or 16-bit integers represented by int values truncate their input to their least significant bytes.
val get_uint8 : bytes -> int -> int

get_uint8 b i is b's unsigned 8-bit integer starting at byte index i.

  • since 4.08
val get_int8 : bytes -> int -> int

get_int8 b i is b's signed 8-bit integer starting at byte index i.

  • since 4.08
val get_uint16_ne : bytes -> int -> int

get_uint16_ne b i is b's native-endian unsigned 16-bit integer starting at byte index i.

  • since 4.08
val get_uint16_be : bytes -> int -> int

get_uint16_be b i is b's big-endian unsigned 16-bit integer starting at byte index i.

  • since 4.08
val get_uint16_le : bytes -> int -> int

get_uint16_le b i is b's little-endian unsigned 16-bit integer starting at byte index i.

  • since 4.08
val get_int16_ne : bytes -> int -> int

get_int16_ne b i is b's native-endian signed 16-bit integer starting at byte index i.

  • since 4.08
val get_int16_be : bytes -> int -> int

get_int16_be b i is b's big-endian signed 16-bit integer starting at byte index i.

  • since 4.08
val get_int16_le : bytes -> int -> int

get_int16_le b i is b's little-endian signed 16-bit integer starting at byte index i.

  • since 4.08
val get_int32_ne : bytes -> int -> int32

get_int32_ne b i is b's native-endian 32-bit integer starting at byte index i.

  • since 4.08
val get_int32_be : bytes -> int -> int32

get_int32_be b i is b's big-endian 32-bit integer starting at byte index i.

  • since 4.08
val get_int32_le : bytes -> int -> int32

get_int32_le b i is b's little-endian 32-bit integer starting at byte index i.

  • since 4.08
val get_int64_ne : bytes -> int -> int64

get_int64_ne b i is b's native-endian 64-bit integer starting at byte index i.

  • since 4.08
val get_int64_be : bytes -> int -> int64

get_int64_be b i is b's big-endian 64-bit integer starting at byte index i.

  • since 4.08
val get_int64_le : bytes -> int -> int64

get_int64_le b i is b's little-endian 64-bit integer starting at byte index i.

  • since 4.08
val set_uint8 : bytes -> int -> int -> unit

set_uint8 b i v sets b's unsigned 8-bit integer starting at byte index i to v.

  • since 4.08
val set_int8 : bytes -> int -> int -> unit

set_int8 b i v sets b's signed 8-bit integer starting at byte index i to v.

  • since 4.08
val set_uint16_ne : bytes -> int -> int -> unit

set_uint16_ne b i v sets b's native-endian unsigned 16-bit integer starting at byte index i to v.

  • since 4.08
val set_uint16_be : bytes -> int -> int -> unit

set_uint16_be b i v sets b's big-endian unsigned 16-bit integer starting at byte index i to v.

  • since 4.08
val set_uint16_le : bytes -> int -> int -> unit

set_uint16_le b i v sets b's little-endian unsigned 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int16_ne : bytes -> int -> int -> unit

set_int16_ne b i v sets b's native-endian signed 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int16_be : bytes -> int -> int -> unit

set_int16_be b i v sets b's big-endian signed 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int16_le : bytes -> int -> int -> unit

set_int16_le b i v sets b's little-endian signed 16-bit integer starting at byte index i to v.

  • since 4.08
val set_int32_ne : bytes -> int -> int32 -> unit

set_int32_ne b i v sets b's native-endian 32-bit integer starting at byte index i to v.

  • since 4.08
val set_int32_be : bytes -> int -> int32 -> unit

set_int32_be b i v sets b's big-endian 32-bit integer starting at byte index i to v.

  • since 4.08
val set_int32_le : bytes -> int -> int32 -> unit

set_int32_le b i v sets b's little-endian 32-bit integer starting at byte index i to v.

  • since 4.08
val set_int64_ne : bytes -> int -> int64 -> unit

set_int64_ne b i v sets b's native-endian 64-bit integer starting at byte index i to v.

  • since 4.08
val set_int64_be : bytes -> int -> int64 -> unit

set_int64_be b i v sets b's big-endian 64-bit integer starting at byte index i to v.

  • since 4.08
val set_int64_le : bytes -> int -> int64 -> unit

set_int64_le b i v sets b's little-endian 64-bit integer starting at byte index i to v.

  • since 4.08

Byte sequences and concurrency safety

Care must be taken when concurrently accessing byte sequences from multiple domains: accessing a byte sequence will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every byte sequence operation that accesses more than one byte is not atomic. This includes iteration and scanning.

For example, consider the following program:

let size = 100_000_000
+let b = Bytes.make size  ' '
+let update b f ()  =
+  Bytes.iteri (fun i x -> Bytes.set b i (Char.chr (f (Char.code x)))) b
+let d1 = Domain.spawn (update b (fun x -> x + 1))
+let d2 = Domain.spawn (update b (fun x -> 2 * x + 1))
+let () = Domain.join d1; Domain.join d2

the bytes sequence b may contain a non-deterministic mixture of '!', 'A', 'B', and 'C' values.

After executing this code, each byte of the sequence b is either '!', 'A', 'B', or 'C'. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of a byte sequence, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same byte without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the elements of the sequence.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location.

Mixed-size accesses

Another subtle point is that if a data race involves mixed-size writes and reads to the same location, the order in which those writes and reads are observed by domains is not specified. For instance, the following code write sequentially a 32-bit integer and a char to the same index

let b = Bytes.make 10 '\000'
+let d1 = Domain.spawn (fun () -> Bytes.set_int32_ne b 0 100; b.[0] <- 'd' )

In this situation, a domain that observes the write of 'd' to b.0 is not guaranteed to also observe the write to indices 1, 2, or 3.

diff --git a/docs/stdlib/Stdlib/Callback/index.html b/docs/stdlib/Stdlib/Callback/index.html new file mode 100644 index 00000000..c9ece54d --- /dev/null +++ b/docs/stdlib/Stdlib/Callback/index.html @@ -0,0 +1,2 @@ + +Callback (docs.stdlib.Stdlib.Callback)

Module Stdlib.Callback

Registering OCaml values with the C runtime.

This module allows OCaml values to be registered with the C runtime under a symbolic name, so that C code can later call back registered OCaml functions, or raise registered OCaml exceptions.

val register : string -> 'a -> unit

Callback.register n v registers the value v under the name n. C code can later retrieve a handle to v by calling caml_named_value(n).

val register_exception : string -> exn -> unit

Callback.register_exception n exn registers the exception contained in the exception value exn under the name n. C code can later retrieve a handle to the exception by calling caml_named_value(n). The exception value thus obtained is suitable for passing as first argument to raise_constant or raise_with_arg.

diff --git a/docs/stdlib/Stdlib/Char/index.html b/docs/stdlib/Stdlib/Char/index.html new file mode 100644 index 00000000..2050c7ea --- /dev/null +++ b/docs/stdlib/Stdlib/Char/index.html @@ -0,0 +1,2 @@ + +Char (docs.stdlib.Stdlib.Char)

Module Stdlib.Char

Character operations.

val code : char -> int

Return the ASCII code of the argument.

val chr : int -> char

Return the character with the given ASCII code.

val escaped : char -> string

Return a string representing the given character, with special characters escaped following the lexical conventions of OCaml. All characters outside the ASCII printable range (32..126) are escaped, as well as backslash, double-quote, and single-quote.

val lowercase_ascii : char -> char

Convert the given character to its equivalent lowercase character, using the US-ASCII character set.

  • since 4.03
val uppercase_ascii : char -> char

Convert the given character to its equivalent uppercase character, using the US-ASCII character set.

  • since 4.03
type t = char

An alias for the type of characters.

val compare : t -> t -> int

The comparison function for characters, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Char to be passed as argument to the functors Set.Make and Map.Make.

val equal : t -> t -> bool

The equal function for chars.

  • since 4.03
val seeded_hash : int -> t -> int

A seeded hash function for characters, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : t -> int

An unseeded hash function for characters, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Complex/index.html b/docs/stdlib/Stdlib/Complex/index.html new file mode 100644 index 00000000..d92a3e0e --- /dev/null +++ b/docs/stdlib/Stdlib/Complex/index.html @@ -0,0 +1,2 @@ + +Complex (docs.stdlib.Stdlib.Complex)

Module Stdlib.Complex

Complex numbers.

This module provides arithmetic operations on complex numbers. Complex numbers are represented by their real and imaginary parts (cartesian representation). Each part is represented by a double-precision floating-point number (type float).

type t = {
  1. re : float;
  2. im : float;
}

The type of complex numbers. re is the real part and im the imaginary part.

val zero : t

The complex number 0.

val one : t

The complex number 1.

val i : t

The complex number i.

val neg : t -> t

Unary negation.

val conj : t -> t

Conjugate: given the complex x + i.y, returns x - i.y.

val add : t -> t -> t

Addition

val sub : t -> t -> t

Subtraction

val mul : t -> t -> t

Multiplication

val inv : t -> t

Multiplicative inverse (1/z).

val div : t -> t -> t

Division

val sqrt : t -> t

Square root. The result x + i.y is such that x > 0 or x = 0 and y >= 0. This function has a discontinuity along the negative real axis.

val norm2 : t -> float

Norm squared: given x + i.y, returns x^2 + y^2.

val norm : t -> float

Norm: given x + i.y, returns sqrt(x^2 + y^2).

val arg : t -> float

Argument. The argument of a complex number is the angle in the complex plane between the positive real axis and a line passing through zero and the number. This angle ranges from -pi to pi. This function has a discontinuity along the negative real axis.

val polar : float -> float -> t

polar norm arg returns the complex having norm norm and argument arg.

val exp : t -> t

Exponentiation. exp z returns e to the z power.

val log : t -> t

Natural logarithm (in base e).

val pow : t -> t -> t

Power function. pow z1 z2 returns z1 to the z2 power.

diff --git a/docs/stdlib/Stdlib/Condition/index.html b/docs/stdlib/Stdlib/Condition/index.html new file mode 100644 index 00000000..4fa1938a --- /dev/null +++ b/docs/stdlib/Stdlib/Condition/index.html @@ -0,0 +1,31 @@ + +Condition (docs.stdlib.Stdlib.Condition)

Module Stdlib.Condition

Condition variables.

Condition variables are useful when several threads wish to access a shared data structure that is protected by a mutex (a mutual exclusion lock).

A condition variable is a communication channel. On the receiver side, one or more threads can indicate that they wish to wait for a certain property to become true. On the sender side, a thread can signal that this property has become true, causing one (or more) waiting threads to be woken up.

For instance, in the implementation of a queue data structure, if a thread that wishes to extract an element finds that the queue is currently empty, then this thread waits for the queue to become nonempty. A thread that inserts an element into the queue signals that the queue has become nonempty. A condition variable is used for this purpose. This communication channel conveys the information that the property "the queue is nonempty" is true, or more accurately, may be true. (We explain below why the receiver of a signal cannot be certain that the property holds.)

To continue the example of the queue, assuming that the queue has a fixed maximum capacity, then a thread that wishes to insert an element may find that the queue is full. Then, this thread must wait for the queue to become not full, and a thread that extracts an element of the queue signals that the queue has become not full. Another condition variable is used for this purpose.

In short, a condition variable c is used to convey the information that a certain property P about a shared data structure D, protected by a mutex m, may be true.

Condition variables provide an efficient alternative to busy-waiting. When one wishes to wait for the property P to be true, instead of writing a busy-waiting loop:

Mutex.lock m;
+while not P do
+  Mutex.unlock m; Mutex.lock m
+done;
+<update the data structure>;
+Mutex.unlock m

one uses wait in the body of the loop, as follows:

Mutex.lock m;
+while not P do
+  Condition.wait c m
+done;
+<update the data structure>;
+Mutex.unlock m

The busy-waiting loop is inefficient because the waiting thread consumes processing time and creates contention of the mutex m. Calling wait allows the waiting thread to be suspended, so it does not consume any computing resources while waiting.

With a condition variable c, exactly one mutex m is associated. This association is implicit: the mutex m is not explicitly passed as an argument to create. It is up to the programmer to know, for each condition variable c, which is the associated mutex m.

With a mutex m, several condition variables can be associated. In the example of the bounded queue, one condition variable is used to indicate that the queue is nonempty, and another condition variable is used to indicate that the queue is not full.

With a condition variable c, exactly one logical property P should be associated. Examples of such properties include "the queue is nonempty" and "the queue is not full". It is up to the programmer to keep track, for each condition variable, of the corresponding property P. A signal is sent on the condition variable c as an indication that the property P is true, or may be true. On the receiving end, however, a thread that is woken up cannot assume that P is true; after a call to wait terminates, one must explicitly test whether P is true. There are several reasons why this is so. One reason is that, between the moment when the signal is sent and the moment when a waiting thread receives the signal and is scheduled, the property P may be falsified by some other thread that is able to acquire the mutex m and alter the data structure D. Another reason is that spurious wakeups may occur: a waiting thread can be woken up even if no signal was sent.

Here is a complete example, where a mutex protects a sequential unbounded queue, and where a condition variable is used to signal that the queue is nonempty.

type 'a safe_queue =
+  { queue : 'a Queue.t; mutex : Mutex.t; nonempty : Condition.t }
+
+let create () =
+  { queue = Queue.create(); mutex = Mutex.create();
+    nonempty = Condition.create() }
+
+let add v q =
+  Mutex.lock q.mutex;
+  let was_empty = Queue.is_empty q.queue in
+  Queue.add v q.queue;
+  if was_empty then Condition.broadcast q.nonempty;
+  Mutex.unlock q.mutex
+
+let take q =
+  Mutex.lock q.mutex;
+  while Queue.is_empty q.queue do Condition.wait q.nonempty q.mutex done;
+  let v = Queue.take q.queue in (* cannot fail since queue is nonempty *)
+  Mutex.unlock q.mutex;
+  v

Because the call to broadcast takes place inside the critical section, the following property holds whenever the mutex is unlocked: if the queue is nonempty, then no thread is waiting, or, in other words, if some thread is waiting, then the queue must be empty. This is a desirable property: if a thread that attempts to execute a take operation could remain suspended even though the queue is nonempty, that would be a problematic situation, known as a deadlock.

type t

The type of condition variables.

val create : unit -> t

create() creates and returns a new condition variable. This condition variable should be associated (in the programmer's mind) with a certain mutex m and with a certain property P of the data structure that is protected by the mutex m.

val wait : t -> Mutex.t -> unit

The call wait c m is permitted only if m is the mutex associated with the condition variable c, and only if m is currently locked. This call atomically unlocks the mutex m and suspends the current thread on the condition variable c. This thread can later be woken up after the condition variable c has been signaled via signal or broadcast; however, it can also be woken up for no reason. The mutex m is locked again before wait returns. One cannot assume that the property P associated with the condition variable c holds when wait returns; one must explicitly test whether P holds after calling wait.

val signal : t -> unit

signal c wakes up one of the threads waiting on the condition variable c, if there is one. If there is none, this call has no effect.

It is recommended to call signal c inside a critical section, that is, while the mutex m associated with c is locked.

val broadcast : t -> unit

broadcast c wakes up all threads waiting on the condition variable c. If there are none, this call has no effect.

It is recommended to call broadcast c inside a critical section, that is, while the mutex m associated with c is locked.

diff --git a/docs/stdlib/Stdlib/Digest/index.html b/docs/stdlib/Stdlib/Digest/index.html new file mode 100644 index 00000000..06cb5e1d --- /dev/null +++ b/docs/stdlib/Stdlib/Digest/index.html @@ -0,0 +1,2 @@ + +Digest (docs.stdlib.Stdlib.Digest)

Module Stdlib.Digest

MD5 message digest.

This module provides functions to compute 128-bit 'digests' of arbitrary-length strings or files. The algorithm used is MD5.

The MD5 hash function is not cryptographically secure. Hence, this module should not be used for security-sensitive applications. More recent, stronger cryptographic primitives should be used instead.

type t = string

The type of digests: 16-character strings.

val compare : t -> t -> int

The comparison function for 16-character digest, with the same specification as Stdlib.compare and the implementation shared with String.compare. Along with the type t, this function compare allows the module Digest to be passed as argument to the functors Set.Make and Map.Make.

  • since 4.00
val equal : t -> t -> bool

The equal function for 16-character digest.

  • since 4.03
val string : string -> t

Return the digest of the given string.

val bytes : bytes -> t

Return the digest of the given byte sequence.

  • since 4.02
val substring : string -> int -> int -> t

Digest.substring s ofs len returns the digest of the substring of s starting at index ofs and containing len characters.

val subbytes : bytes -> int -> int -> t

Digest.subbytes s ofs len returns the digest of the subsequence of s starting at index ofs and containing len bytes.

  • since 4.02
val channel : in_channel -> int -> t

If len is nonnegative, Digest.channel ic len reads len characters from channel ic and returns their digest, or raises End_of_file if end-of-file is reached before len characters are read. If len is negative, Digest.channel ic len reads all characters from ic until end-of-file is reached and return their digest.

val file : string -> t

Return the digest of the file whose name is given.

val output : out_channel -> t -> unit

Write a digest on the given output channel.

val input : in_channel -> t

Read a digest from the given input channel.

val to_hex : t -> string

Return the printable hexadecimal representation of the given digest.

val from_hex : string -> t

Convert a hexadecimal representation back into the corresponding digest.

  • raises Invalid_argument

    if the argument is not exactly 32 hexadecimal characters.

  • since 4.00
diff --git a/docs/stdlib/Stdlib/Domain/DLS/index.html b/docs/stdlib/Stdlib/Domain/DLS/index.html new file mode 100644 index 00000000..6991ae4e --- /dev/null +++ b/docs/stdlib/Stdlib/Domain/DLS/index.html @@ -0,0 +1,12 @@ + +DLS (docs.stdlib.Stdlib.Domain.DLS)

Module Domain.DLS

Domain-local Storage

type 'a key

Type of a DLS key

val new_key : ?split_from_parent:('a -> 'a) -> (unit -> 'a) -> 'a key

new_key f returns a new key bound to initialiser f for accessing , domain-local variables.

If split_from_parent is not provided, the value for a new domain will be computed on-demand by the new domain: the first get call will call the initializer f and store that value.

If split_from_parent is provided, spawning a domain will derive the child value (for this key) from the parent value. This computation happens in the parent domain and it always happens, regardless of whether the child domain will use it. If the splitting function is expensive or requires child-side computation, consider using 'a Lazy.t key:

let init () = ...
+
+let split_from_parent parent_value =
+  ... parent-side computation ...;
+  lazy (
+    ... child-side computation ...
+  )
+
+let key = Domain.DLS.new_key ~split_from_parent init
+
+let get () = Lazy.force (Domain.DLS.get key)

In this case a part of the computation happens on the child domain; in particular, it can access parent_value concurrently with the parent domain, which may require explicit synchronization to avoid data races.

val get : 'a key -> 'a

get k returns v if a value v is associated to the key k on the calling domain's domain-local state. Sets k's value with its initialiser and returns it otherwise.

val set : 'a key -> 'a -> unit

set k v updates the calling domain's domain-local state to associate the key k with value v. It overwrites any previous values associated to k, which cannot be restored later.

diff --git a/docs/stdlib/Stdlib/Domain/index.html b/docs/stdlib/Stdlib/Domain/index.html new file mode 100644 index 00000000..d1c03ca8 --- /dev/null +++ b/docs/stdlib/Stdlib/Domain/index.html @@ -0,0 +1,5 @@ + +Domain (docs.stdlib.Stdlib.Domain)

Module Stdlib.Domain

  • alert unstable The Domain interface may change in incompatible ways in the future.

Domains.

See 'Parallel programming' chapter in the manual.

  • since 5.0
  • alert unstable The Domain interface may change in incompatible ways in the future.
type !'a t

A domain of type 'a t runs independently, eventually producing a result of type 'a, or an exception

val spawn : (unit -> 'a) -> 'a t

spawn f creates a new domain that runs in parallel with the current domain.

  • raises Failure

    if the program has insufficient resources to create another domain.

val join : 'a t -> 'a

join d blocks until domain d runs to completion. If d results in a value, then that is returned by join d. If d raises an uncaught exception, then that is re-raised by join d.

type id = private int

Domains have unique integer identifiers

val get_id : 'a t -> id

get_id d returns the identifier of the domain d

val self : unit -> id

self () is the identifier of the currently running domain

val before_first_spawn : (unit -> unit) -> unit

before_first_spawn f registers f to be called before the first domain is spawned by the program. The functions registered with before_first_spawn are called on the main (initial) domain. The functions registered with before_first_spawn are called in 'first in, first out' order: the oldest function added with before_first_spawn is called first.

val at_exit : (unit -> unit) -> unit

at_exit f registers f to be called when the current domain exits. Note that at_exit callbacks are domain-local and only apply to the calling domain. The registered functions are called in 'last in, first out' order: the function most recently added with at_exit is called first. An example:

let temp_file_key = Domain.DLS.new_key (fun _ ->
+  let tmp = snd (Filename.open_temp_file "" "") in
+  Domain.at_exit (fun () -> close_out_noerr tmp);
+  tmp)

The snippet above creates a key that when retrieved for the first time will open a temporary file and register an at_exit callback to close it, thus guaranteeing the descriptor is not leaked in case the current domain exits.

val cpu_relax : unit -> unit

If busy-waiting, calling cpu_relax () between iterations will improve performance on some CPU architectures

val is_main_domain : unit -> bool

is_main_domain () returns true if called from the initial domain.

The recommended maximum number of domains which should be running simultaneously (including domains already running).

The value returned is at least 1.

module DLS : sig ... end

Domain-local Storage

diff --git a/docs/stdlib/Stdlib/Effect/Deep/index.html b/docs/stdlib/Stdlib/Effect/Deep/index.html new file mode 100644 index 00000000..6d3f36db --- /dev/null +++ b/docs/stdlib/Stdlib/Effect/Deep/index.html @@ -0,0 +1,6 @@ + +Deep (docs.stdlib.Stdlib.Effect.Deep)

Module Effect.Deep

Deep handlers

type ('a, 'b) continuation

('a,'b) continuation is a delimited continuation that expects a 'a value and returns a 'b value.

val continue : ('a, 'b) continuation -> 'a -> 'b

continue k x resumes the continuation k by passing x to k.

val discontinue : ('a, 'b) continuation -> exn -> 'b

discontinue k e resumes the continuation k by raising the exception e in k.

val discontinue_with_backtrace : + ('a, 'b) continuation -> + exn -> + Printexc.raw_backtrace -> + 'b

discontinue_with_backtrace k e bt resumes the continuation k by raising the exception e in k using bt as the origin for the exception.

type ('a, 'b) handler = {
  1. retc : 'a -> 'b;
  2. exnc : exn -> 'b;
  3. effc : 'c. 'c t -> (('c, 'b) continuation -> 'b) option;
}

('a,'b) handler is a handler record with three fields -- retc is the value handler, exnc handles exceptions, and effc handles the effects performed by the computation enclosed by the handler.

val match_with : ('c -> 'a) -> 'c -> ('a, 'b) handler -> 'b

match_with f v h runs the computation f v in the handler h.

type 'a effect_handler = {
  1. effc : 'b. 'b t -> (('b, 'a) continuation -> 'a) option;
}

'a effect_handler is a deep handler with an identity value handler fun x -> x and an exception handler that raises any exception fun e -> raise e.

val try_with : ('b -> 'a) -> 'b -> 'a effect_handler -> 'a

try_with f v h runs the computation f v under the handler h.

val get_callstack : ('a, 'b) continuation -> int -> Printexc.raw_backtrace

get_callstack c n returns a description of the top of the call stack on the continuation c, with at most n entries.

diff --git a/docs/stdlib/Stdlib/Effect/Shallow/index.html b/docs/stdlib/Stdlib/Effect/Shallow/index.html new file mode 100644 index 00000000..e476b10d --- /dev/null +++ b/docs/stdlib/Stdlib/Effect/Shallow/index.html @@ -0,0 +1,7 @@ + +Shallow (docs.stdlib.Stdlib.Effect.Shallow)

Module Effect.Shallow

type ('a, 'b) continuation

('a,'b) continuation is a delimited continuation that expects a 'a value and returns a 'b value.

val fiber : ('a -> 'b) -> ('a, 'b) continuation

fiber f constructs a continuation that runs the computation f.

type ('a, 'b) handler = {
  1. retc : 'a -> 'b;
  2. exnc : exn -> 'b;
  3. effc : 'c. 'c t -> (('c, 'a) continuation -> 'b) option;
}

('a,'b) handler is a handler record with three fields -- retc is the value handler, exnc handles exceptions, and effc handles the effects performed by the computation enclosed by the handler.

val continue_with : ('c, 'a) continuation -> 'c -> ('a, 'b) handler -> 'b

continue_with k v h resumes the continuation k with value v with the handler h.

val discontinue_with : ('c, 'a) continuation -> exn -> ('a, 'b) handler -> 'b

discontinue_with k e h resumes the continuation k by raising the exception e with the handler h.

val discontinue_with_backtrace : + ('a, 'b) continuation -> + exn -> + Printexc.raw_backtrace -> + ('b, 'c) handler -> + 'c

discontinue_with k e bt h resumes the continuation k by raising the exception e with the handler h using the raw backtrace bt as the origin of the exception.

val get_callstack : ('a, 'b) continuation -> int -> Printexc.raw_backtrace

get_callstack c n returns a description of the top of the call stack on the continuation c, with at most n entries.

diff --git a/docs/stdlib/Stdlib/Effect/index.html b/docs/stdlib/Stdlib/Effect/index.html new file mode 100644 index 00000000..98d07ba3 --- /dev/null +++ b/docs/stdlib/Stdlib/Effect/index.html @@ -0,0 +1,2 @@ + +Effect (docs.stdlib.Stdlib.Effect)

Module Stdlib.Effect

  • alert unstable The Effect interface may change in incompatible ways in the future.

Effects.

See 'Language extensions/Effect handlers' section in the manual.

  • since 5.0
  • alert unstable The Effect interface may change in incompatible ways in the future.
type _ t = ..

The type of effects.

exception Unhandled : 'a t -> exn

Unhandled e is raised when effect e is performed and there is no handler for it.

exception Continuation_already_resumed

Exception raised when a continuation is continued or discontinued more than once.

val perform : 'a t -> 'a

perform e performs an effect e.

  • raises Unhandled

    if there is no handler for e.

module Deep : sig ... end

Deep handlers

module Shallow : sig ... end
diff --git a/docs/stdlib/Stdlib/Either/index.html b/docs/stdlib/Stdlib/Either/index.html new file mode 100644 index 00000000..305247da --- /dev/null +++ b/docs/stdlib/Stdlib/Either/index.html @@ -0,0 +1,17 @@ + +Either (docs.stdlib.Stdlib.Either)

Module Stdlib.Either

Either type.

Either is the simplest and most generic sum/variant type: a value of ('a, 'b) Either.t is either a Left (v : 'a) or a Right (v : 'b).

It is a natural choice in the API of generic functions where values could fall in two different cases, possibly at different types, without assigning a specific meaning to what each case should be.

For example:

List.partition_map:
+  ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list

If you are looking for a parametrized type where one alternative means success and the other means failure, you should use the more specific type Result.t.

  • since 4.12
type ('a, 'b) t =
  1. | Left of 'a
  2. | Right of 'b

A value of ('a, 'b) Either.t contains either a value of 'a or a value of 'b

val left : 'a -> ('a, 'b) t

left v is Left v.

val right : 'b -> ('a, 'b) t

right v is Right v.

val is_left : ('a, 'b) t -> bool

is_left (Left v) is true, is_left (Right v) is false.

val is_right : ('a, 'b) t -> bool

is_right (Left v) is false, is_right (Right v) is true.

val find_left : ('a, 'b) t -> 'a option

find_left (Left v) is Some v, find_left (Right _) is None

val find_right : ('a, 'b) t -> 'b option

find_right (Right v) is Some v, find_right (Left _) is None

val map_left : ('a1 -> 'a2) -> ('a1, 'b) t -> ('a2, 'b) t

map_left f e is Left (f v) if e is Left v and e if e is Right _.

val map_right : ('b1 -> 'b2) -> ('a, 'b1) t -> ('a, 'b2) t

map_right f e is Right (f v) if e is Right v and e if e is Left _.

val map : + left:('a1 -> 'a2) -> + right:('b1 -> 'b2) -> + ('a1, 'b1) t -> + ('a2, 'b2) t

map ~left ~right (Left v) is Left (left v), map ~left ~right (Right v) is Right (right v).

val fold : left:('a -> 'c) -> right:('b -> 'c) -> ('a, 'b) t -> 'c

fold ~left ~right (Left v) is left v, and fold ~left ~right (Right v) is right v.

val iter : left:('a -> unit) -> right:('b -> unit) -> ('a, 'b) t -> unit

iter ~left ~right (Left v) is left v, and iter ~left ~right (Right v) is right v.

val for_all : left:('a -> bool) -> right:('b -> bool) -> ('a, 'b) t -> bool

for_all ~left ~right (Left v) is left v, and for_all ~left ~right (Right v) is right v.

val equal : + left:('a -> 'a -> bool) -> + right:('b -> 'b -> bool) -> + ('a, 'b) t -> + ('a, 'b) t -> + bool

equal ~left ~right e0 e1 tests equality of e0 and e1 using left and right to respectively compare values wrapped by Left _ and Right _.

val compare : + left:('a -> 'a -> int) -> + right:('b -> 'b -> int) -> + ('a, 'b) t -> + ('a, 'b) t -> + int

compare ~left ~right e0 e1 totally orders e0 and e1 using left and right to respectively compare values wrapped by Left _ and Right _. Left _ values are smaller than Right _ values.

diff --git a/docs/stdlib/Stdlib/Ephemeron/K1/Bucket/index.html b/docs/stdlib/Stdlib/Ephemeron/K1/Bucket/index.html new file mode 100644 index 00000000..c4e07f2d --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K1/Bucket/index.html @@ -0,0 +1,2 @@ + +Bucket (docs.stdlib.Stdlib.Ephemeron.K1.Bucket)

Module K1.Bucket

type ('k, 'd) t

A bucket is a mutable "list" of ephemerons.

val make : unit -> ('k, 'd) t

Create a new bucket.

val add : ('k, 'd) t -> 'k -> 'd -> unit

Add an ephemeron to the bucket.

val remove : ('k, 'd) t -> 'k -> unit

remove b k removes from b the most-recently added ephemeron with key k, or does nothing if there is no such ephemeron.

val find : ('k, 'd) t -> 'k -> 'd option

Returns the data of the most-recently added ephemeron with the given key, or None if there is no such ephemeron.

val length : ('k, 'd) t -> int

Returns an upper bound on the length of the bucket.

val clear : ('k, 'd) t -> unit

Remove all ephemerons from the bucket.

diff --git a/docs/stdlib/Stdlib/Ephemeron/K1/Make/argument-1-H/index.html b/docs/stdlib/Stdlib/Ephemeron/K1/Make/argument-1-H/index.html new file mode 100644 index 00000000..114ce9bd --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K1/Make/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Ephemeron.K1.Make.H)

Parameter Make.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Ephemeron/K1/Make/index.html b/docs/stdlib/Stdlib/Ephemeron/K1/Make/index.html new file mode 100644 index 00000000..0474559c --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K1/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.Ephemeron.K1.Make)

Module K1.Make

Functor building an implementation of a weak hash table

Propose the same interface as usual hash table. However since the bindings are weak, even if mem h k is true, a subsequent find h k may raise Not_found because the garbage collector can run between the two.

Parameters

Signature

type key = H.t
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/argument-1-H/index.html b/docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/argument-1-H/index.html new file mode 100644 index 00000000..e06ed642 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Ephemeron.K1.MakeSeeded.H)

Parameter MakeSeeded.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/index.html b/docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/index.html new file mode 100644 index 00000000..5b925211 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K1/MakeSeeded/index.html @@ -0,0 +1,2 @@ + +MakeSeeded (docs.stdlib.Stdlib.Ephemeron.K1.MakeSeeded)

Module K1.MakeSeeded

Functor building an implementation of a weak hash table. The seed is similar to the one of Hashtbl.MakeSeeded.

Parameters

Signature

type key = H.t
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/K1/index.html b/docs/stdlib/Stdlib/Ephemeron/K1/index.html new file mode 100644 index 00000000..e46d5bc9 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K1/index.html @@ -0,0 +1,2 @@ + +K1 (docs.stdlib.Stdlib.Ephemeron.K1)

Module Ephemeron.K1

Ephemerons with one key.

type ('k, 'd) t

an ephemeron with one key

val make : 'k -> 'd -> ('k, 'd) t

Ephemeron.K1.make k d creates an ephemeron with key k and data d.

val query : ('k, 'd) t -> 'k -> 'd option

Ephemeron.K1.query eph key returns Some x (where x is the ephemeron's data) if key is physically equal to eph's key, and None if eph is empty or key is not equal to eph's key.

module Make (H : Hashtbl.HashedType) : S with type key = H.t

Functor building an implementation of a weak hash table

Functor building an implementation of a weak hash table. The seed is similar to the one of Hashtbl.MakeSeeded.

module Bucket : sig ... end
diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/Bucket/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/Bucket/index.html new file mode 100644 index 00000000..d276b67c --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/Bucket/index.html @@ -0,0 +1,2 @@ + +Bucket (docs.stdlib.Stdlib.Ephemeron.K2.Bucket)

Module K2.Bucket

type ('k1, 'k2, 'd) t

A bucket is a mutable "list" of ephemerons.

val make : unit -> ('k1, 'k2, 'd) t

Create a new bucket.

val add : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> 'd -> unit

Add an ephemeron to the bucket.

val remove : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> unit

remove b k1 k2 removes from b the most-recently added ephemeron with keys k1 and k2, or does nothing if there is no such ephemeron.

val find : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> 'd option

Returns the data of the most-recently added ephemeron with the given keys, or None if there is no such ephemeron.

val length : ('k1, 'k2, 'd) t -> int

Returns an upper bound on the length of the bucket.

val clear : ('k1, 'k2, 'd) t -> unit

Remove all ephemerons from the bucket.

diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-1-H1/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-1-H1/index.html new file mode 100644 index 00000000..b12c49c9 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-1-H1/index.html @@ -0,0 +1,2 @@ + +H1 (docs.stdlib.Stdlib.Ephemeron.K2.Make.H1)

Parameter Make.H1

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-2-H2/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-2-H2/index.html new file mode 100644 index 00000000..e553f3c9 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/Make/argument-2-H2/index.html @@ -0,0 +1,2 @@ + +H2 (docs.stdlib.Stdlib.Ephemeron.K2.Make.H2)

Parameter Make.H2

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/Make/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/Make/index.html new file mode 100644 index 00000000..4c7cc5b6 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.Ephemeron.K2.Make)

Module K2.Make

Functor building an implementation of a weak hash table

Propose the same interface as usual hash table. However since the bindings are weak, even if mem h k is true, a subsequent find h k may raise Not_found because the garbage collector can run between the two.

Parameters

Signature

type key = H1.t * H2.t
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-1-H1/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-1-H1/index.html new file mode 100644 index 00000000..fa8a6e3f --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-1-H1/index.html @@ -0,0 +1,2 @@ + +H1 (docs.stdlib.Stdlib.Ephemeron.K2.MakeSeeded.H1)

Parameter MakeSeeded.H1

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-2-H2/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-2-H2/index.html new file mode 100644 index 00000000..12e7cf7e --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/argument-2-H2/index.html @@ -0,0 +1,2 @@ + +H2 (docs.stdlib.Stdlib.Ephemeron.K2.MakeSeeded.H2)

Parameter MakeSeeded.H2

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/index.html new file mode 100644 index 00000000..24b0c1ec --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/MakeSeeded/index.html @@ -0,0 +1,2 @@ + +MakeSeeded (docs.stdlib.Stdlib.Ephemeron.K2.MakeSeeded)

Module K2.MakeSeeded

Functor building an implementation of a weak hash table. The seed is similar to the one of Hashtbl.MakeSeeded.

Parameters

Signature

type key = H1.t * H2.t
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/K2/index.html b/docs/stdlib/Stdlib/Ephemeron/K2/index.html new file mode 100644 index 00000000..19e6cfc2 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/K2/index.html @@ -0,0 +1,8 @@ + +K2 (docs.stdlib.Stdlib.Ephemeron.K2)

Module Ephemeron.K2

Ephemerons with two keys.

type ('k1, 'k2, 'd) t

an ephemeron with two keys

val make : 'k1 -> 'k2 -> 'd -> ('k1, 'k2, 'd) t
val query : ('k1, 'k2, 'd) t -> 'k1 -> 'k2 -> 'd option
module Make + (H1 : Hashtbl.HashedType) + (H2 : Hashtbl.HashedType) : + S with type key = H1.t * H2.t

Functor building an implementation of a weak hash table

Functor building an implementation of a weak hash table. The seed is similar to the one of Hashtbl.MakeSeeded.

module Bucket : sig ... end
diff --git a/docs/stdlib/Stdlib/Ephemeron/Kn/Bucket/index.html b/docs/stdlib/Stdlib/Ephemeron/Kn/Bucket/index.html new file mode 100644 index 00000000..7eb677c6 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/Kn/Bucket/index.html @@ -0,0 +1,2 @@ + +Bucket (docs.stdlib.Stdlib.Ephemeron.Kn.Bucket)

Module Kn.Bucket

type ('k, 'd) t

A bucket is a mutable "list" of ephemerons.

val make : unit -> ('k, 'd) t

Create a new bucket.

val add : ('k, 'd) t -> 'k array -> 'd -> unit

Add an ephemeron to the bucket.

val remove : ('k, 'd) t -> 'k array -> unit

remove b k removes from b the most-recently added ephemeron with keys k, or does nothing if there is no such ephemeron.

val find : ('k, 'd) t -> 'k array -> 'd option

Returns the data of the most-recently added ephemeron with the given keys, or None if there is no such ephemeron.

val length : ('k, 'd) t -> int

Returns an upper bound on the length of the bucket.

val clear : ('k, 'd) t -> unit

Remove all ephemerons from the bucket.

diff --git a/docs/stdlib/Stdlib/Ephemeron/Kn/Make/argument-1-H/index.html b/docs/stdlib/Stdlib/Ephemeron/Kn/Make/argument-1-H/index.html new file mode 100644 index 00000000..c85ccaa5 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/Kn/Make/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Ephemeron.Kn.Make.H)

Parameter Make.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Ephemeron/Kn/Make/index.html b/docs/stdlib/Stdlib/Ephemeron/Kn/Make/index.html new file mode 100644 index 00000000..c0c98253 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/Kn/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.Ephemeron.Kn.Make)

Module Kn.Make

Functor building an implementation of a weak hash table

Propose the same interface as usual hash table. However since the bindings are weak, even if mem h k is true, a subsequent find h k may raise Not_found because the garbage collector can run between the two.

Parameters

Signature

type key = H.t array
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/argument-1-H/index.html b/docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/argument-1-H/index.html new file mode 100644 index 00000000..80268ebb --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Ephemeron.Kn.MakeSeeded.H)

Parameter MakeSeeded.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/index.html b/docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/index.html new file mode 100644 index 00000000..a47dc20f --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/Kn/MakeSeeded/index.html @@ -0,0 +1,2 @@ + +MakeSeeded (docs.stdlib.Stdlib.Ephemeron.Kn.MakeSeeded)

Module Kn.MakeSeeded

Functor building an implementation of a weak hash table. The seed is similar to the one of Hashtbl.MakeSeeded.

Parameters

Signature

type key = H.t array
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/Kn/index.html b/docs/stdlib/Stdlib/Ephemeron/Kn/index.html new file mode 100644 index 00000000..3618b374 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/Kn/index.html @@ -0,0 +1,4 @@ + +Kn (docs.stdlib.Stdlib.Ephemeron.Kn)

Module Ephemeron.Kn

Ephemerons with arbitrary number of keys of the same type.

type ('k, 'd) t

an ephemeron with an arbitrary number of keys of the same type

val make : 'k array -> 'd -> ('k, 'd) t
val query : ('k, 'd) t -> 'k array -> 'd option
module Make (H : Hashtbl.HashedType) : S with type key = H.t array

Functor building an implementation of a weak hash table

module MakeSeeded + (H : Hashtbl.SeededHashedType) : + SeededS with type key = H.t array

Functor building an implementation of a weak hash table. The seed is similar to the one of Hashtbl.MakeSeeded.

module Bucket : sig ... end
diff --git a/docs/stdlib/Stdlib/Ephemeron/index.html b/docs/stdlib/Stdlib/Ephemeron/index.html new file mode 100644 index 00000000..286d78a0 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/index.html @@ -0,0 +1,2 @@ + +Ephemeron (docs.stdlib.Stdlib.Ephemeron)

Module Stdlib.Ephemeron

Ephemerons and weak hash tables.

Ephemerons and weak hash tables are useful when one wants to cache or memorize the computation of a function, as long as the arguments and the function are used, without creating memory leaks by continuously keeping old computation results that are not useful anymore because one argument or the function is freed. An implementation using Hashtbl.t is not suitable because all associations would keep the arguments and the result in memory.

Ephemerons can also be used for "adding" a field to an arbitrary boxed OCaml value: you can attach some information to a value created by an external library without memory leaks.

Ephemerons hold some keys and one or no data. They are all boxed OCaml values. The keys of an ephemeron have the same behavior as weak pointers according to the garbage collector. In fact OCaml weak pointers are implemented as ephemerons without data.

The keys and data of an ephemeron are said to be full if they point to a value, or empty if the value has never been set, has been unset, or was erased by the GC. In the function that accesses the keys or data these two states are represented by the option type.

The data is considered by the garbage collector alive if all the full keys are alive and if the ephemeron is alive. When one of the keys is not considered alive anymore by the GC, the data is emptied from the ephemeron. The data could be alive for another reason and in that case the GC will not free it, but the ephemeron will not hold the data anymore.

The ephemerons complicate the notion of liveness of values, because it is not anymore an equivalence with the reachability from root value by usual pointers (not weak and not ephemerons). With ephemerons the notion of liveness is constructed by the least fixpoint of: A value is alive if:

  • it is a root value
  • it is reachable from alive value by usual pointers
  • it is the data of an alive ephemeron with all its full keys alive

Notes:

Ephemerons are defined in a language agnostic way in this paper: B. Hayes, Ephemerons: A New Finalization Mechanism, OOPSLA'97

  • since 4.03

Unsynchronized accesses

Unsynchronized accesses to a weak hash table may lead to an invalid weak hash table state. Thus, concurrent accesses to a buffer must be synchronized (for instance with a Mutex.t).

module type S = sig ... end

The output signature of the functors K1.Make and K2.Make. These hash tables are weak in the keys. If all the keys of a binding are alive the binding is kept, but if one of the keys of the binding is dead then the binding is removed.

module type SeededS = sig ... end

The output signature of the functors K1.MakeSeeded and K2.MakeSeeded.

module K1 : sig ... end

Ephemerons with one key.

module K2 : sig ... end

Ephemerons with two keys.

module Kn : sig ... end

Ephemerons with arbitrary number of keys of the same type.

diff --git a/docs/stdlib/Stdlib/Ephemeron/module-type-S/index.html b/docs/stdlib/Stdlib/Ephemeron/module-type-S/index.html new file mode 100644 index 00000000..7667103c --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/module-type-S/index.html @@ -0,0 +1,2 @@ + +S (docs.stdlib.Stdlib.Ephemeron.S)

Module type Ephemeron.S

The output signature of the functors K1.Make and K2.Make. These hash tables are weak in the keys. If all the keys of a binding are alive the binding is kept, but if one of the keys of the binding is dead then the binding is removed.

Propose the same interface as usual hash table. However since the bindings are weak, even if mem h k is true, a subsequent find h k may raise Not_found because the garbage collector can run between the two.

type key
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Ephemeron/module-type-SeededS/index.html b/docs/stdlib/Stdlib/Ephemeron/module-type-SeededS/index.html new file mode 100644 index 00000000..e9e2fe39 --- /dev/null +++ b/docs/stdlib/Stdlib/Ephemeron/module-type-SeededS/index.html @@ -0,0 +1,2 @@ + +SeededS (docs.stdlib.Stdlib.Ephemeron.SeededS)

Module type Ephemeron.SeededS

The output signature of the functors K1.MakeSeeded and K2.MakeSeeded.

type key
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val length : 'a t -> int
val stats : 'a t -> Hashtbl.statistics
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
val of_seq : (key * 'a) Seq.t -> 'a t
val clean : 'a t -> unit

remove all dead bindings. Done automatically during automatic resizing.

val stats_alive : 'a t -> Hashtbl.statistics

same as Hashtbl.SeededS.stats but only count the alive bindings

diff --git a/docs/stdlib/Stdlib/Filename/index.html b/docs/stdlib/Stdlib/Filename/index.html new file mode 100644 index 00000000..7e3d4b6d --- /dev/null +++ b/docs/stdlib/Stdlib/Filename/index.html @@ -0,0 +1,14 @@ + +Filename (docs.stdlib.Stdlib.Filename)

Module Stdlib.Filename

Operations on file names.

val current_dir_name : string

The conventional name for the current directory (e.g. . in Unix).

val parent_dir_name : string

The conventional name for the parent of the current directory (e.g. .. in Unix).

val dir_sep : string

The directory separator (e.g. / in Unix).

  • since 3.11.2
val concat : string -> string -> string

concat dir file returns a file name that designates file file in directory dir.

val is_relative : string -> bool

Return true if the file name is relative to the current directory, false if it is absolute (i.e. in Unix, starts with /).

val is_implicit : string -> bool

Return true if the file name is relative and does not start with an explicit reference to the current directory (./ or ../ in Unix), false if it starts with an explicit reference to the root directory or the current directory.

val check_suffix : string -> string -> bool

check_suffix name suff returns true if the filename name ends with the suffix suff.

Under Windows ports (including Cygwin), comparison is case-insensitive, relying on String.lowercase_ascii. Note that this does not match exactly the interpretation of case-insensitive filename equivalence from Windows.

val chop_suffix : string -> string -> string

chop_suffix name suff removes the suffix suff from the filename name.

val chop_suffix_opt : suffix:string -> string -> string option

chop_suffix_opt ~suffix filename removes the suffix from the filename if possible, or returns None if the filename does not end with the suffix.

Under Windows ports (including Cygwin), comparison is case-insensitive, relying on String.lowercase_ascii. Note that this does not match exactly the interpretation of case-insensitive filename equivalence from Windows.

  • since 4.08
val extension : string -> string

extension name is the shortest suffix ext of name0 where:

  • name0 is the longest suffix of name that does not contain a directory separator;
  • ext starts with a period;
  • ext is preceded by at least one non-period character in name0.

If such a suffix does not exist, extension name is the empty string.

  • since 4.04
val remove_extension : string -> string

Return the given file name without its extension, as defined in Filename.extension. If the extension is empty, the function returns the given file name.

The following invariant holds for any file name s:

remove_extension s ^ extension s = s

  • since 4.04
val chop_extension : string -> string

Same as Filename.remove_extension, but raise Invalid_argument if the given name has an empty extension.

val basename : string -> string

Split a file name into directory name / base file name. If name is a valid file name, then concat (dirname name) (basename name) returns a file name which is equivalent to name. Moreover, after setting the current directory to dirname name (with Sys.chdir), references to basename name (which is a relative file name) designate the same file as name before the call to Sys.chdir.

This function conforms to the specification of POSIX.1-2008 for the basename utility.

val dirname : string -> string

See Filename.basename. This function conforms to the specification of POSIX.1-2008 for the dirname utility.

val null : string

null is "/dev/null" on POSIX and "NUL" on Windows. It represents a file on the OS that discards all writes and returns end of file on reads.

  • since 4.10
val temp_file : ?temp_dir:string -> string -> string -> string

temp_file prefix suffix returns the name of a fresh temporary file in the temporary directory. The base name of the temporary file is formed by concatenating prefix, then a suitably chosen integer number, then suffix. The optional argument temp_dir indicates the temporary directory to use, defaulting to the current result of Filename.get_temp_dir_name. The temporary file is created empty, with permissions 0o600 (readable and writable only by the file owner). The file is guaranteed to be different from any other file that existed when temp_file was called.

  • raises Sys_error

    if the file could not be created.

  • before 3.11.2

    no ?temp_dir optional argument

val open_temp_file : + ?mode:open_flag list -> + ?perms:int -> + ?temp_dir:string -> + string -> + string -> + string * out_channel

Same as Filename.temp_file, but returns both the name of a fresh temporary file, and an output channel opened (atomically) on this file. This function is more secure than temp_file: there is no risk that the temporary file will be modified (e.g. replaced by a symbolic link) before the program opens it. The optional argument mode is a list of additional flags to control the opening of the file. It can contain one or several of Open_append, Open_binary, and Open_text. The default is [Open_text] (open in text mode). The file is created with permissions perms (defaults to readable and writable only by the file owner, 0o600).

  • raises Sys_error

    if the file could not be opened.

  • before 4.03

    no ?perms optional argument

  • before 3.11.2

    no ?temp_dir optional argument

val temp_dir : ?temp_dir:string -> ?perms:int -> string -> string -> string

temp_dir prefix suffix creates and returns the name of a fresh temporary directory with permissions perms (defaults to 0o700) inside temp_dir. The base name of the temporary directory is formed by concatenating prefix, then a suitably chosen integer number, then suffix. The optional argument temp_dir indicates the temporary directory to use, defaulting to the current result of Filename.get_temp_dir_name. The temporary directory is created empty, with permissions 0o700 (readable, writable, and searchable only by the file owner). The directory is guaranteed to be different from any other directory that existed when temp_dir was called.

If temp_dir does not exist, this function does not create it. Instead, it raises Sys_error.

  • raises Sys_error

    if the directory could not be created.

  • since 5.1
val get_temp_dir_name : unit -> string

The name of the temporary directory: Under Unix, the value of the TMPDIR environment variable, or "/tmp" if the variable is not set. Under Windows, the value of the TEMP environment variable, or "." if the variable is not set. The temporary directory can be changed with Filename.set_temp_dir_name.

  • since 4.00
val set_temp_dir_name : string -> unit

Change the temporary directory returned by Filename.get_temp_dir_name and used by Filename.temp_file and Filename.open_temp_file. The temporary directory is a domain-local value which is inherited by child domains.

  • since 4.00
val quote : string -> string

Return a quoted version of a file name, suitable for use as one argument in a command line, escaping all meta-characters. Warning: under Windows, the output is only suitable for use with programs that follow the standard Windows quoting conventions.

val quote_command : + string -> + ?stdin:string -> + ?stdout:string -> + ?stderr:string -> + string list -> + string

quote_command cmd args returns a quoted command line, suitable for use as an argument to Sys.command, Unix.system, and the Unix.open_process functions.

The string cmd is the command to call. The list args is the list of arguments to pass to this command. It can be empty.

The optional arguments ?stdin and ?stdout and ?stderr are file names used to redirect the standard input, the standard output, or the standard error of the command. If ~stdin:f is given, a redirection < f is performed and the standard input of the command reads from file f. If ~stdout:f is given, a redirection > f is performed and the standard output of the command is written to file f. If ~stderr:f is given, a redirection 2> f is performed and the standard error of the command is written to file f. If both ~stdout:f and ~stderr:f are given, with the exact same file name f, a 2>&1 redirection is performed so that the standard output and the standard error of the command are interleaved and redirected to the same file f.

Under Unix and Cygwin, the command, the arguments, and the redirections if any are quoted using Filename.quote, then concatenated. Under Win32, additional quoting is performed as required by the cmd.exe shell that is called by Sys.command.

  • raises Failure

    if the command cannot be escaped on the current platform.

  • since 4.10
diff --git a/docs/stdlib/Stdlib/Float/Array/index.html b/docs/stdlib/Stdlib/Float/Array/index.html new file mode 100644 index 00000000..397e2e4e --- /dev/null +++ b/docs/stdlib/Stdlib/Float/Array/index.html @@ -0,0 +1,13 @@ + +Array (docs.stdlib.Stdlib.Float.Array)

Module Float.Array

Float arrays with packed representation.

type t = floatarray

The type of float arrays with packed representation.

  • since 4.08
val length : t -> int

Return the length (number of elements) of the given floatarray.

val get : t -> int -> float

get a n returns the element number n of floatarray a.

val set : t -> int -> float -> unit

set a n x modifies floatarray a in place, replacing element number n with x.

val make : int -> float -> t

make n x returns a fresh floatarray of length n, initialized with x.

val create : int -> t

create n returns a fresh floatarray of length n, with uninitialized data.

val init : int -> (int -> float) -> t

init n f returns a fresh floatarray of length n, with element number i initialized to the result of f i. In other terms, init n f tabulates the results of f applied to the integers 0 to n-1.

val append : t -> t -> t

append v1 v2 returns a fresh floatarray containing the concatenation of the floatarrays v1 and v2.

val concat : t list -> t

Same as append, but concatenates a list of floatarrays.

val sub : t -> int -> int -> t

sub a pos len returns a fresh floatarray of length len, containing the elements number pos to pos + len - 1 of floatarray a.

  • raises Invalid_argument

    if pos and len do not designate a valid subarray of a; that is, if pos < 0, or len < 0, or pos + len > length a.

val copy : t -> t

copy a returns a copy of a, that is, a fresh floatarray containing the same elements as a.

val fill : t -> int -> int -> float -> unit

fill a pos len x modifies the floatarray a in place, storing x in elements number pos to pos + len - 1.

val blit : t -> int -> t -> int -> int -> unit

blit src src_pos dst dst_pos len copies len elements from floatarray src, starting at element number src_pos, to floatarray dst, starting at element number dst_pos. It works correctly even if src and dst are the same floatarray, and the source and destination chunks overlap.

  • raises Invalid_argument

    if src_pos and len do not designate a valid subarray of src, or if dst_pos and len do not designate a valid subarray of dst.

val to_list : t -> float list

to_list a returns the list of all the elements of a.

val of_list : float list -> t

of_list l returns a fresh floatarray containing the elements of l.

  • raises Invalid_argument

    if the length of l is greater than Sys.max_floatarray_length.

Iterators

val iter : (float -> unit) -> t -> unit

iter f a applies function f in turn to all the elements of a. It is equivalent to f a.(0); f a.(1); ...; f a.(length a - 1); ().

val iteri : (int -> float -> unit) -> t -> unit

Same as iter, but the function is applied with the index of the element as first argument, and the element itself as second argument.

val map : (float -> float) -> t -> t

map f a applies function f to all the elements of a, and builds a floatarray with the results returned by f.

val map_inplace : (float -> float) -> t -> unit

map_inplace f a applies function f to all elements of a, and updates their values in place.

  • since 5.1
val mapi : (int -> float -> float) -> t -> t

Same as map, but the function is applied to the index of the element as first argument, and the element itself as second argument.

val mapi_inplace : (int -> float -> float) -> t -> unit

Same as map_inplace, but the function is applied to the index of the element as first argument, and the element itself as second argument.

  • since 5.1
val fold_left : ('acc -> float -> 'acc) -> 'acc -> t -> 'acc

fold_left f x init computes f (... (f (f x init.(0)) init.(1)) ...) init.(n-1), where n is the length of the floatarray init.

val fold_right : (float -> 'acc -> 'acc) -> t -> 'acc -> 'acc

fold_right f a init computes f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...)), where n is the length of the floatarray a.

Iterators on two arrays

val iter2 : (float -> float -> unit) -> t -> t -> unit

Array.iter2 f a b applies function f to all the elements of a and b.

val map2 : (float -> float -> float) -> t -> t -> t

map2 f a b applies function f to all the elements of a and b, and builds a floatarray with the results returned by f: [| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|].

Array scanning

val for_all : (float -> bool) -> t -> bool

for_all f [|a1; ...; an|] checks if all elements of the floatarray satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an).

val exists : (float -> bool) -> t -> bool

exists f [|a1; ...; an|] checks if at least one element of the floatarray satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an).

val mem : float -> t -> bool

mem a set is true if and only if there is an element of set that is structurally equal to a, i.e. there is an x in set such that compare a x = 0.

val mem_ieee : float -> t -> bool

Same as mem, but uses IEEE equality instead of structural equality.

Array searching

val find_opt : (float -> bool) -> t -> float option
val find_index : (float -> bool) -> t -> int option

find_index f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

  • since 5.1
val find_map : (float -> 'a option) -> t -> 'a option
val find_mapi : (int -> float -> 'a option) -> t -> 'a option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 5.1

Sorting

val sort : (float -> float -> int) -> t -> unit

Sort a floatarray in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, Stdlib.compare is a suitable comparison function. After calling sort, the array is sorted in place in increasing order. sort is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses Heap Sort. It runs in constant stack space.

Specification of the comparison function: Let a be the floatarray and cmp the comparison function. The following must be true for all x, y, z in a :

  • cmp x y > 0 if and only if cmp y x < 0
  • if cmp x y >= 0 and cmp y z >= 0 then cmp x z >= 0

When sort returns, a contains the same elements as before, reordered in such a way that for all i and j valid indices of a :

  • cmp a.(i) a.(j) >= 0 if and only if i >= j
val stable_sort : (float -> float -> int) -> t -> unit

Same as sort, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary floatarray of length n/2, where n is the length of the floatarray. It is usually faster than the current implementation of sort.

val fast_sort : (float -> float -> int) -> t -> unit

Same as sort or stable_sort, whichever is faster on typical input.

Float arrays and Sequences

val to_seq : t -> float Seq.t

Iterate on the floatarray, in increasing order. Modifications of the floatarray during iteration will be reflected in the sequence.

val to_seqi : t -> (int * float) Seq.t

Iterate on the floatarray, in increasing order, yielding indices along elements. Modifications of the floatarray during iteration will be reflected in the sequence.

val of_seq : float Seq.t -> t

Create an array from the generator.

val map_to_array : (float -> 'a) -> t -> 'a array

map_to_array f a applies function f to all the elements of a, and builds an array with the results returned by f: [| f a.(0); f a.(1); ...; f a.(length a - 1) |].

val map_from_array : ('a -> float) -> 'a array -> t

map_from_array f a applies function f to all the elements of a, and builds a floatarray with the results returned by f.

Arrays and concurrency safety

Care must be taken when concurrently accessing float arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every float array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.

For example, consider the following program:

let size = 100_000_000
+let a = Float.Array.make size 1.
+let update a f () =
+   Float.Array.iteri (fun i x -> Float.Array.set a i (f x)) a
+let d1 = Domain.spawn (update a (fun x -> x +. 1.))
+let d2 = Domain.spawn (update a (fun x ->  2. *. x +. 1.))
+let () = Domain.join d1; Domain.join d2

After executing this code, each field of the float array a is either 2., 3., 4. or 5.. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location with a few exceptions.

Tearing

Float arrays have two supplementary caveats in the presence of data races.

First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.

For instance, at the end of

let zeros = Float.Array.make size 0.
+let max_floats = Float.Array.make size Float.max_float
+let res = Float.Array.copy zeros
+let d1 = Domain.spawn (fun () -> Float.Array.blit zeros 0 res 0 size)
+let d2 = Domain.spawn (fun () -> Float.Array.blit max_floats 0 res 0 size)
+let () = Domain.join d1; Domain.join d2

the res float array might contain values that are neither 0. nor max_float.

Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.

diff --git a/docs/stdlib/Stdlib/Float/ArrayLabels/index.html b/docs/stdlib/Stdlib/Float/ArrayLabels/index.html new file mode 100644 index 00000000..46f1d0bf --- /dev/null +++ b/docs/stdlib/Stdlib/Float/ArrayLabels/index.html @@ -0,0 +1,13 @@ + +ArrayLabels (docs.stdlib.Stdlib.Float.ArrayLabels)

Module Float.ArrayLabels

Float arrays with packed representation (labeled functions).

type t = floatarray

The type of float arrays with packed representation.

  • since 4.08
val length : t -> int

Return the length (number of elements) of the given floatarray.

val get : t -> int -> float

get a n returns the element number n of floatarray a.

val set : t -> int -> float -> unit

set a n x modifies floatarray a in place, replacing element number n with x.

val make : int -> float -> t

make n x returns a fresh floatarray of length n, initialized with x.

val create : int -> t

create n returns a fresh floatarray of length n, with uninitialized data.

val init : int -> f:(int -> float) -> t

init n ~f returns a fresh floatarray of length n, with element number i initialized to the result of f i. In other terms, init n ~f tabulates the results of f applied to the integers 0 to n-1.

val append : t -> t -> t

append v1 v2 returns a fresh floatarray containing the concatenation of the floatarrays v1 and v2.

val concat : t list -> t

Same as append, but concatenates a list of floatarrays.

val sub : t -> pos:int -> len:int -> t

sub a ~pos ~len returns a fresh floatarray of length len, containing the elements number pos to pos + len - 1 of floatarray a.

  • raises Invalid_argument

    if pos and len do not designate a valid subarray of a; that is, if pos < 0, or len < 0, or pos + len > length a.

val copy : t -> t

copy a returns a copy of a, that is, a fresh floatarray containing the same elements as a.

val fill : t -> pos:int -> len:int -> float -> unit

fill a ~pos ~len x modifies the floatarray a in place, storing x in elements number pos to pos + len - 1.

val blit : src:t -> src_pos:int -> dst:t -> dst_pos:int -> len:int -> unit

blit ~src ~src_pos ~dst ~dst_pos ~len copies len elements from floatarray src, starting at element number src_pos, to floatarray dst, starting at element number dst_pos. It works correctly even if src and dst are the same floatarray, and the source and destination chunks overlap.

  • raises Invalid_argument

    if src_pos and len do not designate a valid subarray of src, or if dst_pos and len do not designate a valid subarray of dst.

val to_list : t -> float list

to_list a returns the list of all the elements of a.

val of_list : float list -> t

of_list l returns a fresh floatarray containing the elements of l.

  • raises Invalid_argument

    if the length of l is greater than Sys.max_floatarray_length.

Iterators

val iter : f:(float -> unit) -> t -> unit

iter ~f a applies function f in turn to all the elements of a. It is equivalent to f a.(0); f a.(1); ...; f a.(length a - 1); ().

val iteri : f:(int -> float -> unit) -> t -> unit

Same as iter, but the function is applied with the index of the element as first argument, and the element itself as second argument.

val map : f:(float -> float) -> t -> t

map ~f a applies function f to all the elements of a, and builds a floatarray with the results returned by f.

val map_inplace : f:(float -> float) -> t -> unit

map_inplace f a applies function f to all elements of a, and updates their values in place.

  • since 5.1
val mapi : f:(int -> float -> float) -> t -> t

Same as map, but the function is applied to the index of the element as first argument, and the element itself as second argument.

val mapi_inplace : f:(int -> float -> float) -> t -> unit

Same as map_inplace, but the function is applied to the index of the element as first argument, and the element itself as second argument.

  • since 5.1
val fold_left : f:('acc -> float -> 'acc) -> init:'acc -> t -> 'acc

fold_left ~f x ~init computes f (... (f (f x init.(0)) init.(1)) ...) init.(n-1), where n is the length of the floatarray init.

val fold_right : f:(float -> 'acc -> 'acc) -> t -> init:'acc -> 'acc

fold_right f a init computes f a.(0) (f a.(1) ( ... (f a.(n-1) init) ...)), where n is the length of the floatarray a.

Iterators on two arrays

val iter2 : f:(float -> float -> unit) -> t -> t -> unit

Array.iter2 ~f a b applies function f to all the elements of a and b.

val map2 : f:(float -> float -> float) -> t -> t -> t

map2 ~f a b applies function f to all the elements of a and b, and builds a floatarray with the results returned by f: [| f a.(0) b.(0); ...; f a.(length a - 1) b.(length b - 1)|].

Array scanning

val for_all : f:(float -> bool) -> t -> bool

for_all ~f [|a1; ...; an|] checks if all elements of the floatarray satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an).

val exists : f:(float -> bool) -> t -> bool

exists f [|a1; ...; an|] checks if at least one element of the floatarray satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an).

val mem : float -> set:t -> bool

mem a ~set is true if and only if there is an element of set that is structurally equal to a, i.e. there is an x in set such that compare a x = 0.

val mem_ieee : float -> set:t -> bool

Same as mem, but uses IEEE equality instead of structural equality.

Array searching

val find_opt : f:(float -> bool) -> t -> float option
val find_index : f:(float -> bool) -> t -> int option

find_index ~f a returns Some i, where i is the index of the first element of the array a that satisfies f x, if there is such an element.

It returns None if there is no such element.

  • since 5.1
val find_map : f:(float -> 'a option) -> t -> 'a option
val find_mapi : f:(int -> float -> 'a option) -> t -> 'a option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 5.1

Sorting

val sort : cmp:(float -> float -> int) -> t -> unit

Sort a floatarray in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see below for a complete specification). For example, Stdlib.compare is a suitable comparison function. After calling sort, the array is sorted in place in increasing order. sort is guaranteed to run in constant heap space and (at most) logarithmic stack space.

The current implementation uses Heap Sort. It runs in constant stack space.

Specification of the comparison function: Let a be the floatarray and cmp the comparison function. The following must be true for all x, y, z in a :

  • cmp x y > 0 if and only if cmp y x < 0
  • if cmp x y >= 0 and cmp y z >= 0 then cmp x z >= 0

When sort returns, a contains the same elements as before, reordered in such a way that for all i and j valid indices of a :

  • cmp a.(i) a.(j) >= 0 if and only if i >= j
val stable_sort : cmp:(float -> float -> int) -> t -> unit

Same as sort, but the sorting algorithm is stable (i.e. elements that compare equal are kept in their original order) and not guaranteed to run in constant heap space.

The current implementation uses Merge Sort. It uses a temporary floatarray of length n/2, where n is the length of the floatarray. It is usually faster than the current implementation of sort.

val fast_sort : cmp:(float -> float -> int) -> t -> unit

Same as sort or stable_sort, whichever is faster on typical input.

Float arrays and Sequences

val to_seq : t -> float Seq.t

Iterate on the floatarray, in increasing order. Modifications of the floatarray during iteration will be reflected in the sequence.

val to_seqi : t -> (int * float) Seq.t

Iterate on the floatarray, in increasing order, yielding indices along elements. Modifications of the floatarray during iteration will be reflected in the sequence.

val of_seq : float Seq.t -> t

Create an array from the generator.

val map_to_array : f:(float -> 'a) -> t -> 'a array

map_to_array ~f a applies function f to all the elements of a, and builds an array with the results returned by f: [| f a.(0); f a.(1); ...; f a.(length a - 1) |].

val map_from_array : f:('a -> float) -> 'a array -> t

map_from_array ~f a applies function f to all the elements of a, and builds a floatarray with the results returned by f.

Arrays and concurrency safety

Care must be taken when concurrently accessing float arrays from multiple domains: accessing an array will never crash a program, but unsynchronized accesses might yield surprising (non-sequentially-consistent) results.

Atomicity

Every float array operation that accesses more than one array element is not atomic. This includes iteration, scanning, sorting, splitting and combining arrays.

For example, consider the following program:

let size = 100_000_000
+let a = Float.ArrayLabels.make size 1.
+let update a f () =
+   Float.ArrayLabels.iteri ~f:(fun i x -> Float.Array.set a i (f x)) a
+let d1 = Domain.spawn (update a (fun x -> x +. 1.))
+let d2 = Domain.spawn (update a (fun x ->  2. *. x +. 1.))
+let () = Domain.join d1; Domain.join d2

After executing this code, each field of the float array a is either 2., 3., 4. or 5.. If atomicity is required, then the user must implement their own synchronization (for example, using Mutex.t).

Data races

If two domains only access disjoint parts of the array, then the observed behaviour is the equivalent to some sequential interleaving of the operations from the two domains.

A data race is said to occur when two domains access the same array element without synchronization and at least one of the accesses is a write. In the absence of data races, the observed behaviour is equivalent to some sequential interleaving of the operations from different domains.

Whenever possible, data races should be avoided by using synchronization to mediate the accesses to the array elements.

Indeed, in the presence of data races, programs will not crash but the observed behaviour may not be equivalent to any sequential interleaving of operations from different domains. Nevertheless, even in the presence of data races, a read operation will return the value of some prior write to that location with a few exceptions.

Tearing

Float arrays have two supplementary caveats in the presence of data races.

First, the blit operation might copy an array byte-by-byte. Data races between such a blit operation and another operation might produce surprising values due to tearing: partial writes interleaved with other operations can create float values that would not exist with a sequential execution.

For instance, at the end of

let zeros = Float.Array.make size 0.
+let max_floats = Float.Array.make size Float.max_float
+let res = Float.Array.copy zeros
+let d1 = Domain.spawn (fun () -> Float.Array.blit zeros 0 res 0 size)
+let d2 = Domain.spawn (fun () -> Float.Array.blit max_floats 0 res 0 size)
+let () = Domain.join d1; Domain.join d2

the res float array might contain values that are neither 0. nor max_float.

Second, on 32-bit architectures, getting or setting a field involves two separate memory accesses. In the presence of data races, the user may observe tearing on any operation.

diff --git a/docs/stdlib/Stdlib/Float/index.html b/docs/stdlib/Stdlib/Float/index.html new file mode 100644 index 00000000..7d6f9457 --- /dev/null +++ b/docs/stdlib/Stdlib/Float/index.html @@ -0,0 +1,2 @@ + +Float (docs.stdlib.Stdlib.Float)

Module Stdlib.Float

Floating-point arithmetic.

OCaml's floating-point numbers follow the IEEE 754 standard, using double precision (64 bits) numbers. Floating-point operations never raise an exception on overflow, underflow, division by zero, etc. Instead, special IEEE numbers are returned as appropriate, such as infinity for 1.0 /. 0.0, neg_infinity for -1.0 /. 0.0, and nan ('not a number') for 0.0 /. 0.0. These special numbers then propagate through floating-point computations as expected: for instance, 1.0 /. infinity is 0.0, basic arithmetic operations (+., -., *., /.) with nan as an argument return nan, ...

  • since 4.07
val zero : float

The floating point 0.

  • since 4.08
val one : float

The floating-point 1.

  • since 4.08
val minus_one : float

The floating-point -1.

  • since 4.08
val neg : float -> float

Unary negation.

val add : float -> float -> float

Floating-point addition.

val sub : float -> float -> float

Floating-point subtraction.

val mul : float -> float -> float

Floating-point multiplication.

val div : float -> float -> float

Floating-point division.

val fma : float -> float -> float -> float

fma x y z returns x * y + z, with a best effort for computing this expression with a single rounding, using either hardware instructions (providing full IEEE compliance) or a software emulation.

On 64-bit Cygwin, 64-bit mingw-w64 and MSVC 2017 and earlier, this function may be emulated owing to known bugs on limitations on these platforms. Note: since software emulation of the fma is costly, make sure that you are using hardware fma support if performance matters.

  • since 4.08
val rem : float -> float -> float

rem a b returns the remainder of a with respect to b. The returned value is a -. n *. b, where n is the quotient a /. b rounded towards zero to an integer.

val succ : float -> float

succ x returns the floating point number right after x i.e., the smallest floating-point number greater than x. See also next_after.

  • since 4.08
val pred : float -> float

pred x returns the floating-point number right before x i.e., the greatest floating-point number smaller than x. See also next_after.

  • since 4.08
val abs : float -> float

abs f returns the absolute value of f.

val infinity : float

Positive infinity.

val neg_infinity : float

Negative infinity.

val nan : float

A special floating-point value denoting the result of an undefined operation such as 0.0 /. 0.0. Stands for 'not a number'. Any floating-point operation with nan as argument returns nan as result, unless otherwise specified in IEEE 754 standard. As for floating-point comparisons, =, <, <=, > and >= return false and <> returns true if one or both of their arguments is nan.

nan is quiet_nan since 5.1; it was a signaling NaN before.

val signaling_nan : float

Signaling NaN. The corresponding signals do not raise OCaml exception, but the value can be useful for interoperability with C libraries.

  • since 5.1
val quiet_nan : float

Quiet NaN.

  • since 5.1
val pi : float

The constant pi.

val max_float : float

The largest positive finite value of type float.

val min_float : float

The smallest positive, non-zero, non-denormalized value of type float.

val epsilon : float

The difference between 1.0 and the smallest exactly representable floating-point number greater than 1.0.

val is_finite : float -> bool

is_finite x is true if and only if x is finite i.e., not infinite and not nan.

  • since 4.08
val is_infinite : float -> bool

is_infinite x is true if and only if x is infinity or neg_infinity.

  • since 4.08
val is_nan : float -> bool

is_nan x is true if and only if x is not a number (see nan).

  • since 4.08
val is_integer : float -> bool

is_integer x is true if and only if x is an integer.

  • since 4.08
val of_int : int -> float

Convert an integer to floating-point.

val to_int : float -> int

Truncate the given floating-point number to an integer. The result is unspecified if the argument is nan or falls outside the range of representable integers.

val of_string : string -> float

Convert the given string to a float. The string is read in decimal (by default) or in hexadecimal (marked by 0x or 0X). The format of decimal floating-point numbers is [-] dd.ddd (e|E) [+|-] dd , where d stands for a decimal digit. The format of hexadecimal floating-point numbers is [-] 0(x|X) hh.hhh (p|P) [+|-] dd , where h stands for an hexadecimal digit and d for a decimal digit. In both cases, at least one of the integer and fractional parts must be given; the exponent part is optional. The _ (underscore) character can appear anywhere in the string and is ignored. Depending on the execution platforms, other representations of floating-point numbers can be accepted, but should not be relied upon.

  • raises Failure

    if the given string is not a valid representation of a float.

val of_string_opt : string -> float option

Same as of_string, but returns None instead of raising.

val to_string : float -> string

Return a string representation of a floating-point number.

This conversion can involve a loss of precision. For greater control over the manner in which the number is printed, see Printf.

This function is an alias for Stdlib.string_of_float.

type fpclass = fpclass =
  1. | FP_normal
    (*

    Normal number, none of the below

    *)
  2. | FP_subnormal
    (*

    Number very close to 0.0, has reduced precision

    *)
  3. | FP_zero
    (*

    Number is 0.0 or -0.0

    *)
  4. | FP_infinite
    (*

    Number is positive or negative infinity

    *)
  5. | FP_nan
    (*

    Not a number: result of an undefined operation

    *)

The five classes of floating-point numbers, as determined by the classify_float function.

val classify_float : float -> fpclass

Return the class of the given floating-point number: normal, subnormal, zero, infinite, or not a number.

val pow : float -> float -> float

Exponentiation.

val sqrt : float -> float

Square root.

val cbrt : float -> float

Cube root.

  • since 4.13
val exp : float -> float

Exponential.

val exp2 : float -> float

Base 2 exponential function.

  • since 4.13
val log : float -> float

Natural logarithm.

val log10 : float -> float

Base 10 logarithm.

val log2 : float -> float

Base 2 logarithm.

  • since 4.13
val expm1 : float -> float

expm1 x computes exp x -. 1.0, giving numerically-accurate results even if x is close to 0.0.

val log1p : float -> float

log1p x computes log(1.0 +. x) (natural logarithm), giving numerically-accurate results even if x is close to 0.0.

val cos : float -> float

Cosine. Argument is in radians.

val sin : float -> float

Sine. Argument is in radians.

val tan : float -> float

Tangent. Argument is in radians.

val acos : float -> float

Arc cosine. The argument must fall within the range [-1.0, 1.0]. Result is in radians and is between 0.0 and pi.

val asin : float -> float

Arc sine. The argument must fall within the range [-1.0, 1.0]. Result is in radians and is between -pi/2 and pi/2.

val atan : float -> float

Arc tangent. Result is in radians and is between -pi/2 and pi/2.

val atan2 : float -> float -> float

atan2 y x returns the arc tangent of y /. x. The signs of x and y are used to determine the quadrant of the result. Result is in radians and is between -pi and pi.

val hypot : float -> float -> float

hypot x y returns sqrt(x *. x +. y *. y), that is, the length of the hypotenuse of a right-angled triangle with sides of length x and y, or, equivalently, the distance of the point (x,y) to origin. If one of x or y is infinite, returns infinity even if the other is nan.

val cosh : float -> float

Hyperbolic cosine. Argument is in radians.

val sinh : float -> float

Hyperbolic sine. Argument is in radians.

val tanh : float -> float

Hyperbolic tangent. Argument is in radians.

val acosh : float -> float

Hyperbolic arc cosine. The argument must fall within the range [1.0, inf]. Result is in radians and is between 0.0 and inf.

  • since 4.13
val asinh : float -> float

Hyperbolic arc sine. The argument and result range over the entire real line. Result is in radians.

  • since 4.13
val atanh : float -> float

Hyperbolic arc tangent. The argument must fall within the range [-1.0, 1.0]. Result is in radians and ranges over the entire real line.

  • since 4.13
val erf : float -> float

Error function. The argument ranges over the entire real line. The result is always within [-1.0, 1.0].

  • since 4.13
val erfc : float -> float

Complementary error function (erfc x = 1 - erf x). The argument ranges over the entire real line. The result is always within [-1.0, 1.0].

  • since 4.13
val trunc : float -> float

trunc x rounds x to the nearest integer whose absolute value is less than or equal to x.

  • since 4.08
val round : float -> float

round x rounds x to the nearest integer with ties (fractional values of 0.5) rounded away from zero, regardless of the current rounding direction. If x is an integer, +0., -0., nan, or infinite, x itself is returned.

On 64-bit mingw-w64, this function may be emulated owing to a bug in the C runtime library (CRT) on this platform.

  • since 4.08
val ceil : float -> float

Round above to an integer value. ceil f returns the least integer value greater than or equal to f. The result is returned as a float.

val floor : float -> float

Round below to an integer value. floor f returns the greatest integer value less than or equal to f. The result is returned as a float.

val next_after : float -> float -> float

next_after x y returns the next representable floating-point value following x in the direction of y. More precisely, if y is greater (resp. less) than x, it returns the smallest (resp. largest) representable number greater (resp. less) than x. If x equals y, the function returns y. If x or y is nan, a nan is returned. Note that next_after max_float infinity = infinity and that next_after 0. infinity is the smallest denormalized positive number. If x is the smallest denormalized positive number, next_after x 0. = 0.

  • since 4.08
val copy_sign : float -> float -> float

copy_sign x y returns a float whose absolute value is that of x and whose sign is that of y. If x is nan, returns nan. If y is nan, returns either x or -. x, but it is not specified which.

val sign_bit : float -> bool

sign_bit x is true if and only if the sign bit of x is set. For example sign_bit 1. and signbit 0. are false while sign_bit (-1.) and sign_bit (-0.) are true.

  • since 4.08
val frexp : float -> float * int

frexp f returns the pair of the significant and the exponent of f. When f is zero, the significant x and the exponent n of f are equal to zero. When f is non-zero, they are defined by f = x *. 2 ** n and 0.5 <= x < 1.0.

val ldexp : float -> int -> float

ldexp x n returns x *. 2 ** n.

val modf : float -> float * float

modf f returns the pair of the fractional and integral part of f.

type t = float

An alias for the type of floating-point numbers.

val compare : t -> t -> int

compare x y returns 0 if x is equal to y, a negative integer if x is less than y, and a positive integer if x is greater than y. compare treats nan as equal to itself and less than any other float value. This treatment of nan ensures that compare defines a total ordering relation.

val equal : t -> t -> bool

The equal function for floating-point numbers, compared using compare.

val min : t -> t -> t

min x y returns the minimum of x and y. It returns nan when x or y is nan. Moreover min (-0.) (+0.) = -0.

  • since 4.08
val max : float -> float -> float

max x y returns the maximum of x and y. It returns nan when x or y is nan. Moreover max (-0.) (+0.) = +0.

  • since 4.08
val min_max : float -> float -> float * float

min_max x y is (min x y, max x y), just more efficient.

  • since 4.08
val min_num : t -> t -> t

min_num x y returns the minimum of x and y treating nan as missing values. If both x and y are nan, nan is returned. Moreover min_num (-0.) (+0.) = -0.

  • since 4.08
val max_num : t -> t -> t

max_num x y returns the maximum of x and y treating nan as missing values. If both x and y are nan nan is returned. Moreover max_num (-0.) (+0.) = +0.

  • since 4.08
val min_max_num : float -> float -> float * float

min_max_num x y is (min_num x y, max_num x y), just more efficient. Note that in particular min_max_num x nan = (x, x) and min_max_num nan y = (y, y).

  • since 4.08
val seeded_hash : int -> t -> int

A seeded hash function for floats, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : t -> int

An unseeded hash function for floats, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

module Array : sig ... end

Float arrays with packed representation.

module ArrayLabels : sig ... end

Float arrays with packed representation (labeled functions).

diff --git a/docs/stdlib/Stdlib/Format/index.html b/docs/stdlib/Stdlib/Format/index.html new file mode 100644 index 00000000..3e99f7de --- /dev/null +++ b/docs/stdlib/Stdlib/Format/index.html @@ -0,0 +1,148 @@ + +Format (docs.stdlib.Stdlib.Format)

Module Stdlib.Format

Pretty-printing.

If you are new to this module, see the examples below.

This module implements a pretty-printing facility to format values within 'pretty-printing boxes' and 'semantic tags' combined with a set of printf-like functions. The pretty-printer splits lines at specified break hints, and indents lines according to the box structure. Similarly, semantic tags can be used to decouple text presentation from its contents.

This pretty-printing facility is implemented as an overlay on top of abstract formatters which provide basic output functions. Some formatters are predefined, notably:

Most functions in the Format module come in two variants: a short version that operates on the current domain's standard formatter as obtained using get_std_formatter and the generic version prefixed by pp_ that takes a formatter as its first argument. For the version that operates on the current domain's standard formatter, the call to get_std_formatter is delayed until the last argument is received.

More formatters can be created with formatter_of_out_channel, formatter_of_buffer, formatter_of_symbolic_output_buffer or using custom formatters.

Warning: Since formatters contain mutable state, it is not thread-safe to use the same formatter on multiple domains in parallel without synchronization.

If multiple domains write to the same output channel using the predefined formatters (as obtained by get_std_formatter or get_err_formatter), the output from the domains will be interleaved with each other at points where the formatters are flushed, such as with print_flush. This synchronization is not performed by formatters obtained from formatter_of_out_channel (on the standard out channels or others).

Introduction

You may consider this module as providing an extension to the printf facility to provide automatic line splitting. The addition of pretty-printing annotations to your regular printf format strings gives you fancy indentation and line breaks. Pretty-printing annotations are described below in the documentation of the function Format.fprintf.

You may also use the explicit pretty-printing box management and printing functions provided by this module. This style is more basic but more verbose than the concise fprintf format strings.

For instance, the sequence open_box 0; print_string "x ="; print_space (); + print_int 1; close_box (); print_newline () that prints x = 1 within a pretty-printing box, can be abbreviated as printf "@[%s@ %i@]@." "x =" 1, or even shorter printf "@[x =@ %i@]@." 1.

Rule of thumb for casual users of this library:

  • use simple pretty-printing boxes (as obtained by open_box 0);
  • use simple break hints as obtained by print_cut () that outputs a simple break hint, or by print_space () that outputs a space indicating a break hint;
  • once a pretty-printing box is open, display its material with basic printing functions (e. g. print_int and print_string);
  • when the material for a pretty-printing box has been printed, call close_box () to close the box;
  • at the end of pretty-printing, flush the pretty-printer to display all the remaining material, e.g. evaluate print_newline ().

The behavior of pretty-printing commands is unspecified if there is no open pretty-printing box. Each box opened by one of the open_ functions below must be closed using close_box for proper formatting. Otherwise, some of the material printed in the boxes may not be output, or may be formatted incorrectly.

In case of interactive use, each phrase is executed in the initial state of the standard pretty-printer: after each phrase execution, the interactive system closes all open pretty-printing boxes, flushes all pending text, and resets the standard pretty-printer.

Warning: mixing calls to pretty-printing functions of this module with calls to Stdlib low level output functions is error prone.

The pretty-printing functions output material that is delayed in the pretty-printer queue and stacks in order to compute proper line splitting. In contrast, basic I/O output functions write directly in their output device. As a consequence, the output of a basic I/O function may appear before the output of a pretty-printing function that has been called before. For instance, + Stdlib.print_string "<"; + Format.print_string "PRETTY"; + Stdlib.print_string ">"; + Format.print_string "TEXT"; + leads to output <>PRETTYTEXT.

Formatters

type formatter

Abstract data corresponding to a pretty-printer (also called a formatter) and all its machinery. See also Defining formatters.

Pretty-printing boxes

The pretty-printing engine uses the concepts of pretty-printing box and break hint to drive indentation and line splitting behavior of the pretty-printer.

Each different pretty-printing box kind introduces a specific line splitting policy:

  • within an horizontal box, break hints never split the line (but the line may be split in a box nested deeper),
  • within a vertical box, break hints always split the line,
  • within an horizontal/vertical box, if the box fits on the current line then break hints never split the line, otherwise break hint always split the line,
  • within a compacting box, a break hint never splits the line, unless there is no more room on the current line.

Note that line splitting policy is box specific: the policy of a box does not rule the policy of inner boxes. For instance, if a vertical box is nested in an horizontal box, all break hints within the vertical box will split the line.

Moreover, opening a box after the maximum indentation limit splits the line whether or not the box would end up fitting on the line.

val pp_open_box : formatter -> int -> unit
val open_box : int -> unit

pp_open_box ppf d opens a new compacting pretty-printing box with offset d in the formatter ppf.

Within this box, the pretty-printer prints as much as possible material on every line.

A break hint splits the line if there is no more room on the line to print the remainder of the box.

Within this box, the pretty-printer emphasizes the box structure: if a structural box does not fit fully on a simple line, a break hint also splits the line if the splitting ``moves to the left'' (i.e. the new line gets an indentation smaller than the one of the current line).

This box is the general purpose pretty-printing box.

If the pretty-printer splits the line in the box, offset d is added to the current indentation.

val pp_close_box : formatter -> unit -> unit
val close_box : unit -> unit

Closes the most recently open pretty-printing box.

val pp_open_hbox : formatter -> unit -> unit
val open_hbox : unit -> unit

pp_open_hbox ppf () opens a new 'horizontal' pretty-printing box.

This box prints material on a single line.

Break hints in a horizontal box never split the line. (Line splitting may still occur inside boxes nested deeper).

val pp_open_vbox : formatter -> int -> unit
val open_vbox : int -> unit

pp_open_vbox ppf d opens a new 'vertical' pretty-printing box with offset d.

This box prints material on as many lines as break hints in the box.

Every break hint in a vertical box splits the line.

If the pretty-printer splits the line in the box, d is added to the current indentation.

val pp_open_hvbox : formatter -> int -> unit
val open_hvbox : int -> unit

pp_open_hvbox ppf d opens a new 'horizontal/vertical' pretty-printing box with offset d.

This box behaves as an horizontal box if it fits on a single line, otherwise it behaves as a vertical box.

If the pretty-printer splits the line in the box, d is added to the current indentation.

val pp_open_hovbox : formatter -> int -> unit
val open_hovbox : int -> unit

pp_open_hovbox ppf d opens a new 'horizontal-or-vertical' pretty-printing box with offset d.

This box prints material as much as possible on every line.

A break hint splits the line if there is no more room on the line to print the remainder of the box.

If the pretty-printer splits the line in the box, d is added to the current indentation.

Formatting functions

val pp_print_string : formatter -> string -> unit
val print_string : string -> unit

pp_print_string ppf s prints s in the current pretty-printing box.

val pp_print_bytes : formatter -> bytes -> unit
val print_bytes : bytes -> unit

pp_print_bytes ppf b prints b in the current pretty-printing box.

  • since 4.13
val pp_print_as : formatter -> int -> string -> unit
val print_as : int -> string -> unit

pp_print_as ppf len s prints s in the current pretty-printing box. The pretty-printer formats s as if it were of length len.

val pp_print_int : formatter -> int -> unit
val print_int : int -> unit

Print an integer in the current pretty-printing box.

val pp_print_float : formatter -> float -> unit
val print_float : float -> unit

Print a floating point number in the current pretty-printing box.

val pp_print_char : formatter -> char -> unit
val print_char : char -> unit

Print a character in the current pretty-printing box.

val pp_print_bool : formatter -> bool -> unit
val print_bool : bool -> unit

Print a boolean in the current pretty-printing box.

Break hints

A 'break hint' tells the pretty-printer to output some space or split the line whichever way is more appropriate to the current pretty-printing box splitting rules.

Break hints are used to separate printing items and are mandatory to let the pretty-printer correctly split lines and indent items.

Simple break hints are:

  • the 'space': output a space or split the line if appropriate,
  • the 'cut': split the line if appropriate.

Note: the notions of space and line splitting are abstract for the pretty-printing engine, since those notions can be completely redefined by the programmer. However, in the pretty-printer default setting, ``output a space'' simply means printing a space character (ASCII code 32) and ``split the line'' means printing a newline character (ASCII code 10).

val pp_print_space : formatter -> unit -> unit
val print_space : unit -> unit

pp_print_space ppf () emits a 'space' break hint: the pretty-printer may split the line at this point, otherwise it prints one space.

pp_print_space ppf () is equivalent to pp_print_break ppf 1 0.

val pp_print_cut : formatter -> unit -> unit
val print_cut : unit -> unit

pp_print_cut ppf () emits a 'cut' break hint: the pretty-printer may split the line at this point, otherwise it prints nothing.

pp_print_cut ppf () is equivalent to pp_print_break ppf 0 0.

val pp_print_break : formatter -> int -> int -> unit
val print_break : int -> int -> unit

pp_print_break ppf nspaces offset emits a 'full' break hint: the pretty-printer may split the line at this point, otherwise it prints nspaces spaces.

If the pretty-printer splits the line, offset is added to the current indentation.

val pp_print_custom_break : + formatter -> + fits:(string * int * string) -> + breaks:(string * int * string) -> + unit

pp_print_custom_break ppf ~fits:(s1, n, s2) ~breaks:(s3, m, s4) emits a custom break hint: the pretty-printer may split the line at this point.

If it does not split the line, then the s1 is emitted, then n spaces, then s2.

If it splits the line, then it emits the s3 string, then an indent (according to the box rules), then an offset of m spaces, then the s4 string.

While n and m are handled by formatter_out_functions.out_indent, the strings will be handled by formatter_out_functions.out_string. This allows for a custom formatter that handles indentation distinctly, for example, outputs <br/> tags or &nbsp; entities.

The custom break is useful if you want to change which visible (non-whitespace) characters are printed in case of break or no break. For example, when printing a list [a; b; c] , you might want to add a trailing semicolon when it is printed vertically:

[
+  a;
+  b;
+  c;
+]

You can do this as follows:

printf "@[<v 0>[@;<0 2>@[<v 0>a;@,b;@,c@]%t]@]@\n"
+  (pp_print_custom_break ~fits:("", 0, "") ~breaks:(";", 0, ""))
  • since 4.08
val pp_force_newline : formatter -> unit -> unit
val force_newline : unit -> unit

Force a new line in the current pretty-printing box.

The pretty-printer must split the line at this point,

Not the normal way of pretty-printing, since imperative line splitting may interfere with current line counters and box size calculation. Using break hints within an enclosing vertical box is a better alternative.

val pp_print_if_newline : formatter -> unit -> unit
val print_if_newline : unit -> unit

Execute the next formatting command if the preceding line has just been split. Otherwise, ignore the next formatting command.

Pretty-printing termination

val pp_print_flush : formatter -> unit -> unit
val print_flush : unit -> unit

End of pretty-printing: resets the pretty-printer to initial state.

All open pretty-printing boxes are closed, all pending text is printed. In addition, the pretty-printer low level output device is flushed to ensure that all pending text is really displayed.

Note: never use print_flush in the normal course of a pretty-printing routine, since the pretty-printer uses a complex buffering machinery to properly indent the output; manually flushing those buffers at random would conflict with the pretty-printer strategy and result to poor rendering.

Only consider using print_flush when displaying all pending material is mandatory (for instance in case of interactive use when you want the user to read some text) and when resetting the pretty-printer state will not disturb further pretty-printing.

Warning: If the output device of the pretty-printer is an output channel, repeated calls to print_flush means repeated calls to Stdlib.flush to flush the out channel; these explicit flush calls could foil the buffering strategy of output channels and could dramatically impact efficiency.

val pp_print_newline : formatter -> unit -> unit
val print_newline : unit -> unit

End of pretty-printing: resets the pretty-printer to initial state.

All open pretty-printing boxes are closed, all pending text is printed.

Equivalent to print_flush with a new line emitted on the pretty-printer low-level output device immediately before the device is flushed. See corresponding words of caution for print_flush.

Note: this is not the normal way to output a new line; the preferred method is using break hints within a vertical pretty-printing box.

Margin

val pp_set_margin : formatter -> int -> unit
val set_margin : int -> unit

pp_set_margin ppf d sets the right margin to d (in characters): the pretty-printer splits lines that overflow the right margin according to the break hints given. Setting the margin to d means that the formatting engine aims at printing at most d-1 characters per line. Nothing happens if d is smaller than 2. If d is too large, the right margin is set to the maximum admissible value (which is greater than 10 ^ 9). If d is less than the current maximum indentation limit, the maximum indentation limit is decreased while trying to preserve a minimal ratio max_indent/margin>=50% and if possible the current difference margin - max_indent.

See also pp_set_geometry.

val pp_get_margin : formatter -> unit -> int
val get_margin : unit -> int

Returns the position of the right margin.

Maximum indentation limit

val pp_set_max_indent : formatter -> int -> unit
val set_max_indent : int -> unit

pp_set_max_indent ppf d sets the maximum indentation limit of lines to d (in characters): once this limit is reached, new pretty-printing boxes are rejected to the left, unless the enclosing box fully fits on the current line. As an illustration,

set_margin 10; set_max_indent 5; printf "@[123456@[7@]89A@]@." 

yields

123456
+789A

because the nested box "@[7@]" is opened after the maximum indentation limit (7>5) and its parent box does not fit on the current line. Either decreasing the length of the parent box to make it fit on a line:

printf "@[123456@[7@]89@]@." 

or opening an intermediary box before the maximum indentation limit which fits on the current line

printf "@[123@[456@[7@]89@]A@]@." 

avoids the rejection to the left of the inner boxes and print respectively "123456789" and "123456789A" . Note also that vertical boxes never fit on a line whereas horizontal boxes always fully fit on the current line. Opening a box may split a line whereas the contents may have fit. If this behavior is problematic, it can be curtailed by setting the maximum indentation limit to margin - 1. Note that setting the maximum indentation limit to margin is invalid.

Nothing happens if d is smaller than 2.

If d is too large, the limit is set to the maximum admissible value (which is greater than 10 ^ 9).

If d is greater or equal than the current margin, it is ignored, and the current maximum indentation limit is kept.

See also pp_set_geometry.

val pp_get_max_indent : formatter -> unit -> int
val get_max_indent : unit -> int

Return the maximum indentation limit (in characters).

Geometry

Geometric functions can be used to manipulate simultaneously the coupled variables, margin and maximum indentation limit.

type geometry = {
  1. max_indent : int;
  2. margin : int;
}
  • since 4.08
val check_geometry : geometry -> bool

Check if the formatter geometry is valid: 1 < max_indent < margin

  • since 4.08
val pp_set_geometry : formatter -> max_indent:int -> margin:int -> unit
val set_geometry : max_indent:int -> margin:int -> unit
val pp_safe_set_geometry : formatter -> max_indent:int -> margin:int -> unit
val safe_set_geometry : max_indent:int -> margin:int -> unit

pp_set_geometry ppf ~max_indent ~margin sets both the margin and maximum indentation limit for ppf.

When 1 < max_indent < margin, pp_set_geometry ppf ~max_indent ~margin is equivalent to pp_set_margin ppf margin; pp_set_max_indent ppf max_indent; and avoids the subtly incorrect pp_set_max_indent ppf max_indent; pp_set_margin ppf margin;

Outside of this domain, pp_set_geometry raises an invalid argument exception whereas pp_safe_set_geometry does nothing.

  • since 4.08
val pp_update_geometry : formatter -> (geometry -> geometry) -> unit

pp_update_geometry ppf (fun geo -> { geo with ... }) lets you update a formatter's geometry in a way that is robust to extension of the geometry record with new fields.

Raises an invalid argument exception if the returned geometry does not satisfy check_geometry.

  • since 4.11
val update_geometry : (geometry -> geometry) -> unit
val pp_get_geometry : formatter -> unit -> geometry
val get_geometry : unit -> geometry

Return the current geometry of the formatter

  • since 4.08

Maximum formatting depth

The maximum formatting depth is the maximum number of pretty-printing boxes simultaneously open.

Material inside boxes nested deeper is printed as an ellipsis (more precisely as the text returned by get_ellipsis_text ()).

val pp_set_max_boxes : formatter -> int -> unit
val set_max_boxes : int -> unit

pp_set_max_boxes ppf max sets the maximum number of pretty-printing boxes simultaneously open.

Material inside boxes nested deeper is printed as an ellipsis (more precisely as the text returned by get_ellipsis_text ()).

Nothing happens if max is smaller than 2.

val pp_get_max_boxes : formatter -> unit -> int
val get_max_boxes : unit -> int

Returns the maximum number of pretty-printing boxes allowed before ellipsis.

val pp_over_max_boxes : formatter -> unit -> bool
val over_max_boxes : unit -> bool

Tests if the maximum number of pretty-printing boxes allowed have already been opened.

Tabulation boxes

A tabulation box prints material on lines divided into cells of fixed length. A tabulation box provides a simple way to display vertical columns of left adjusted text.

This box features command set_tab to define cell boundaries, and command print_tab to move from cell to cell and split the line when there is no more cells to print on the line.

Note: printing within tabulation box is line directed, so arbitrary line splitting inside a tabulation box leads to poor rendering. Yet, controlled use of tabulation boxes allows simple printing of columns within module Format.

val pp_open_tbox : formatter -> unit -> unit
val open_tbox : unit -> unit

open_tbox () opens a new tabulation box.

This box prints lines separated into cells of fixed width.

Inside a tabulation box, special tabulation markers defines points of interest on the line (for instance to delimit cell boundaries). Function Format.set_tab sets a tabulation marker at insertion point.

A tabulation box features specific tabulation breaks to move to next tabulation marker or split the line. Function Format.print_tbreak prints a tabulation break.

val pp_close_tbox : formatter -> unit -> unit
val close_tbox : unit -> unit

Closes the most recently opened tabulation box.

val pp_set_tab : formatter -> unit -> unit
val set_tab : unit -> unit

Sets a tabulation marker at current insertion point.

val pp_print_tab : formatter -> unit -> unit
val print_tab : unit -> unit

print_tab () emits a 'next' tabulation break hint: if not already set on a tabulation marker, the insertion point moves to the first tabulation marker on the right, or the pretty-printer splits the line and insertion point moves to the leftmost tabulation marker.

It is equivalent to print_tbreak 0 0.

val pp_print_tbreak : formatter -> int -> int -> unit
val print_tbreak : int -> int -> unit

print_tbreak nspaces offset emits a 'full' tabulation break hint.

If not already set on a tabulation marker, the insertion point moves to the first tabulation marker on the right and the pretty-printer prints nspaces spaces.

If there is no next tabulation marker on the right, the pretty-printer splits the line at this point, then insertion point moves to the leftmost tabulation marker of the box.

If the pretty-printer splits the line, offset is added to the current indentation.

Ellipsis

val pp_set_ellipsis_text : formatter -> string -> unit
val set_ellipsis_text : string -> unit

Set the text of the ellipsis printed when too many pretty-printing boxes are open (a single dot, ., by default).

val pp_get_ellipsis_text : formatter -> unit -> string
val get_ellipsis_text : unit -> string

Return the text of the ellipsis.

Semantic tags

type stag = ..

Semantic tags (or simply tags) are user's defined annotations to associate user's specific operations to printed entities.

Common usage of semantic tags is text decoration to get specific font or text size rendering for a display device, or marking delimitation of entities (e.g. HTML or TeX elements or terminal escape sequences). More sophisticated usage of semantic tags could handle dynamic modification of the pretty-printer behavior to properly print the material within some specific tags. For instance, we can define an RGB tag like so:

type stag += RGB of {r:int;g:int;b:int}

In order to properly delimit printed entities, a semantic tag must be opened before and closed after the entity. Semantic tags must be properly nested like parentheses using pp_open_stag and pp_close_stag.

Tag specific operations occur any time a tag is opened or closed, At each occurrence, two kinds of operations are performed tag-marking and tag-printing:

  • The tag-marking operation is the simpler tag specific operation: it simply writes a tag specific string into the output device of the formatter. Tag-marking does not interfere with line-splitting computation.
  • The tag-printing operation is the more involved tag specific operation: it can print arbitrary material to the formatter. Tag-printing is tightly linked to the current pretty-printer operations.

Roughly speaking, tag-marking is commonly used to get a better rendering of texts in the rendering device, while tag-printing allows fine tuning of printing routines to print the same entity differently according to the semantic tags (i.e. print additional material or even omit parts of the output).

More precisely: when a semantic tag is opened or closed then both and successive 'tag-printing' and 'tag-marking' operations occur:

  • Tag-printing a semantic tag means calling the formatter specific function print_open_stag (resp. print_close_stag) with the name of the tag as argument: that tag-printing function can then print any regular material to the formatter (so that this material is enqueued as usual in the formatter queue for further line splitting computation).
  • Tag-marking a semantic tag means calling the formatter specific function mark_open_stag (resp. mark_close_stag) with the name of the tag as argument: that tag-marking function can then return the 'tag-opening marker' (resp. `tag-closing marker') for direct output into the output device of the formatter.

Being written directly into the output device of the formatter, semantic tag marker strings are not considered as part of the printing material that drives line splitting (in other words, the length of the strings corresponding to tag markers is considered as zero for line splitting).

Thus, semantic tag handling is in some sense transparent to pretty-printing and does not interfere with usual indentation. Hence, a single pretty-printing routine can output both simple 'verbatim' material or richer decorated output depending on the treatment of tags. By default, tags are not active, hence the output is not decorated with tag information. Once set_tags is set to true, the pretty-printer engine honors tags and decorates the output accordingly.

Default tag-marking functions behave the HTML way: string tags are enclosed in "<" and ">" while other tags are ignored; hence, opening marker for tag string "t" is "<t>" and closing marker is "</t>".

Default tag-printing functions just do nothing.

Tag-marking and tag-printing functions are user definable and can be set by calling set_formatter_stag_functions.

Semantic tag operations may be set on or off with set_tags. Tag-marking operations may be set on or off with set_mark_tags. Tag-printing operations may be set on or off with set_print_tags.

  • since 4.08
type tag = string
type stag +=
  1. | String_tag of tag
    (*

    String_tag s is a string tag s. String tags can be inserted either by explicitly using the constructor String_tag or by using the dedicated format syntax "@{<s> ... @}".

    • since 4.08
    *)
val pp_open_stag : formatter -> stag -> unit
val open_stag : stag -> unit

pp_open_stag ppf t opens the semantic tag named t.

The print_open_stag tag-printing function of the formatter is called with t as argument; then the opening tag marker for t, as given by mark_open_stag t, is written into the output device of the formatter.

  • since 4.08
val pp_close_stag : formatter -> unit -> unit
val close_stag : unit -> unit

pp_close_stag ppf () closes the most recently opened semantic tag t.

The closing tag marker, as given by mark_close_stag t, is written into the output device of the formatter; then the print_close_stag tag-printing function of the formatter is called with t as argument.

  • since 4.08
val pp_set_tags : formatter -> bool -> unit
val set_tags : bool -> unit

pp_set_tags ppf b turns on or off the treatment of semantic tags (default is off).

val pp_set_print_tags : formatter -> bool -> unit
val set_print_tags : bool -> unit

pp_set_print_tags ppf b turns on or off the tag-printing operations.

val pp_set_mark_tags : formatter -> bool -> unit
val set_mark_tags : bool -> unit

pp_set_mark_tags ppf b turns on or off the tag-marking operations.

val pp_get_print_tags : formatter -> unit -> bool
val get_print_tags : unit -> bool

Return the current status of tag-printing operations.

val pp_get_mark_tags : formatter -> unit -> bool
val get_mark_tags : unit -> bool

Return the current status of tag-marking operations.

val pp_set_formatter_out_channel : formatter -> out_channel -> unit

Redirecting the standard formatter output

val set_formatter_out_channel : out_channel -> unit

Redirect the standard pretty-printer output to the given channel. (All the output functions of the standard formatter are set to the default output functions printing to the given channel.)

set_formatter_out_channel is equivalent to pp_set_formatter_out_channel std_formatter.

val pp_set_formatter_output_functions : + formatter -> + (string -> int -> int -> unit) -> + (unit -> unit) -> + unit
val set_formatter_output_functions : + (string -> int -> int -> unit) -> + (unit -> unit) -> + unit

pp_set_formatter_output_functions ppf out flush redirects the standard pretty-printer output functions to the functions out and flush.

The out function performs all the pretty-printer string output. It is called with a string s, a start position p, and a number of characters n; it is supposed to output characters p to p + n - 1 of s.

The flush function is called whenever the pretty-printer is flushed (via conversion %!, or pretty-printing indications @? or @., or using low level functions print_flush or print_newline).

val pp_get_formatter_output_functions : + formatter -> + unit -> + (string -> int -> int -> unit) * (unit -> unit)
val get_formatter_output_functions : + unit -> + (string -> int -> int -> unit) * (unit -> unit)

Return the current output functions of the standard pretty-printer.

Redefining formatter output

The Format module is versatile enough to let you completely redefine the meaning of pretty-printing output: you may provide your own functions to define how to handle indentation, line splitting, and even printing of all the characters that have to be printed!

Redefining output functions

type formatter_out_functions = {
  1. out_string : string -> int -> int -> unit;
  2. out_flush : unit -> unit;
  3. out_newline : unit -> unit;
  4. out_spaces : int -> unit;
  5. out_indent : int -> unit;
    (*
    • since 4.06
    *)
}

The set of output functions specific to a formatter:

  • the out_string function performs all the pretty-printer string output. It is called with a string s, a start position p, and a number of characters n; it is supposed to output characters p to p + n - 1 of s.
  • the out_flush function flushes the pretty-printer output device.
  • out_newline is called to open a new line when the pretty-printer splits the line.
  • the out_spaces function outputs spaces when a break hint leads to spaces instead of a line split. It is called with the number of spaces to output.
  • the out_indent function performs new line indentation when the pretty-printer splits the line. It is called with the indentation value of the new line.

By default:

  • fields out_string and out_flush are output device specific; (e.g. Stdlib.output_string and Stdlib.flush for a Stdlib.out_channel device, or Buffer.add_substring and Stdlib.ignore for a Buffer.t output device),
  • field out_newline is equivalent to out_string "\n" 0 1;
  • fields out_spaces and out_indent are equivalent to out_string (String.make n ' ') 0 n.
  • since 4.01
val pp_set_formatter_out_functions : + formatter -> + formatter_out_functions -> + unit
val set_formatter_out_functions : formatter_out_functions -> unit

pp_set_formatter_out_functions ppf out_funs Set all the pretty-printer output functions of ppf to those of argument out_funs,

This way, you can change the meaning of indentation (which can be something else than just printing space characters) and the meaning of new lines opening (which can be connected to any other action needed by the application at hand).

Reasonable defaults for functions out_spaces and out_newline are respectively out_funs.out_string (String.make n ' ') 0 n and out_funs.out_string "\n" 0 1.

  • since 4.01
val pp_get_formatter_out_functions : + formatter -> + unit -> + formatter_out_functions
val get_formatter_out_functions : unit -> formatter_out_functions

Return the current output functions of the pretty-printer, including line splitting and indentation functions. Useful to record the current setting and restore it afterwards.

  • since 4.01

Redefining semantic tag operations

type formatter_stag_functions = {
  1. mark_open_stag : stag -> string;
  2. mark_close_stag : stag -> string;
  3. print_open_stag : stag -> unit;
  4. print_close_stag : stag -> unit;
}

The semantic tag handling functions specific to a formatter: mark versions are the 'tag-marking' functions that associate a string marker to a tag in order for the pretty-printing engine to write those markers as 0 length tokens in the output device of the formatter. print versions are the 'tag-printing' functions that can perform regular printing when a tag is closed or opened.

  • since 4.08
val pp_set_formatter_stag_functions : + formatter -> + formatter_stag_functions -> + unit
val set_formatter_stag_functions : formatter_stag_functions -> unit

pp_set_formatter_stag_functions ppf tag_funs changes the meaning of opening and closing semantic tag operations to use the functions in tag_funs when printing on ppf.

When opening a semantic tag with name t, the string t is passed to the opening tag-marking function (the mark_open_stag field of the record tag_funs), that must return the opening tag marker for that name. When the next call to close_stag () happens, the semantic tag name t is sent back to the closing tag-marking function (the mark_close_stag field of record tag_funs), that must return a closing tag marker for that name.

The print_ field of the record contains the tag-printing functions that are called at tag opening and tag closing time, to output regular material in the pretty-printer queue.

  • since 4.08
val pp_get_formatter_stag_functions : + formatter -> + unit -> + formatter_stag_functions
val get_formatter_stag_functions : unit -> formatter_stag_functions

Return the current semantic tag operation functions of the standard pretty-printer.

  • since 4.08

Defining formatters

Defining new formatters permits unrelated output of material in parallel on several output devices. All the parameters of a formatter are local to the formatter: right margin, maximum indentation limit, maximum number of pretty-printing boxes simultaneously open, ellipsis, and so on, are specific to each formatter and may be fixed independently.

For instance, given a Buffer.t buffer b, formatter_of_buffer b returns a new formatter using buffer b as its output device. Similarly, given a Stdlib.out_channel output channel oc, formatter_of_out_channel oc returns a new formatter using channel oc as its output device.

Alternatively, given out_funs, a complete set of output functions for a formatter, then formatter_of_out_functions out_funs computes a new formatter using those functions for output.

val formatter_of_out_channel : out_channel -> formatter

formatter_of_out_channel oc returns a new formatter writing to the corresponding output channel oc.

val synchronized_formatter_of_out_channel : + out_channel -> + formatter Domain.DLS.key

synchronized_formatter_of_out_channel oc returns the key to the domain-local state that holds the domain-local formatter for writing to the corresponding output channel oc.

When the formatter is used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with print_flush.

  • alert unstable
val std_formatter : formatter

The initial domain's standard formatter to write to standard output.

It is defined as formatter_of_out_channel Stdlib.stdout.

val get_std_formatter : unit -> formatter

get_std_formatter () returns the current domain's standard formatter used to write to standard output.

  • since 5.0
val err_formatter : formatter

The initial domain's formatter to write to standard error.

It is defined as formatter_of_out_channel Stdlib.stderr.

val get_err_formatter : unit -> formatter

get_err_formatter () returns the current domain's formatter used to write to standard error.

  • since 5.0
val formatter_of_buffer : Buffer.t -> formatter

formatter_of_buffer b returns a new formatter writing to buffer b. At the end of pretty-printing, the formatter must be flushed using pp_print_flush or pp_print_newline, to print all the pending material into the buffer.

val stdbuf : Buffer.t

The initial domain's string buffer in which str_formatter writes.

val get_stdbuf : unit -> Buffer.t

get_stdbuf () returns the current domain's string buffer in which the current domain's string formatter writes.

  • since 5.0
val str_formatter : formatter

The initial domain's formatter to output to the stdbuf string buffer.

str_formatter is defined as formatter_of_buffer stdbuf.

val get_str_formatter : unit -> formatter

The current domain's formatter to output to the current domains string buffer.

  • since 5.0
val flush_str_formatter : unit -> string

Returns the material printed with str_formatter of the current domain, flushes the formatter and resets the corresponding buffer.

val make_formatter : + (string -> int -> int -> unit) -> + (unit -> unit) -> + formatter

make_formatter out flush returns a new formatter that outputs with function out, and flushes with function flush.

For instance,

make_formatter
+  (Stdlib.output oc)
+  (fun () -> Stdlib.flush oc)

returns a formatter to the Stdlib.out_channel oc.

val make_synchronized_formatter : + (string -> int -> int -> unit) -> + (unit -> unit) -> + formatter Domain.DLS.key

make_synchronized_formatter out flush returns the key to the domain-local state that holds the domain-local formatter that outputs with function out, and flushes with function flush.

When the formatter is used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with print_flush.

  • since 5.0
  • alert unstable
val formatter_of_out_functions : formatter_out_functions -> formatter

formatter_of_out_functions out_funs returns a new formatter that writes with the set of output functions out_funs.

See definition of type formatter_out_functions for the meaning of argument out_funs.

  • since 4.06

Symbolic pretty-printing

Symbolic pretty-printing is pretty-printing using a symbolic formatter, i.e. a formatter that outputs symbolic pretty-printing items.

When using a symbolic formatter, all regular pretty-printing activities occur but output material is symbolic and stored in a buffer of output items. At the end of pretty-printing, flushing the output buffer allows post-processing of symbolic output before performing low level output operations.

In practice, first define a symbolic output buffer b using:

  • let sob = make_symbolic_output_buffer (). Then define a symbolic formatter with:
  • let ppf = formatter_of_symbolic_output_buffer sob

Use symbolic formatter ppf as usual, and retrieve symbolic items at end of pretty-printing by flushing symbolic output buffer sob with:

  • flush_symbolic_output_buffer sob.
type symbolic_output_item =
  1. | Output_flush
    (*

    symbolic flush command

    *)
  2. | Output_newline
    (*

    symbolic newline command

    *)
  3. | Output_string of string
    (*

    Output_string s: symbolic output for string s

    *)
  4. | Output_spaces of int
    (*

    Output_spaces n: symbolic command to output n spaces

    *)
  5. | Output_indent of int
    (*

    Output_indent i: symbolic indentation of size i

    *)

Items produced by symbolic pretty-printers

  • since 4.06
type symbolic_output_buffer

The output buffer of a symbolic pretty-printer.

  • since 4.06
val make_symbolic_output_buffer : unit -> symbolic_output_buffer

make_symbolic_output_buffer () returns a fresh buffer for symbolic output.

  • since 4.06
val clear_symbolic_output_buffer : symbolic_output_buffer -> unit

clear_symbolic_output_buffer sob resets buffer sob.

  • since 4.06
val get_symbolic_output_buffer : + symbolic_output_buffer -> + symbolic_output_item list

get_symbolic_output_buffer sob returns the contents of buffer sob.

  • since 4.06
val flush_symbolic_output_buffer : + symbolic_output_buffer -> + symbolic_output_item list

flush_symbolic_output_buffer sob returns the contents of buffer sob and resets buffer sob. flush_symbolic_output_buffer sob is equivalent to let items = get_symbolic_output_buffer sob in + clear_symbolic_output_buffer sob; items

  • since 4.06
val add_symbolic_output_item : + symbolic_output_buffer -> + symbolic_output_item -> + unit

add_symbolic_output_item sob itm adds item itm to buffer sob.

  • since 4.06
val formatter_of_symbolic_output_buffer : symbolic_output_buffer -> formatter

formatter_of_symbolic_output_buffer sob returns a symbolic formatter that outputs to symbolic_output_buffer sob.

  • since 4.06

Convenience formatting functions.

val pp_print_iter : + ?pp_sep:(formatter -> unit -> unit) -> + (('a -> unit) -> 'b -> unit) -> + (formatter -> 'a -> unit) -> + formatter -> + 'b -> + unit

pp_print_iter ~pp_sep iter pp_v ppf v formats on ppf the iterations of iter over a collection v of values using pp_v. Iterations are separated by pp_sep (defaults to pp_print_cut).

  • since 5.1
val pp_print_list : + ?pp_sep:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> + formatter -> + 'a list -> + unit

pp_print_list ?pp_sep pp_v ppf l prints items of list l, using pp_v to print each item, and calling pp_sep between items (pp_sep defaults to pp_print_cut). Does nothing on empty lists.

  • since 4.02
val pp_print_array : + ?pp_sep:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> + formatter -> + 'a array -> + unit

pp_print_array ?pp_sep pp_v ppf a prints items of array a, using pp_v to print each item, and calling pp_sep between items (pp_sep defaults to pp_print_cut). Does nothing on empty arrays.

If a is mutated after pp_print_array is called, the printed values may not be what is expected because Format can delay the printing. This can be avoided by flushing ppf.

  • since 5.1
val pp_print_seq : + ?pp_sep:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> + formatter -> + 'a Seq.t -> + unit

pp_print_seq ?pp_sep pp_v ppf s prints items of sequence s, using pp_v to print each item, and calling pp_sep between items (pp_sep defaults to pp_print_cut. Does nothing on empty sequences.

This function does not terminate on infinite sequences.

  • since 4.12
val pp_print_text : formatter -> string -> unit

pp_print_text ppf s prints s with spaces and newlines respectively printed using pp_print_space and pp_force_newline.

  • since 4.02
val pp_print_option : + ?none:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> + formatter -> + 'a option -> + unit

pp_print_option ?none pp_v ppf o prints o on ppf using pp_v if o is Some v and none if it is None. none prints nothing by default.

  • since 4.08
val pp_print_result : + ok:(formatter -> 'a -> unit) -> + error:(formatter -> 'e -> unit) -> + formatter -> + ('a, 'e) result -> + unit

pp_print_result ~ok ~error ppf r prints r on ppf using ok if r is Ok _ and error if r is Error _.

  • since 4.08
val pp_print_either : + left:(formatter -> 'a -> unit) -> + right:(formatter -> 'b -> unit) -> + formatter -> + ('a, 'b) Either.t -> + unit

pp_print_either ~left ~right ppf e prints e on ppf using left if e is Either.Left _ and right if e is Either.Right _.

  • since 4.13

Formatted pretty-printing

Module Format provides a complete set of printf like functions for pretty-printing using format string specifications.

Specific annotations may be added in the format strings to give pretty-printing commands to the pretty-printing engine.

Those annotations are introduced in the format strings using the @ character. For instance, @ means a space break, @, means a cut, @[ opens a new box, and @] closes the last open box.

val fprintf : formatter -> ('a, formatter, unit) format -> 'a

fprintf ff fmt arg1 ... argN formats the arguments arg1 to argN according to the format string fmt, and outputs the resulting string on the formatter ff.

The format string fmt is a character string which contains three types of objects: plain characters and conversion specifications as specified in the Printf module, and pretty-printing indications specific to the Format module.

The pretty-printing indication characters are introduced by a @ character, and their meanings are:

  • @[: open a pretty-printing box. The type and offset of the box may be optionally specified with the following syntax: the < character, followed by an optional box type indication, then an optional integer offset, and the closing > character. Pretty-printing box type is one of h, v, hv, b, or hov. 'h' stands for an 'horizontal' pretty-printing box, 'v' stands for a 'vertical' pretty-printing box, 'hv' stands for an 'horizontal/vertical' pretty-printing box, 'b' stands for an 'horizontal-or-vertical' pretty-printing box demonstrating indentation, 'hov' stands a simple 'horizontal-or-vertical' pretty-printing box. For instance, @[<hov 2> opens an 'horizontal-or-vertical' pretty-printing box with indentation 2 as obtained with open_hovbox 2. For more details about pretty-printing boxes, see the various box opening functions open_*box.
  • @]: close the most recently opened pretty-printing box.
  • @,: output a 'cut' break hint, as with print_cut ().
  • @ : output a 'space' break hint, as with print_space ().
  • @;: output a 'full' break hint as with print_break. The nspaces and offset parameters of the break hint may be optionally specified with the following syntax: the < character, followed by an integer nspaces value, then an integer offset, and a closing > character. If no parameters are provided, the full break defaults to a 'space' break hint.
  • @.: flush the pretty-printer and split the line, as with print_newline ().
  • @<n>: print the following item as if it were of length n. Hence, printf "@<0>%s" arg prints arg as a zero length string. If @<n> is not followed by a conversion specification, then the following character of the format is printed as if it were of length n.
  • @\{: open a semantic tag. The name of the tag may be optionally specified with the following syntax: the < character, followed by an optional string specification, and the closing > character. The string specification is any character string that does not contain the closing character '>'. If omitted, the tag name defaults to the empty string. For more details about semantic tags, see the functions open_stag and close_stag.
  • @\}: close the most recently opened semantic tag.
  • @?: flush the pretty-printer as with print_flush (). This is equivalent to the conversion %!.
  • @\n: force a newline, as with force_newline (), not the normal way of pretty-printing, you should prefer using break hints inside a vertical pretty-printing box.

Note: To prevent the interpretation of a @ character as a pretty-printing indication, escape it with a % character. Old quotation mode @@ is deprecated since it is not compatible with formatted input interpretation of character '@'.

Example: printf "@[%s@ %d@]@." "x =" 1 is equivalent to open_box (); print_string "x ="; print_space (); + print_int 1; close_box (); print_newline (). It prints x = 1 within a pretty-printing 'horizontal-or-vertical' box.

val printf : ('a, formatter, unit) format -> 'a

Same as fprintf above, but output on get_std_formatter ().

It is defined similarly to fun fmt -> fprintf (get_std_formatter ()) fmt but delays calling get_std_formatter until after the final argument required by the format is received. When used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with print_flush.

val eprintf : ('a, formatter, unit) format -> 'a

Same as fprintf above, but output on get_err_formatter ().

It is defined similarly to fun fmt -> fprintf (get_err_formatter ()) fmt but delays calling get_err_formatter until after the final argument required by the format is received. When used with multiple domains, the output from the domains will be interleaved with each other at points where the formatter is flushed, such as with print_flush.

val sprintf : ('a, unit, string) format -> 'a

Same as printf above, but instead of printing on a formatter, returns a string containing the result of formatting the arguments. Note that the pretty-printer queue is flushed at the end of each call to sprintf. Note that if your format string contains a %a, you should use asprintf.

In case of multiple and related calls to sprintf to output material on a single string, you should consider using fprintf with the predefined formatter str_formatter and call flush_str_formatter () to get the final result.

Alternatively, you can use Format.fprintf with a formatter writing to a buffer of your own: flushing the formatter and the buffer at the end of pretty-printing returns the desired string.

val asprintf : ('a, formatter, unit, string) format4 -> 'a

Same as printf above, but instead of printing on a formatter, returns a string containing the result of formatting the arguments. The type of asprintf is general enough to interact nicely with %a conversions.

  • since 4.01
val dprintf : ('a, formatter, unit, formatter -> unit) format4 -> 'a

Same as fprintf, except the formatter is the last argument. dprintf "..." a b c is a function of type formatter -> unit which can be given to a format specifier %t.

This can be used as a replacement for asprintf to delay formatting decisions. Using the string returned by asprintf in a formatting context forces formatting decisions to be taken in isolation, and the final string may be created prematurely. dprintf allows delay of formatting decisions until the final formatting context is known. For example:

let t = Format.dprintf "%i@ %i@ %i" 1 2 3 in
+...
+Format.printf "@[<v>%t@]" t
  • since 4.08
val ifprintf : formatter -> ('a, formatter, unit) format -> 'a

Same as fprintf above, but does not print anything. Useful to ignore some material when conditionally printing.

  • since 3.10

Formatted Pretty-Printing with continuations.

val kfprintf : + (formatter -> 'a) -> + formatter -> + ('b, formatter, unit, 'a) format4 -> + 'b

Same as fprintf above, but instead of returning immediately, passes the formatter to its first argument at the end of printing.

val kdprintf : + ((formatter -> unit) -> 'a) -> + ('b, formatter, unit, 'a) format4 -> + 'b

Same as dprintf above, but instead of returning immediately, passes the suspended printer to its first argument at the end of printing.

  • since 4.08
val ikfprintf : + (formatter -> 'a) -> + formatter -> + ('b, formatter, unit, 'a) format4 -> + 'b

Same as kfprintf above, but does not print anything. Useful to ignore some material when conditionally printing.

  • since 3.12
val ksprintf : (string -> 'a) -> ('b, unit, string, 'a) format4 -> 'b

Same as sprintf above, but instead of returning the string, passes it to the first argument.

val kasprintf : (string -> 'a) -> ('b, formatter, unit, 'a) format4 -> 'b

Same as asprintf above, but instead of returning the string, passes it to the first argument.

  • since 4.03

Examples

A few warmup examples to get an idea of how Format is used.

We have a list l of pairs (int * bool), which the toplevel prints for us:

# let l = List.init 20 (fun n -> n, n mod 2 = 0)
+val l : (int * bool) list =
+[(0, true); (1, false); (2, true); (3, false); (4, true); (5, false);
+ (6, true); (7, false); (8, true); (9, false); (10, true); (11, false);
+ (12, true); (13, false); (14, true); (15, false); (16, true); (17, false);
+ (18, true); (19, false)]

If we want to print it ourself without the toplevel magic, we can try this:

# let pp_pair out (x,y) = Format.fprintf out "(%d, %b)" x y
+val pp_pair : Format.formatter -> int * bool -> unit = <fun>
+# Format.printf "l: [@[<hov>%a@]]@."
+  Format.(pp_print_list ~pp_sep:(fun out () -> fprintf out ";@ ") pp_pair) l
+  l: [(0, true); (1, false); (2, true); (3, false); (4, true); (5, false);
+      (6, true); (7, false); (8, true); (9, false); (10, true); (11, false);
+      (12, true); (13, false); (14, true); (15, false); (16, true);
+      (17, false); (18, true); (19, false)]

What this does, briefly, is:

  • pp_pair prints a pair bool*int surrounded in "(" ")". It takes a formatter (into which formatting happens), and the pair itself. When printing is done it returns ().
  • Format.printf "l = [@[<hov>%a@]]@." ... l is like printf, but with additional formatting instructions (denoted with "@"). The pair "@<hov>" and "@" is a "horizontal-or-vertical box".
  • "@." ends formatting with a newline. It is similar to "\n" but is also aware of the Format.formatter's state. Do not use "\n" with Format.
  • "%a" is a formatting instruction, like "%d" or "%s" for printf. However, where "%d" prints an integer and "%s" prints a string, "%a" takes a printer (of type Format.formatter -> 'a -> unit) and a value (of type 'a) and applies the printer to the value. This is key to compositionality of printers.
  • We build a list printer using Format.pp_print_list ~pp_sep:(...) pp_pair. pp_print_list takes an element printer and returns a list printer. The ?pp_sep optional argument, if provided, is called in between each element to print a separator.
  • Here, for a separator, we use (fun out () -> Format.fprintf out ";@ "). It prints ";", and then "@ " which is a breaking space (either it prints " ", or it prints a newline if the box is about to overflow). This "@ " is responsible for the list printing splitting into several lines.

If we omit "@ ", we get an ugly single-line print:

# Format.printf "l: [@[<hov>%a@]]@."
+      Format.(pp_print_list ~pp_sep:(fun out () -> fprintf out "; ") pp_pair) l
+  l: [(0, true); (1, false); (2, true); (* ... *); (18, true); (19, false)]
+- : unit = ()

Generally, it is good practice to define custom printers for important types in your program. If, for example, you were to define basic geometry types like so:

type point = {
+  x: float;
+  y: float;
+}
+
+type rectangle = {
+  ll: point; (* lower left *)
+  ur: point; (* upper right *)
+}

For debugging purpose, or to display information in logs, or on the console, it would be convenient to define printers for these types. Here is an example of to do it. Note that "%.3f" is a float printer up to 3 digits of precision after the dot; "%f" would print as many digits as required, which is somewhat verbose; "%h" is an hexadecimal float printer.

let pp_point out (p:point) =
+  Format.fprintf out "{ @[x=%.3f;@ y=%.3f@] }" p.x p.y
+
+let pp_rectangle out (r:rectangle) =
+  Format.fprintf out "{ @[ll=%a;@ ur=%a@] }"
+    pp_point r.ll pp_point r.ur

In the .mli file, we could have:

val pp_point : Format.formatter -> point -> unit
+
+val pp_rectangle : Format.formatter -> rectangle -> unit

These printers can now be used with "%a" inside other printers.

# Format.printf "some rectangle: %a@."
+      (Format.pp_print_option pp_rectangle)
+      (Some {ll={x=1.; y=2.}; ur={x=42.; y=500.12345}})
+some rectangle: { l={ x=1.000; y=2.000 }; ur={ x=42.000; y=500.123 } }
+
+# Format.printf "no rectangle: %a@."
+      (Format.pp_option pp_rectangle)
+      None
+no rectangle:

See how we combine pp_print_option (option printer) and our newly defined rectangle printer, like we did with pp_print_list earlier.

For a more extensive tutorial, see "Using the Format module".

A final note: the Format module is a starting point. The OCaml ecosystem has libraries that makes formatting easier and more expressive, with more combinators, more concise names, etc. An example of such a library is Fmt.

Automatic deriving of pretty-printers from type definitions is also possible, using https://github.com/ocaml-ppx/ppx_deriving or similar ppx derivers.

diff --git a/docs/stdlib/Stdlib/Fun/index.html b/docs/stdlib/Stdlib/Fun/index.html new file mode 100644 index 00000000..551ee34c --- /dev/null +++ b/docs/stdlib/Stdlib/Fun/index.html @@ -0,0 +1,2 @@ + +Fun (docs.stdlib.Stdlib.Fun)

Module Stdlib.Fun

Function manipulation.

  • since 4.08

Combinators

val id : 'a -> 'a

id is the identity function. For any argument x, id x is x.

val const : 'a -> _ -> 'a

const c is a function that always returns the value c. For any argument x, (const c) x is c.

val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c

flip f reverses the argument order of the binary function f. For any arguments x and y, (flip f) x y is f y x.

val negate : ('a -> bool) -> 'a -> bool

negate p is the negation of the predicate function p. For any argument x, (negate p) x is not (p x).

Exception handling

val protect : finally:(unit -> unit) -> (unit -> 'a) -> 'a

protect ~finally work invokes work () and then finally () before work () returns with its value or an exception. In the latter case the exception is re-raised after finally (). If finally () raises an exception, then the exception Finally_raised is raised instead.

protect can be used to enforce local invariants whether work () returns normally or raises an exception. However, it does not protect against unexpected exceptions raised inside finally () such as Stdlib.Out_of_memory, Stdlib.Stack_overflow, or asynchronous exceptions raised by signal handlers (e.g. Sys.Break).

Note: It is a programming error if other kinds of exceptions are raised by finally, as any exception raised in work () will be lost in the event of a Finally_raised exception. Therefore, one should make sure to handle those inside the finally.

exception Finally_raised of exn

Finally_raised exn is raised by protect ~finally work when finally raises an exception exn. This exception denotes either an unexpected exception or a programming error. As a general rule, one should not catch a Finally_raised exception except as part of a catch-all handler.

diff --git a/docs/stdlib/Stdlib/Gc/Memprof/index.html b/docs/stdlib/Stdlib/Gc/Memprof/index.html new file mode 100644 index 00000000..5189b2c9 --- /dev/null +++ b/docs/stdlib/Stdlib/Gc/Memprof/index.html @@ -0,0 +1,6 @@ + +Memprof (docs.stdlib.Stdlib.Gc.Memprof)

Module Gc.Memprof

Memprof is a sampling engine for allocated memory words. Every allocated word has a probability of being sampled equal to a configurable sampling rate. Once a block is sampled, it becomes tracked. A tracked block triggers a user-defined callback as soon as it is allocated, promoted or deallocated.

Since blocks are composed of several words, a block can potentially be sampled several times. If a block is sampled several times, then each of the callback is called once for each event of this block: the multiplicity is given in the n_samples field of the allocation structure.

This engine makes it possible to implement a low-overhead memory profiler as an OCaml library.

Note: this API is EXPERIMENTAL. It may change without prior notice.

type allocation_source =
  1. | Normal
  2. | Marshal
  3. | Custom
type allocation = private {
  1. n_samples : int;
    (*

    The number of samples in this block (>= 1).

    *)
  2. size : int;
    (*

    The size of the block, in words, excluding the header.

    *)
  3. source : allocation_source;
    (*

    The type of the allocation.

    *)
  4. callstack : Printexc.raw_backtrace;
    (*

    The callstack for the allocation.

    *)
}

The type of metadata associated with allocations. This is the type of records passed to the callback triggered by the sampling of an allocation.

type ('minor, 'major) tracker = {
  1. alloc_minor : allocation -> 'minor option;
  2. alloc_major : allocation -> 'major option;
  3. promote : 'minor -> 'major option;
  4. dealloc_minor : 'minor -> unit;
  5. dealloc_major : 'major -> unit;
}

A ('minor, 'major) tracker describes how memprof should track sampled blocks over their lifetime, keeping a user-defined piece of metadata for each of them: 'minor is the type of metadata to keep for minor blocks, and 'major the type of metadata for major blocks.

When using threads, it is guaranteed that allocation callbacks are always run in the thread where the allocation takes place.

If an allocation-tracking or promotion-tracking function returns None, memprof stops tracking the corresponding value.

val null_tracker : ('minor, 'major) tracker

Default callbacks simply return None or ()

val start : + sampling_rate:float -> + ?callstack_size:int -> + ('minor, 'major) tracker -> + unit

Start the sampling with the given parameters. Fails if sampling is already active.

The parameter sampling_rate is the sampling rate in samples per word (including headers). Usually, with cheap callbacks, a rate of 1e-4 has no visible effect on performance, and 1e-3 causes the program to run a few percent slower

The parameter callstack_size is the length of the callstack recorded at every sample. Its default is max_int.

The parameter tracker determines how to track sampled blocks over their lifetime in the minor and major heap.

Sampling is temporarily disabled when calling a callback for the current thread. So they do not need to be re-entrant if the program is single-threaded. However, if threads are used, it is possible that a context switch occurs during a callback, in this case the callback functions must be re-entrant.

Note that the callback can be postponed slightly after the actual event. The callstack passed to the callback is always accurate, but the program state may have evolved.

val stop : unit -> unit

Stop the sampling. Fails if sampling is not active.

This function does not allocate memory.

All the already tracked blocks are discarded. If there are pending postponed callbacks, they may be discarded.

Calling stop when a callback is running can lead to callbacks not being called even though some events happened.

diff --git a/docs/stdlib/Stdlib/Gc/index.html b/docs/stdlib/Stdlib/Gc/index.html new file mode 100644 index 00000000..2556426a --- /dev/null +++ b/docs/stdlib/Stdlib/Gc/index.html @@ -0,0 +1,2 @@ + +Gc (docs.stdlib.Stdlib.Gc)

Module Stdlib.Gc

Memory management control and statistics; finalised values.

type stat = {
  1. minor_words : float;
    (*

    Number of words allocated in the minor heap since the program was started.

    *)
  2. promoted_words : float;
    (*

    Number of words allocated in the minor heap that survived a minor collection and were moved to the major heap since the program was started.

    *)
  3. major_words : float;
    (*

    Number of words allocated in the major heap, including the promoted words, since the program was started.

    *)
  4. minor_collections : int;
    (*

    Number of minor collections since the program was started.

    *)
  5. major_collections : int;
    (*

    Number of major collection cycles completed since the program was started.

    *)
  6. heap_words : int;
    (*

    Total size of the major heap, in words.

    *)
  7. heap_chunks : int;
    (*

    Number of contiguous pieces of memory that make up the major heap. This metrics is currently not available in OCaml 5: the field value is always 0.

    *)
  8. live_words : int;
    (*

    Number of words of live data in the major heap, including the header words.

    Note that "live" words refers to every word in the major heap that isn't currently known to be collectable, which includes words that have become unreachable by the program after the start of the previous gc cycle. It is typically much simpler and more predictable to call Gc.full_major (or Gc.compact) then computing gc stats, as then "live" words has the simple meaning of "reachable by the program". One caveat is that a single call to Gc.full_major will not reclaim values that have a finaliser from Gc.finalise (this does not apply to Gc.finalise_last). If this caveat matters, simply call Gc.full_major twice instead of once.

    *)
  9. live_blocks : int;
    (*

    Number of live blocks in the major heap.

    See live_words for a caveat about what "live" means.

    *)
  10. free_words : int;
    (*

    Number of words in the free list.

    *)
  11. free_blocks : int;
    (*

    Number of blocks in the free list. This metrics is currently not available in OCaml 5: the field value is always 0.

    *)
  12. largest_free : int;
    (*

    Size (in words) of the largest block in the free list. This metrics is currently not available in OCaml 5: the field value is always 0.

    *)
  13. fragments : int;
    (*

    Number of wasted words due to fragmentation. These are 1-words free blocks placed between two live blocks. They are not available for allocation.

    *)
  14. compactions : int;
    (*

    Number of heap compactions since the program was started.

    *)
  15. top_heap_words : int;
    (*

    Maximum size reached by the major heap, in words.

    *)
  16. stack_size : int;
    (*

    Current size of the stack, in words. This metrics is currently not available in OCaml 5: the field value is always 0.

    • since 3.12
    *)
  17. forced_major_collections : int;
    (*

    Number of forced full major collections completed since the program was started.

    • since 4.12
    *)
}

The memory management counters are returned in a stat record. These counters give values for the whole program.

The total amount of memory allocated by the program since it was started is (in words) minor_words + major_words - promoted_words. Multiply by the word size (4 on a 32-bit machine, 8 on a 64-bit machine) to get the number of bytes.

type control = {
  1. minor_heap_size : int;
    (*

    The size (in words) of the minor heap. Changing this parameter will trigger a minor collection. The total size of the minor heap used by this program is the sum of the heap sizes of the active domains. Default: 256k.

    *)
  2. major_heap_increment : int;
    (*

    How much to add to the major heap when increasing it. If this number is less than or equal to 1000, it is a percentage of the current heap size (i.e. setting it to 100 will double the heap size at each increase). If it is more than 1000, it is a fixed number of words that will be added to the heap. Default: 15.

    *)
  3. space_overhead : int;
    (*

    The major GC speed is computed from this parameter. This is the memory that will be "wasted" because the GC does not immediately collect unreachable blocks. It is expressed as a percentage of the memory used for live data. The GC will work more (use more CPU time and collect blocks more eagerly) if space_overhead is smaller. Default: 120.

    *)
  4. verbose : int;
    (*

    This value controls the GC messages on standard error output. It is a sum of some of the following flags, to print messages on the corresponding events:

    • 0x001 Start and end of major GC cycle.
    • 0x002 Minor collection and major GC slice.
    • 0x004 Growing and shrinking of the heap.
    • 0x008 Resizing of stacks and memory manager tables.
    • 0x010 Heap compaction.
    • 0x020 Change of GC parameters.
    • 0x040 Computation of major GC slice size.
    • 0x080 Calling of finalisation functions.
    • 0x100 Bytecode executable and shared library search at start-up.
    • 0x200 Computation of compaction-triggering condition.
    • 0x400 Output GC statistics at program exit. Default: 0.
    *)
  5. max_overhead : int;
    (*

    Heap compaction is triggered when the estimated amount of "wasted" memory is more than max_overhead percent of the amount of live data. If max_overhead is set to 0, heap compaction is triggered at the end of each major GC cycle (this setting is intended for testing purposes only). If max_overhead >= 1000000, compaction is never triggered. If compaction is permanently disabled, it is strongly suggested to set allocation_policy to 2. Default: 500.

    *)
  6. stack_limit : int;
    (*

    The maximum size of the fiber stacks (in words). Default: 1024k.

    *)
  7. allocation_policy : int;
    (*

    The policy used for allocating in the major heap. Possible values are 0, 1 and 2.

    • 0 is the next-fit policy, which is usually fast but can result in fragmentation, increasing memory consumption.
    • 1 is the first-fit policy, which avoids fragmentation but has corner cases (in certain realistic workloads) where it is sensibly slower.
    • 2 is the best-fit policy, which is fast and avoids fragmentation. In our experiments it is faster and uses less memory than both next-fit and first-fit. (since OCaml 4.10)

    The default is best-fit.

    On one example that was known to be bad for next-fit and first-fit, next-fit takes 28s using 855Mio of memory, first-fit takes 47s using 566Mio of memory, best-fit takes 27s using 545Mio of memory.

    Note: If you change to next-fit, you may need to reduce the space_overhead setting, for example using 80 instead of the default 120 which is tuned for best-fit. Otherwise, your program will need more memory.

    Note: changing the allocation policy at run-time forces a heap compaction, which is a lengthy operation unless the heap is small (e.g. at the start of the program).

    Default: 2.

    • since 3.11
    *)
  8. window_size : int;
    (*

    The size of the window used by the major GC for smoothing out variations in its workload. This is an integer between 1 and 50. Default: 1.

    • since 4.03
    *)
  9. custom_major_ratio : int;
    (*

    Target ratio of floating garbage to major heap size for out-of-heap memory held by custom values located in the major heap. The GC speed is adjusted to try to use this much memory for dead values that are not yet collected. Expressed as a percentage of major heap size. The default value keeps the out-of-heap floating garbage about the same size as the in-heap overhead. Note: this only applies to values allocated with caml_alloc_custom_mem (e.g. bigarrays). Default: 44.

    • since 4.08
    *)
  10. custom_minor_ratio : int;
    (*

    Bound on floating garbage for out-of-heap memory held by custom values in the minor heap. A minor GC is triggered when this much memory is held by custom values located in the minor heap. Expressed as a percentage of minor heap size. Note: this only applies to values allocated with caml_alloc_custom_mem (e.g. bigarrays). Default: 100.

    • since 4.08
    *)
  11. custom_minor_max_size : int;
    (*

    Maximum amount of out-of-heap memory for each custom value allocated in the minor heap. When a custom value is allocated on the minor heap and holds more than this many bytes, only this value is counted against custom_minor_ratio and the rest is directly counted against custom_major_ratio. Note: this only applies to values allocated with caml_alloc_custom_mem (e.g. bigarrays). Default: 8192 bytes.

    • since 4.08
    *)
}

The GC parameters are given as a control record. Note that these parameters can also be initialised by setting the OCAMLRUNPARAM environment variable. See the documentation of ocamlrun.

val stat : unit -> stat

Return the current values of the memory management counters in a stat record that represent the program's total memory stats. This function causes a full major collection.

val quick_stat : unit -> stat

Same as stat except that live_words, live_blocks, free_words, free_blocks, largest_free, and fragments are set to 0. Due to per-domain buffers it may only represent the state of the program's total memory usage since the last minor collection. This function is much faster than stat because it does not need to trigger a full major collection.

val counters : unit -> float * float * float

Return (minor_words, promoted_words, major_words) for the current domain or potentially previous domains. This function is as fast as quick_stat.

val minor_words : unit -> float

Number of words allocated in the minor heap by this domain or potentially previous domains. This number is accurate in byte-code programs, but only an approximation in programs compiled to native code.

In native code this function does not allocate.

  • since 4.04
val get : unit -> control

Return the current values of the GC parameters in a control record.

  • alert unsynchronized_access GC parameters are a mutable global state.
val set : control -> unit

set r changes the GC parameters according to the control record r. The normal usage is: Gc.set { (Gc.get()) with Gc.verbose = 0x00d }

  • alert unsynchronized_access GC parameters are a mutable global state.
val minor : unit -> unit

Trigger a minor collection.

val major_slice : int -> int

major_slice n Do a minor collection and a slice of major collection. n is the size of the slice: the GC will do enough work to free (on average) n words of memory. If n = 0, the GC will try to do enough work to ensure that the next automatic slice has no work to do. This function returns an unspecified integer (currently: 0).

val major : unit -> unit

Do a minor collection and finish the current major collection cycle.

val full_major : unit -> unit

Do a minor collection, finish the current major collection cycle, and perform a complete new cycle. This will collect all currently unreachable blocks.

val compact : unit -> unit

Perform a full major collection and compact the heap. Note that heap compaction is a lengthy operation.

val print_stat : out_channel -> unit

Print the current values of the memory management counters (in human-readable form) of the total program into the channel argument.

val allocated_bytes : unit -> float

Return the number of bytes allocated by this domain and potentially a previous domain. It is returned as a float to avoid overflow problems with int on 32-bit machines.

val get_minor_free : unit -> int

Return the current size of the free space inside the minor heap of this domain.

  • since 4.03
val finalise : ('a -> unit) -> 'a -> unit

finalise f v registers f as a finalisation function for v. v must be heap-allocated. f will be called with v as argument at some point between the first time v becomes unreachable (including through weak pointers) and the time v is collected by the GC. Several functions can be registered for the same value, or even several instances of the same function. Each instance will be called once (or never, if the program terminates before v becomes unreachable).

The GC will call the finalisation functions in the order of deallocation. When several values become unreachable at the same time (i.e. during the same GC cycle), the finalisation functions will be called in the reverse order of the corresponding calls to finalise. If finalise is called in the same order as the values are allocated, that means each value is finalised before the values it depends upon. Of course, this becomes false if additional dependencies are introduced by assignments.

In the presence of multiple OCaml threads it should be assumed that any particular finaliser may be executed in any of the threads.

Anything reachable from the closure of finalisation functions is considered reachable, so the following code will not work as expected:

  • let v = ... in Gc.finalise (fun _ -> ...v...) v

Instead you should make sure that v is not in the closure of the finalisation function by writing:

  • let f = fun x -> ... let v = ... in Gc.finalise f v

The f function can use all features of OCaml, including assignments that make the value reachable again. It can also loop forever (in this case, the other finalisation functions will not be called during the execution of f, unless it calls finalise_release). It can call finalise on v or other values to register other functions or even itself. It can raise an exception; in this case the exception will interrupt whatever the program was doing when the function was called.

finalise will raise Invalid_argument if v is not guaranteed to be heap-allocated. Some examples of values that are not heap-allocated are integers, constant constructors, booleans, the empty array, the empty list, the unit value. The exact list of what is heap-allocated or not is implementation-dependent. Some constant values can be heap-allocated but never deallocated during the lifetime of the program, for example a list of integer constants; this is also implementation-dependent. Note that values of types float are sometimes allocated and sometimes not, so finalising them is unsafe, and finalise will also raise Invalid_argument for them. Values of type 'a Lazy.t (for any 'a) are like float in this respect, except that the compiler sometimes optimizes them in a way that prevents finalise from detecting them. In this case, it will not raise Invalid_argument, but you should still avoid calling finalise on lazy values.

The results of calling String.make, Bytes.make, Bytes.create, Array.make, and Stdlib.ref are guaranteed to be heap-allocated and non-constant except when the length argument is 0.

val finalise_last : (unit -> unit) -> 'a -> unit

same as finalise except the value is not given as argument. So you can't use the given value for the computation of the finalisation function. The benefit is that the function is called after the value is unreachable for the last time instead of the first time. So contrary to finalise the value will never be reachable again or used again. In particular every weak pointer and ephemeron that contained this value as key or data is unset before running the finalisation function. Moreover the finalisation functions attached with finalise are always called before the finalisation functions attached with finalise_last.

  • since 4.04
val finalise_release : unit -> unit

A finalisation function may call finalise_release to tell the GC that it can launch the next finalisation function without waiting for the current one to return.

type alarm

An alarm is a piece of data that calls a user function at the end of each major GC cycle. The following functions are provided to create and delete alarms.

val create_alarm : (unit -> unit) -> alarm

create_alarm f will arrange for f to be called at the end of each major GC cycle, not caused by f itself, starting with the current cycle or the next one. A value of type alarm is returned that you can use to call delete_alarm.

val delete_alarm : alarm -> unit

delete_alarm a will stop the calls to the function associated to a. Calling delete_alarm a again has no effect.

val eventlog_pause : unit -> unit
  • deprecated Use Runtime_events.pause instead.
val eventlog_resume : unit -> unit
  • deprecated Use Runtime_events.resume instead.
module Memprof : sig ... end

Memprof is a sampling engine for allocated memory words. Every allocated word has a probability of being sampled equal to a configurable sampling rate. Once a block is sampled, it becomes tracked. A tracked block triggers a user-defined callback as soon as it is allocated, promoted or deallocated.

diff --git a/docs/stdlib/Stdlib/Hashtbl/Make/argument-1-H/index.html b/docs/stdlib/Stdlib/Hashtbl/Make/argument-1-H/index.html new file mode 100644 index 00000000..e3c2c456 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/Make/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Hashtbl.Make.H)

Parameter Make.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Hashtbl/Make/index.html b/docs/stdlib/Stdlib/Hashtbl/Make/index.html new file mode 100644 index 00000000..f332c2e3 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.Hashtbl.Make)

Module Hashtbl.Make

Functor building an implementation of the hashtable structure. The functor Hashtbl.Make returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the hashing and equality functions specified in the functor argument H instead of generic equality and hashing. Since the hash function is not seeded, the create operation of the result structure always returns non-randomized hash tables.

Parameters

module H : HashedType

Signature

type key = H.t
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
  • since 4.00
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val filter_map_inplace : (key -> 'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
  • since 4.00
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/Hashtbl/MakeSeeded/argument-1-H/index.html b/docs/stdlib/Stdlib/Hashtbl/MakeSeeded/argument-1-H/index.html new file mode 100644 index 00000000..e316c0a7 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/MakeSeeded/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Hashtbl.MakeSeeded.H)

Parameter MakeSeeded.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/Hashtbl/MakeSeeded/index.html b/docs/stdlib/Stdlib/Hashtbl/MakeSeeded/index.html new file mode 100644 index 00000000..4897c957 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/MakeSeeded/index.html @@ -0,0 +1,2 @@ + +MakeSeeded (docs.stdlib.Stdlib.Hashtbl.MakeSeeded)

Module Hashtbl.MakeSeeded

Functor building an implementation of the hashtable structure. The functor Hashtbl.MakeSeeded returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the seeded hashing and equality functions specified in the functor argument H instead of generic equality and hashing. The create operation of the result structure supports the ~random optional parameter and returns randomized hash tables if ~random:true is passed or if randomization is globally on (see Hashtbl.randomize).

  • since 4.00

Parameters

Signature

type key = H.t
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val filter_map_inplace : (key -> 'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/Hashtbl/index.html b/docs/stdlib/Stdlib/Hashtbl/index.html new file mode 100644 index 00000000..85f5f9e3 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/index.html @@ -0,0 +1,80 @@ + +Hashtbl (docs.stdlib.Stdlib.Hashtbl)

Module Stdlib.Hashtbl

Hash tables and hash functions.

Hash tables are hashed association tables, with in-place modification. Because most operations on a hash table modify their input, they're more commonly used in imperative code. The lookup of the value associated with a key (see find, find_opt) is normally very fast, often faster than the equivalent lookup in Map.

The functors Make and MakeSeeded can be used when performance or flexibility are key. The user provides custom equality and hash functions for the key type, and obtains a custom hash table type for this particular type of key.

Warning a hash table is only as good as the hash function. A bad hash function will turn the table into a degenerate association list, with linear time lookup instead of constant time lookup.

The polymorphic t hash table is useful in simpler cases or in interactive environments. It uses the polymorphic hash function defined in the OCaml runtime (at the time of writing, it's SipHash), as well as the polymorphic equality (=).

See the examples section.

Unsynchronized accesses

Unsynchronized accesses to a hash table may lead to an invalid hash table state. Thus, concurrent accesses to a hash tables must be synchronized (for instance with a Mutex.t).

Generic interface

type (!'a, !'b) t

The type of hash tables from type 'a to type 'b.

val create : ?random:bool -> int -> ('a, 'b) t

Hashtbl.create n creates a new, empty hash table, with initial size n. For best results, n should be on the order of the expected number of elements that will be in the table. The table grows as needed, so n is just an initial guess.

The optional ~random parameter (a boolean) controls whether the internal organization of the hash table is randomized at each execution of Hashtbl.create or deterministic over all executions.

A hash table that is created with ~random set to false uses a fixed hash function (hash) to distribute keys among buckets. As a consequence, collisions between keys happen deterministically. In Web-facing applications or other security-sensitive applications, the deterministic collision patterns can be exploited by a malicious user to create a denial-of-service attack: the attacker sends input crafted to create many collisions in the table, slowing the application down.

A hash table that is created with ~random set to true uses the seeded hash function seeded_hash with a seed that is randomly chosen at hash table creation time. In effect, the hash function used is randomly selected among 2^{30} different hash functions. All these hash functions have different collision patterns, rendering ineffective the denial-of-service attack described above. However, because of randomization, enumerating all elements of the hash table using fold or iter is no longer deterministic: elements are enumerated in different orders at different runs of the program.

If no ~random parameter is given, hash tables are created in non-random mode by default. This default can be changed either programmatically by calling randomize or by setting the R flag in the OCAMLRUNPARAM environment variable.

  • before 4.00

    the ~random parameter was not present and all hash tables were created in non-randomized mode.

val clear : ('a, 'b) t -> unit

Empty a hash table. Use reset instead of clear to shrink the size of the bucket table to its initial size.

val reset : ('a, 'b) t -> unit

Empty a hash table and shrink the size of the bucket table to its initial size.

  • since 4.00
val copy : ('a, 'b) t -> ('a, 'b) t

Return a copy of the given hashtable.

val add : ('a, 'b) t -> 'a -> 'b -> unit

Hashtbl.add tbl key data adds a binding of key to data in table tbl.

Warning: Previous bindings for key are not removed, but simply hidden. That is, after performing remove tbl key, the previous binding for key, if any, is restored. (Same behavior as with association lists.)

If you desire the classic behavior of replacing elements, see replace.

val find : ('a, 'b) t -> 'a -> 'b

Hashtbl.find tbl x returns the current binding of x in tbl, or raises Not_found if no such binding exists.

val find_opt : ('a, 'b) t -> 'a -> 'b option

Hashtbl.find_opt tbl x returns the current binding of x in tbl, or None if no such binding exists.

  • since 4.05
val find_all : ('a, 'b) t -> 'a -> 'b list

Hashtbl.find_all tbl x returns the list of all data associated with x in tbl. The current binding is returned first, then the previous bindings, in reverse order of introduction in the table.

val mem : ('a, 'b) t -> 'a -> bool

Hashtbl.mem tbl x checks if x is bound in tbl.

val remove : ('a, 'b) t -> 'a -> unit

Hashtbl.remove tbl x removes the current binding of x in tbl, restoring the previous binding if it exists. It does nothing if x is not bound in tbl.

val replace : ('a, 'b) t -> 'a -> 'b -> unit

Hashtbl.replace tbl key data replaces the current binding of key in tbl by a binding of key to data. If key is unbound in tbl, a binding of key to data is added to tbl. This is functionally equivalent to remove tbl key followed by add tbl key data.

val iter : ('a -> 'b -> unit) -> ('a, 'b) t -> unit

Hashtbl.iter f tbl applies f to all bindings in table tbl. f receives the key as first argument, and the associated value as second argument. Each binding is presented exactly once to f.

The order in which the bindings are passed to f is unspecified. However, if the table contains several bindings for the same key, they are passed to f in reverse order of introduction, that is, the most recent binding is passed first.

If the hash table was created in non-randomized mode, the order in which the bindings are enumerated is reproducible between successive runs of the program, and even between minor versions of OCaml. For randomized hash tables, the order of enumeration is entirely random.

The behavior is not specified if the hash table is modified by f during the iteration.

val filter_map_inplace : ('a -> 'b -> 'b option) -> ('a, 'b) t -> unit

Hashtbl.filter_map_inplace f tbl applies f to all bindings in table tbl and update each binding depending on the result of f. If f returns None, the binding is discarded. If it returns Some new_val, the binding is update to associate the key to new_val.

Other comments for iter apply as well.

  • since 4.03
val fold : ('a -> 'b -> 'acc -> 'acc) -> ('a, 'b) t -> 'acc -> 'acc

Hashtbl.fold f tbl init computes (f kN dN ... (f k1 d1 init)...), where k1 ... kN are the keys of all bindings in tbl, and d1 ... dN are the associated values. Each binding is presented exactly once to f.

The order in which the bindings are passed to f is unspecified. However, if the table contains several bindings for the same key, they are passed to f in reverse order of introduction, that is, the most recent binding is passed first.

If the hash table was created in non-randomized mode, the order in which the bindings are enumerated is reproducible between successive runs of the program, and even between minor versions of OCaml. For randomized hash tables, the order of enumeration is entirely random.

The behavior is not specified if the hash table is modified by f during the iteration.

val length : ('a, 'b) t -> int

Hashtbl.length tbl returns the number of bindings in tbl. It takes constant time. Multiple bindings are counted once each, so Hashtbl.length gives the number of times Hashtbl.iter calls its first argument.

val randomize : unit -> unit

After a call to Hashtbl.randomize(), hash tables are created in randomized mode by default: create returns randomized hash tables, unless the ~random:false optional parameter is given. The same effect can be achieved by setting the R parameter in the OCAMLRUNPARAM environment variable.

It is recommended that applications or Web frameworks that need to protect themselves against the denial-of-service attack described in create call Hashtbl.randomize() at initialization time before any domains are created.

Note that once Hashtbl.randomize() was called, there is no way to revert to the non-randomized default behavior of create. This is intentional. Non-randomized hash tables can still be created using Hashtbl.create ~random:false.

  • since 4.00
val is_randomized : unit -> bool

Return true if the tables are currently created in randomized mode by default, false otherwise.

  • since 4.03
val rebuild : ?random:bool -> ('a, 'b) t -> ('a, 'b) t

Return a copy of the given hashtable. Unlike copy, rebuild h re-hashes all the (key, value) entries of the original table h. The returned hash table is randomized if h was randomized, or the optional random parameter is true, or if the default is to create randomized hash tables; see create for more information.

rebuild can safely be used to import a hash table built by an old version of the Hashtbl module, then marshaled to persistent storage. After unmarshaling, apply rebuild to produce a hash table for the current version of the Hashtbl module.

  • since 4.12
type statistics = {
  1. num_bindings : int;
    (*

    Number of bindings present in the table. Same value as returned by length.

    *)
  2. num_buckets : int;
    (*

    Number of buckets in the table.

    *)
  3. max_bucket_length : int;
    (*

    Maximal number of bindings per bucket.

    *)
  4. bucket_histogram : int array;
    (*

    Histogram of bucket sizes. This array histo has length max_bucket_length + 1. The value of histo.(i) is the number of buckets whose size is i.

    *)
}
  • since 4.00
val stats : ('a, 'b) t -> statistics

Hashtbl.stats tbl returns statistics about the table tbl: number of buckets, size of the biggest bucket, distribution of buckets by size.

  • since 4.00

Hash tables and Sequences

val to_seq : ('a, 'b) t -> ('a * 'b) Seq.t

Iterate on the whole table. The order in which the bindings appear in the sequence is unspecified. However, if the table contains several bindings for the same key, they appear in reversed order of introduction, that is, the most recent binding appears first.

The behavior is not specified if the hash table is modified during the iteration.

  • since 4.07
val to_seq_keys : ('a, _) t -> 'a Seq.t

Same as Seq.map fst (to_seq m)

  • since 4.07
val to_seq_values : (_, 'b) t -> 'b Seq.t

Same as Seq.map snd (to_seq m)

  • since 4.07
val add_seq : ('a, 'b) t -> ('a * 'b) Seq.t -> unit

Add the given bindings to the table, using add

  • since 4.07
val replace_seq : ('a, 'b) t -> ('a * 'b) Seq.t -> unit

Add the given bindings to the table, using replace

  • since 4.07
val of_seq : ('a * 'b) Seq.t -> ('a, 'b) t

Build a table from the given bindings. The bindings are added in the same order they appear in the sequence, using replace_seq, which means that if two pairs have the same key, only the latest one will appear in the table.

  • since 4.07

Functorial interface

The functorial interface allows the use of specific comparison and hash functions, either for performance/security concerns, or because keys are not hashable/comparable with the polymorphic builtins.

For instance, one might want to specialize a table for integer keys:

module IntHash =
+  struct
+    type t = int
+    let equal i j = i=j
+    let hash i = i land max_int
+  end
+
+module IntHashtbl = Hashtbl.Make(IntHash)
+
+let h = IntHashtbl.create 17 in
+IntHashtbl.add h 12 "hello"

This creates a new module IntHashtbl, with a new type 'a + IntHashtbl.t of tables from int to 'a. In this example, h contains string values so its type is string IntHashtbl.t.

Note that the new type 'a IntHashtbl.t is not compatible with the type ('a,'b) Hashtbl.t of the generic interface. For example, Hashtbl.length h would not type-check, you must use IntHashtbl.length.

module type HashedType = sig ... end

The input signature of the functor Make.

module type S = sig ... end

The output signature of the functor Make.

module Make (H : HashedType) : S with type key = H.t

Functor building an implementation of the hashtable structure. The functor Hashtbl.Make returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the hashing and equality functions specified in the functor argument H instead of generic equality and hashing. Since the hash function is not seeded, the create operation of the result structure always returns non-randomized hash tables.

module type SeededHashedType = sig ... end

The input signature of the functor MakeSeeded.

module type SeededS = sig ... end

The output signature of the functor MakeSeeded.

module MakeSeeded (H : SeededHashedType) : SeededS with type key = H.t

Functor building an implementation of the hashtable structure. The functor Hashtbl.MakeSeeded returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the seeded hashing and equality functions specified in the functor argument H instead of generic equality and hashing. The create operation of the result structure supports the ~random optional parameter and returns randomized hash tables if ~random:true is passed or if randomization is globally on (see Hashtbl.randomize).

The polymorphic hash functions

val hash : 'a -> int

Hashtbl.hash x associates a nonnegative integer to any value of any type. It is guaranteed that if x = y or Stdlib.compare x y = 0, then hash x = hash y. Moreover, hash always terminates, even on cyclic structures.

val seeded_hash : int -> 'a -> int

A variant of hash that is further parameterized by an integer seed.

  • since 4.00
val hash_param : int -> int -> 'a -> int

Hashtbl.hash_param meaningful total x computes a hash value for x, with the same properties as for hash. The two extra integer parameters meaningful and total give more precise control over hashing. Hashing performs a breadth-first, left-to-right traversal of the structure x, stopping after meaningful meaningful nodes were encountered, or total nodes (meaningful or not) were encountered. If total as specified by the user exceeds a certain value, currently 256, then it is capped to that value. Meaningful nodes are: integers; floating-point numbers; strings; characters; booleans; and constant constructors. Larger values of meaningful and total means that more nodes are taken into account to compute the final hash value, and therefore collisions are less likely to happen. However, hashing takes longer. The parameters meaningful and total govern the tradeoff between accuracy and speed. As default choices, hash and seeded_hash take meaningful = 10 and total = 100.

val seeded_hash_param : int -> int -> int -> 'a -> int

A variant of hash_param that is further parameterized by an integer seed. Usage: Hashtbl.seeded_hash_param meaningful total seed x.

  • since 4.00

Examples

Basic Example

(* 0...99 *)
+let seq = Seq.ints 0 |> Seq.take 100
+
+(* build from Seq.t *)
+# let tbl =
+    seq
+    |> Seq.map (fun x -> x, string_of_int x)
+    |> Hashtbl.of_seq
+val tbl : (int, string) Hashtbl.t = <abstr>
+
+# Hashtbl.length tbl
+- : int = 100
+
+# Hashtbl.find_opt tbl 32
+- : string option = Some "32"
+
+# Hashtbl.find_opt tbl 166
+- : string option = None
+
+# Hashtbl.replace tbl 166 "one six six"
+- : unit = ()
+
+# Hashtbl.find_opt tbl 166
+- : string option = Some "one six six"
+
+# Hashtbl.length tbl
+- : int = 101

Counting Elements

Given a sequence of elements (here, a Seq.t), we want to count how many times each distinct element occurs in the sequence. A simple way to do this, assuming the elements are comparable and hashable, is to use a hash table that maps elements to their number of occurrences.

Here we illustrate that principle using a sequence of (ascii) characters (type char). We use a custom Char_tbl specialized for char.

# module Char_tbl = Hashtbl.Make(struct
+    type t = char
+    let equal = Char.equal
+    let hash = Hashtbl.hash
+  end)
+
+(*  count distinct occurrences of chars in [seq] *)
+# let count_chars (seq : char Seq.t) : _ list =
+    let counts = Char_tbl.create 16 in
+    Seq.iter
+      (fun c ->
+        let count_c =
+          Char_tbl.find_opt counts c
+          |> Option.value ~default:0
+        in
+        Char_tbl.replace counts c (count_c + 1))
+      seq;
+    (* turn into a list *)
+    Char_tbl.fold (fun c n l -> (c,n) :: l) counts []
+      |> List.sort (fun (c1,_)(c2,_) -> Char.compare c1 c2)
+val count_chars : Char_tbl.key Seq.t -> (Char.t * int) list = <fun>
+
+(* basic seq from a string *)
+# let seq = String.to_seq "hello world, and all the camels in it!"
+val seq : char Seq.t = <fun>
+
+# count_chars seq
+- : (Char.t * int) list =
+[(' ', 7); ('!', 1); (',', 1); ('a', 3); ('c', 1); ('d', 2); ('e', 3);
+ ('h', 2); ('i', 2); ('l', 6); ('m', 1); ('n', 2); ('o', 2); ('r', 1);
+ ('s', 1); ('t', 2); ('w', 1)]
+
+(* "abcabcabc..." *)
+# let seq2 =
+    Seq.cycle (String.to_seq "abc") |> Seq.take 31
+val seq2 : char Seq.t = <fun>
+
+# String.of_seq seq2
+- : String.t = "abcabcabcabcabcabcabcabcabcabca"
+
+# count_chars seq2
+- : (Char.t * int) list = [('a', 11); ('b', 10); ('c', 10)]
diff --git a/docs/stdlib/Stdlib/Hashtbl/module-type-HashedType/index.html b/docs/stdlib/Stdlib/Hashtbl/module-type-HashedType/index.html new file mode 100644 index 00000000..8a633dd5 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/module-type-HashedType/index.html @@ -0,0 +1,2 @@ + +HashedType (docs.stdlib.Stdlib.Hashtbl.HashedType)

Module type Hashtbl.HashedType

The input signature of the functor Make.

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Hashtbl/module-type-S/index.html b/docs/stdlib/Stdlib/Hashtbl/module-type-S/index.html new file mode 100644 index 00000000..96f210c5 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/module-type-S/index.html @@ -0,0 +1,2 @@ + +S (docs.stdlib.Stdlib.Hashtbl.S)

Module type Hashtbl.S

The output signature of the functor Make.

type key
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
  • since 4.00
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val filter_map_inplace : (key -> 'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
  • since 4.00
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/Hashtbl/module-type-SeededHashedType/index.html b/docs/stdlib/Stdlib/Hashtbl/module-type-SeededHashedType/index.html new file mode 100644 index 00000000..645b00f5 --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/module-type-SeededHashedType/index.html @@ -0,0 +1,2 @@ + +SeededHashedType (docs.stdlib.Stdlib.Hashtbl.SeededHashedType)

Module type Hashtbl.SeededHashedType

The input signature of the functor MakeSeeded.

  • since 4.00
type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/Hashtbl/module-type-SeededS/index.html b/docs/stdlib/Stdlib/Hashtbl/module-type-SeededS/index.html new file mode 100644 index 00000000..e13eeb2c --- /dev/null +++ b/docs/stdlib/Stdlib/Hashtbl/module-type-SeededS/index.html @@ -0,0 +1,2 @@ + +SeededS (docs.stdlib.Stdlib.Hashtbl.SeededS)

Module type Hashtbl.SeededS

The output signature of the functor MakeSeeded.

  • since 4.00
type key
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key -> 'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key -> 'a -> unit
val mem : 'a t -> key -> bool
val iter : (key -> 'a -> unit) -> 'a t -> unit
val filter_map_inplace : (key -> 'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/In_channel/index.html b/docs/stdlib/Stdlib/In_channel/index.html new file mode 100644 index 00000000..95c1c4d4 --- /dev/null +++ b/docs/stdlib/Stdlib/In_channel/index.html @@ -0,0 +1,3 @@ + +In_channel (docs.stdlib.Stdlib.In_channel)

Module Stdlib.In_channel

Input channels.

This module provides functions for working with input channels.

See the example section below.

  • since 4.14

Channels

type t = in_channel

The type of input channel.

type open_flag = open_flag =
  1. | Open_rdonly
    (*

    open for reading.

    *)
  2. | Open_wronly
    (*

    open for writing.

    *)
  3. | Open_append
    (*

    open for appending: always write at end of file.

    *)
  4. | Open_creat
    (*

    create the file if it does not exist.

    *)
  5. | Open_trunc
    (*

    empty the file if it already exists.

    *)
  6. | Open_excl
    (*

    fail if Open_creat and the file already exists.

    *)
  7. | Open_binary
    (*

    open in binary mode (no conversion).

    *)
  8. | Open_text
    (*

    open in text mode (may perform conversions).

    *)
  9. | Open_nonblock
    (*

    open in non-blocking mode.

    *)

Opening modes for open_gen.

val stdin : t

The standard input for the process.

val open_bin : string -> t

Open the named file for reading, and return a new input channel on that file, positioned at the beginning of the file.

val open_text : string -> t

Same as open_bin, but the file is opened in text mode, so that newline translation takes place during reads. On operating systems that do not distinguish between text mode and binary mode, this function behaves like open_bin.

val open_gen : open_flag list -> int -> string -> t

open_gen mode perm filename opens the named file for reading, as described above. The extra arguments mode and perm specify the opening mode and file permissions. open_text and open_bin are special cases of this function.

val with_open_bin : string -> (t -> 'a) -> 'a

with_open_bin fn f opens a channel ic on file fn and returns f + ic. After f returns, either with a value or by raising an exception, ic is guaranteed to be closed.

val with_open_text : string -> (t -> 'a) -> 'a

Like with_open_bin, but the channel is opened in text mode (see open_text).

val with_open_gen : open_flag list -> int -> string -> (t -> 'a) -> 'a

Like with_open_bin, but can specify the opening mode and file permission, in case the file must be created (see open_gen).

val close : t -> unit

Close the given channel. Input functions raise a Sys_error exception when they are applied to a closed input channel, except close, which does nothing when applied to an already closed channel.

val close_noerr : t -> unit

Same as close, but ignore all errors.

Input

val input_char : t -> char option

Read one character from the given input channel. Returns None if there are no more characters to read.

val input_byte : t -> int option

Same as input_char, but return the 8-bit integer representing the character. Returns None if the end of file was reached.

val input_line : t -> string option

input_line ic reads characters from ic until a newline or the end of file is reached. Returns the string of all characters read, without the newline (if any). Returns None if the end of the file has been reached. In particular, this will be the case if the last line of input is empty.

A newline is the character \n unless the file is open in text mode and Sys.win32 is true in which case it is the sequence of characters \r\n.

val really_input_string : t -> int -> string option

really_input_string ic len reads len characters from channel ic and returns them in a new string. Returns None if the end of file is reached before len characters have been read.

If the same channel is read concurrently by multiple threads, the returned string is not guaranteed to contain contiguous characters from the input.

val input_all : t -> string

input_all ic reads all remaining data from ic.

If the same channel is read concurrently by multiple threads, the returned string is not guaranteed to contain contiguous characters from the input.

val input_lines : t -> string list

input_lines ic reads lines using input_line until the end of file is reached. It returns the list of all lines read, in the order they were read. The newline characters that terminate lines are not included in the returned strings. Empty lines produce empty strings.

  • since 5.1

Advanced input

val input : t -> bytes -> int -> int -> int

input ic buf pos len reads up to len characters from the given channel ic, storing them in byte sequence buf, starting at character number pos. It returns the actual number of characters read, between 0 and len (inclusive). A return value of 0 means that the end of file was reached.

Use really_input to read exactly len characters.

val really_input : t -> bytes -> int -> int -> unit option

really_input ic buf pos len reads len characters from channel ic, storing them in byte sequence buf, starting at character number pos.

Returns None if the end of file is reached before len characters have been read.

If the same channel is read concurrently by multiple threads, the bytes read by really_input are not guaranteed to be contiguous.

val fold_lines : ('acc -> string -> 'acc) -> 'acc -> t -> 'acc

fold_lines f init ic reads lines from ic using input_line until the end of file is reached, and successively passes each line to function f in the style of a fold. More precisely, if lines l1, ..., lN are read, fold_lines f init ic computes f (... (f (f init l1) l2) ...) lN. If f has no side effects, this is equivalent to List.fold_left f init (In_channel.input_lines ic), but is more efficient since it does not construct the list of all lines read.

  • since 5.1

Seeking

val seek : t -> int64 -> unit

seek chan pos sets the current reading position to pos for channel chan. This works only for regular files. On files of other kinds, the behavior is unspecified.

val pos : t -> int64

Return the current reading position for the given channel. For files opened in text mode under Windows, the returned position is approximate (owing to end-of-line conversion); in particular, saving the current position with pos, then going back to this position using seek will not work. For this programming idiom to work reliably and portably, the file must be opened in binary mode.

Attributes

val length : t -> int64

Return the size (number of characters) of the regular file on which the given channel is opened. If the channel is opened on a file that is not a regular file, the result is meaningless. The returned size does not take into account the end-of-line translations that can be performed when reading from a channel opened in text mode.

val set_binary_mode : t -> bool -> unit

set_binary_mode ic true sets the channel ic to binary mode: no translations take place during input.

set_binary_mode ic false sets the channel ic to text mode: depending on the operating system, some translations may take place during input. For instance, under Windows, end-of-lines will be translated from \r\n to \n.

This function has no effect under operating systems that do not distinguish between text mode and binary mode.

val isatty : t -> bool

isatty ic is true if ic refers to a terminal or console window, false otherwise.

  • since 5.1

Examples

Reading the contents of a file:

let read_file file = In_channel.with_open_bin file In_channel.input_all

Reading a line from stdin:

let user_input () = In_channel.input_line In_channel.stdin
diff --git a/docs/stdlib/Stdlib/Int/index.html b/docs/stdlib/Stdlib/Int/index.html new file mode 100644 index 00000000..355d315e --- /dev/null +++ b/docs/stdlib/Stdlib/Int/index.html @@ -0,0 +1,2 @@ + +Int (docs.stdlib.Stdlib.Int)

Module Stdlib.Int

Integer values.

Integers are Sys.int_size bits wide and use two's complement representation. All operations are taken modulo 2Sys.int_size. They do not fail on overflow.

  • since 4.08

Integers

type t = int

The type for integer values.

val zero : int

zero is the integer 0.

val one : int

one is the integer 1.

val minus_one : int

minus_one is the integer -1.

val neg : int -> int

neg x is ~-x.

val add : int -> int -> int

add x y is the addition x + y.

val sub : int -> int -> int

sub x y is the subtraction x - y.

val mul : int -> int -> int

mul x y is the multiplication x * y.

val div : int -> int -> int

div x y is the division x / y. See Stdlib.(/) for details.

val rem : int -> int -> int

rem x y is the remainder x mod y. See Stdlib.(mod) for details.

val succ : int -> int

succ x is add x 1.

val pred : int -> int

pred x is sub x 1.

val abs : int -> int

abs x is the absolute value of x. That is x if x is positive and neg x if x is negative. Warning. This may be negative if the argument is min_int.

val max_int : int

max_int is the greatest representable integer, 2{^[Sys.int_size - 1]} - 1.

val min_int : int

min_int is the smallest representable integer, -2{^[Sys.int_size - 1]}.

val logand : int -> int -> int

logand x y is the bitwise logical and of x and y.

val logor : int -> int -> int

logor x y is the bitwise logical or of x and y.

val logxor : int -> int -> int

logxor x y is the bitwise logical exclusive or of x and y.

val lognot : int -> int

lognot x is the bitwise logical negation of x.

val shift_left : int -> int -> int

shift_left x n shifts x to the left by n bits. The result is unspecified if n < 0 or n > Sys.int_size.

val shift_right : int -> int -> int

shift_right x n shifts x to the right by n bits. This is an arithmetic shift: the sign bit of x is replicated and inserted in the vacated bits. The result is unspecified if n < 0 or n > Sys.int_size.

val shift_right_logical : int -> int -> int

shift_right x n shifts x to the right by n bits. This is a logical shift: zeroes are inserted in the vacated bits regardless of the sign of x. The result is unspecified if n < 0 or n > Sys.int_size.

Predicates and comparisons

val equal : int -> int -> bool

equal x y is true if and only if x = y.

val compare : int -> int -> int

compare x y is Stdlib.compare x y but more efficient.

val min : int -> int -> int

Return the smaller of the two arguments.

  • since 4.13
val max : int -> int -> int

Return the greater of the two arguments.

  • since 4.13

Converting

val to_float : int -> float

to_float x is x as a floating point number.

val of_float : float -> int

of_float x truncates x to an integer. The result is unspecified if the argument is nan or falls outside the range of representable integers.

val to_string : int -> string

to_string x is the written representation of x in decimal.

val seeded_hash : int -> int -> int

A seeded hash function for ints, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : int -> int

An unseeded hash function for ints, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Int32/index.html b/docs/stdlib/Stdlib/Int32/index.html new file mode 100644 index 00000000..5e092338 --- /dev/null +++ b/docs/stdlib/Stdlib/Int32/index.html @@ -0,0 +1,4 @@ + +Int32 (docs.stdlib.Stdlib.Int32)

Module Stdlib.Int32

32-bit integers.

This module provides operations on the type int32 of signed 32-bit integers. Unlike the built-in int type, the type int32 is guaranteed to be exactly 32-bit wide on all platforms. All arithmetic operations over int32 are taken modulo 232.

Performance notice: values of type int32 occupy more memory space than values of type int, and arithmetic operations on int32 are generally slower than those on int. Use int32 only when the application requires exact 32-bit arithmetic.

Literals for 32-bit integers are suffixed by l:

let zero: int32 = 0l
+let one: int32 = 1l
+let m_one: int32 = -1l
val zero : int32

The 32-bit integer 0.

val one : int32

The 32-bit integer 1.

val minus_one : int32

The 32-bit integer -1.

val neg : int32 -> int32

Unary negation.

val add : int32 -> int32 -> int32

Addition.

val sub : int32 -> int32 -> int32

Subtraction.

val mul : int32 -> int32 -> int32

Multiplication.

val div : int32 -> int32 -> int32

Integer division. This division rounds the real quotient of its arguments towards zero, as specified for Stdlib.(/).

val unsigned_div : int32 -> int32 -> int32

Same as div, except that arguments and result are interpreted as unsigned 32-bit integers.

  • since 4.08
val rem : int32 -> int32 -> int32

Integer remainder. If y is not zero, the result of Int32.rem x y satisfies the following property: x = Int32.add (Int32.mul (Int32.div x y) y) (Int32.rem x y). If y = 0, Int32.rem x y raises Division_by_zero.

val unsigned_rem : int32 -> int32 -> int32

Same as rem, except that arguments and result are interpreted as unsigned 32-bit integers.

  • since 4.08
val succ : int32 -> int32

Successor. Int32.succ x is Int32.add x Int32.one.

val pred : int32 -> int32

Predecessor. Int32.pred x is Int32.sub x Int32.one.

val abs : int32 -> int32

abs x is the absolute value of x. On min_int this is min_int itself and thus remains negative.

val max_int : int32

The greatest representable 32-bit integer, 231 - 1.

val min_int : int32

The smallest representable 32-bit integer, -231.

val logand : int32 -> int32 -> int32

Bitwise logical and.

val logor : int32 -> int32 -> int32

Bitwise logical or.

val logxor : int32 -> int32 -> int32

Bitwise logical exclusive or.

val lognot : int32 -> int32

Bitwise logical negation.

val shift_left : int32 -> int -> int32

Int32.shift_left x y shifts x to the left by y bits. The result is unspecified if y < 0 or y >= 32.

val shift_right : int32 -> int -> int32

Int32.shift_right x y shifts x to the right by y bits. This is an arithmetic shift: the sign bit of x is replicated and inserted in the vacated bits. The result is unspecified if y < 0 or y >= 32.

val shift_right_logical : int32 -> int -> int32

Int32.shift_right_logical x y shifts x to the right by y bits. This is a logical shift: zeroes are inserted in the vacated bits regardless of the sign of x. The result is unspecified if y < 0 or y >= 32.

val of_int : int -> int32

Convert the given integer (type int) to a 32-bit integer (type int32). On 64-bit platforms, the argument is taken modulo 232.

val to_int : int32 -> int

Convert the given 32-bit integer (type int32) to an integer (type int). On 32-bit platforms, the 32-bit integer is taken modulo 231, i.e. the high-order bit is lost during the conversion. On 64-bit platforms, the conversion is exact.

val unsigned_to_int : int32 -> int option

Same as to_int, but interprets the argument as an unsigned integer. Returns None if the unsigned value of the argument cannot fit into an int.

  • since 4.08
val of_float : float -> int32

Convert the given floating-point number to a 32-bit integer, discarding the fractional part (truncate towards 0). If the truncated floating-point number is outside the range [Int32.min_int, Int32.max_int], no exception is raised, and an unspecified, platform-dependent integer is returned.

val to_float : int32 -> float

Convert the given 32-bit integer to a floating-point number.

val of_string : string -> int32

Convert the given string to a 32-bit integer. The string is read in decimal (by default, or if the string begins with 0u) or in hexadecimal, octal or binary if the string begins with 0x, 0o or 0b respectively.

The 0u prefix reads the input as an unsigned integer in the range [0, 2*Int32.max_int+1]. If the input exceeds Int32.max_int it is converted to the signed integer Int32.min_int + input - Int32.max_int - 1.

The _ (underscore) character can appear anywhere in the string and is ignored.

  • raises Failure

    if the given string is not a valid representation of an integer, or if the integer represented exceeds the range of integers representable in type int32.

val of_string_opt : string -> int32 option

Same as of_string, but return None instead of raising.

  • since 4.05
val to_string : int32 -> string

Return the string representation of its argument, in signed decimal.

val bits_of_float : float -> int32

Return the internal representation of the given float according to the IEEE 754 floating-point 'single format' bit layout. Bit 31 of the result represents the sign of the float; bits 30 to 23 represent the (biased) exponent; bits 22 to 0 represent the mantissa.

val float_of_bits : int32 -> float

Return the floating-point number whose internal representation, according to the IEEE 754 floating-point 'single format' bit layout, is the given int32.

type t = int32

An alias for the type of 32-bit integers.

val compare : t -> t -> int

The comparison function for 32-bit integers, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Int32 to be passed as argument to the functors Set.Make and Map.Make.

val unsigned_compare : t -> t -> int

Same as compare, except that arguments are interpreted as unsigned 32-bit integers.

  • since 4.08
val equal : t -> t -> bool

The equal function for int32s.

  • since 4.03
val min : t -> t -> t

Return the smaller of the two arguments.

  • since 4.13
val max : t -> t -> t

Return the greater of the two arguments.

  • since 4.13
val seeded_hash : int -> t -> int

A seeded hash function for 32-bit ints, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : t -> int

An unseeded hash function for 32-bit ints, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Int64/index.html b/docs/stdlib/Stdlib/Int64/index.html new file mode 100644 index 00000000..833e3717 --- /dev/null +++ b/docs/stdlib/Stdlib/Int64/index.html @@ -0,0 +1,4 @@ + +Int64 (docs.stdlib.Stdlib.Int64)

Module Stdlib.Int64

64-bit integers.

This module provides operations on the type int64 of signed 64-bit integers. Unlike the built-in int type, the type int64 is guaranteed to be exactly 64-bit wide on all platforms. All arithmetic operations over int64 are taken modulo 264

Performance notice: values of type int64 occupy more memory space than values of type int, and arithmetic operations on int64 are generally slower than those on int. Use int64 only when the application requires exact 64-bit arithmetic.

Literals for 64-bit integers are suffixed by L:

let zero: int64 = 0L
+let one: int64 = 1L
+let m_one: int64 = -1L
val zero : int64

The 64-bit integer 0.

val one : int64

The 64-bit integer 1.

val minus_one : int64

The 64-bit integer -1.

val neg : int64 -> int64

Unary negation.

val add : int64 -> int64 -> int64

Addition.

val sub : int64 -> int64 -> int64

Subtraction.

val mul : int64 -> int64 -> int64

Multiplication.

val div : int64 -> int64 -> int64

Integer division.

  • raises Division_by_zero

    if the second argument is zero. This division rounds the real quotient of its arguments towards zero, as specified for Stdlib.(/).

val unsigned_div : int64 -> int64 -> int64

Same as div, except that arguments and result are interpreted as unsigned 64-bit integers.

  • since 4.08
val rem : int64 -> int64 -> int64

Integer remainder. If y is not zero, the result of Int64.rem x y satisfies the following property: x = Int64.add (Int64.mul (Int64.div x y) y) (Int64.rem x y). If y = 0, Int64.rem x y raises Division_by_zero.

val unsigned_rem : int64 -> int64 -> int64

Same as rem, except that arguments and result are interpreted as unsigned 64-bit integers.

  • since 4.08
val succ : int64 -> int64

Successor. Int64.succ x is Int64.add x Int64.one.

val pred : int64 -> int64

Predecessor. Int64.pred x is Int64.sub x Int64.one.

val abs : int64 -> int64

abs x is the absolute value of x. On min_int this is min_int itself and thus remains negative.

val max_int : int64

The greatest representable 64-bit integer, 263 - 1.

val min_int : int64

The smallest representable 64-bit integer, -263.

val logand : int64 -> int64 -> int64

Bitwise logical and.

val logor : int64 -> int64 -> int64

Bitwise logical or.

val logxor : int64 -> int64 -> int64

Bitwise logical exclusive or.

val lognot : int64 -> int64

Bitwise logical negation.

val shift_left : int64 -> int -> int64

Int64.shift_left x y shifts x to the left by y bits. The result is unspecified if y < 0 or y >= 64.

val shift_right : int64 -> int -> int64

Int64.shift_right x y shifts x to the right by y bits. This is an arithmetic shift: the sign bit of x is replicated and inserted in the vacated bits. The result is unspecified if y < 0 or y >= 64.

val shift_right_logical : int64 -> int -> int64

Int64.shift_right_logical x y shifts x to the right by y bits. This is a logical shift: zeroes are inserted in the vacated bits regardless of the sign of x. The result is unspecified if y < 0 or y >= 64.

val of_int : int -> int64

Convert the given integer (type int) to a 64-bit integer (type int64).

val to_int : int64 -> int

Convert the given 64-bit integer (type int64) to an integer (type int). On 64-bit platforms, the 64-bit integer is taken modulo 263, i.e. the high-order bit is lost during the conversion. On 32-bit platforms, the 64-bit integer is taken modulo 231, i.e. the top 33 bits are lost during the conversion.

val unsigned_to_int : int64 -> int option

Same as to_int, but interprets the argument as an unsigned integer. Returns None if the unsigned value of the argument cannot fit into an int.

  • since 4.08
val of_float : float -> int64

Convert the given floating-point number to a 64-bit integer, discarding the fractional part (truncate towards 0). If the truncated floating-point number is outside the range [Int64.min_int, Int64.max_int], no exception is raised, and an unspecified, platform-dependent integer is returned.

val to_float : int64 -> float

Convert the given 64-bit integer to a floating-point number.

val of_int32 : int32 -> int64

Convert the given 32-bit integer (type int32) to a 64-bit integer (type int64).

val to_int32 : int64 -> int32

Convert the given 64-bit integer (type int64) to a 32-bit integer (type int32). The 64-bit integer is taken modulo 232, i.e. the top 32 bits are lost during the conversion.

val of_nativeint : nativeint -> int64

Convert the given native integer (type nativeint) to a 64-bit integer (type int64).

val to_nativeint : int64 -> nativeint

Convert the given 64-bit integer (type int64) to a native integer. On 32-bit platforms, the 64-bit integer is taken modulo 232. On 64-bit platforms, the conversion is exact.

val of_string : string -> int64

Convert the given string to a 64-bit integer. The string is read in decimal (by default, or if the string begins with 0u) or in hexadecimal, octal or binary if the string begins with 0x, 0o or 0b respectively.

The 0u prefix reads the input as an unsigned integer in the range [0, 2*Int64.max_int+1]. If the input exceeds Int64.max_int it is converted to the signed integer Int64.min_int + input - Int64.max_int - 1.

The _ (underscore) character can appear anywhere in the string and is ignored.

  • raises Failure

    if the given string is not a valid representation of an integer, or if the integer represented exceeds the range of integers representable in type int64.

val of_string_opt : string -> int64 option

Same as of_string, but return None instead of raising.

  • since 4.05
val to_string : int64 -> string

Return the string representation of its argument, in decimal.

val bits_of_float : float -> int64

Return the internal representation of the given float according to the IEEE 754 floating-point 'double format' bit layout. Bit 63 of the result represents the sign of the float; bits 62 to 52 represent the (biased) exponent; bits 51 to 0 represent the mantissa.

val float_of_bits : int64 -> float

Return the floating-point number whose internal representation, according to the IEEE 754 floating-point 'double format' bit layout, is the given int64.

type t = int64

An alias for the type of 64-bit integers.

val compare : t -> t -> int

The comparison function for 64-bit integers, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Int64 to be passed as argument to the functors Set.Make and Map.Make.

val unsigned_compare : t -> t -> int

Same as compare, except that arguments are interpreted as unsigned 64-bit integers.

  • since 4.08
val equal : t -> t -> bool

The equal function for int64s.

  • since 4.03
val min : t -> t -> t

Return the smaller of the two arguments.

  • since 4.13
val max : t -> t -> t

Return the greater of the two arguments.

  • since 4.13
val seeded_hash : int -> t -> int

A seeded hash function for 64-bit ints, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : t -> int

An unseeded hash function for 64-bit ints, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/LargeFile/index.html b/docs/stdlib/Stdlib/LargeFile/index.html new file mode 100644 index 00000000..ff4a8400 --- /dev/null +++ b/docs/stdlib/Stdlib/LargeFile/index.html @@ -0,0 +1,2 @@ + +LargeFile (docs.stdlib.Stdlib.LargeFile)

Module Stdlib.LargeFile

Operations on large files. This sub-module provides 64-bit variants of the channel functions that manipulate file positions and file sizes. By representing positions and sizes by 64-bit integers (type int64) instead of regular integers (type int), these alternate functions allow operating on files whose sizes are greater than max_int.

val seek_out : out_channel -> int64 -> unit
val pos_out : out_channel -> int64
val out_channel_length : out_channel -> int64
val seek_in : in_channel -> int64 -> unit
val pos_in : in_channel -> int64
val in_channel_length : in_channel -> int64
diff --git a/docs/stdlib/Stdlib/Lazy/index.html b/docs/stdlib/Stdlib/Lazy/index.html new file mode 100644 index 00000000..a70986ad --- /dev/null +++ b/docs/stdlib/Stdlib/Lazy/index.html @@ -0,0 +1,5 @@ + +Lazy (docs.stdlib.Stdlib.Lazy)

Module Stdlib.Lazy

Deferred computations.

type 'a t = 'a CamlinternalLazy.t

A value of type 'a Lazy.t is a deferred computation, called a suspension, that has a result of type 'a. The special expression syntax lazy (expr) makes a suspension of the computation of expr, without computing expr itself yet. "Forcing" the suspension will then compute expr and return its result. Matching a suspension with the special pattern syntax lazy(pattern) also computes the underlying expression and tries to bind it to pattern:

let lazy_option_map f x =
+match x with
+| lazy (Some x) -> Some (Lazy.force f x)
+| _ -> None

Note: If lazy patterns appear in multiple cases in a pattern-matching, lazy expressions may be forced even outside of the case ultimately selected by the pattern matching. In the example above, the suspension x is always computed.

Note: lazy_t is the built-in type constructor used by the compiler for the lazy keyword. You should not use it directly. Always use Lazy.t instead.

Note: Lazy.force is not concurrency-safe. If you use this module with multiple fibers, systhreads or domains, then you will need to add some locks. The module however ensures memory-safety, and hence, concurrently accessing this module will not lead to a crash but the behaviour is unspecified.

Note: if the program is compiled with the -rectypes option, ill-founded recursive definitions of the form let rec x = lazy x or let rec x = lazy(lazy(...(lazy x))) are accepted by the type-checker and lead, when forced, to ill-formed values that trigger infinite loops in the garbage collector and other parts of the run-time system. Without the -rectypes option, such ill-founded recursive definitions are rejected by the type-checker.

exception Undefined

Raised when forcing a suspension concurrently from multiple fibers, systhreads or domains, or when the suspension tries to force itself recursively.

val force : 'a t -> 'a

force x forces the suspension x and returns its result. If x has already been forced, Lazy.force x returns the same value again without recomputing it. If it raised an exception, the same exception is raised again.

Iterators

val map : ('a -> 'b) -> 'a t -> 'b t

map f x returns a suspension that, when forced, forces x and applies f to its value.

It is equivalent to lazy (f (Lazy.force x)).

  • since 4.13

Reasoning on already-forced suspensions

val is_val : 'a t -> bool

is_val x returns true if x has already been forced and did not raise an exception.

  • since 4.00
val from_val : 'a -> 'a t

from_val v evaluates v first (as any function would) and returns an already-forced suspension of its result. It is the same as let x = v in lazy x, but uses dynamic tests to optimize suspension creation in some cases.

  • since 4.00
val map_val : ('a -> 'b) -> 'a t -> 'b t

map_val f x applies f directly if x is already forced, otherwise it behaves as map f x.

When x is already forced, this behavior saves the construction of a suspension, but on the other hand it performs more work eagerly that may not be useful if you never force the function result.

If f raises an exception, it will be raised immediately when is_val x, or raised only when forcing the thunk otherwise.

If map_val f x does not raise an exception, then is_val (map_val f x) is equal to is_val x.

  • since 4.13

Advanced

The following definitions are for advanced uses only; they require familiary with the lazy compilation scheme to be used appropriately.

val from_fun : (unit -> 'a) -> 'a t

from_fun f is the same as lazy (f ()) but slightly more efficient.

It should only be used if the function f is already defined. In particular it is always less efficient to write from_fun (fun () -> expr) than lazy expr.

  • since 4.00
val force_val : 'a t -> 'a

force_val x forces the suspension x and returns its result. If x has already been forced, force_val x returns the same value again without recomputing it.

If the computation of x raises an exception, it is unspecified whether force_val x raises the same exception or Undefined.

  • raises Undefined

    if the forcing of x tries to force x itself recursively.

diff --git a/docs/stdlib/Stdlib/Lexing/index.html b/docs/stdlib/Stdlib/Lexing/index.html new file mode 100644 index 00000000..c48262a7 --- /dev/null +++ b/docs/stdlib/Stdlib/Lexing/index.html @@ -0,0 +1,2 @@ + +Lexing (docs.stdlib.Stdlib.Lexing)

Module Stdlib.Lexing

The run-time library for lexers generated by ocamllex.

Positions

type position = {
  1. pos_fname : string;
  2. pos_lnum : int;
  3. pos_bol : int;
  4. pos_cnum : int;
}

A value of type position describes a point in a source file. pos_fname is the file name; pos_lnum is the line number; pos_bol is the offset of the beginning of the line (number of characters between the beginning of the lexbuf and the beginning of the line); pos_cnum is the offset of the position (number of characters between the beginning of the lexbuf and the position). The difference between pos_cnum and pos_bol is the character offset within the line (i.e. the column number, assuming each character is one column wide).

See the documentation of type lexbuf for information about how the lexing engine will manage positions.

val dummy_pos : position

A value of type position, guaranteed to be different from any valid position.

Lexer buffers

type lexbuf = {
  1. refill_buff : lexbuf -> unit;
  2. mutable lex_buffer : bytes;
  3. mutable lex_buffer_len : int;
  4. mutable lex_abs_pos : int;
  5. mutable lex_start_pos : int;
  6. mutable lex_curr_pos : int;
  7. mutable lex_last_pos : int;
  8. mutable lex_last_action : int;
  9. mutable lex_eof_reached : bool;
  10. mutable lex_mem : int array;
  11. mutable lex_start_p : position;
  12. mutable lex_curr_p : position;
}

The type of lexer buffers. A lexer buffer is the argument passed to the scanning functions defined by the generated scanners. The lexer buffer holds the current state of the scanner, plus a function to refill the buffer from the input.

Lexers can optionally maintain the lex_curr_p and lex_start_p position fields. This "position tracking" mode is the default, and it corresponds to passing ~with_position:true to functions that create lexer buffers. In this mode, the lexing engine and lexer actions are co-responsible for properly updating the position fields, as described in the next paragraph. When the mode is explicitly disabled (with ~with_position:false), the lexing engine will not touch the position fields and the lexer actions should be careful not to do it either; the lex_curr_p and lex_start_p field will then always hold the dummy_pos invalid position. Not tracking positions avoids allocations and memory writes and can significantly improve the performance of the lexer in contexts where lex_start_p and lex_curr_p are not needed.

Position tracking mode works as follows. At each token, the lexing engine will copy lex_curr_p to lex_start_p, then change the pos_cnum field of lex_curr_p by updating it with the number of characters read since the start of the lexbuf. The other fields are left unchanged by the lexing engine. In order to keep them accurate, they must be initialised before the first use of the lexbuf, and updated by the relevant lexer actions (i.e. at each end of line -- see also new_line).

val from_channel : ?with_positions:bool -> in_channel -> lexbuf

Create a lexer buffer on the given input channel. Lexing.from_channel inchan returns a lexer buffer which reads from the input channel inchan, at the current reading position.

val from_string : ?with_positions:bool -> string -> lexbuf

Create a lexer buffer which reads from the given string. Reading starts from the first character in the string. An end-of-input condition is generated when the end of the string is reached.

val from_function : ?with_positions:bool -> (bytes -> int -> int) -> lexbuf

Create a lexer buffer with the given function as its reading method. When the scanner needs more characters, it will call the given function, giving it a byte sequence s and a byte count n. The function should put n bytes or fewer in s, starting at index 0, and return the number of bytes provided. A return value of 0 means end of input.

val set_position : lexbuf -> position -> unit

Set the initial tracked input position for lexbuf to a custom value. Ignores pos_fname. See set_filename for changing this field.

  • since 4.11
val set_filename : lexbuf -> string -> unit

Set filename in the initial tracked position to file in lexbuf.

  • since 4.11
val with_positions : lexbuf -> bool

Tell whether the lexer buffer keeps track of position fields lex_curr_p / lex_start_p, as determined by the corresponding optional argument for functions that create lexer buffers (whose default value is true).

When with_positions is false, lexer actions should not modify position fields. Doing it nevertheless could re-enable the with_position mode and degrade performances.

Functions for lexer semantic actions

The following functions can be called from the semantic actions of lexer definitions (the ML code enclosed in braces that computes the value returned by lexing functions). They give access to the character string matched by the regular expression associated with the semantic action. These functions must be applied to the argument lexbuf, which, in the code generated by ocamllex, is bound to the lexer buffer passed to the parsing function.

val lexeme : lexbuf -> string

Lexing.lexeme lexbuf returns the string matched by the regular expression.

val lexeme_char : lexbuf -> int -> char

Lexing.lexeme_char lexbuf i returns character number i in the matched string.

val lexeme_start : lexbuf -> int

Lexing.lexeme_start lexbuf returns the offset in the input stream of the first character of the matched string. The first character of the stream has offset 0.

val lexeme_end : lexbuf -> int

Lexing.lexeme_end lexbuf returns the offset in the input stream of the character following the last character of the matched string. The first character of the stream has offset 0.

val lexeme_start_p : lexbuf -> position

Like lexeme_start, but return a complete position instead of an offset. When position tracking is disabled, the function returns dummy_pos.

val lexeme_end_p : lexbuf -> position

Like lexeme_end, but return a complete position instead of an offset. When position tracking is disabled, the function returns dummy_pos.

val new_line : lexbuf -> unit

Update the lex_curr_p field of the lexbuf to reflect the start of a new line. You can call this function in the semantic action of the rule that matches the end-of-line character. The function does nothing when position tracking is disabled.

  • since 3.11

Miscellaneous functions

val flush_input : lexbuf -> unit

Discard the contents of the buffer and reset the current position to 0. The next use of the lexbuf will trigger a refill.

diff --git a/docs/stdlib/Stdlib/List/index.html b/docs/stdlib/Stdlib/List/index.html new file mode 100644 index 00000000..9149b50a --- /dev/null +++ b/docs/stdlib/Stdlib/List/index.html @@ -0,0 +1,16 @@ + +List (docs.stdlib.Stdlib.List)

Module Stdlib.List

List operations.

Some functions are flagged as not tail-recursive. A tail-recursive function uses constant stack space, while a non-tail-recursive function uses stack space proportional to the length of its list argument, which can be a problem with very long lists. When the function takes several list arguments, an approximate formula giving stack usage (in some unspecified constant unit) is shown in parentheses.

The above considerations can usually be ignored if your lists are not longer than about 10000 elements.

The labeled version of this module can be used as described in the StdLabels module.

type 'a t = 'a list =
  1. | []
  2. | :: of 'a * 'a list

An alias for the type of lists.

val length : 'a list -> int

Return the length (number of elements) of the given list.

val compare_lengths : 'a list -> 'b list -> int

Compare the lengths of two lists. compare_lengths l1 l2 is equivalent to compare (length l1) (length l2), except that the computation stops after reaching the end of the shortest list.

  • since 4.05
val compare_length_with : 'a list -> int -> int

Compare the length of a list to an integer. compare_length_with l len is equivalent to compare (length l) len, except that the computation stops after at most len iterations on the list.

  • since 4.05
val is_empty : 'a list -> bool

is_empty l is true if and only if l has no elements. It is equivalent to compare_length_with l 0 = 0.

  • since 5.1
val cons : 'a -> 'a list -> 'a list

cons x xs is x :: xs

  • since 4.03 (4.05 in ListLabels)
val hd : 'a list -> 'a

Return the first element of the given list.

  • raises Failure

    if the list is empty.

val tl : 'a list -> 'a list

Return the given list without its first element.

  • raises Failure

    if the list is empty.

val nth : 'a list -> int -> 'a

Return the n-th element of the given list. The first element (head of the list) is at position 0.

  • raises Failure

    if the list is too short.

val nth_opt : 'a list -> int -> 'a option

Return the n-th element of the given list. The first element (head of the list) is at position 0. Return None if the list is too short.

  • since 4.05
val rev : 'a list -> 'a list

List reversal.

val init : int -> (int -> 'a) -> 'a list

init len f is [f 0; f 1; ...; f (len-1)], evaluated left to right.

  • since 4.06
val append : 'a list -> 'a list -> 'a list

append l0 l1 appends l1 to l0. Same function as the infix operator @.

  • since 5.1 this function is tail-recursive.
val rev_append : 'a list -> 'a list -> 'a list

rev_append l1 l2 reverses l1 and concatenates it with l2. This is equivalent to (rev l1) @ l2.

val concat : 'a list list -> 'a list

Concatenate a list of lists. The elements of the argument are all concatenated together (in the same order) to give the result. Not tail-recursive (length of the argument + length of the longest sub-list).

val flatten : 'a list list -> 'a list

Same as concat. Not tail-recursive (length of the argument + length of the longest sub-list).

Comparison

val equal : ('a -> 'a -> bool) -> 'a list -> 'a list -> bool

equal eq [a1; ...; an] [b1; ..; bm] holds when the two input lists have the same length, and for each pair of elements ai, bi at the same position we have eq ai bi.

Note: the eq function may be called even if the lists have different length. If you know your equality function is costly, you may want to check compare_lengths first.

  • since 4.12
val compare : ('a -> 'a -> int) -> 'a list -> 'a list -> int

compare cmp [a1; ...; an] [b1; ...; bm] performs a lexicographic comparison of the two input lists, using the same 'a -> 'a -> int interface as Stdlib.compare:

  • a1 :: l1 is smaller than a2 :: l2 (negative result) if a1 is smaller than a2, or if they are equal (0 result) and l1 is smaller than l2
  • the empty list [] is strictly smaller than non-empty lists

Note: the cmp function will be called even if the lists have different lengths.

  • since 4.12

Iterators

val iter : ('a -> unit) -> 'a list -> unit

iter f [a1; ...; an] applies function f in turn to [a1; ...; an]. It is equivalent to f a1; f a2; ...; f an.

val iteri : (int -> 'a -> unit) -> 'a list -> unit

Same as iter, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 4.00
val map : ('a -> 'b) -> 'a list -> 'b list

map f [a1; ...; an] applies function f to a1, ..., an, and builds the list [f a1; ...; f an] with the results returned by f.

val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list

Same as map, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 4.00
val rev_map : ('a -> 'b) -> 'a list -> 'b list

rev_map f l gives the same result as rev (map f l), but is more efficient.

val filter_map : ('a -> 'b option) -> 'a list -> 'b list

filter_map f l applies f to every element of l, filters out the None elements and returns the list of the arguments of the Some elements.

  • since 4.08
val concat_map : ('a -> 'b list) -> 'a list -> 'b list

concat_map f l gives the same result as concat (map f l). Tail-recursive.

  • since 4.10
val fold_left_map : + ('acc -> 'a -> 'acc * 'b) -> + 'acc -> + 'a list -> + 'acc * 'b list

fold_left_map is a combination of fold_left and map that threads an accumulator through calls to f.

  • since 4.11
val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a list -> 'acc

fold_left f init [b1; ...; bn] is f (... (f (f init b1) b2) ...) bn.

val fold_right : ('a -> 'acc -> 'acc) -> 'a list -> 'acc -> 'acc

fold_right f [a1; ...; an] init is f a1 (f a2 (... (f an init) ...)). Not tail-recursive.

Iterators on two lists

val iter2 : ('a -> 'b -> unit) -> 'a list -> 'b list -> unit

iter2 f [a1; ...; an] [b1; ...; bn] calls in turn f a1 b1; ...; f an bn.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

map2 f [a1; ...; an] [b1; ...; bn] is [f a1 b1; ...; f an bn].

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val rev_map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

rev_map2 f l1 l2 gives the same result as rev (map2 f l1 l2), but is more efficient.

val fold_left2 : + ('acc -> 'a -> 'b -> 'acc) -> + 'acc -> + 'a list -> + 'b list -> + 'acc

fold_left2 f init [a1; ...; an] [b1; ...; bn] is f (... (f (f init a1 b1) a2 b2) ...) an bn.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val fold_right2 : + ('a -> 'b -> 'acc -> 'acc) -> + 'a list -> + 'b list -> + 'acc -> + 'acc

fold_right2 f [a1; ...; an] [b1; ...; bn] init is f a1 b1 (f a2 b2 (... (f an bn init) ...)).

  • raises Invalid_argument

    if the two lists are determined to have different lengths. Not tail-recursive.

List scanning

val for_all : ('a -> bool) -> 'a list -> bool

for_all f [a1; ...; an] checks if all elements of the list satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an) for a non-empty list and true if the list is empty.

val exists : ('a -> bool) -> 'a list -> bool

exists f [a1; ...; an] checks if at least one element of the list satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an) for a non-empty list and false if the list is empty.

val for_all2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool

Same as for_all, but for a two-argument predicate.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val exists2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool

Same as exists, but for a two-argument predicate.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val mem : 'a -> 'a list -> bool

mem a set is true if and only if a is equal to an element of set.

val memq : 'a -> 'a list -> bool

Same as mem, but uses physical equality instead of structural equality to compare list elements.

List searching

val find : ('a -> bool) -> 'a list -> 'a

find f l returns the first element of the list l that satisfies the predicate f.

  • raises Not_found

    if there is no value that satisfies f in the list l.

val find_opt : ('a -> bool) -> 'a list -> 'a option

find f l returns the first element of the list l that satisfies the predicate f. Returns None if there is no value that satisfies f in the list l.

  • since 4.05
val find_index : ('a -> bool) -> 'a list -> int option

find_index f xs returns Some i, where i is the index of the first element of the list xs that satisfies f x, if there is such an element.

It returns None if there is no such element.

  • since 5.1
val find_map : ('a -> 'b option) -> 'a list -> 'b option

find_map f l applies f to the elements of l in order, and returns the first result of the form Some v, or None if none exist.

  • since 4.10
val find_mapi : (int -> 'a -> 'b option) -> 'a list -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 5.1
val filter : ('a -> bool) -> 'a list -> 'a list

filter f l returns all the elements of the list l that satisfy the predicate f. The order of the elements in the input list is preserved.

val find_all : ('a -> bool) -> 'a list -> 'a list

find_all is another name for filter.

val filteri : (int -> 'a -> bool) -> 'a list -> 'a list

Same as filter, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 4.11
val partition : ('a -> bool) -> 'a list -> 'a list * 'a list

partition f l returns a pair of lists (l1, l2), where l1 is the list of all the elements of l that satisfy the predicate f, and l2 is the list of all the elements of l that do not satisfy f. The order of the elements in the input list is preserved.

val partition_map : ('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list

partition_map f l returns a pair of lists (l1, l2) such that, for each element x of the input list l:

  • if f x is Left y1, then y1 is in l1, and
  • if f x is Right y2, then y2 is in l2.

The output elements are included in l1 and l2 in the same relative order as the corresponding input elements in l.

In particular, partition_map (fun x -> if f x then Left x else Right x) l is equivalent to partition f l.

  • since 4.12

Association lists

val assoc : 'a -> ('a * 'b) list -> 'b

assoc a l returns the value associated with key a in the list of pairs l. That is, assoc a [ ...; (a,b); ...] = b if (a,b) is the leftmost binding of a in list l.

  • raises Not_found

    if there is no value associated with a in the list l.

val assoc_opt : 'a -> ('a * 'b) list -> 'b option

assoc_opt a l returns the value associated with key a in the list of pairs l. That is, assoc_opt a [ ...; (a,b); ...] = Some b if (a,b) is the leftmost binding of a in list l. Returns None if there is no value associated with a in the list l.

  • since 4.05
val assq : 'a -> ('a * 'b) list -> 'b

Same as assoc, but uses physical equality instead of structural equality to compare keys.

val assq_opt : 'a -> ('a * 'b) list -> 'b option

Same as assoc_opt, but uses physical equality instead of structural equality to compare keys.

  • since 4.05
val mem_assoc : 'a -> ('a * 'b) list -> bool

Same as assoc, but simply return true if a binding exists, and false if no bindings exist for the given key.

val mem_assq : 'a -> ('a * 'b) list -> bool

Same as mem_assoc, but uses physical equality instead of structural equality to compare keys.

val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list

remove_assoc a l returns the list of pairs l without the first pair with key a, if any. Not tail-recursive.

val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list

Same as remove_assoc, but uses physical equality instead of structural equality to compare keys. Not tail-recursive.

Lists of pairs

val split : ('a * 'b) list -> 'a list * 'b list

Transform a list of pairs into a pair of lists: split [(a1,b1); ...; (an,bn)] is ([a1; ...; an], [b1; ...; bn]). Not tail-recursive.

val combine : 'a list -> 'b list -> ('a * 'b) list

Transform a pair of lists into a list of pairs: combine [a1; ...; an] [b1; ...; bn] is [(a1,b1); ...; (an,bn)].

  • raises Invalid_argument

    if the two lists have different lengths. Not tail-recursive.

Sorting

val sort : ('a -> 'a -> int) -> 'a list -> 'a list

Sort a list in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see Array.sort for a complete specification). For example, Stdlib.compare is a suitable comparison function. The resulting list is sorted in increasing order. sort is guaranteed to run in constant heap space (in addition to the size of the result list) and logarithmic stack space.

The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space.

val stable_sort : ('a -> 'a -> int) -> 'a list -> 'a list

Same as sort, but the sorting algorithm is guaranteed to be stable (i.e. elements that compare equal are kept in their original order).

The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space.

val fast_sort : ('a -> 'a -> int) -> 'a list -> 'a list

Same as sort or stable_sort, whichever is faster on typical input.

val sort_uniq : ('a -> 'a -> int) -> 'a list -> 'a list

Same as sort, but also remove duplicates.

  • since 4.02 (4.03 in ListLabels)
val merge : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list

Merge two lists: Assuming that l1 and l2 are sorted according to the comparison function cmp, merge cmp l1 l2 will return a sorted list containing all the elements of l1 and l2. If several elements compare equal, the elements of l1 will be before the elements of l2. Not tail-recursive (sum of the lengths of the arguments).

Lists and Sequences

val to_seq : 'a list -> 'a Seq.t

Iterate on the list.

  • since 4.07
val of_seq : 'a Seq.t -> 'a list

Create a list from a sequence.

  • since 4.07
diff --git a/docs/stdlib/Stdlib/ListLabels/index.html b/docs/stdlib/Stdlib/ListLabels/index.html new file mode 100644 index 00000000..3a9d7b65 --- /dev/null +++ b/docs/stdlib/Stdlib/ListLabels/index.html @@ -0,0 +1,16 @@ + +ListLabels (docs.stdlib.Stdlib.ListLabels)

Module Stdlib.ListLabels

List operations.

Some functions are flagged as not tail-recursive. A tail-recursive function uses constant stack space, while a non-tail-recursive function uses stack space proportional to the length of its list argument, which can be a problem with very long lists. When the function takes several list arguments, an approximate formula giving stack usage (in some unspecified constant unit) is shown in parentheses.

The above considerations can usually be ignored if your lists are not longer than about 10000 elements.

The labeled version of this module can be used as described in the StdLabels module.

type 'a t = 'a list =
  1. | []
  2. | :: of 'a * 'a list

An alias for the type of lists.

val length : 'a list -> int

Return the length (number of elements) of the given list.

val compare_lengths : 'a list -> 'b list -> int

Compare the lengths of two lists. compare_lengths l1 l2 is equivalent to compare (length l1) (length l2), except that the computation stops after reaching the end of the shortest list.

  • since 4.05
val compare_length_with : 'a list -> len:int -> int

Compare the length of a list to an integer. compare_length_with l len is equivalent to compare (length l) len, except that the computation stops after at most len iterations on the list.

  • since 4.05
val is_empty : 'a list -> bool

is_empty l is true if and only if l has no elements. It is equivalent to compare_length_with l 0 = 0.

  • since 5.1
val cons : 'a -> 'a list -> 'a list

cons x xs is x :: xs

  • since 4.05
val hd : 'a list -> 'a

Return the first element of the given list.

  • raises Failure

    if the list is empty.

val tl : 'a list -> 'a list

Return the given list without its first element.

  • raises Failure

    if the list is empty.

val nth : 'a list -> int -> 'a

Return the n-th element of the given list. The first element (head of the list) is at position 0.

  • raises Failure

    if the list is too short.

val nth_opt : 'a list -> int -> 'a option

Return the n-th element of the given list. The first element (head of the list) is at position 0. Return None if the list is too short.

  • since 4.05
val rev : 'a list -> 'a list

List reversal.

val init : len:int -> f:(int -> 'a) -> 'a list

init ~len ~f is [f 0; f 1; ...; f (len-1)], evaluated left to right.

  • since 4.06
val append : 'a list -> 'a list -> 'a list

append l0 l1 appends l1 to l0. Same function as the infix operator @.

  • since 5.1 this function is tail-recursive.
val rev_append : 'a list -> 'a list -> 'a list

rev_append l1 l2 reverses l1 and concatenates it with l2. This is equivalent to (rev l1) @ l2.

val concat : 'a list list -> 'a list

Concatenate a list of lists. The elements of the argument are all concatenated together (in the same order) to give the result. Not tail-recursive (length of the argument + length of the longest sub-list).

val flatten : 'a list list -> 'a list

Same as concat. Not tail-recursive (length of the argument + length of the longest sub-list).

Comparison

val equal : eq:('a -> 'a -> bool) -> 'a list -> 'a list -> bool

equal eq [a1; ...; an] [b1; ..; bm] holds when the two input lists have the same length, and for each pair of elements ai, bi at the same position we have eq ai bi.

Note: the eq function may be called even if the lists have different length. If you know your equality function is costly, you may want to check compare_lengths first.

  • since 4.12
val compare : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> int

compare cmp [a1; ...; an] [b1; ...; bm] performs a lexicographic comparison of the two input lists, using the same 'a -> 'a -> int interface as Stdlib.compare:

  • a1 :: l1 is smaller than a2 :: l2 (negative result) if a1 is smaller than a2, or if they are equal (0 result) and l1 is smaller than l2
  • the empty list [] is strictly smaller than non-empty lists

Note: the cmp function will be called even if the lists have different lengths.

  • since 4.12

Iterators

val iter : f:('a -> unit) -> 'a list -> unit

iter ~f [a1; ...; an] applies function f in turn to [a1; ...; an]. It is equivalent to f a1; f a2; ...; f an.

val iteri : f:(int -> 'a -> unit) -> 'a list -> unit

Same as iter, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 4.00
val map : f:('a -> 'b) -> 'a list -> 'b list

map ~f [a1; ...; an] applies function f to a1, ..., an, and builds the list [f a1; ...; f an] with the results returned by f.

val mapi : f:(int -> 'a -> 'b) -> 'a list -> 'b list

Same as map, but the function is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 4.00
val rev_map : f:('a -> 'b) -> 'a list -> 'b list

rev_map ~f l gives the same result as rev (map f l), but is more efficient.

val filter_map : f:('a -> 'b option) -> 'a list -> 'b list

filter_map ~f l applies f to every element of l, filters out the None elements and returns the list of the arguments of the Some elements.

  • since 4.08
val concat_map : f:('a -> 'b list) -> 'a list -> 'b list

concat_map ~f l gives the same result as concat (map f l). Tail-recursive.

  • since 4.10
val fold_left_map : + f:('acc -> 'a -> 'acc * 'b) -> + init:'acc -> + 'a list -> + 'acc * 'b list

fold_left_map is a combination of fold_left and map that threads an accumulator through calls to f.

  • since 4.11
val fold_left : f:('acc -> 'a -> 'acc) -> init:'acc -> 'a list -> 'acc

fold_left ~f ~init [b1; ...; bn] is f (... (f (f init b1) b2) ...) bn.

val fold_right : f:('a -> 'acc -> 'acc) -> 'a list -> init:'acc -> 'acc

fold_right ~f [a1; ...; an] ~init is f a1 (f a2 (... (f an init) ...)). Not tail-recursive.

Iterators on two lists

val iter2 : f:('a -> 'b -> unit) -> 'a list -> 'b list -> unit

iter2 ~f [a1; ...; an] [b1; ...; bn] calls in turn f a1 b1; ...; f an bn.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val map2 : f:('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

map2 ~f [a1; ...; an] [b1; ...; bn] is [f a1 b1; ...; f an bn].

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val rev_map2 : f:('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list

rev_map2 ~f l1 l2 gives the same result as rev (map2 f l1 l2), but is more efficient.

val fold_left2 : + f:('acc -> 'a -> 'b -> 'acc) -> + init:'acc -> + 'a list -> + 'b list -> + 'acc

fold_left2 ~f ~init [a1; ...; an] [b1; ...; bn] is f (... (f (f init a1 b1) a2 b2) ...) an bn.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val fold_right2 : + f:('a -> 'b -> 'acc -> 'acc) -> + 'a list -> + 'b list -> + init:'acc -> + 'acc

fold_right2 ~f [a1; ...; an] [b1; ...; bn] ~init is f a1 b1 (f a2 b2 (... (f an bn init) ...)).

  • raises Invalid_argument

    if the two lists are determined to have different lengths. Not tail-recursive.

List scanning

val for_all : f:('a -> bool) -> 'a list -> bool

for_all ~f [a1; ...; an] checks if all elements of the list satisfy the predicate f. That is, it returns (f a1) && (f a2) && ... && (f an) for a non-empty list and true if the list is empty.

val exists : f:('a -> bool) -> 'a list -> bool

exists ~f [a1; ...; an] checks if at least one element of the list satisfies the predicate f. That is, it returns (f a1) || (f a2) || ... || (f an) for a non-empty list and false if the list is empty.

val for_all2 : f:('a -> 'b -> bool) -> 'a list -> 'b list -> bool

Same as for_all, but for a two-argument predicate.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val exists2 : f:('a -> 'b -> bool) -> 'a list -> 'b list -> bool

Same as exists, but for a two-argument predicate.

  • raises Invalid_argument

    if the two lists are determined to have different lengths.

val mem : 'a -> set:'a list -> bool

mem a ~set is true if and only if a is equal to an element of set.

val memq : 'a -> set:'a list -> bool

Same as mem, but uses physical equality instead of structural equality to compare list elements.

List searching

val find : f:('a -> bool) -> 'a list -> 'a

find ~f l returns the first element of the list l that satisfies the predicate f.

  • raises Not_found

    if there is no value that satisfies f in the list l.

val find_opt : f:('a -> bool) -> 'a list -> 'a option

find ~f l returns the first element of the list l that satisfies the predicate f. Returns None if there is no value that satisfies f in the list l.

  • since 4.05
val find_index : f:('a -> bool) -> 'a list -> int option

find_index ~f xs returns Some i, where i is the index of the first element of the list xs that satisfies f x, if there is such an element.

It returns None if there is no such element.

  • since 5.1
val find_map : f:('a -> 'b option) -> 'a list -> 'b option

find_map ~f l applies f to the elements of l in order, and returns the first result of the form Some v, or None if none exist.

  • since 4.10
val find_mapi : f:(int -> 'a -> 'b option) -> 'a list -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 5.1
val filter : f:('a -> bool) -> 'a list -> 'a list

filter ~f l returns all the elements of the list l that satisfy the predicate f. The order of the elements in the input list is preserved.

val find_all : f:('a -> bool) -> 'a list -> 'a list

find_all is another name for filter.

val filteri : f:(int -> 'a -> bool) -> 'a list -> 'a list

Same as filter, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

  • since 4.11
val partition : f:('a -> bool) -> 'a list -> 'a list * 'a list

partition ~f l returns a pair of lists (l1, l2), where l1 is the list of all the elements of l that satisfy the predicate f, and l2 is the list of all the elements of l that do not satisfy f. The order of the elements in the input list is preserved.

val partition_map : f:('a -> ('b, 'c) Either.t) -> 'a list -> 'b list * 'c list

partition_map f l returns a pair of lists (l1, l2) such that, for each element x of the input list l:

  • if f x is Left y1, then y1 is in l1, and
  • if f x is Right y2, then y2 is in l2.

The output elements are included in l1 and l2 in the same relative order as the corresponding input elements in l.

In particular, partition_map (fun x -> if f x then Left x else Right x) l is equivalent to partition f l.

  • since 4.12

Association lists

val assoc : 'a -> ('a * 'b) list -> 'b

assoc a l returns the value associated with key a in the list of pairs l. That is, assoc a [ ...; (a,b); ...] = b if (a,b) is the leftmost binding of a in list l.

  • raises Not_found

    if there is no value associated with a in the list l.

val assoc_opt : 'a -> ('a * 'b) list -> 'b option

assoc_opt a l returns the value associated with key a in the list of pairs l. That is, assoc_opt a [ ...; (a,b); ...] = Some b if (a,b) is the leftmost binding of a in list l. Returns None if there is no value associated with a in the list l.

  • since 4.05
val assq : 'a -> ('a * 'b) list -> 'b

Same as assoc, but uses physical equality instead of structural equality to compare keys.

val assq_opt : 'a -> ('a * 'b) list -> 'b option

Same as assoc_opt, but uses physical equality instead of structural equality to compare keys.

  • since 4.05
val mem_assoc : 'a -> map:('a * 'b) list -> bool

Same as assoc, but simply return true if a binding exists, and false if no bindings exist for the given key.

val mem_assq : 'a -> map:('a * 'b) list -> bool

Same as mem_assoc, but uses physical equality instead of structural equality to compare keys.

val remove_assoc : 'a -> ('a * 'b) list -> ('a * 'b) list

remove_assoc a l returns the list of pairs l without the first pair with key a, if any. Not tail-recursive.

val remove_assq : 'a -> ('a * 'b) list -> ('a * 'b) list

Same as remove_assoc, but uses physical equality instead of structural equality to compare keys. Not tail-recursive.

Lists of pairs

val split : ('a * 'b) list -> 'a list * 'b list

Transform a list of pairs into a pair of lists: split [(a1,b1); ...; (an,bn)] is ([a1; ...; an], [b1; ...; bn]). Not tail-recursive.

val combine : 'a list -> 'b list -> ('a * 'b) list

Transform a pair of lists into a list of pairs: combine [a1; ...; an] [b1; ...; bn] is [(a1,b1); ...; (an,bn)].

  • raises Invalid_argument

    if the two lists have different lengths. Not tail-recursive.

Sorting

val sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list

Sort a list in increasing order according to a comparison function. The comparison function must return 0 if its arguments compare as equal, a positive integer if the first is greater, and a negative integer if the first is smaller (see Array.sort for a complete specification). For example, Stdlib.compare is a suitable comparison function. The resulting list is sorted in increasing order. sort is guaranteed to run in constant heap space (in addition to the size of the result list) and logarithmic stack space.

The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space.

val stable_sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list

Same as sort, but the sorting algorithm is guaranteed to be stable (i.e. elements that compare equal are kept in their original order).

The current implementation uses Merge Sort. It runs in constant heap space and logarithmic stack space.

val fast_sort : cmp:('a -> 'a -> int) -> 'a list -> 'a list

Same as sort or stable_sort, whichever is faster on typical input.

val sort_uniq : cmp:('a -> 'a -> int) -> 'a list -> 'a list

Same as sort, but also remove duplicates.

  • since 4.03
val merge : cmp:('a -> 'a -> int) -> 'a list -> 'a list -> 'a list

Merge two lists: Assuming that l1 and l2 are sorted according to the comparison function cmp, merge ~cmp l1 l2 will return a sorted list containing all the elements of l1 and l2. If several elements compare equal, the elements of l1 will be before the elements of l2. Not tail-recursive (sum of the lengths of the arguments).

Lists and Sequences

val to_seq : 'a list -> 'a Seq.t

Iterate on the list.

  • since 4.07
val of_seq : 'a Seq.t -> 'a list

Create a list from a sequence.

  • since 4.07
diff --git a/docs/stdlib/Stdlib/Map/Make/argument-1-Ord/index.html b/docs/stdlib/Stdlib/Map/Make/argument-1-Ord/index.html new file mode 100644 index 00000000..95d531c2 --- /dev/null +++ b/docs/stdlib/Stdlib/Map/Make/argument-1-Ord/index.html @@ -0,0 +1,2 @@ + +Ord (docs.stdlib.Stdlib.Map.Make.Ord)

Parameter Make.Ord

type t

The type of the map keys.

val compare : t -> t -> int

A total ordering function over the keys. This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/Map/Make/index.html b/docs/stdlib/Stdlib/Map/Make/index.html new file mode 100644 index 00000000..f9f849f9 --- /dev/null +++ b/docs/stdlib/Stdlib/Map/Make/index.html @@ -0,0 +1,8 @@ + +Make (docs.stdlib.Stdlib.Map.Make)

Module Map.Make

Functor building an implementation of the map structure given a totally ordered type.

Parameters

module Ord : OrderedType

Signature

Maps

type key = Ord.t

The type of the map keys.

type !+'a t

The type of maps from type key to type 'a.

val empty : 'a t

The empty map.

val add : key -> 'a -> 'a t -> 'a t

add key data m returns a map containing the same bindings as m, plus a binding of key to data. If key was already bound in m to a value that is physically equal to data, m is returned unchanged (the result of the function is then physically equal to m). Otherwise, the previous binding of key in m disappears.

  • before 4.03

    Physical equality was not ensured.

val add_to_list : key -> 'a -> 'a list t -> 'a list t

add_to_list key data m is m with key mapped to l such that l is data :: Map.find key m if key was bound in m and [v] otherwise.

  • since 5.1
val update : key -> ('a option -> 'a option) -> 'a t -> 'a t

update key f m returns a map containing the same bindings as m, except for the binding of key. Depending on the value of y where y is f (find_opt key m), the binding of key is added, removed or updated. If y is None, the binding is removed if it exists; otherwise, if y is Some z then key is associated to z in the resulting map. If key was already bound in m to a value that is physically equal to z, m is returned unchanged (the result of the function is then physically equal to m).

  • since 4.06
val singleton : key -> 'a -> 'a t

singleton x y returns the one-element map that contains a binding y for x.

  • since 3.12
val remove : key -> 'a t -> 'a t

remove x m returns a map containing the same bindings as m, except for x which is unbound in the returned map. If x was not in m, m is returned unchanged (the result of the function is then physically equal to m).

  • before 4.03

    Physical equality was not ensured.

val merge : + (key -> 'a option -> 'b option -> 'c option) -> + 'a t -> + 'b t -> + 'c t

merge f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. The presence of each such binding, and the corresponding value, is determined with the function f. In terms of the find_opt operation, we have find_opt x (merge f m1 m2) = f x (find_opt x m1) (find_opt x m2) for any key x, provided that f x None None = None.

  • since 3.12
val union : (key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t

union f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. When the same binding is defined in both arguments, the function f is used to combine them. This is a special case of merge: union f m1 m2 is equivalent to merge f' m1 m2, where

  • f' _key None None = None
  • f' _key (Some v) None = Some v
  • f' _key None (Some v) = Some v
  • f' key (Some v1) (Some v2) = f key v1 v2
  • since 4.03
val cardinal : 'a t -> int

Return the number of bindings of a map.

  • since 3.12

Bindings

val bindings : 'a t -> (key * 'a) list

Return the list of all bindings of the given map. The returned list is sorted in increasing order of keys with respect to the ordering Ord.compare, where Ord is the argument given to Map.Make.

  • since 3.12
val min_binding : 'a t -> key * 'a

Return the binding with the smallest key in a given map (with respect to the Ord.compare ordering), or raise Not_found if the map is empty.

  • since 3.12
val min_binding_opt : 'a t -> (key * 'a) option

Return the binding with the smallest key in the given map (with respect to the Ord.compare ordering), or None if the map is empty.

  • since 4.05
val max_binding : 'a t -> key * 'a

Same as min_binding, but returns the binding with the largest key in the given map.

  • since 3.12
val max_binding_opt : 'a t -> (key * 'a) option

Same as min_binding_opt, but returns the binding with the largest key in the given map.

  • since 4.05
val choose : 'a t -> key * 'a

Return one binding of the given map, or raise Not_found if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 3.12
val choose_opt : 'a t -> (key * 'a) option

Return one binding of the given map, or None if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 4.05

Searching

val find : key -> 'a t -> 'a

find x m returns the current value of x in m, or raises Not_found if no binding for x exists.

val find_opt : key -> 'a t -> 'a option

find_opt x m returns Some v if the current value of x in m is v, or None if no binding for x exists.

  • since 4.05
val find_first : (key -> bool) -> 'a t -> key * 'a

find_first f m, where f is a monotonically increasing function, returns the binding of m with the lowest key k such that f k, or raises Not_found if no such key exists.

For example, find_first (fun k -> Ord.compare k x >= 0) m will return the first binding k, v of m where Ord.compare k x >= 0 (intuitively: k >= x), or raise Not_found if x is greater than any element of m.

  • since 4.05
val find_first_opt : (key -> bool) -> 'a t -> (key * 'a) option

find_first_opt f m, where f is a monotonically increasing function, returns an option containing the binding of m with the lowest key k such that f k, or None if no such key exists.

  • since 4.05
val find_last : (key -> bool) -> 'a t -> key * 'a

find_last f m, where f is a monotonically decreasing function, returns the binding of m with the highest key k such that f k, or raises Not_found if no such key exists.

  • since 4.05
val find_last_opt : (key -> bool) -> 'a t -> (key * 'a) option

find_last_opt f m, where f is a monotonically decreasing function, returns an option containing the binding of m with the highest key k such that f k, or None if no such key exists.

  • since 4.05

Traversing

val iter : (key -> 'a -> unit) -> 'a t -> unit

iter f m applies f to all bindings in map m. f receives the key as first argument, and the associated value as second argument. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc

fold f m init computes (f kN dN ... (f k1 d1 init)...), where k1 ... kN are the keys of all bindings in m (in increasing order), and d1 ... dN are the associated data.

Transforming

val map : ('a -> 'b) -> 'a t -> 'b t

map f m returns a map with same domain as m, where the associated value a of all bindings of m has been replaced by the result of the application of f to a. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t

Same as map, but the function receives as arguments both the key and the associated value for each binding of the map.

val filter : (key -> 'a -> bool) -> 'a t -> 'a t

filter f m returns the map with all the bindings in m that satisfy predicate p. If every binding in m satisfies f, m is returned unchanged (the result of the function is then physically equal to m)

  • since 3.12
  • before 4.03

    Physical equality was not ensured.

val filter_map : (key -> 'a -> 'b option) -> 'a t -> 'b t

filter_map f m applies the function f to every binding of m, and builds a map from the results. For each binding (k, v) in the input map:

  • if f k v is None then k is not in the result,
  • if f k v is Some v' then the binding (k, v') is in the output map.

For example, the following function on maps whose values are lists

filter_map
+  (fun _k li -> match li with [] -> None | _::tl -> Some tl)
+  m

drops all bindings of m whose value is an empty list, and pops the first element of each value that is non-empty.

  • since 4.11
val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t

partition f m returns a pair of maps (m1, m2), where m1 contains all the bindings of m that satisfy the predicate f, and m2 is the map with all the bindings of m that do not satisfy f.

  • since 3.12
val split : key -> 'a t -> 'a t * 'a option * 'a t

split x m returns a triple (l, data, r), where l is the map with all the bindings of m whose key is strictly less than x; r is the map with all the bindings of m whose key is strictly greater than x; data is None if m contains no binding for x, or Some v if m binds v to x.

  • since 3.12

Predicates and comparisons

val is_empty : 'a t -> bool

Test whether a map is empty or not.

val mem : key -> 'a t -> bool

mem x m returns true if m contains a binding for x, and false otherwise.

val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool

equal cmp m1 m2 tests whether the maps m1 and m2 are equal, that is, contain equal keys and associate them with equal data. cmp is the equality predicate used to compare the data associated with the keys.

val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int

Total ordering between maps. The first argument is a total ordering used to compare data associated with equal keys in the two maps.

val for_all : (key -> 'a -> bool) -> 'a t -> bool

for_all f m checks if all the bindings of the map satisfy the predicate f.

  • since 3.12
val exists : (key -> 'a -> bool) -> 'a t -> bool

exists f m checks if at least one binding of the map satisfies the predicate f.

  • since 3.12

Converting

val to_list : 'a t -> (key * 'a) list

to_list m is bindings m.

  • since 5.1
val of_list : (key * 'a) list -> 'a t

of_list bs adds the bindings of bs to the empty map, in list order (if a key is bound twice in bs the last one takes over).

  • since 5.1
val to_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in ascending order of keys

  • since 4.07
val to_rev_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in descending order of keys

  • since 4.12
val to_seq_from : key -> 'a t -> (key * 'a) Seq.t

to_seq_from k m iterates on a subset of the bindings of m, in ascending order of keys, from key k or above.

  • since 4.07
val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t

Add the given bindings to the map, in order.

  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t

Build a map from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/Map/index.html b/docs/stdlib/Stdlib/Map/index.html new file mode 100644 index 00000000..130f2e5a --- /dev/null +++ b/docs/stdlib/Stdlib/Map/index.html @@ -0,0 +1,13 @@ + +Map (docs.stdlib.Stdlib.Map)

Module Stdlib.Map

Association tables over ordered types.

This module implements applicative association tables, also known as finite maps or dictionaries, given a total ordering function over the keys. All operations over maps are purely applicative (no side-effects). The implementation uses balanced binary trees, and therefore searching and insertion take time logarithmic in the size of the map.

For instance:

module IntPairs =
+  struct
+    type t = int * int
+    let compare (x0,y0) (x1,y1) =
+      match Stdlib.compare x0 x1 with
+          0 -> Stdlib.compare y0 y1
+        | c -> c
+  end
+
+module PairsMap = Map.Make(IntPairs)
+
+let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world")

This creates a new module PairsMap, with a new type 'a PairsMap.t of maps from int * int to 'a. In this example, m contains string values so its type is string PairsMap.t.

module type OrderedType = sig ... end

Input signature of the functor Make.

module type S = sig ... end

Output signature of the functor Make.

module Make (Ord : OrderedType) : S with type key = Ord.t

Functor building an implementation of the map structure given a totally ordered type.

diff --git a/docs/stdlib/Stdlib/Map/module-type-OrderedType/index.html b/docs/stdlib/Stdlib/Map/module-type-OrderedType/index.html new file mode 100644 index 00000000..332c64d4 --- /dev/null +++ b/docs/stdlib/Stdlib/Map/module-type-OrderedType/index.html @@ -0,0 +1,2 @@ + +OrderedType (docs.stdlib.Stdlib.Map.OrderedType)

Module type Map.OrderedType

Input signature of the functor Make.

type t

The type of the map keys.

val compare : t -> t -> int

A total ordering function over the keys. This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/Map/module-type-S/index.html b/docs/stdlib/Stdlib/Map/module-type-S/index.html new file mode 100644 index 00000000..1868d775 --- /dev/null +++ b/docs/stdlib/Stdlib/Map/module-type-S/index.html @@ -0,0 +1,8 @@ + +S (docs.stdlib.Stdlib.Map.S)

Module type Map.S

Output signature of the functor Make.

Maps

type key

The type of the map keys.

type !+'a t

The type of maps from type key to type 'a.

val empty : 'a t

The empty map.

val add : key -> 'a -> 'a t -> 'a t

add key data m returns a map containing the same bindings as m, plus a binding of key to data. If key was already bound in m to a value that is physically equal to data, m is returned unchanged (the result of the function is then physically equal to m). Otherwise, the previous binding of key in m disappears.

  • before 4.03

    Physical equality was not ensured.

val add_to_list : key -> 'a -> 'a list t -> 'a list t

add_to_list key data m is m with key mapped to l such that l is data :: Map.find key m if key was bound in m and [v] otherwise.

  • since 5.1
val update : key -> ('a option -> 'a option) -> 'a t -> 'a t

update key f m returns a map containing the same bindings as m, except for the binding of key. Depending on the value of y where y is f (find_opt key m), the binding of key is added, removed or updated. If y is None, the binding is removed if it exists; otherwise, if y is Some z then key is associated to z in the resulting map. If key was already bound in m to a value that is physically equal to z, m is returned unchanged (the result of the function is then physically equal to m).

  • since 4.06
val singleton : key -> 'a -> 'a t

singleton x y returns the one-element map that contains a binding y for x.

  • since 3.12
val remove : key -> 'a t -> 'a t

remove x m returns a map containing the same bindings as m, except for x which is unbound in the returned map. If x was not in m, m is returned unchanged (the result of the function is then physically equal to m).

  • before 4.03

    Physical equality was not ensured.

val merge : + (key -> 'a option -> 'b option -> 'c option) -> + 'a t -> + 'b t -> + 'c t

merge f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. The presence of each such binding, and the corresponding value, is determined with the function f. In terms of the find_opt operation, we have find_opt x (merge f m1 m2) = f x (find_opt x m1) (find_opt x m2) for any key x, provided that f x None None = None.

  • since 3.12
val union : (key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t

union f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. When the same binding is defined in both arguments, the function f is used to combine them. This is a special case of merge: union f m1 m2 is equivalent to merge f' m1 m2, where

  • f' _key None None = None
  • f' _key (Some v) None = Some v
  • f' _key None (Some v) = Some v
  • f' key (Some v1) (Some v2) = f key v1 v2
  • since 4.03
val cardinal : 'a t -> int

Return the number of bindings of a map.

  • since 3.12

Bindings

val bindings : 'a t -> (key * 'a) list

Return the list of all bindings of the given map. The returned list is sorted in increasing order of keys with respect to the ordering Ord.compare, where Ord is the argument given to Map.Make.

  • since 3.12
val min_binding : 'a t -> key * 'a

Return the binding with the smallest key in a given map (with respect to the Ord.compare ordering), or raise Not_found if the map is empty.

  • since 3.12
val min_binding_opt : 'a t -> (key * 'a) option

Return the binding with the smallest key in the given map (with respect to the Ord.compare ordering), or None if the map is empty.

  • since 4.05
val max_binding : 'a t -> key * 'a

Same as min_binding, but returns the binding with the largest key in the given map.

  • since 3.12
val max_binding_opt : 'a t -> (key * 'a) option

Same as min_binding_opt, but returns the binding with the largest key in the given map.

  • since 4.05
val choose : 'a t -> key * 'a

Return one binding of the given map, or raise Not_found if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 3.12
val choose_opt : 'a t -> (key * 'a) option

Return one binding of the given map, or None if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 4.05

Searching

val find : key -> 'a t -> 'a

find x m returns the current value of x in m, or raises Not_found if no binding for x exists.

val find_opt : key -> 'a t -> 'a option

find_opt x m returns Some v if the current value of x in m is v, or None if no binding for x exists.

  • since 4.05
val find_first : (key -> bool) -> 'a t -> key * 'a

find_first f m, where f is a monotonically increasing function, returns the binding of m with the lowest key k such that f k, or raises Not_found if no such key exists.

For example, find_first (fun k -> Ord.compare k x >= 0) m will return the first binding k, v of m where Ord.compare k x >= 0 (intuitively: k >= x), or raise Not_found if x is greater than any element of m.

  • since 4.05
val find_first_opt : (key -> bool) -> 'a t -> (key * 'a) option

find_first_opt f m, where f is a monotonically increasing function, returns an option containing the binding of m with the lowest key k such that f k, or None if no such key exists.

  • since 4.05
val find_last : (key -> bool) -> 'a t -> key * 'a

find_last f m, where f is a monotonically decreasing function, returns the binding of m with the highest key k such that f k, or raises Not_found if no such key exists.

  • since 4.05
val find_last_opt : (key -> bool) -> 'a t -> (key * 'a) option

find_last_opt f m, where f is a monotonically decreasing function, returns an option containing the binding of m with the highest key k such that f k, or None if no such key exists.

  • since 4.05

Traversing

val iter : (key -> 'a -> unit) -> 'a t -> unit

iter f m applies f to all bindings in map m. f receives the key as first argument, and the associated value as second argument. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val fold : (key -> 'a -> 'acc -> 'acc) -> 'a t -> 'acc -> 'acc

fold f m init computes (f kN dN ... (f k1 d1 init)...), where k1 ... kN are the keys of all bindings in m (in increasing order), and d1 ... dN are the associated data.

Transforming

val map : ('a -> 'b) -> 'a t -> 'b t

map f m returns a map with same domain as m, where the associated value a of all bindings of m has been replaced by the result of the application of f to a. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t

Same as map, but the function receives as arguments both the key and the associated value for each binding of the map.

val filter : (key -> 'a -> bool) -> 'a t -> 'a t

filter f m returns the map with all the bindings in m that satisfy predicate p. If every binding in m satisfies f, m is returned unchanged (the result of the function is then physically equal to m)

  • since 3.12
  • before 4.03

    Physical equality was not ensured.

val filter_map : (key -> 'a -> 'b option) -> 'a t -> 'b t

filter_map f m applies the function f to every binding of m, and builds a map from the results. For each binding (k, v) in the input map:

  • if f k v is None then k is not in the result,
  • if f k v is Some v' then the binding (k, v') is in the output map.

For example, the following function on maps whose values are lists

filter_map
+  (fun _k li -> match li with [] -> None | _::tl -> Some tl)
+  m

drops all bindings of m whose value is an empty list, and pops the first element of each value that is non-empty.

  • since 4.11
val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t

partition f m returns a pair of maps (m1, m2), where m1 contains all the bindings of m that satisfy the predicate f, and m2 is the map with all the bindings of m that do not satisfy f.

  • since 3.12
val split : key -> 'a t -> 'a t * 'a option * 'a t

split x m returns a triple (l, data, r), where l is the map with all the bindings of m whose key is strictly less than x; r is the map with all the bindings of m whose key is strictly greater than x; data is None if m contains no binding for x, or Some v if m binds v to x.

  • since 3.12

Predicates and comparisons

val is_empty : 'a t -> bool

Test whether a map is empty or not.

val mem : key -> 'a t -> bool

mem x m returns true if m contains a binding for x, and false otherwise.

val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool

equal cmp m1 m2 tests whether the maps m1 and m2 are equal, that is, contain equal keys and associate them with equal data. cmp is the equality predicate used to compare the data associated with the keys.

val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int

Total ordering between maps. The first argument is a total ordering used to compare data associated with equal keys in the two maps.

val for_all : (key -> 'a -> bool) -> 'a t -> bool

for_all f m checks if all the bindings of the map satisfy the predicate f.

  • since 3.12
val exists : (key -> 'a -> bool) -> 'a t -> bool

exists f m checks if at least one binding of the map satisfies the predicate f.

  • since 3.12

Converting

val to_list : 'a t -> (key * 'a) list

to_list m is bindings m.

  • since 5.1
val of_list : (key * 'a) list -> 'a t

of_list bs adds the bindings of bs to the empty map, in list order (if a key is bound twice in bs the last one takes over).

  • since 5.1
val to_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in ascending order of keys

  • since 4.07
val to_rev_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in descending order of keys

  • since 4.12
val to_seq_from : key -> 'a t -> (key * 'a) Seq.t

to_seq_from k m iterates on a subset of the bindings of m, in ascending order of keys, from key k or above.

  • since 4.07
val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t

Add the given bindings to the map, in order.

  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t

Build a map from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/Marshal/index.html b/docs/stdlib/Stdlib/Marshal/index.html new file mode 100644 index 00000000..9a6231f9 --- /dev/null +++ b/docs/stdlib/Stdlib/Marshal/index.html @@ -0,0 +1,2 @@ + +Marshal (docs.stdlib.Stdlib.Marshal)

Module Stdlib.Marshal

Marshaling of data structures.

This module provides functions to encode arbitrary data structures as sequences of bytes, which can then be written on a file or sent over a pipe or network connection. The bytes can then be read back later, possibly in another process, and decoded back into a data structure. The format for the byte sequences is compatible across all machines for a given version of OCaml.

Warning: marshaling is currently not type-safe. The type of marshaled data is not transmitted along the value of the data, making it impossible to check that the data read back possesses the type expected by the context. In particular, the result type of the Marshal.from_* functions is given as 'a, but this is misleading: the returned OCaml value does not possess type 'a for all 'a; it has one, unique type which cannot be determined at compile-time. The programmer should explicitly give the expected type of the returned value, using the following syntax:

  • (Marshal.from_channel chan : type). Anything can happen at run-time if the object in the file does not belong to the given type.

Values of extensible variant types, for example exceptions (of extensible type exn), returned by the unmarshaller should not be pattern-matched over through match ... with or try ... with, because unmarshalling does not preserve the information required for matching their constructors. Structural equalities with other extensible variant values does not work either. Most other uses such as Printexc.to_string, will still work as expected.

The representation of marshaled values is not human-readable, and uses bytes that are not printable characters. Therefore, input and output channels used in conjunction with Marshal.to_channel and Marshal.from_channel must be opened in binary mode, using e.g. open_out_bin or open_in_bin; channels opened in text mode will cause unmarshaling errors on platforms where text channels behave differently than binary channels, e.g. Windows.

type extern_flags =
  1. | No_sharing
    (*

    Don't preserve sharing

    *)
  2. | Closures
    (*

    Send function closures

    *)
  3. | Compat_32
    (*

    Ensure 32-bit compatibility

    *)
  4. | Compression
    (*

    Compress the output if possible

    • since 5.1
    *)

The flags to the Marshal.to_* functions below.

val to_channel : out_channel -> 'a -> extern_flags list -> unit

Marshal.to_channel chan v flags writes the representation of v on channel chan. The flags argument is a possibly empty list of flags that governs the marshaling behavior with respect to sharing, functional values, and compatibility between 32- and 64-bit platforms.

If flags does not contain Marshal.No_sharing, circularities and sharing inside the value v are detected and preserved in the sequence of bytes produced. In particular, this guarantees that marshaling always terminates. Sharing between values marshaled by successive calls to Marshal.to_channel is neither detected nor preserved, though. If flags contains Marshal.No_sharing, sharing is ignored. This results in faster marshaling if v contains no shared substructures, but may cause slower marshaling and larger byte representations if v actually contains sharing, or even non-termination if v contains cycles.

If flags does not contain Marshal.Closures, marshaling fails when it encounters a functional value inside v: only 'pure' data structures, containing neither functions nor objects, can safely be transmitted between different programs. If flags contains Marshal.Closures, functional values will be marshaled as a the position in the code of the program together with the values corresponding to the free variables captured in the closure. In this case, the output of marshaling can only be read back in processes that run exactly the same program, with exactly the same compiled code. (This is checked at un-marshaling time, using an MD5 digest of the code transmitted along with the code position.)

The exact definition of which free variables are captured in a closure is not specified and can vary between bytecode and native code (and according to optimization flags). In particular, a function value accessing a global reference may or may not include the reference in its closure. If it does, unmarshaling the corresponding closure will create a new reference, different from the global one.

If flags contains Marshal.Compression, the marshaled data representing value v is compressed before being written to channel chan. Decompression takes place automatically in the unmarshaling functions Stdlib.input_value, Marshal.from_channel, Marshal.from_string, etc. For large values v, compression typically reduces the size of marshaled data by a factor 2 to 4, but slows down marshaling and, to a lesser extent, unmarshaling. Compression is not supported on some platforms; in this case, the Marshal.Compression flag is silently ignored and uncompressed data is written to channel chan.

If flags contains Marshal.Compat_32, marshaling fails when it encounters an integer value outside the range [-2{^30}, 2{^30}-1] of integers that are representable on a 32-bit platform. This ensures that marshaled data generated on a 64-bit platform can be safely read back on a 32-bit platform. If flags does not contain Marshal.Compat_32, integer values outside the range [-2{^30}, 2{^30}-1] are marshaled, and can be read back on a 64-bit platform, but will cause an error at un-marshaling time when read back on a 32-bit platform. The Mashal.Compat_32 flag only matters when marshaling is performed on a 64-bit platform; it has no effect if marshaling is performed on a 32-bit platform.

  • raises Failure

    if chan is not in binary mode.

  • before 5.1

    Compression mode was not supported

val to_bytes : 'a -> extern_flags list -> bytes

Marshal.to_bytes v flags returns a byte sequence containing the representation of v. The flags argument has the same meaning as for Marshal.to_channel.

  • since 4.02
val to_string : 'a -> extern_flags list -> string

Same as to_bytes but return the result as a string instead of a byte sequence.

val to_buffer : bytes -> int -> int -> 'a -> extern_flags list -> int

Marshal.to_buffer buff ofs len v flags marshals the value v, storing its byte representation in the sequence buff, starting at index ofs, and writing at most len bytes. It returns the number of bytes actually written to the sequence. If the byte representation of v does not fit in len characters, the exception Failure is raised.

val from_channel : in_channel -> 'a

Marshal.from_channel chan reads from channel chan the byte representation of a structured value, as produced by one of the Marshal.to_* functions, and reconstructs and returns the corresponding value.

  • raises End_of_file

    if chan is already at the end of the file.

  • raises Failure

    if the end of the file is reached during unmarshalling itself or if chan is not in binary mode.

val from_bytes : bytes -> int -> 'a

Marshal.from_bytes buff ofs unmarshals a structured value like Marshal.from_channel does, except that the byte representation is not read from a channel, but taken from the byte sequence buff, starting at position ofs. The byte sequence is not mutated.

  • since 4.02
val from_string : string -> int -> 'a

Same as from_bytes but take a string as argument instead of a byte sequence.

val header_size : int

The bytes representing a marshaled value are composed of a fixed-size header and a variable-sized data part, whose size can be determined from the header. Marshal.header_size is the size, in bytes, of the header. Marshal.data_size buff ofs is the size, in bytes, of the data part, assuming a valid header is stored in buff starting at position ofs. Finally, Marshal.total_size buff ofs is the total size, in bytes, of the marshaled value. Both Marshal.data_size and Marshal.total_size raise Failure if buff, ofs does not contain a valid header.

To read the byte representation of a marshaled value into a byte sequence, the program needs to read first Marshal.header_size bytes into the sequence, then determine the length of the remainder of the representation using Marshal.data_size, make sure the sequence is large enough to hold the remaining data, then read it, and finally call Marshal.from_bytes to unmarshal the value.

val data_size : bytes -> int -> int
val total_size : bytes -> int -> int
val compression_supported : unit -> bool

Indicates whether the compressed data format is supported.

If Marshal.compression_supported() is true, compressed data is unmarshaled safely by Stdlib.input_value, Marshal.from_channel, Marshal.from_string and related functions. Moreover, the Marshal.Compression flag is honored by the Marshal.to_channel, Marshal.to_string and related functions, resulting in the production of compressed data.

If Marshal.compression_supported() is false, compressed data causes Stdlib.input_value, Marshal.from_channel, Marshal.from_string and related functions to fail and a Failure exception to be raised. Moreover, Marshal.to_channel, Marshal.to_string and related functions ignore the Marshal.Compression flag and produce uncompressed data.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/argument-1-H/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/argument-1-H/index.html new file mode 100644 index 00000000..1f8db036 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.MoreLabels.Hashtbl.Make.H)

Parameter Make.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/index.html new file mode 100644 index 00000000..77791906 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.MoreLabels.Hashtbl.Make)

Module Hashtbl.Make

Functor building an implementation of the hashtable structure. The functor Hashtbl.Make returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the hashing and equality functions specified in the functor argument H instead of generic equality and hashing. Since the hash function is not seeded, the create operation of the result structure always returns non-randomized hash tables.

Parameters

module H : HashedType

Signature

type key = H.t
type 'a t = 'a Hashtbl.Make(H).t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
  • since 4.00
val copy : 'a t -> 'a t
val add : 'a t -> key:key -> data:'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key:key -> data:'a -> unit
val mem : 'a t -> key -> bool
val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit
val filter_map_inplace : f:(key:key -> data:'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : f:(key:key -> data:'a -> 'acc -> 'acc) -> 'a t -> init:'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
  • since 4.00
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/argument-1-H/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/argument-1-H/index.html new file mode 100644 index 00000000..e72b7a04 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.MoreLabels.Hashtbl.MakeSeeded.H)

Parameter MakeSeeded.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/index.html new file mode 100644 index 00000000..b6fb4149 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/MakeSeeded/index.html @@ -0,0 +1,2 @@ + +MakeSeeded (docs.stdlib.Stdlib.MoreLabels.Hashtbl.MakeSeeded)

Module Hashtbl.MakeSeeded

Functor building an implementation of the hashtable structure. The functor Hashtbl.MakeSeeded returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the seeded hashing and equality functions specified in the functor argument H instead of generic equality and hashing. The create operation of the result structure supports the ~random optional parameter and returns randomized hash tables if ~random:true is passed or if randomization is globally on (see Hashtbl.randomize).

  • since 4.00

Parameters

Signature

type key = H.t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key:key -> data:'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key:key -> data:'a -> unit
val mem : 'a t -> key -> bool
val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit
val filter_map_inplace : f:(key:key -> data:'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : f:(key:key -> data:'a -> 'acc -> 'acc) -> 'a t -> init:'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/index.html new file mode 100644 index 00000000..bcda6278 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/index.html @@ -0,0 +1,91 @@ + +Hashtbl (docs.stdlib.Stdlib.MoreLabels.Hashtbl)

Module MoreLabels.Hashtbl

Hash tables and hash functions.

Hash tables are hashed association tables, with in-place modification. Because most operations on a hash table modify their input, they're more commonly used in imperative code. The lookup of the value associated with a key (see find, find_opt) is normally very fast, often faster than the equivalent lookup in Map.

The functors Make and MakeSeeded can be used when performance or flexibility are key. The user provides custom equality and hash functions for the key type, and obtains a custom hash table type for this particular type of key.

Warning a hash table is only as good as the hash function. A bad hash function will turn the table into a degenerate association list, with linear time lookup instead of constant time lookup.

The polymorphic t hash table is useful in simpler cases or in interactive environments. It uses the polymorphic hash function defined in the OCaml runtime (at the time of writing, it's SipHash), as well as the polymorphic equality (=).

See the examples section.

Unsynchronized accesses

Unsynchronized accesses to a hash table may lead to an invalid hash table state. Thus, concurrent accesses to a hash tables must be synchronized (for instance with a Mutex.t).

Generic interface

type (!'a, !'b) t = ('a, 'b) Hashtbl.t

The type of hash tables from type 'a to type 'b.

val create : ?random:bool -> int -> ('a, 'b) t

Hashtbl.create n creates a new, empty hash table, with initial size n. For best results, n should be on the order of the expected number of elements that will be in the table. The table grows as needed, so n is just an initial guess.

The optional ~random parameter (a boolean) controls whether the internal organization of the hash table is randomized at each execution of Hashtbl.create or deterministic over all executions.

A hash table that is created with ~random set to false uses a fixed hash function (hash) to distribute keys among buckets. As a consequence, collisions between keys happen deterministically. In Web-facing applications or other security-sensitive applications, the deterministic collision patterns can be exploited by a malicious user to create a denial-of-service attack: the attacker sends input crafted to create many collisions in the table, slowing the application down.

A hash table that is created with ~random set to true uses the seeded hash function seeded_hash with a seed that is randomly chosen at hash table creation time. In effect, the hash function used is randomly selected among 2^{30} different hash functions. All these hash functions have different collision patterns, rendering ineffective the denial-of-service attack described above. However, because of randomization, enumerating all elements of the hash table using fold or iter is no longer deterministic: elements are enumerated in different orders at different runs of the program.

If no ~random parameter is given, hash tables are created in non-random mode by default. This default can be changed either programmatically by calling randomize or by setting the R flag in the OCAMLRUNPARAM environment variable.

  • before 4.00

    the ~random parameter was not present and all hash tables were created in non-randomized mode.

val clear : ('a, 'b) t -> unit

Empty a hash table. Use reset instead of clear to shrink the size of the bucket table to its initial size.

val reset : ('a, 'b) t -> unit

Empty a hash table and shrink the size of the bucket table to its initial size.

  • since 4.00
val copy : ('a, 'b) t -> ('a, 'b) t

Return a copy of the given hashtable.

val add : ('a, 'b) t -> key:'a -> data:'b -> unit

Hashtbl.add tbl ~key ~data adds a binding of key to data in table tbl.

Warning: Previous bindings for key are not removed, but simply hidden. That is, after performing remove tbl key, the previous binding for key, if any, is restored. (Same behavior as with association lists.)

If you desire the classic behavior of replacing elements, see replace.

val find : ('a, 'b) t -> 'a -> 'b

Hashtbl.find tbl x returns the current binding of x in tbl, or raises Not_found if no such binding exists.

val find_opt : ('a, 'b) t -> 'a -> 'b option

Hashtbl.find_opt tbl x returns the current binding of x in tbl, or None if no such binding exists.

  • since 4.05
val find_all : ('a, 'b) t -> 'a -> 'b list

Hashtbl.find_all tbl x returns the list of all data associated with x in tbl. The current binding is returned first, then the previous bindings, in reverse order of introduction in the table.

val mem : ('a, 'b) t -> 'a -> bool

Hashtbl.mem tbl x checks if x is bound in tbl.

val remove : ('a, 'b) t -> 'a -> unit

Hashtbl.remove tbl x removes the current binding of x in tbl, restoring the previous binding if it exists. It does nothing if x is not bound in tbl.

val replace : ('a, 'b) t -> key:'a -> data:'b -> unit

Hashtbl.replace tbl ~key ~data replaces the current binding of key in tbl by a binding of key to data. If key is unbound in tbl, a binding of key to data is added to tbl. This is functionally equivalent to remove tbl key followed by add tbl key data.

val iter : f:(key:'a -> data:'b -> unit) -> ('a, 'b) t -> unit

Hashtbl.iter ~f tbl applies f to all bindings in table tbl. f receives the key as first argument, and the associated value as second argument. Each binding is presented exactly once to f.

The order in which the bindings are passed to f is unspecified. However, if the table contains several bindings for the same key, they are passed to f in reverse order of introduction, that is, the most recent binding is passed first.

If the hash table was created in non-randomized mode, the order in which the bindings are enumerated is reproducible between successive runs of the program, and even between minor versions of OCaml. For randomized hash tables, the order of enumeration is entirely random.

The behavior is not specified if the hash table is modified by f during the iteration.

val filter_map_inplace : + f:(key:'a -> data:'b -> 'b option) -> + ('a, 'b) t -> + unit

Hashtbl.filter_map_inplace ~f tbl applies f to all bindings in table tbl and update each binding depending on the result of f. If f returns None, the binding is discarded. If it returns Some new_val, the binding is update to associate the key to new_val.

Other comments for iter apply as well.

  • since 4.03
val fold : + f:(key:'a -> data:'b -> 'acc -> 'acc) -> + ('a, 'b) t -> + init:'acc -> + 'acc

Hashtbl.fold ~f tbl ~init computes (f kN dN ... (f k1 d1 init)...), where k1 ... kN are the keys of all bindings in tbl, and d1 ... dN are the associated values. Each binding is presented exactly once to f.

The order in which the bindings are passed to f is unspecified. However, if the table contains several bindings for the same key, they are passed to f in reverse order of introduction, that is, the most recent binding is passed first.

If the hash table was created in non-randomized mode, the order in which the bindings are enumerated is reproducible between successive runs of the program, and even between minor versions of OCaml. For randomized hash tables, the order of enumeration is entirely random.

The behavior is not specified if the hash table is modified by f during the iteration.

val length : ('a, 'b) t -> int

Hashtbl.length tbl returns the number of bindings in tbl. It takes constant time. Multiple bindings are counted once each, so Hashtbl.length gives the number of times Hashtbl.iter calls its first argument.

val randomize : unit -> unit

After a call to Hashtbl.randomize(), hash tables are created in randomized mode by default: create returns randomized hash tables, unless the ~random:false optional parameter is given. The same effect can be achieved by setting the R parameter in the OCAMLRUNPARAM environment variable.

It is recommended that applications or Web frameworks that need to protect themselves against the denial-of-service attack described in create call Hashtbl.randomize() at initialization time before any domains are created.

Note that once Hashtbl.randomize() was called, there is no way to revert to the non-randomized default behavior of create. This is intentional. Non-randomized hash tables can still be created using Hashtbl.create ~random:false.

  • since 4.00
val is_randomized : unit -> bool

Return true if the tables are currently created in randomized mode by default, false otherwise.

  • since 4.03
val rebuild : ?random:bool -> ('a, 'b) t -> ('a, 'b) t

Return a copy of the given hashtable. Unlike copy, rebuild h re-hashes all the (key, value) entries of the original table h. The returned hash table is randomized if h was randomized, or the optional random parameter is true, or if the default is to create randomized hash tables; see create for more information.

rebuild can safely be used to import a hash table built by an old version of the Hashtbl module, then marshaled to persistent storage. After unmarshaling, apply rebuild to produce a hash table for the current version of the Hashtbl module.

  • since 4.12
type statistics = Hashtbl.statistics = {
  1. num_bindings : int;
    (*

    Number of bindings present in the table. Same value as returned by length.

    *)
  2. num_buckets : int;
    (*

    Number of buckets in the table.

    *)
  3. max_bucket_length : int;
    (*

    Maximal number of bindings per bucket.

    *)
  4. bucket_histogram : int array;
    (*

    Histogram of bucket sizes. This array histo has length max_bucket_length + 1. The value of histo.(i) is the number of buckets whose size is i.

    *)
}
  • since 4.00
val stats : ('a, 'b) t -> statistics

Hashtbl.stats tbl returns statistics about the table tbl: number of buckets, size of the biggest bucket, distribution of buckets by size.

  • since 4.00

Hash tables and Sequences

val to_seq : ('a, 'b) t -> ('a * 'b) Seq.t

Iterate on the whole table. The order in which the bindings appear in the sequence is unspecified. However, if the table contains several bindings for the same key, they appear in reversed order of introduction, that is, the most recent binding appears first.

The behavior is not specified if the hash table is modified during the iteration.

  • since 4.07
val to_seq_keys : ('a, _) t -> 'a Seq.t

Same as Seq.map fst (to_seq m)

  • since 4.07
val to_seq_values : (_, 'b) t -> 'b Seq.t

Same as Seq.map snd (to_seq m)

  • since 4.07
val add_seq : ('a, 'b) t -> ('a * 'b) Seq.t -> unit

Add the given bindings to the table, using add

  • since 4.07
val replace_seq : ('a, 'b) t -> ('a * 'b) Seq.t -> unit

Add the given bindings to the table, using replace

  • since 4.07
val of_seq : ('a * 'b) Seq.t -> ('a, 'b) t

Build a table from the given bindings. The bindings are added in the same order they appear in the sequence, using replace_seq, which means that if two pairs have the same key, only the latest one will appear in the table.

  • since 4.07

Functorial interface

The functorial interface allows the use of specific comparison and hash functions, either for performance/security concerns, or because keys are not hashable/comparable with the polymorphic builtins.

For instance, one might want to specialize a table for integer keys:

module IntHash =
+  struct
+    type t = int
+    let equal i j = i=j
+    let hash i = i land max_int
+  end
+
+module IntHashtbl = Hashtbl.Make(IntHash)
+
+let h = IntHashtbl.create 17 in
+IntHashtbl.add h 12 "hello"

This creates a new module IntHashtbl, with a new type 'a + IntHashtbl.t of tables from int to 'a. In this example, h contains string values so its type is string IntHashtbl.t.

Note that the new type 'a IntHashtbl.t is not compatible with the type ('a,'b) Hashtbl.t of the generic interface. For example, Hashtbl.length h would not type-check, you must use IntHashtbl.length.

module type HashedType = sig ... end

The input signature of the functor Make.

module type S = sig ... end

The output signature of the functor Make.

module Make + (H : HashedType) : + S with type key = H.t and type 'a t = 'a Hashtbl.Make(H).t

Functor building an implementation of the hashtable structure. The functor Hashtbl.Make returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the hashing and equality functions specified in the functor argument H instead of generic equality and hashing. Since the hash function is not seeded, the create operation of the result structure always returns non-randomized hash tables.

module type SeededHashedType = sig ... end

The input signature of the functor MakeSeeded.

module type SeededS = sig ... end

The output signature of the functor MakeSeeded.

module MakeSeeded + (H : SeededHashedType) : + SeededS with type key = H.t and type 'a t = 'a Hashtbl.MakeSeeded(H).t

Functor building an implementation of the hashtable structure. The functor Hashtbl.MakeSeeded returns a structure containing a type key of keys and a type 'a t of hash tables associating data of type 'a to keys of type key. The operations perform similarly to those of the generic interface, but use the seeded hashing and equality functions specified in the functor argument H instead of generic equality and hashing. The create operation of the result structure supports the ~random optional parameter and returns randomized hash tables if ~random:true is passed or if randomization is globally on (see Hashtbl.randomize).

The polymorphic hash functions

val hash : 'a -> int

Hashtbl.hash x associates a nonnegative integer to any value of any type. It is guaranteed that if x = y or Stdlib.compare x y = 0, then hash x = hash y. Moreover, hash always terminates, even on cyclic structures.

val seeded_hash : int -> 'a -> int

A variant of hash that is further parameterized by an integer seed.

  • since 4.00
val hash_param : int -> int -> 'a -> int

Hashtbl.hash_param meaningful total x computes a hash value for x, with the same properties as for hash. The two extra integer parameters meaningful and total give more precise control over hashing. Hashing performs a breadth-first, left-to-right traversal of the structure x, stopping after meaningful meaningful nodes were encountered, or total nodes (meaningful or not) were encountered. If total as specified by the user exceeds a certain value, currently 256, then it is capped to that value. Meaningful nodes are: integers; floating-point numbers; strings; characters; booleans; and constant constructors. Larger values of meaningful and total means that more nodes are taken into account to compute the final hash value, and therefore collisions are less likely to happen. However, hashing takes longer. The parameters meaningful and total govern the tradeoff between accuracy and speed. As default choices, hash and seeded_hash take meaningful = 10 and total = 100.

val seeded_hash_param : int -> int -> int -> 'a -> int

A variant of hash_param that is further parameterized by an integer seed. Usage: Hashtbl.seeded_hash_param meaningful total seed x.

  • since 4.00

Examples

Basic Example

(* 0...99 *)
+let seq = Seq.ints 0 |> Seq.take 100
+
+(* build from Seq.t *)
+# let tbl =
+    seq
+    |> Seq.map (fun x -> x, string_of_int x)
+    |> Hashtbl.of_seq
+val tbl : (int, string) Hashtbl.t = <abstr>
+
+# Hashtbl.length tbl
+- : int = 100
+
+# Hashtbl.find_opt tbl 32
+- : string option = Some "32"
+
+# Hashtbl.find_opt tbl 166
+- : string option = None
+
+# Hashtbl.replace tbl 166 "one six six"
+- : unit = ()
+
+# Hashtbl.find_opt tbl 166
+- : string option = Some "one six six"
+
+# Hashtbl.length tbl
+- : int = 101

Counting Elements

Given a sequence of elements (here, a Seq.t), we want to count how many times each distinct element occurs in the sequence. A simple way to do this, assuming the elements are comparable and hashable, is to use a hash table that maps elements to their number of occurrences.

Here we illustrate that principle using a sequence of (ascii) characters (type char). We use a custom Char_tbl specialized for char.

# module Char_tbl = Hashtbl.Make(struct
+    type t = char
+    let equal = Char.equal
+    let hash = Hashtbl.hash
+  end)
+
+(*  count distinct occurrences of chars in [seq] *)
+# let count_chars (seq : char Seq.t) : _ list =
+    let counts = Char_tbl.create 16 in
+    Seq.iter
+      (fun c ->
+        let count_c =
+          Char_tbl.find_opt counts c
+          |> Option.value ~default:0
+        in
+        Char_tbl.replace counts c (count_c + 1))
+      seq;
+    (* turn into a list *)
+    Char_tbl.fold (fun c n l -> (c,n) :: l) counts []
+      |> List.sort (fun (c1,_)(c2,_) -> Char.compare c1 c2)
+val count_chars : Char_tbl.key Seq.t -> (Char.t * int) list = <fun>
+
+(* basic seq from a string *)
+# let seq = String.to_seq "hello world, and all the camels in it!"
+val seq : char Seq.t = <fun>
+
+# count_chars seq
+- : (Char.t * int) list =
+[(' ', 7); ('!', 1); (',', 1); ('a', 3); ('c', 1); ('d', 2); ('e', 3);
+ ('h', 2); ('i', 2); ('l', 6); ('m', 1); ('n', 2); ('o', 2); ('r', 1);
+ ('s', 1); ('t', 2); ('w', 1)]
+
+(* "abcabcabc..." *)
+# let seq2 =
+    Seq.cycle (String.to_seq "abc") |> Seq.take 31
+val seq2 : char Seq.t = <fun>
+
+# String.of_seq seq2
+- : String.t = "abcabcabcabcabcabcabcabcabcabca"
+
+# count_chars seq2
+- : (Char.t * int) list = [('a', 11); ('b', 10); ('c', 10)]
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-HashedType/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-HashedType/index.html new file mode 100644 index 00000000..44b38ce0 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-HashedType/index.html @@ -0,0 +1,2 @@ + +HashedType (docs.stdlib.Stdlib.MoreLabels.Hashtbl.HashedType)

Module type Hashtbl.HashedType

The input signature of the functor Make.

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-S/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-S/index.html new file mode 100644 index 00000000..cfb9751f --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-S/index.html @@ -0,0 +1,2 @@ + +S (docs.stdlib.Stdlib.MoreLabels.Hashtbl.S)

Module type Hashtbl.S

The output signature of the functor Make.

type key
type !'a t
val create : int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
  • since 4.00
val copy : 'a t -> 'a t
val add : 'a t -> key:key -> data:'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key:key -> data:'a -> unit
val mem : 'a t -> key -> bool
val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit
val filter_map_inplace : f:(key:key -> data:'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : f:(key:key -> data:'a -> 'acc -> 'acc) -> 'a t -> init:'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
  • since 4.00
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededHashedType/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededHashedType/index.html new file mode 100644 index 00000000..f2ab0876 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededHashedType/index.html @@ -0,0 +1,2 @@ + +SeededHashedType (docs.stdlib.Stdlib.MoreLabels.Hashtbl.SeededHashedType)

Module type Hashtbl.SeededHashedType

The input signature of the functor MakeSeeded.

  • since 4.00
type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val seeded_hash : int -> t -> int

A seeded hashing function on keys. The first argument is the seed. It must be the case that if equal x y is true, then seeded_hash seed x = seeded_hash seed y for any value of seed. A suitable choice for seeded_hash is the function Hashtbl.seeded_hash below.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededS/index.html b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededS/index.html new file mode 100644 index 00000000..dfad5cca --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Hashtbl/module-type-SeededS/index.html @@ -0,0 +1,2 @@ + +SeededS (docs.stdlib.Stdlib.MoreLabels.Hashtbl.SeededS)

Module type Hashtbl.SeededS

The output signature of the functor MakeSeeded.

  • since 4.00
type key
type !'a t
val create : ?random:bool -> int -> 'a t
val clear : 'a t -> unit
val reset : 'a t -> unit
val copy : 'a t -> 'a t
val add : 'a t -> key:key -> data:'a -> unit
val remove : 'a t -> key -> unit
val find : 'a t -> key -> 'a
val find_opt : 'a t -> key -> 'a option
  • since 4.05
val find_all : 'a t -> key -> 'a list
val replace : 'a t -> key:key -> data:'a -> unit
val mem : 'a t -> key -> bool
val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit
val filter_map_inplace : f:(key:key -> data:'a -> 'a option) -> 'a t -> unit
  • since 4.03
val fold : f:(key:key -> data:'a -> 'acc -> 'acc) -> 'a t -> init:'acc -> 'acc
val length : 'a t -> int
val stats : 'a t -> statistics
val to_seq : 'a t -> (key * 'a) Seq.t
  • since 4.07
val to_seq_keys : _ t -> key Seq.t
  • since 4.07
val to_seq_values : 'a t -> 'a Seq.t
  • since 4.07
val add_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val replace_seq : 'a t -> (key * 'a) Seq.t -> unit
  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t
  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Map/Make/argument-1-Ord/index.html b/docs/stdlib/Stdlib/MoreLabels/Map/Make/argument-1-Ord/index.html new file mode 100644 index 00000000..6f78db6c --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Map/Make/argument-1-Ord/index.html @@ -0,0 +1,2 @@ + +Ord (docs.stdlib.Stdlib.MoreLabels.Map.Make.Ord)

Parameter Make.Ord

type t

The type of the map keys.

val compare : t -> t -> int

A total ordering function over the keys. This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Map/Make/index.html b/docs/stdlib/Stdlib/MoreLabels/Map/Make/index.html new file mode 100644 index 00000000..03764b0e --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Map/Make/index.html @@ -0,0 +1,8 @@ + +Make (docs.stdlib.Stdlib.MoreLabels.Map.Make)

Module Map.Make

Functor building an implementation of the map structure given a totally ordered type.

Parameters

module Ord : OrderedType

Signature

Maps

type key = Ord.t

The type of the map keys.

type 'a t = 'a Map.Make(Ord).t

The type of maps from type key to type 'a.

val empty : 'a t

The empty map.

val add : key:key -> data:'a -> 'a t -> 'a t

add ~key ~data m returns a map containing the same bindings as m, plus a binding of key to data. If key was already bound in m to a value that is physically equal to data, m is returned unchanged (the result of the function is then physically equal to m). Otherwise, the previous binding of key in m disappears.

  • before 4.03

    Physical equality was not ensured.

val add_to_list : key:key -> data:'a -> 'a list t -> 'a list t

add_to_list ~key ~data m is m with key mapped to l such that l is data :: Map.find key m if key was bound in m and [v] otherwise.

  • since 5.1
val update : key:key -> f:('a option -> 'a option) -> 'a t -> 'a t

update ~key ~f m returns a map containing the same bindings as m, except for the binding of key. Depending on the value of y where y is f (find_opt key m), the binding of key is added, removed or updated. If y is None, the binding is removed if it exists; otherwise, if y is Some z then key is associated to z in the resulting map. If key was already bound in m to a value that is physically equal to z, m is returned unchanged (the result of the function is then physically equal to m).

  • since 4.06
val singleton : key -> 'a -> 'a t

singleton x y returns the one-element map that contains a binding y for x.

  • since 3.12
val remove : key -> 'a t -> 'a t

remove x m returns a map containing the same bindings as m, except for x which is unbound in the returned map. If x was not in m, m is returned unchanged (the result of the function is then physically equal to m).

  • before 4.03

    Physical equality was not ensured.

val merge : + f:(key -> 'a option -> 'b option -> 'c option) -> + 'a t -> + 'b t -> + 'c t

merge ~f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. The presence of each such binding, and the corresponding value, is determined with the function f. In terms of the find_opt operation, we have find_opt x (merge f m1 m2) = f x (find_opt x m1) (find_opt x m2) for any key x, provided that f x None None = None.

  • since 3.12
val union : f:(key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t

union ~f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. When the same binding is defined in both arguments, the function f is used to combine them. This is a special case of merge: union f m1 m2 is equivalent to merge f' m1 m2, where

  • f' _key None None = None
  • f' _key (Some v) None = Some v
  • f' _key None (Some v) = Some v
  • f' key (Some v1) (Some v2) = f key v1 v2
  • since 4.03
val cardinal : 'a t -> int

Return the number of bindings of a map.

  • since 3.12

Bindings

val bindings : 'a t -> (key * 'a) list

Return the list of all bindings of the given map. The returned list is sorted in increasing order of keys with respect to the ordering Ord.compare, where Ord is the argument given to Map.Make.

  • since 3.12
val min_binding : 'a t -> key * 'a

Return the binding with the smallest key in a given map (with respect to the Ord.compare ordering), or raise Not_found if the map is empty.

  • since 3.12
val min_binding_opt : 'a t -> (key * 'a) option

Return the binding with the smallest key in the given map (with respect to the Ord.compare ordering), or None if the map is empty.

  • since 4.05
val max_binding : 'a t -> key * 'a

Same as min_binding, but returns the binding with the largest key in the given map.

  • since 3.12
val max_binding_opt : 'a t -> (key * 'a) option

Same as min_binding_opt, but returns the binding with the largest key in the given map.

  • since 4.05
val choose : 'a t -> key * 'a

Return one binding of the given map, or raise Not_found if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 3.12
val choose_opt : 'a t -> (key * 'a) option

Return one binding of the given map, or None if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 4.05

Searching

val find : key -> 'a t -> 'a

find x m returns the current value of x in m, or raises Not_found if no binding for x exists.

val find_opt : key -> 'a t -> 'a option

find_opt x m returns Some v if the current value of x in m is v, or None if no binding for x exists.

  • since 4.05
val find_first : f:(key -> bool) -> 'a t -> key * 'a

find_first ~f m, where f is a monotonically increasing function, returns the binding of m with the lowest key k such that f k, or raises Not_found if no such key exists.

For example, find_first (fun k -> Ord.compare k x >= 0) m will return the first binding k, v of m where Ord.compare k x >= 0 (intuitively: k >= x), or raise Not_found if x is greater than any element of m.

  • since 4.05
val find_first_opt : f:(key -> bool) -> 'a t -> (key * 'a) option

find_first_opt ~f m, where f is a monotonically increasing function, returns an option containing the binding of m with the lowest key k such that f k, or None if no such key exists.

  • since 4.05
val find_last : f:(key -> bool) -> 'a t -> key * 'a

find_last ~f m, where f is a monotonically decreasing function, returns the binding of m with the highest key k such that f k, or raises Not_found if no such key exists.

  • since 4.05
val find_last_opt : f:(key -> bool) -> 'a t -> (key * 'a) option

find_last_opt ~f m, where f is a monotonically decreasing function, returns an option containing the binding of m with the highest key k such that f k, or None if no such key exists.

  • since 4.05

Traversing

val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit

iter ~f m applies f to all bindings in map m. f receives the key as first argument, and the associated value as second argument. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val fold : f:(key:key -> data:'a -> 'acc -> 'acc) -> 'a t -> init:'acc -> 'acc

fold ~f m ~init computes (f kN dN ... (f k1 d1 init)...), where k1 ... kN are the keys of all bindings in m (in increasing order), and d1 ... dN are the associated data.

Transforming

val map : f:('a -> 'b) -> 'a t -> 'b t

map ~f m returns a map with same domain as m, where the associated value a of all bindings of m has been replaced by the result of the application of f to a. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t

Same as map, but the function receives as arguments both the key and the associated value for each binding of the map.

val filter : f:(key -> 'a -> bool) -> 'a t -> 'a t

filter ~f m returns the map with all the bindings in m that satisfy predicate p. If every binding in m satisfies f, m is returned unchanged (the result of the function is then physically equal to m)

  • since 3.12
  • before 4.03

    Physical equality was not ensured.

val filter_map : f:(key -> 'a -> 'b option) -> 'a t -> 'b t

filter_map ~f m applies the function f to every binding of m, and builds a map from the results. For each binding (k, v) in the input map:

  • if f k v is None then k is not in the result,
  • if f k v is Some v' then the binding (k, v') is in the output map.

For example, the following function on maps whose values are lists

filter_map
+  (fun _k li -> match li with [] -> None | _::tl -> Some tl)
+  m

drops all bindings of m whose value is an empty list, and pops the first element of each value that is non-empty.

  • since 4.11
val partition : f:(key -> 'a -> bool) -> 'a t -> 'a t * 'a t

partition ~f m returns a pair of maps (m1, m2), where m1 contains all the bindings of m that satisfy the predicate f, and m2 is the map with all the bindings of m that do not satisfy f.

  • since 3.12
val split : key -> 'a t -> 'a t * 'a option * 'a t

split x m returns a triple (l, data, r), where l is the map with all the bindings of m whose key is strictly less than x; r is the map with all the bindings of m whose key is strictly greater than x; data is None if m contains no binding for x, or Some v if m binds v to x.

  • since 3.12

Predicates and comparisons

val is_empty : 'a t -> bool

Test whether a map is empty or not.

val mem : key -> 'a t -> bool

mem x m returns true if m contains a binding for x, and false otherwise.

val equal : cmp:('a -> 'a -> bool) -> 'a t -> 'a t -> bool

equal ~cmp m1 m2 tests whether the maps m1 and m2 are equal, that is, contain equal keys and associate them with equal data. cmp is the equality predicate used to compare the data associated with the keys.

val compare : cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int

Total ordering between maps. The first argument is a total ordering used to compare data associated with equal keys in the two maps.

val for_all : f:(key -> 'a -> bool) -> 'a t -> bool

for_all ~f m checks if all the bindings of the map satisfy the predicate f.

  • since 3.12
val exists : f:(key -> 'a -> bool) -> 'a t -> bool

exists ~f m checks if at least one binding of the map satisfies the predicate f.

  • since 3.12

Converting

val to_list : 'a t -> (key * 'a) list

to_list m is bindings m.

  • since 5.1
val of_list : (key * 'a) list -> 'a t

of_list bs adds the bindings of bs to the empty map, in list order (if a key is bound twice in bs the last one takes over).

  • since 5.1
val to_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in ascending order of keys

  • since 4.07
val to_rev_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in descending order of keys

  • since 4.12
val to_seq_from : key -> 'a t -> (key * 'a) Seq.t

to_seq_from k m iterates on a subset of the bindings of m, in ascending order of keys, from key k or above.

  • since 4.07
val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t

Add the given bindings to the map, in order.

  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t

Build a map from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Map/index.html b/docs/stdlib/Stdlib/MoreLabels/Map/index.html new file mode 100644 index 00000000..a292b972 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Map/index.html @@ -0,0 +1,15 @@ + +Map (docs.stdlib.Stdlib.MoreLabels.Map)

Module MoreLabels.Map

Association tables over ordered types.

This module implements applicative association tables, also known as finite maps or dictionaries, given a total ordering function over the keys. All operations over maps are purely applicative (no side-effects). The implementation uses balanced binary trees, and therefore searching and insertion take time logarithmic in the size of the map.

For instance:

module IntPairs =
+  struct
+    type t = int * int
+    let compare (x0,y0) (x1,y1) =
+      match Stdlib.compare x0 x1 with
+          0 -> Stdlib.compare y0 y1
+        | c -> c
+  end
+
+module PairsMap = Map.Make(IntPairs)
+
+let m = PairsMap.(empty |> add (0,1) "hello" |> add (1,0) "world")

This creates a new module PairsMap, with a new type 'a PairsMap.t of maps from int * int to 'a. In this example, m contains string values so its type is string PairsMap.t.

module type OrderedType = sig ... end

Input signature of the functor Make.

module type S = sig ... end

Output signature of the functor Make.

module Make + (Ord : OrderedType) : + S with type key = Ord.t and type 'a t = 'a Map.Make(Ord).t

Functor building an implementation of the map structure given a totally ordered type.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Map/module-type-OrderedType/index.html b/docs/stdlib/Stdlib/MoreLabels/Map/module-type-OrderedType/index.html new file mode 100644 index 00000000..7cfce626 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Map/module-type-OrderedType/index.html @@ -0,0 +1,2 @@ + +OrderedType (docs.stdlib.Stdlib.MoreLabels.Map.OrderedType)

Module type Map.OrderedType

Input signature of the functor Make.

type t

The type of the map keys.

val compare : t -> t -> int

A total ordering function over the keys. This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Map/module-type-S/index.html b/docs/stdlib/Stdlib/MoreLabels/Map/module-type-S/index.html new file mode 100644 index 00000000..e06a9fb2 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Map/module-type-S/index.html @@ -0,0 +1,8 @@ + +S (docs.stdlib.Stdlib.MoreLabels.Map.S)

Module type Map.S

Output signature of the functor Make.

Maps

type key

The type of the map keys.

type !+'a t

The type of maps from type key to type 'a.

val empty : 'a t

The empty map.

val add : key:key -> data:'a -> 'a t -> 'a t

add ~key ~data m returns a map containing the same bindings as m, plus a binding of key to data. If key was already bound in m to a value that is physically equal to data, m is returned unchanged (the result of the function is then physically equal to m). Otherwise, the previous binding of key in m disappears.

  • before 4.03

    Physical equality was not ensured.

val add_to_list : key:key -> data:'a -> 'a list t -> 'a list t

add_to_list ~key ~data m is m with key mapped to l such that l is data :: Map.find key m if key was bound in m and [v] otherwise.

  • since 5.1
val update : key:key -> f:('a option -> 'a option) -> 'a t -> 'a t

update ~key ~f m returns a map containing the same bindings as m, except for the binding of key. Depending on the value of y where y is f (find_opt key m), the binding of key is added, removed or updated. If y is None, the binding is removed if it exists; otherwise, if y is Some z then key is associated to z in the resulting map. If key was already bound in m to a value that is physically equal to z, m is returned unchanged (the result of the function is then physically equal to m).

  • since 4.06
val singleton : key -> 'a -> 'a t

singleton x y returns the one-element map that contains a binding y for x.

  • since 3.12
val remove : key -> 'a t -> 'a t

remove x m returns a map containing the same bindings as m, except for x which is unbound in the returned map. If x was not in m, m is returned unchanged (the result of the function is then physically equal to m).

  • before 4.03

    Physical equality was not ensured.

val merge : + f:(key -> 'a option -> 'b option -> 'c option) -> + 'a t -> + 'b t -> + 'c t

merge ~f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. The presence of each such binding, and the corresponding value, is determined with the function f. In terms of the find_opt operation, we have find_opt x (merge f m1 m2) = f x (find_opt x m1) (find_opt x m2) for any key x, provided that f x None None = None.

  • since 3.12
val union : f:(key -> 'a -> 'a -> 'a option) -> 'a t -> 'a t -> 'a t

union ~f m1 m2 computes a map whose keys are a subset of the keys of m1 and of m2. When the same binding is defined in both arguments, the function f is used to combine them. This is a special case of merge: union f m1 m2 is equivalent to merge f' m1 m2, where

  • f' _key None None = None
  • f' _key (Some v) None = Some v
  • f' _key None (Some v) = Some v
  • f' key (Some v1) (Some v2) = f key v1 v2
  • since 4.03
val cardinal : 'a t -> int

Return the number of bindings of a map.

  • since 3.12

Bindings

val bindings : 'a t -> (key * 'a) list

Return the list of all bindings of the given map. The returned list is sorted in increasing order of keys with respect to the ordering Ord.compare, where Ord is the argument given to Map.Make.

  • since 3.12
val min_binding : 'a t -> key * 'a

Return the binding with the smallest key in a given map (with respect to the Ord.compare ordering), or raise Not_found if the map is empty.

  • since 3.12
val min_binding_opt : 'a t -> (key * 'a) option

Return the binding with the smallest key in the given map (with respect to the Ord.compare ordering), or None if the map is empty.

  • since 4.05
val max_binding : 'a t -> key * 'a

Same as min_binding, but returns the binding with the largest key in the given map.

  • since 3.12
val max_binding_opt : 'a t -> (key * 'a) option

Same as min_binding_opt, but returns the binding with the largest key in the given map.

  • since 4.05
val choose : 'a t -> key * 'a

Return one binding of the given map, or raise Not_found if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 3.12
val choose_opt : 'a t -> (key * 'a) option

Return one binding of the given map, or None if the map is empty. Which binding is chosen is unspecified, but equal bindings will be chosen for equal maps.

  • since 4.05

Searching

val find : key -> 'a t -> 'a

find x m returns the current value of x in m, or raises Not_found if no binding for x exists.

val find_opt : key -> 'a t -> 'a option

find_opt x m returns Some v if the current value of x in m is v, or None if no binding for x exists.

  • since 4.05
val find_first : f:(key -> bool) -> 'a t -> key * 'a

find_first ~f m, where f is a monotonically increasing function, returns the binding of m with the lowest key k such that f k, or raises Not_found if no such key exists.

For example, find_first (fun k -> Ord.compare k x >= 0) m will return the first binding k, v of m where Ord.compare k x >= 0 (intuitively: k >= x), or raise Not_found if x is greater than any element of m.

  • since 4.05
val find_first_opt : f:(key -> bool) -> 'a t -> (key * 'a) option

find_first_opt ~f m, where f is a monotonically increasing function, returns an option containing the binding of m with the lowest key k such that f k, or None if no such key exists.

  • since 4.05
val find_last : f:(key -> bool) -> 'a t -> key * 'a

find_last ~f m, where f is a monotonically decreasing function, returns the binding of m with the highest key k such that f k, or raises Not_found if no such key exists.

  • since 4.05
val find_last_opt : f:(key -> bool) -> 'a t -> (key * 'a) option

find_last_opt ~f m, where f is a monotonically decreasing function, returns an option containing the binding of m with the highest key k such that f k, or None if no such key exists.

  • since 4.05

Traversing

val iter : f:(key:key -> data:'a -> unit) -> 'a t -> unit

iter ~f m applies f to all bindings in map m. f receives the key as first argument, and the associated value as second argument. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val fold : f:(key:key -> data:'a -> 'acc -> 'acc) -> 'a t -> init:'acc -> 'acc

fold ~f m ~init computes (f kN dN ... (f k1 d1 init)...), where k1 ... kN are the keys of all bindings in m (in increasing order), and d1 ... dN are the associated data.

Transforming

val map : f:('a -> 'b) -> 'a t -> 'b t

map ~f m returns a map with same domain as m, where the associated value a of all bindings of m has been replaced by the result of the application of f to a. The bindings are passed to f in increasing order with respect to the ordering over the type of the keys.

val mapi : f:(key -> 'a -> 'b) -> 'a t -> 'b t

Same as map, but the function receives as arguments both the key and the associated value for each binding of the map.

val filter : f:(key -> 'a -> bool) -> 'a t -> 'a t

filter ~f m returns the map with all the bindings in m that satisfy predicate p. If every binding in m satisfies f, m is returned unchanged (the result of the function is then physically equal to m)

  • since 3.12
  • before 4.03

    Physical equality was not ensured.

val filter_map : f:(key -> 'a -> 'b option) -> 'a t -> 'b t

filter_map ~f m applies the function f to every binding of m, and builds a map from the results. For each binding (k, v) in the input map:

  • if f k v is None then k is not in the result,
  • if f k v is Some v' then the binding (k, v') is in the output map.

For example, the following function on maps whose values are lists

filter_map
+  (fun _k li -> match li with [] -> None | _::tl -> Some tl)
+  m

drops all bindings of m whose value is an empty list, and pops the first element of each value that is non-empty.

  • since 4.11
val partition : f:(key -> 'a -> bool) -> 'a t -> 'a t * 'a t

partition ~f m returns a pair of maps (m1, m2), where m1 contains all the bindings of m that satisfy the predicate f, and m2 is the map with all the bindings of m that do not satisfy f.

  • since 3.12
val split : key -> 'a t -> 'a t * 'a option * 'a t

split x m returns a triple (l, data, r), where l is the map with all the bindings of m whose key is strictly less than x; r is the map with all the bindings of m whose key is strictly greater than x; data is None if m contains no binding for x, or Some v if m binds v to x.

  • since 3.12

Predicates and comparisons

val is_empty : 'a t -> bool

Test whether a map is empty or not.

val mem : key -> 'a t -> bool

mem x m returns true if m contains a binding for x, and false otherwise.

val equal : cmp:('a -> 'a -> bool) -> 'a t -> 'a t -> bool

equal ~cmp m1 m2 tests whether the maps m1 and m2 are equal, that is, contain equal keys and associate them with equal data. cmp is the equality predicate used to compare the data associated with the keys.

val compare : cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int

Total ordering between maps. The first argument is a total ordering used to compare data associated with equal keys in the two maps.

val for_all : f:(key -> 'a -> bool) -> 'a t -> bool

for_all ~f m checks if all the bindings of the map satisfy the predicate f.

  • since 3.12
val exists : f:(key -> 'a -> bool) -> 'a t -> bool

exists ~f m checks if at least one binding of the map satisfies the predicate f.

  • since 3.12

Converting

val to_list : 'a t -> (key * 'a) list

to_list m is bindings m.

  • since 5.1
val of_list : (key * 'a) list -> 'a t

of_list bs adds the bindings of bs to the empty map, in list order (if a key is bound twice in bs the last one takes over).

  • since 5.1
val to_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in ascending order of keys

  • since 4.07
val to_rev_seq : 'a t -> (key * 'a) Seq.t

Iterate on the whole map, in descending order of keys

  • since 4.12
val to_seq_from : key -> 'a t -> (key * 'a) Seq.t

to_seq_from k m iterates on a subset of the bindings of m, in ascending order of keys, from key k or above.

  • since 4.07
val add_seq : (key * 'a) Seq.t -> 'a t -> 'a t

Add the given bindings to the map, in order.

  • since 4.07
val of_seq : (key * 'a) Seq.t -> 'a t

Build a map from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Set/Make/argument-1-Ord/index.html b/docs/stdlib/Stdlib/MoreLabels/Set/Make/argument-1-Ord/index.html new file mode 100644 index 00000000..ca5b59df --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Set/Make/argument-1-Ord/index.html @@ -0,0 +1,2 @@ + +Ord (docs.stdlib.Stdlib.MoreLabels.Set.Make.Ord)

Parameter Make.Ord

type t

The type of the set elements.

val compare : t -> t -> int

A total ordering function over the set elements. This is a two-argument function f such that f e1 e2 is zero if the elements e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Set/Make/index.html b/docs/stdlib/Stdlib/MoreLabels/Set/Make/index.html new file mode 100644 index 00000000..ed2d5914 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Set/Make/index.html @@ -0,0 +1,3 @@ + +Make (docs.stdlib.Stdlib.MoreLabels.Set.Make)

Module Set.Make

Functor building an implementation of the set structure given a totally ordered type.

Parameters

module Ord : OrderedType

Signature

Sets

type elt = Ord.t

The type of the set elements.

The type of sets.

val empty : t

The empty set.

val add : elt -> t -> t

add x s returns a set containing all elements of s, plus x. If x was already in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val singleton : elt -> t

singleton x returns the one-element set containing only x.

val remove : elt -> t -> t

remove x s returns a set containing all elements of s, except x. If x was not in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val union : t -> t -> t

Set union.

val inter : t -> t -> t

Set intersection.

val disjoint : t -> t -> bool

Test if two sets are disjoint.

  • since 4.08
val diff : t -> t -> t

Set difference: diff s1 s2 contains the elements of s1 that are not in s2.

val cardinal : t -> int

Return the number of elements of a set.

Elements

val elements : t -> elt list

Return the list of all elements of the given set. The returned list is sorted in increasing order with respect to the ordering Ord.compare, where Ord is the argument given to Set.Make.

val min_elt : t -> elt

Return the smallest element of the given set (with respect to the Ord.compare ordering), or raise Not_found if the set is empty.

val min_elt_opt : t -> elt option

Return the smallest element of the given set (with respect to the Ord.compare ordering), or None if the set is empty.

  • since 4.05
val max_elt : t -> elt

Same as min_elt, but returns the largest element of the given set.

val max_elt_opt : t -> elt option

Same as min_elt_opt, but returns the largest element of the given set.

  • since 4.05
val choose : t -> elt

Return one element of the given set, or raise Not_found if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

val choose_opt : t -> elt option

Return one element of the given set, or None if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

  • since 4.05

Searching

val find : elt -> t -> elt

find x s returns the element of s equal to x (according to Ord.compare), or raise Not_found if no such element exists.

  • since 4.01
val find_opt : elt -> t -> elt option

find_opt x s returns the element of s equal to x (according to Ord.compare), or None if no such element exists.

  • since 4.05
val find_first : f:(elt -> bool) -> t -> elt

find_first ~f s, where f is a monotonically increasing function, returns the lowest element e of s such that f e, or raises Not_found if no such element exists.

For example, find_first (fun e -> Ord.compare e x >= 0) s will return the first element e of s where Ord.compare e x >= 0 (intuitively: e >= x), or raise Not_found if x is greater than any element of s.

  • since 4.05
val find_first_opt : f:(elt -> bool) -> t -> elt option

find_first_opt ~f s, where f is a monotonically increasing function, returns an option containing the lowest element e of s such that f e, or None if no such element exists.

  • since 4.05
val find_last : f:(elt -> bool) -> t -> elt

find_last ~f s, where f is a monotonically decreasing function, returns the highest element e of s such that f e, or raises Not_found if no such element exists.

  • since 4.05
val find_last_opt : f:(elt -> bool) -> t -> elt option

find_last_opt ~f s, where f is a monotonically decreasing function, returns an option containing the highest element e of s such that f e, or None if no such element exists.

  • since 4.05

Traversing

val iter : f:(elt -> unit) -> t -> unit

iter ~f s applies f in turn to all elements of s. The elements of s are presented to f in increasing order with respect to the ordering over the type of the elements.

val fold : f:(elt -> 'acc -> 'acc) -> t -> init:'acc -> 'acc

fold ~f s init computes (f xN ... (f x2 (f x1 init))...), where x1 ... xN are the elements of s, in increasing order.

Transforming

val map : f:(elt -> elt) -> t -> t

map ~f s is the set whose elements are f a0,f a1... f + aN, where a0,a1...aN are the elements of s.

The elements are passed to f in increasing order with respect to the ordering over the type of the elements.

If no element of s is changed by f, s is returned unchanged. (If each output of f is physically equal to its input, the returned set is physically equal to s.)

  • since 4.04
val filter : f:(elt -> bool) -> t -> t

filter ~f s returns the set of all elements in s that satisfy predicate f. If f satisfies every element in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val filter_map : f:(elt -> elt option) -> t -> t

filter_map ~f s returns the set of all v such that f x = Some v for some element x of s.

For example,

filter_map (fun n -> if n mod 2 = 0 then Some (n / 2) else None) s

is the set of halves of the even elements of s.

If no element of s is changed or dropped by f (if f x = Some x for each element x), then s is returned unchanged: the result of the function is then physically equal to s.

  • since 4.11
val partition : f:(elt -> bool) -> t -> t * t

partition ~f s returns a pair of sets (s1, s2), where s1 is the set of all the elements of s that satisfy the predicate f, and s2 is the set of all the elements of s that do not satisfy f.

val split : elt -> t -> t * bool * t

split x s returns a triple (l, present, r), where l is the set of elements of s that are strictly less than x; r is the set of elements of s that are strictly greater than x; present is false if s contains no element equal to x, or true if s contains an element equal to x.

Predicates and comparisons

val is_empty : t -> bool

Test whether a set is empty or not.

val mem : elt -> t -> bool

mem x s tests whether x belongs to the set s.

val equal : t -> t -> bool

equal s1 s2 tests whether the sets s1 and s2 are equal, that is, contain equal elements.

val compare : t -> t -> int

Total ordering between sets. Can be used as the ordering function for doing sets of sets.

val subset : t -> t -> bool

subset s1 s2 tests whether the set s1 is a subset of the set s2.

val for_all : f:(elt -> bool) -> t -> bool

for_all ~f s checks if all elements of the set satisfy the predicate f.

val exists : f:(elt -> bool) -> t -> bool

exists ~f s checks if at least one element of the set satisfies the predicate f.

Converting

val to_list : t -> elt list

to_list s is elements s.

  • since 5.1
val of_list : elt list -> t

of_list l creates a set from a list of elements. This is usually more efficient than folding add over the list, except perhaps for lists with many duplicated elements.

  • since 4.02
val to_seq_from : elt -> t -> elt Seq.t

to_seq_from x s iterates on a subset of the elements of s in ascending order, from x or above.

  • since 4.07
val to_seq : t -> elt Seq.t

Iterate on the whole set, in ascending order

  • since 4.07
val to_rev_seq : t -> elt Seq.t

Iterate on the whole set, in descending order

  • since 4.12
val add_seq : elt Seq.t -> t -> t

Add the given elements to the set, in order.

  • since 4.07
val of_seq : elt Seq.t -> t

Build a set from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/Set/index.html b/docs/stdlib/Stdlib/MoreLabels/Set/index.html new file mode 100644 index 00000000..3f22286a --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Set/index.html @@ -0,0 +1,15 @@ + +Set (docs.stdlib.Stdlib.MoreLabels.Set)

Module MoreLabels.Set

Sets over ordered types.

This module implements the set data structure, given a total ordering function over the set elements. All operations over sets are purely applicative (no side-effects). The implementation uses balanced binary trees, and is therefore reasonably efficient: insertion and membership take time logarithmic in the size of the set, for instance.

The Make functor constructs implementations for any type, given a compare function. For instance:

module IntPairs =
+  struct
+    type t = int * int
+    let compare (x0,y0) (x1,y1) =
+      match Stdlib.compare x0 x1 with
+          0 -> Stdlib.compare y0 y1
+        | c -> c
+  end
+
+module PairsSet = Set.Make(IntPairs)
+
+let m = PairsSet.(empty |> add (2,3) |> add (5,7) |> add (11,13))

This creates a new module PairsSet, with a new type PairsSet.t of sets of int * int.

module type OrderedType = sig ... end

Input signature of the functor Make.

module type S = sig ... end

Output signature of the functor Make.

module Make + (Ord : OrderedType) : + S with type elt = Ord.t and type t = Set.Make(Ord).t

Functor building an implementation of the set structure given a totally ordered type.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Set/module-type-OrderedType/index.html b/docs/stdlib/Stdlib/MoreLabels/Set/module-type-OrderedType/index.html new file mode 100644 index 00000000..aaeadfd5 --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Set/module-type-OrderedType/index.html @@ -0,0 +1,2 @@ + +OrderedType (docs.stdlib.Stdlib.MoreLabels.Set.OrderedType)

Module type Set.OrderedType

Input signature of the functor Make.

type t

The type of the set elements.

val compare : t -> t -> int

A total ordering function over the set elements. This is a two-argument function f such that f e1 e2 is zero if the elements e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/MoreLabels/Set/module-type-S/index.html b/docs/stdlib/Stdlib/MoreLabels/Set/module-type-S/index.html new file mode 100644 index 00000000..141eb18a --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/Set/module-type-S/index.html @@ -0,0 +1,3 @@ + +S (docs.stdlib.Stdlib.MoreLabels.Set.S)

Module type Set.S

Output signature of the functor Make.

Sets

type elt

The type of the set elements.

type t

The type of sets.

val empty : t

The empty set.

val add : elt -> t -> t

add x s returns a set containing all elements of s, plus x. If x was already in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val singleton : elt -> t

singleton x returns the one-element set containing only x.

val remove : elt -> t -> t

remove x s returns a set containing all elements of s, except x. If x was not in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val union : t -> t -> t

Set union.

val inter : t -> t -> t

Set intersection.

val disjoint : t -> t -> bool

Test if two sets are disjoint.

  • since 4.08
val diff : t -> t -> t

Set difference: diff s1 s2 contains the elements of s1 that are not in s2.

val cardinal : t -> int

Return the number of elements of a set.

Elements

val elements : t -> elt list

Return the list of all elements of the given set. The returned list is sorted in increasing order with respect to the ordering Ord.compare, where Ord is the argument given to Set.Make.

val min_elt : t -> elt

Return the smallest element of the given set (with respect to the Ord.compare ordering), or raise Not_found if the set is empty.

val min_elt_opt : t -> elt option

Return the smallest element of the given set (with respect to the Ord.compare ordering), or None if the set is empty.

  • since 4.05
val max_elt : t -> elt

Same as min_elt, but returns the largest element of the given set.

val max_elt_opt : t -> elt option

Same as min_elt_opt, but returns the largest element of the given set.

  • since 4.05
val choose : t -> elt

Return one element of the given set, or raise Not_found if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

val choose_opt : t -> elt option

Return one element of the given set, or None if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

  • since 4.05

Searching

val find : elt -> t -> elt

find x s returns the element of s equal to x (according to Ord.compare), or raise Not_found if no such element exists.

  • since 4.01
val find_opt : elt -> t -> elt option

find_opt x s returns the element of s equal to x (according to Ord.compare), or None if no such element exists.

  • since 4.05
val find_first : f:(elt -> bool) -> t -> elt

find_first ~f s, where f is a monotonically increasing function, returns the lowest element e of s such that f e, or raises Not_found if no such element exists.

For example, find_first (fun e -> Ord.compare e x >= 0) s will return the first element e of s where Ord.compare e x >= 0 (intuitively: e >= x), or raise Not_found if x is greater than any element of s.

  • since 4.05
val find_first_opt : f:(elt -> bool) -> t -> elt option

find_first_opt ~f s, where f is a monotonically increasing function, returns an option containing the lowest element e of s such that f e, or None if no such element exists.

  • since 4.05
val find_last : f:(elt -> bool) -> t -> elt

find_last ~f s, where f is a monotonically decreasing function, returns the highest element e of s such that f e, or raises Not_found if no such element exists.

  • since 4.05
val find_last_opt : f:(elt -> bool) -> t -> elt option

find_last_opt ~f s, where f is a monotonically decreasing function, returns an option containing the highest element e of s such that f e, or None if no such element exists.

  • since 4.05

Traversing

val iter : f:(elt -> unit) -> t -> unit

iter ~f s applies f in turn to all elements of s. The elements of s are presented to f in increasing order with respect to the ordering over the type of the elements.

val fold : f:(elt -> 'acc -> 'acc) -> t -> init:'acc -> 'acc

fold ~f s init computes (f xN ... (f x2 (f x1 init))...), where x1 ... xN are the elements of s, in increasing order.

Transforming

val map : f:(elt -> elt) -> t -> t

map ~f s is the set whose elements are f a0,f a1... f + aN, where a0,a1...aN are the elements of s.

The elements are passed to f in increasing order with respect to the ordering over the type of the elements.

If no element of s is changed by f, s is returned unchanged. (If each output of f is physically equal to its input, the returned set is physically equal to s.)

  • since 4.04
val filter : f:(elt -> bool) -> t -> t

filter ~f s returns the set of all elements in s that satisfy predicate f. If f satisfies every element in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val filter_map : f:(elt -> elt option) -> t -> t

filter_map ~f s returns the set of all v such that f x = Some v for some element x of s.

For example,

filter_map (fun n -> if n mod 2 = 0 then Some (n / 2) else None) s

is the set of halves of the even elements of s.

If no element of s is changed or dropped by f (if f x = Some x for each element x), then s is returned unchanged: the result of the function is then physically equal to s.

  • since 4.11
val partition : f:(elt -> bool) -> t -> t * t

partition ~f s returns a pair of sets (s1, s2), where s1 is the set of all the elements of s that satisfy the predicate f, and s2 is the set of all the elements of s that do not satisfy f.

val split : elt -> t -> t * bool * t

split x s returns a triple (l, present, r), where l is the set of elements of s that are strictly less than x; r is the set of elements of s that are strictly greater than x; present is false if s contains no element equal to x, or true if s contains an element equal to x.

Predicates and comparisons

val is_empty : t -> bool

Test whether a set is empty or not.

val mem : elt -> t -> bool

mem x s tests whether x belongs to the set s.

val equal : t -> t -> bool

equal s1 s2 tests whether the sets s1 and s2 are equal, that is, contain equal elements.

val compare : t -> t -> int

Total ordering between sets. Can be used as the ordering function for doing sets of sets.

val subset : t -> t -> bool

subset s1 s2 tests whether the set s1 is a subset of the set s2.

val for_all : f:(elt -> bool) -> t -> bool

for_all ~f s checks if all elements of the set satisfy the predicate f.

val exists : f:(elt -> bool) -> t -> bool

exists ~f s checks if at least one element of the set satisfies the predicate f.

Converting

val to_list : t -> elt list

to_list s is elements s.

  • since 5.1
val of_list : elt list -> t

of_list l creates a set from a list of elements. This is usually more efficient than folding add over the list, except perhaps for lists with many duplicated elements.

  • since 4.02
val to_seq_from : elt -> t -> elt Seq.t

to_seq_from x s iterates on a subset of the elements of s in ascending order, from x or above.

  • since 4.07
val to_seq : t -> elt Seq.t

Iterate on the whole set, in ascending order

  • since 4.07
val to_rev_seq : t -> elt Seq.t

Iterate on the whole set, in descending order

  • since 4.12
val add_seq : elt Seq.t -> t -> t

Add the given elements to the set, in order.

  • since 4.07
val of_seq : elt Seq.t -> t

Build a set from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/MoreLabels/index.html b/docs/stdlib/Stdlib/MoreLabels/index.html new file mode 100644 index 00000000..bd945dea --- /dev/null +++ b/docs/stdlib/Stdlib/MoreLabels/index.html @@ -0,0 +1,4 @@ + +MoreLabels (docs.stdlib.Stdlib.MoreLabels)

Module Stdlib.MoreLabels

Extra labeled libraries.

This meta-module provides labelized versions of the Hashtbl, Map and Set modules.

This module is intended to be used through open MoreLabels which replaces Hashtbl, Map, and Set with their labeled counterparts.

For example:

open MoreLabels
+
+Hashtbl.iter ~f:(fun ~key ~data -> g key data) table
module Hashtbl : sig ... end

Hash tables and hash functions.

module Map : sig ... end

Association tables over ordered types.

module Set : sig ... end

Sets over ordered types.

diff --git a/docs/stdlib/Stdlib/Mutex/index.html b/docs/stdlib/Stdlib/Mutex/index.html new file mode 100644 index 00000000..be37952b --- /dev/null +++ b/docs/stdlib/Stdlib/Mutex/index.html @@ -0,0 +1,4 @@ + +Mutex (docs.stdlib.Stdlib.Mutex)

Module Stdlib.Mutex

Locks for mutual exclusion.

Mutexes (mutual-exclusion locks) are used to implement critical sections and protect shared mutable data structures against concurrent accesses. The typical use is (if m is the mutex associated with the data structure D):

Mutex.lock m;
+(* Critical section that operates over D *);
+Mutex.unlock m
type t

The type of mutexes.

val create : unit -> t

Return a new mutex.

val lock : t -> unit

Lock the given mutex. Only one thread can have the mutex locked at any time. A thread that attempts to lock a mutex already locked by another thread will suspend until the other thread unlocks the mutex.

  • before 4.12

    Sys_error was not raised for recursive locking (platform-dependent behaviour)

val try_lock : t -> bool

Same as Mutex.lock, but does not suspend the calling thread if the mutex is already locked: just return false immediately in that case. If the mutex is unlocked, lock it and return true.

val unlock : t -> unit

Unlock the given mutex. Other threads suspended trying to lock the mutex will restart. The mutex must have been previously locked by the thread that calls Mutex.unlock.

  • raises Sys_error

    if the mutex is unlocked or was locked by another thread.

  • before 4.12

    Sys_error was not raised when unlocking an unlocked mutex or when unlocking a mutex from a different thread.

val protect : t -> (unit -> 'a) -> 'a

protect mutex f runs f() in a critical section where mutex is locked (using lock); it then takes care of releasing mutex, whether f() returned a value or raised an exception.

The unlocking operation is guaranteed to always takes place, even in the event an asynchronous exception (e.g. Sys.Break) is raised in some signal handler.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Nativeint/index.html b/docs/stdlib/Stdlib/Nativeint/index.html new file mode 100644 index 00000000..e14198be --- /dev/null +++ b/docs/stdlib/Stdlib/Nativeint/index.html @@ -0,0 +1,5 @@ + +Nativeint (docs.stdlib.Stdlib.Nativeint)

Module Stdlib.Nativeint

Processor-native integers.

This module provides operations on the type nativeint of signed 32-bit integers (on 32-bit platforms) or signed 64-bit integers (on 64-bit platforms). This integer type has exactly the same width as that of a pointer type in the C compiler. All arithmetic operations over nativeint are taken modulo 232 or 264 depending on the word size of the architecture.

Performance notice: values of type nativeint occupy more memory space than values of type int, and arithmetic operations on nativeint are generally slower than those on int. Use nativeint only when the application requires the extra bit of precision over the int type.

Literals for native integers are suffixed by n:

let zero: nativeint = 0n
+let one: nativeint = 1n
+let m_one: nativeint = -1n
val zero : nativeint

The native integer 0.

val one : nativeint

The native integer 1.

val minus_one : nativeint

The native integer -1.

val neg : nativeint -> nativeint

Unary negation.

val add : nativeint -> nativeint -> nativeint

Addition.

val sub : nativeint -> nativeint -> nativeint

Subtraction.

val mul : nativeint -> nativeint -> nativeint

Multiplication.

val div : nativeint -> nativeint -> nativeint

Integer division. This division rounds the real quotient of its arguments towards zero, as specified for Stdlib.(/).

val unsigned_div : nativeint -> nativeint -> nativeint

Same as div, except that arguments and result are interpreted as unsigned native integers.

  • since 4.08
val rem : nativeint -> nativeint -> nativeint

Integer remainder. If y is not zero, the result of Nativeint.rem x y satisfies the following properties: Nativeint.zero <= Nativeint.rem x y < Nativeint.abs y and x = Nativeint.add (Nativeint.mul (Nativeint.div x y) y) + (Nativeint.rem x y). If y = 0, Nativeint.rem x y raises Division_by_zero.

val unsigned_rem : nativeint -> nativeint -> nativeint

Same as rem, except that arguments and result are interpreted as unsigned native integers.

  • since 4.08
val succ : nativeint -> nativeint

Successor. Nativeint.succ x is Nativeint.add x Nativeint.one.

val pred : nativeint -> nativeint

Predecessor. Nativeint.pred x is Nativeint.sub x Nativeint.one.

val abs : nativeint -> nativeint

abs x is the absolute value of x. On min_int this is min_int itself and thus remains negative.

val size : int

The size in bits of a native integer. This is equal to 32 on a 32-bit platform and to 64 on a 64-bit platform.

val max_int : nativeint

The greatest representable native integer, either 231 - 1 on a 32-bit platform, or 263 - 1 on a 64-bit platform.

val min_int : nativeint

The smallest representable native integer, either -231 on a 32-bit platform, or -263 on a 64-bit platform.

val logand : nativeint -> nativeint -> nativeint

Bitwise logical and.

val logor : nativeint -> nativeint -> nativeint

Bitwise logical or.

val logxor : nativeint -> nativeint -> nativeint

Bitwise logical exclusive or.

val lognot : nativeint -> nativeint

Bitwise logical negation.

val shift_left : nativeint -> int -> nativeint

Nativeint.shift_left x y shifts x to the left by y bits. The result is unspecified if y < 0 or y >= bitsize, where bitsize is 32 on a 32-bit platform and 64 on a 64-bit platform.

val shift_right : nativeint -> int -> nativeint

Nativeint.shift_right x y shifts x to the right by y bits. This is an arithmetic shift: the sign bit of x is replicated and inserted in the vacated bits. The result is unspecified if y < 0 or y >= bitsize.

val shift_right_logical : nativeint -> int -> nativeint

Nativeint.shift_right_logical x y shifts x to the right by y bits. This is a logical shift: zeroes are inserted in the vacated bits regardless of the sign of x. The result is unspecified if y < 0 or y >= bitsize.

val of_int : int -> nativeint

Convert the given integer (type int) to a native integer (type nativeint).

val to_int : nativeint -> int

Convert the given native integer (type nativeint) to an integer (type int). The high-order bit is lost during the conversion.

val unsigned_to_int : nativeint -> int option

Same as to_int, but interprets the argument as an unsigned integer. Returns None if the unsigned value of the argument cannot fit into an int.

  • since 4.08
val of_float : float -> nativeint

Convert the given floating-point number to a native integer, discarding the fractional part (truncate towards 0). If the truncated floating-point number is outside the range [Nativeint.min_int, Nativeint.max_int], no exception is raised, and an unspecified, platform-dependent integer is returned.

val to_float : nativeint -> float

Convert the given native integer to a floating-point number.

val of_int32 : int32 -> nativeint

Convert the given 32-bit integer (type int32) to a native integer.

val to_int32 : nativeint -> int32

Convert the given native integer to a 32-bit integer (type int32). On 64-bit platforms, the 64-bit native integer is taken modulo 232, i.e. the top 32 bits are lost. On 32-bit platforms, the conversion is exact.

val of_string : string -> nativeint

Convert the given string to a native integer. The string is read in decimal (by default, or if the string begins with 0u) or in hexadecimal, octal or binary if the string begins with 0x, 0o or 0b respectively.

The 0u prefix reads the input as an unsigned integer in the range [0, 2*Nativeint.max_int+1]. If the input exceeds Nativeint.max_int it is converted to the signed integer Int64.min_int + input - Nativeint.max_int - 1.

  • raises Failure

    if the given string is not a valid representation of an integer, or if the integer represented exceeds the range of integers representable in type nativeint.

val of_string_opt : string -> nativeint option

Same as of_string, but return None instead of raising.

  • since 4.05
val to_string : nativeint -> string

Return the string representation of its argument, in decimal.

type t = nativeint

An alias for the type of native integers.

val compare : t -> t -> int

The comparison function for native integers, with the same specification as Stdlib.compare. Along with the type t, this function compare allows the module Nativeint to be passed as argument to the functors Set.Make and Map.Make.

val unsigned_compare : t -> t -> int

Same as compare, except that arguments are interpreted as unsigned native integers.

  • since 4.08
val equal : t -> t -> bool

The equal function for native ints.

  • since 4.03
val min : t -> t -> t

Return the smaller of the two arguments.

  • since 4.13
val max : t -> t -> t

Return the greater of the two arguments.

  • since 4.13
val seeded_hash : int -> t -> int

A seeded hash function for native ints, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.1
val hash : t -> int

An unseeded hash function for native ints, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Obj/Closure/index.html b/docs/stdlib/Stdlib/Obj/Closure/index.html new file mode 100644 index 00000000..dfc650ec --- /dev/null +++ b/docs/stdlib/Stdlib/Obj/Closure/index.html @@ -0,0 +1,2 @@ + +Closure (docs.stdlib.Stdlib.Obj.Closure)

Module Obj.Closure

type info = {
  1. arity : int;
  2. start_env : int;
}
val info : t -> info
diff --git a/docs/stdlib/Stdlib/Obj/Ephemeron/index.html b/docs/stdlib/Stdlib/Obj/Ephemeron/index.html new file mode 100644 index 00000000..c0270731 --- /dev/null +++ b/docs/stdlib/Stdlib/Obj/Ephemeron/index.html @@ -0,0 +1,2 @@ + +Ephemeron (docs.stdlib.Stdlib.Obj.Ephemeron)

Module Obj.Ephemeron

Ephemeron with arbitrary arity and untyped

type obj_t = t

alias for Obj.t

type t

an ephemeron cf Ephemeron

val create : int -> t

create n returns an ephemeron with n keys. All the keys and the data are initially empty. The argument n must be between zero and max_ephe_length (limits included).

val length : t -> int

return the number of keys

val get_key : t -> int -> obj_t option
val get_key_copy : t -> int -> obj_t option
val set_key : t -> int -> obj_t -> unit
val unset_key : t -> int -> unit
val check_key : t -> int -> bool
val blit_key : t -> int -> t -> int -> int -> unit
val get_data : t -> obj_t option
val get_data_copy : t -> obj_t option
val set_data : t -> obj_t -> unit
val unset_data : t -> unit
val check_data : t -> bool
val blit_data : t -> t -> unit
val max_ephe_length : int

Maximum length of an ephemeron, ie the maximum number of keys an ephemeron could contain

diff --git a/docs/stdlib/Stdlib/Obj/Extension_constructor/index.html b/docs/stdlib/Stdlib/Obj/Extension_constructor/index.html new file mode 100644 index 00000000..79889750 --- /dev/null +++ b/docs/stdlib/Stdlib/Obj/Extension_constructor/index.html @@ -0,0 +1,2 @@ + +Extension_constructor (docs.stdlib.Stdlib.Obj.Extension_constructor)

Module Obj.Extension_constructor

type t = extension_constructor
val of_val : 'a -> t
val name : t -> string
val id : t -> int
diff --git a/docs/stdlib/Stdlib/Obj/index.html b/docs/stdlib/Stdlib/Obj/index.html new file mode 100644 index 00000000..404c6277 --- /dev/null +++ b/docs/stdlib/Stdlib/Obj/index.html @@ -0,0 +1,2 @@ + +Obj (docs.stdlib.Stdlib.Obj)

Module Stdlib.Obj

Operations on internal representations of values.

Not for the casual user.

type t
type raw_data = nativeint
val repr : 'a -> t
val obj : t -> 'a
val magic : 'a -> 'b
val is_block : t -> bool
val is_int : t -> bool
val tag : t -> int
val size : t -> int
val reachable_words : t -> int

Computes the total size (in words, including the headers) of all heap blocks accessible from the argument. Statically allocated blocks are included.

  • since 4.04
val field : t -> int -> t
val set_field : t -> int -> t -> unit

When using flambda:

set_field MUST NOT be called on immutable blocks. (Blocks allocated in C stubs, or with new_block below, are always considered mutable.)

The same goes for set_double_field.

For experts only: set_field et al can be made safe by first wrapping the block in Sys.opaque_identity, so any information about its contents will not be propagated.

val double_field : t -> int -> float
val set_double_field : t -> int -> float -> unit
val raw_field : t -> int -> raw_data
val set_raw_field : t -> int -> raw_data -> unit
val new_block : int -> int -> t
val dup : t -> t
val add_offset : t -> Int32.t -> t
val with_tag : int -> t -> t
val first_non_constant_constructor_tag : int
val last_non_constant_constructor_tag : int
val forcing_tag : int
val cont_tag : int
val lazy_tag : int
val closure_tag : int
val object_tag : int
val infix_tag : int
val forward_tag : int
val no_scan_tag : int
val abstract_tag : int
val string_tag : int
val double_tag : int
val double_array_tag : int
val custom_tag : int
val int_tag : int
val out_of_heap_tag : int
val unaligned_tag : int
module Closure : sig ... end
module Extension_constructor : sig ... end
module Ephemeron : sig ... end

Ephemeron with arbitrary arity and untyped

diff --git a/docs/stdlib/Stdlib/Oo/index.html b/docs/stdlib/Stdlib/Oo/index.html new file mode 100644 index 00000000..605910b8 --- /dev/null +++ b/docs/stdlib/Stdlib/Oo/index.html @@ -0,0 +1,2 @@ + +Oo (docs.stdlib.Stdlib.Oo)

Module Stdlib.Oo

Operations on objects

val copy : < .. > as 'a -> 'a

Oo.copy o returns a copy of object o, that is a fresh object with the same methods and instance variables as o.

  • alert unsynchronized_access Unsynchronized accesses to mutable objects are a programming error.
val id : < .. > -> int

Return an integer identifying this object, unique for the current execution of the program. The generic comparison and hashing functions are based on this integer. When an object is obtained by unmarshaling, the id is refreshed, and thus different from the original object. As a consequence, the internal invariants of data structures such as hash table or sets containing objects are broken after unmarshaling the data structures.

diff --git a/docs/stdlib/Stdlib/Option/index.html b/docs/stdlib/Stdlib/Option/index.html new file mode 100644 index 00000000..5ded0b7c --- /dev/null +++ b/docs/stdlib/Stdlib/Option/index.html @@ -0,0 +1,2 @@ + +Option (docs.stdlib.Stdlib.Option)

Module Stdlib.Option

Option values.

Option values explicitly indicate the presence or absence of a value.

  • since 4.08

Options

type 'a t = 'a option =
  1. | None
  2. | Some of 'a

The type for option values. Either None or a value Some v.

val none : 'a option

none is None.

val some : 'a -> 'a option

some v is Some v.

val value : 'a option -> default:'a -> 'a

value o ~default is v if o is Some v and default otherwise.

val get : 'a option -> 'a

get o is v if o is Some v and raise otherwise.

val bind : 'a option -> ('a -> 'b option) -> 'b option

bind o f is f v if o is Some v and None if o is None.

val join : 'a option option -> 'a option

join oo is Some v if oo is Some (Some v) and None otherwise.

val map : ('a -> 'b) -> 'a option -> 'b option

map f o is None if o is None and Some (f v) if o is Some v.

val fold : none:'a -> some:('b -> 'a) -> 'b option -> 'a

fold ~none ~some o is none if o is None and some v if o is Some v.

val iter : ('a -> unit) -> 'a option -> unit

iter f o is f v if o is Some v and () otherwise.

Predicates and comparisons

val is_none : 'a option -> bool

is_none o is true if and only if o is None.

val is_some : 'a option -> bool

is_some o is true if and only if o is Some o.

val equal : ('a -> 'a -> bool) -> 'a option -> 'a option -> bool

equal eq o0 o1 is true if and only if o0 and o1 are both None or if they are Some v0 and Some v1 and eq v0 v1 is true.

val compare : ('a -> 'a -> int) -> 'a option -> 'a option -> int

compare cmp o0 o1 is a total order on options using cmp to compare values wrapped by Some _. None is smaller than Some _ values.

Converting

val to_result : none:'e -> 'a option -> ('a, 'e) result

to_result ~none o is Ok v if o is Some v and Error none otherwise.

val to_list : 'a option -> 'a list

to_list o is [] if o is None and [v] if o is Some v.

val to_seq : 'a option -> 'a Seq.t

to_seq o is o as a sequence. None is the empty sequence and Some v is the singleton sequence containing v.

diff --git a/docs/stdlib/Stdlib/Out_channel/index.html b/docs/stdlib/Stdlib/Out_channel/index.html new file mode 100644 index 00000000..2f4d36ce --- /dev/null +++ b/docs/stdlib/Stdlib/Out_channel/index.html @@ -0,0 +1,5 @@ + +Out_channel (docs.stdlib.Stdlib.Out_channel)

Module Stdlib.Out_channel

Output channels.

This module provides functions for working with output channels.

See the example section below.

  • since 4.14

Channels

type t = out_channel

The type of output channel.

type open_flag = open_flag =
  1. | Open_rdonly
    (*

    open for reading.

    *)
  2. | Open_wronly
    (*

    open for writing.

    *)
  3. | Open_append
    (*

    open for appending: always write at end of file.

    *)
  4. | Open_creat
    (*

    create the file if it does not exist.

    *)
  5. | Open_trunc
    (*

    empty the file if it already exists.

    *)
  6. | Open_excl
    (*

    fail if Open_creat and the file already exists.

    *)
  7. | Open_binary
    (*

    open in binary mode (no conversion).

    *)
  8. | Open_text
    (*

    open in text mode (may perform conversions).

    *)
  9. | Open_nonblock
    (*

    open in non-blocking mode.

    *)

Opening modes for open_gen.

val stdout : t

The standard output for the process.

val stderr : t

The standard error output for the process.

val open_bin : string -> t

Open the named file for writing, and return a new output channel on that file, positioned at the beginning of the file. The file is truncated to zero length if it already exists. It is created if it does not already exists.

val open_text : string -> t

Same as open_bin, but the file is opened in text mode, so that newline translation takes place during writes. On operating systems that do not distinguish between text mode and binary mode, this function behaves like open_bin.

val open_gen : open_flag list -> int -> string -> t

open_gen mode perm filename opens the named file for writing, as described above. The extra argument mode specifies the opening mode. The extra argument perm specifies the file permissions, in case the file must be created. open_text and open_bin are special cases of this function.

val with_open_bin : string -> (t -> 'a) -> 'a

with_open_bin fn f opens a channel oc on file fn and returns f + oc. After f returns, either with a value or by raising an exception, oc is guaranteed to be closed.

val with_open_text : string -> (t -> 'a) -> 'a

Like with_open_bin, but the channel is opened in text mode (see open_text).

val with_open_gen : open_flag list -> int -> string -> (t -> 'a) -> 'a

Like with_open_bin, but can specify the opening mode and file permission, in case the file must be created (see open_gen).

val close : t -> unit

Close the given channel, flushing all buffered write operations. Output functions raise a Sys_error exception when they are applied to a closed output channel, except close and flush, which do nothing when applied to an already closed channel. Note that close may raise Sys_error if the operating system signals an error when flushing or closing.

val close_noerr : t -> unit

Same as close, but ignore all errors.

Output

val output_char : t -> char -> unit

Write the character on the given output channel.

val output_byte : t -> int -> unit

Write one 8-bit integer (as the single character with that code) on the given output channel. The given integer is taken modulo 256.

val output_string : t -> string -> unit

Write the string on the given output channel.

val output_bytes : t -> bytes -> unit

Write the byte sequence on the given output channel.

Advanced output

val output : t -> bytes -> int -> int -> unit

output oc buf pos len writes len characters from byte sequence buf, starting at offset pos, to the given output channel oc.

val output_substring : t -> string -> int -> int -> unit

Same as output but take a string as argument instead of a byte sequence.

Flushing

val flush : t -> unit

Flush the buffer associated with the given output channel, performing all pending writes on that channel. Interactive programs must be careful about flushing standard output and standard error at the right time.

val flush_all : unit -> unit

Flush all open output channels; ignore errors.

Seeking

val seek : t -> int64 -> unit

seek chan pos sets the current writing position to pos for channel chan. This works only for regular files. On files of other kinds (such as terminals, pipes and sockets), the behavior is unspecified.

val pos : t -> int64

Return the current writing position for the given channel. Does not work on channels opened with the Open_append flag (returns unspecified results).

For files opened in text mode under Windows, the returned position is approximate (owing to end-of-line conversion); in particular, saving the current position with pos, then going back to this position using seek will not work. For this programming idiom to work reliably and portably, the file must be opened in binary mode.

Attributes

val length : t -> int64

Return the size (number of characters) of the regular file on which the given channel is opened. If the channel is opened on a file that is not a regular file, the result is meaningless.

val set_binary_mode : t -> bool -> unit

set_binary_mode oc true sets the channel oc to binary mode: no translations take place during output.

set_binary_mode oc false sets the channel oc to text mode: depending on the operating system, some translations may take place during output. For instance, under Windows, end-of-lines will be translated from \n to \r\n.

This function has no effect under operating systems that do not distinguish between text mode and binary mode.

val set_buffered : t -> bool -> unit

set_buffered oc true sets the channel oc to buffered mode. In this mode, data output on oc will be buffered until either the internal buffer is full or the function flush or flush_all is called, at which point it will be sent to the output device.

set_buffered oc false sets the channel oc to unbuffered mode. In this mode, data output on oc will be sent to the output device immediately.

All channels are open in buffered mode by default.

val is_buffered : t -> bool

is_buffered oc returns whether the channel oc is buffered (see set_buffered).

val isatty : t -> bool

isatty oc is true if oc refers to a terminal or console window, false otherwise.

  • since 5.1

Examples

Writing the contents of a file:

let write_file file s =
+  Out_channel.with_open_bin file
+    (fun oc -> Out_channel.output_string oc s))
diff --git a/docs/stdlib/Stdlib/Parsing/index.html b/docs/stdlib/Stdlib/Parsing/index.html new file mode 100644 index 00000000..af3843e8 --- /dev/null +++ b/docs/stdlib/Stdlib/Parsing/index.html @@ -0,0 +1,2 @@ + +Parsing (docs.stdlib.Stdlib.Parsing)

Module Stdlib.Parsing

The run-time library for parsers generated by ocamlyacc.

val symbol_start : unit -> int

symbol_start and Parsing.symbol_end are to be called in the action part of a grammar rule only. They return the offset of the string that matches the left-hand side of the rule: symbol_start() returns the offset of the first character; symbol_end() returns the offset after the last character. The first character in a file is at offset 0.

val symbol_end : unit -> int
val rhs_start : int -> int

Same as Parsing.symbol_start and Parsing.symbol_end, but return the offset of the string matching the nth item on the right-hand side of the rule, where n is the integer parameter to rhs_start and rhs_end. n is 1 for the leftmost item.

val rhs_end : int -> int
val symbol_start_pos : unit -> Lexing.position

Same as symbol_start, but return a position instead of an offset.

val symbol_end_pos : unit -> Lexing.position

Same as symbol_end, but return a position instead of an offset.

val rhs_start_pos : int -> Lexing.position

Same as rhs_start, but return a position instead of an offset.

val rhs_end_pos : int -> Lexing.position

Same as rhs_end, but return a position instead of an offset.

val clear_parser : unit -> unit

Empty the parser stack. Call it just after a parsing function has returned, to remove all pointers from the parser stack to structures that were built by semantic actions during parsing. This is optional, but lowers the memory requirements of the programs.

exception Parse_error

Raised when a parser encounters a syntax error. Can also be raised from the action part of a grammar rule, to initiate error recovery.

val set_trace : bool -> bool

Control debugging support for ocamlyacc-generated parsers. After Parsing.set_trace true, the pushdown automaton that executes the parsers prints a trace of its actions (reading a token, shifting a state, reducing by a rule) on standard output. Parsing.set_trace false turns this debugging trace off. The boolean returned is the previous state of the trace flag.

  • since 3.11
diff --git a/docs/stdlib/Stdlib/Printexc/Slot/index.html b/docs/stdlib/Stdlib/Printexc/Slot/index.html new file mode 100644 index 00000000..92c63d90 --- /dev/null +++ b/docs/stdlib/Stdlib/Printexc/Slot/index.html @@ -0,0 +1,2 @@ + +Slot (docs.stdlib.Stdlib.Printexc.Slot)

Module Printexc.Slot

  • since 4.02
val is_raise : t -> bool

is_raise slot is true when slot refers to a raising point in the code, and false when it comes from a simple function call.

  • since 4.02
val is_inline : t -> bool

is_inline slot is true when slot refers to a call that got inlined by the compiler, and false when it comes from any other context.

  • since 4.04
val location : t -> location option

location slot returns the location information of the slot, if available, and None otherwise.

Some possible reasons for failing to return a location are as follow:

  • the slot corresponds to a compiler-inserted raise
  • the slot corresponds to a part of the program that has not been compiled with debug information (-g)
  • since 4.02
val name : t -> string option

name slot returns the name of the function or definition enclosing the location referred to by the slot.

name slot returns None if the name is unavailable, which may happen for the same reasons as location returning None.

  • since 4.11
val format : int -> t -> string option

format pos slot returns the string representation of slot as raw_backtrace_to_string would format it, assuming it is the pos-th element of the backtrace: the 0-th element is pretty-printed differently than the others.

Whole-backtrace printing functions also skip some uninformative slots; in that case, format pos slot returns None.

  • since 4.02
diff --git a/docs/stdlib/Stdlib/Printexc/index.html b/docs/stdlib/Stdlib/Printexc/index.html new file mode 100644 index 00000000..07a3ed85 --- /dev/null +++ b/docs/stdlib/Stdlib/Printexc/index.html @@ -0,0 +1,18 @@ + +Printexc (docs.stdlib.Stdlib.Printexc)

Module Stdlib.Printexc

Facilities for printing exceptions and inspecting current call stack.

type t = exn = ..

The type of exception values.

val to_string : exn -> string

Printexc.to_string e returns a string representation of the exception e.

val to_string_default : exn -> string

Printexc.to_string_default e returns a string representation of the exception e, ignoring all registered exception printers.

  • since 4.09
val print : ('a -> 'b) -> 'a -> 'b

Printexc.print fn x applies fn to x and returns the result. If the evaluation of fn x raises any exception, the name of the exception is printed on standard error output, and the exception is raised again. The typical use is to catch and report exceptions that escape a function application.

val catch : ('a -> 'b) -> 'a -> 'b

Printexc.catch fn x is similar to Printexc.print, but aborts the program with exit code 2 after printing the uncaught exception. This function is deprecated: the runtime system is now able to print uncaught exceptions as precisely as Printexc.catch does. Moreover, calling Printexc.catch makes it harder to track the location of the exception using the debugger or the stack backtrace facility. So, do not use Printexc.catch in new code.

  • deprecated This function is no longer needed.
val print_backtrace : out_channel -> unit

Printexc.print_backtrace oc prints an exception backtrace on the output channel oc. The backtrace lists the program locations where the most-recently raised exception was raised and where it was propagated through function calls.

If the call is not inside an exception handler, the returned backtrace is unspecified. If the call is after some exception-catching code (before in the handler, or in a when-guard during the matching of the exception handler), the backtrace may correspond to a later exception than the handled one.

  • since 3.11
val get_backtrace : unit -> string

Printexc.get_backtrace () returns a string containing the same exception backtrace that Printexc.print_backtrace would print. Same restriction usage than print_backtrace.

  • since 3.11
val record_backtrace : bool -> unit

Printexc.record_backtrace b turns recording of exception backtraces on (if b = true) or off (if b = false). Initially, backtraces are not recorded, unless the b flag is given to the program through the OCAMLRUNPARAM variable.

  • since 3.11
val backtrace_status : unit -> bool

Printexc.backtrace_status() returns true if exception backtraces are currently recorded, false if not.

  • since 3.11
val register_printer : (exn -> string option) -> unit

Printexc.register_printer fn registers fn as an exception printer. The printer should return None or raise an exception if it does not know how to convert the passed exception, and Some + s with s the resulting string if it can convert the passed exception. Exceptions raised by the printer are ignored.

When converting an exception into a string, the printers will be invoked in the reverse order of their registrations, until a printer returns a Some s value (if no such printer exists, the runtime will use a generic printer).

When using this mechanism, one should be aware that an exception backtrace is attached to the thread that saw it raised, rather than to the exception itself. Practically, it means that the code related to fn should not use the backtrace if it has itself raised an exception before.

  • since 3.11.2
val use_printers : exn -> string option

Printexc.use_printers e returns None if there are no registered printers and Some s with else as the resulting string otherwise.

  • since 4.09

Raw backtraces

type raw_backtrace

The type raw_backtrace stores a backtrace in a low-level format, which can be converted to usable form using raw_backtrace_entries and backtrace_slots_of_raw_entry below.

Converting backtraces to backtrace_slots is slower than capturing the backtraces. If an application processes many backtraces, it can be useful to use raw_backtrace to avoid or delay conversion.

Raw backtraces cannot be marshalled. If you need marshalling, you should use the array returned by the backtrace_slots function of the next section.

  • since 4.01
type raw_backtrace_entry = private int

A raw_backtrace_entry is an element of a raw_backtrace.

Each raw_backtrace_entry is an opaque integer, whose value is not stable between different programs, or even between different runs of the same binary.

A raw_backtrace_entry can be converted to a usable form using backtrace_slots_of_raw_entry below. Note that, due to inlining, a single raw_backtrace_entry may convert to several backtrace_slots. Since the values of a raw_backtrace_entry are not stable, they cannot be marshalled. If they are to be converted, the conversion must be done by the process that generated them.

Again due to inlining, there may be multiple distinct raw_backtrace_entry values that convert to equal backtrace_slots. However, if two raw_backtrace_entrys are equal as integers, then they represent the same backtrace_slots.

  • since 4.12
val raw_backtrace_entries : raw_backtrace -> raw_backtrace_entry array
  • since 4.12
val get_raw_backtrace : unit -> raw_backtrace

Printexc.get_raw_backtrace () returns the same exception backtrace that Printexc.print_backtrace would print, but in a raw format. Same restriction usage than print_backtrace.

  • since 4.01
val print_raw_backtrace : out_channel -> raw_backtrace -> unit

Print a raw backtrace in the same format Printexc.print_backtrace uses.

  • since 4.01
val raw_backtrace_to_string : raw_backtrace -> string

Return a string from a raw backtrace, in the same format Printexc.get_backtrace uses.

  • since 4.01
val raise_with_backtrace : exn -> raw_backtrace -> 'a

Reraise the exception using the given raw_backtrace for the origin of the exception

  • since 4.05

Current call stack

val get_callstack : int -> raw_backtrace

Printexc.get_callstack n returns a description of the top of the call stack on the current program point (for the current thread), with at most n entries. (Note: this function is not related to exceptions at all, despite being part of the Printexc module.)

  • since 4.01

Uncaught exceptions

val default_uncaught_exception_handler : exn -> raw_backtrace -> unit

Printexc.default_uncaught_exception_handler prints the exception and backtrace on standard error output.

  • since 4.11
val set_uncaught_exception_handler : (exn -> raw_backtrace -> unit) -> unit

Printexc.set_uncaught_exception_handler fn registers fn as the handler for uncaught exceptions. The default handler is Printexc.default_uncaught_exception_handler.

Note that when fn is called all the functions registered with Stdlib.at_exit have already been called. Because of this you must make sure any output channel fn writes on is flushed.

Also note that exceptions raised by user code in the interactive toplevel are not passed to this function as they are caught by the toplevel itself.

If fn raises an exception, both the exceptions passed to fn and raised by fn will be printed with their respective backtrace.

  • since 4.02

Manipulation of backtrace information

These functions are used to traverse the slots of a raw backtrace and extract information from them in a programmer-friendly format.

type backtrace_slot

The abstract type backtrace_slot represents a single slot of a backtrace.

  • since 4.02
val backtrace_slots : raw_backtrace -> backtrace_slot array option

Returns the slots of a raw backtrace, or None if none of them contain useful information.

In the return array, the slot at index 0 corresponds to the most recent function call, raise, or primitive get_backtrace call in the trace.

Some possible reasons for returning None are as follow:

  • none of the slots in the trace come from modules compiled with debug information (-g)
  • the program is a bytecode program that has not been linked with debug information enabled (ocamlc -g)
  • since 4.02
val backtrace_slots_of_raw_entry : + raw_backtrace_entry -> + backtrace_slot array option

Returns the slots of a single raw backtrace entry, or None if this entry lacks debug information.

Slots are returned in the same order as backtrace_slots: the slot at index 0 is the most recent call, raise, or primitive, and subsequent slots represent callers.

  • since 4.12
type location = {
  1. filename : string;
  2. line_number : int;
  3. start_char : int;
  4. end_char : int;
}

The type of location information found in backtraces. start_char and end_char are positions relative to the beginning of the line.

  • since 4.02
module Slot : sig ... end

Raw backtrace slots

type raw_backtrace_slot

This type is used to iterate over the slots of a raw_backtrace. For most purposes, backtrace_slots_of_raw_entry is easier to use.

Like raw_backtrace_entry, values of this type are process-specific and must absolutely not be marshalled, and are unsafe to use for this reason (marshalling them may not fail, but un-marshalling and using the result will result in undefined behavior).

Elements of this type can still be compared and hashed: when two elements are equal, then they represent the same source location (the converse is not necessarily true in presence of inlining, for example).

  • since 4.02
val raw_backtrace_length : raw_backtrace -> int

raw_backtrace_length bckt returns the number of slots in the backtrace bckt.

  • since 4.02
val get_raw_backtrace_slot : raw_backtrace -> int -> raw_backtrace_slot

get_raw_backtrace_slot bckt pos returns the slot in position pos in the backtrace bckt.

  • since 4.02
val convert_raw_backtrace_slot : raw_backtrace_slot -> backtrace_slot

Extracts the user-friendly backtrace_slot from a low-level raw_backtrace_slot.

  • since 4.02
val get_raw_backtrace_next_slot : + raw_backtrace_slot -> + raw_backtrace_slot option

get_raw_backtrace_next_slot slot returns the next slot inlined, if any.

Sample code to iterate over all frames (inlined and non-inlined):

(* Iterate over inlined frames *)
+let rec iter_raw_backtrace_slot f slot =
+  f slot;
+  match get_raw_backtrace_next_slot slot with
+  | None -> ()
+  | Some slot' -> iter_raw_backtrace_slot f slot'
+
+(* Iterate over stack frames *)
+let iter_raw_backtrace f bt =
+  for i = 0 to raw_backtrace_length bt - 1 do
+    iter_raw_backtrace_slot f (get_raw_backtrace_slot bt i)
+  done
  • since 4.04

Exception slots

val exn_slot_id : exn -> int

Printexc.exn_slot_id returns an integer which uniquely identifies the constructor used to create the exception value exn (in the current runtime).

  • since 4.02
val exn_slot_name : exn -> string

Printexc.exn_slot_name exn returns the internal name of the constructor used to create the exception value exn.

  • since 4.02
diff --git a/docs/stdlib/Stdlib/Printf/index.html b/docs/stdlib/Stdlib/Printf/index.html new file mode 100644 index 00000000..724f6b46 --- /dev/null +++ b/docs/stdlib/Stdlib/Printf/index.html @@ -0,0 +1,14 @@ + +Printf (docs.stdlib.Stdlib.Printf)

Module Stdlib.Printf

Formatted output functions.

val fprintf : out_channel -> ('a, out_channel, unit) format -> 'a

fprintf outchan format arg1 ... argN formats the arguments arg1 to argN according to the format string format, and outputs the resulting string on the channel outchan.

The format string is a character string which contains two types of objects: plain characters, which are simply copied to the output channel, and conversion specifications, each of which causes conversion and printing of arguments.

Conversion specifications have the following form:

% [flags] [width] [.precision] type

In short, a conversion specification consists in the % character, followed by optional modifiers and a type which is made of one or two characters.

The types and their meanings are:

  • d, i: convert an integer argument to signed decimal. The flag # adds underscores to large values for readability.
  • u, n, l, L, or N: convert an integer argument to unsigned decimal. Warning: n, l, L, and N are used for scanf, and should not be used for printf. The flag # adds underscores to large values for readability.
  • x: convert an integer argument to unsigned hexadecimal, using lowercase letters. The flag # adds a 0x prefix to non zero values.
  • X: convert an integer argument to unsigned hexadecimal, using uppercase letters. The flag # adds a 0X prefix to non zero values.
  • o: convert an integer argument to unsigned octal. The flag # adds a 0 prefix to non zero values.
  • s: insert a string argument.
  • S: convert a string argument to OCaml syntax (double quotes, escapes).
  • c: insert a character argument.
  • C: convert a character argument to OCaml syntax (single quotes, escapes).
  • f: convert a floating-point argument to decimal notation, in the style dddd.ddd.
  • F: convert a floating-point argument to OCaml syntax (dddd. or dddd.ddd or d.ddd e+-dd). Converts to hexadecimal with the # flag (see h).
  • e or E: convert a floating-point argument to decimal notation, in the style d.ddd e+-dd (mantissa and exponent).
  • g or G: convert a floating-point argument to decimal notation, in style f or e, E (whichever is more compact). Moreover, any trailing zeros are removed from the fractional part of the result and the decimal-point character is removed if there is no fractional part remaining.
  • h or H: convert a floating-point argument to hexadecimal notation, in the style 0xh.hhhh p+-dd (hexadecimal mantissa, exponent in decimal and denotes a power of 2).
  • B: convert a boolean argument to the string true or false
  • b: convert a boolean argument (deprecated; do not use in new programs).
  • ld, li, lu, lx, lX, lo: convert an int32 argument to the format specified by the second letter (decimal, hexadecimal, etc).
  • nd, ni, nu, nx, nX, no: convert a nativeint argument to the format specified by the second letter.
  • Ld, Li, Lu, Lx, LX, Lo: convert an int64 argument to the format specified by the second letter.
  • a: user-defined printer. Take two arguments and apply the first one to outchan (the current output channel) and to the second argument. The first argument must therefore have type out_channel -> 'b -> unit and the second 'b. The output produced by the function is inserted in the output of fprintf at the current point.
  • t: same as %a, but take only one argument (with type out_channel -> unit) and apply it to outchan.
  • \{ fmt %\}: convert a format string argument to its type digest. The argument must have the same type as the internal format string fmt.
  • ( fmt %): format string substitution. Take a format string argument and substitute it to the internal format string fmt to print following arguments. The argument must have the same type as the internal format string fmt.
  • !: take no argument and flush the output.
  • %: take no argument and output one % character.
  • \@: take no argument and output one \@ character.
  • ,: take no argument and output nothing: a no-op delimiter for conversion specifications.

The optional flags are:

  • -: left-justify the output (default is right justification).
  • 0: for numerical conversions, pad with zeroes instead of spaces.
  • +: for signed numerical conversions, prefix number with a + sign if positive.
  • space: for signed numerical conversions, prefix number with a space if positive.
  • #: request an alternate formatting style for the integer types and the floating-point type F.

The optional width is an integer indicating the minimal width of the result. For instance, %6d prints an integer, prefixing it with spaces to fill at least 6 characters.

The optional precision is a dot . followed by an integer indicating how many digits follow the decimal point in the %f, %e, %E, %h, and %H conversions or the maximum number of significant digits to appear for the %F, %g and %G conversions. For instance, %.4f prints a float with 4 fractional digits.

The integer in a width or precision can also be specified as *, in which case an extra integer argument is taken to specify the corresponding width or precision. This integer argument precedes immediately the argument to print. For instance, %.*f prints a float with as many fractional digits as the value of the argument given before the float.

val printf : ('a, out_channel, unit) format -> 'a

Same as Printf.fprintf, but output on stdout.

val eprintf : ('a, out_channel, unit) format -> 'a

Same as Printf.fprintf, but output on stderr.

val sprintf : ('a, unit, string) format -> 'a

Same as Printf.fprintf, but instead of printing on an output channel, return a string containing the result of formatting the arguments.

val bprintf : Buffer.t -> ('a, Buffer.t, unit) format -> 'a

Same as Printf.fprintf, but instead of printing on an output channel, append the formatted arguments to the given extensible buffer (see module Buffer).

val ifprintf : 'b -> ('a, 'b, 'c, unit) format4 -> 'a

Same as Printf.fprintf, but does not print anything. Useful to ignore some material when conditionally printing.

  • since 3.10
val ibprintf : Buffer.t -> ('a, Buffer.t, unit) format -> 'a

Same as Printf.bprintf, but does not print anything. Useful to ignore some material when conditionally printing.

  • since 4.11

Formatted output functions with continuations.

val kfprintf : + (out_channel -> 'd) -> + out_channel -> + ('a, out_channel, unit, 'd) format4 -> + 'a

Same as fprintf, but instead of returning immediately, passes the out channel to its first argument at the end of printing.

  • since 3.09
val ikfprintf : ('b -> 'd) -> 'b -> ('a, 'b, 'c, 'd) format4 -> 'a

Same as kfprintf above, but does not print anything. Useful to ignore some material when conditionally printing.

  • since 4.01
val ksprintf : (string -> 'd) -> ('a, unit, string, 'd) format4 -> 'a

Same as sprintf above, but instead of returning the string, passes it to the first argument.

  • since 3.09
val kbprintf : + (Buffer.t -> 'd) -> + Buffer.t -> + ('a, Buffer.t, unit, 'd) format4 -> + 'a

Same as bprintf, but instead of returning immediately, passes the buffer to its first argument at the end of printing.

  • since 3.10
val ikbprintf : + (Buffer.t -> 'd) -> + Buffer.t -> + ('a, Buffer.t, unit, 'd) format4 -> + 'a

Same as kbprintf above, but does not print anything. Useful to ignore some material when conditionally printing.

  • since 4.11

Deprecated

val kprintf : (string -> 'b) -> ('a, unit, string, 'b) format4 -> 'a

A deprecated synonym for ksprintf.

  • deprecated Use Printf.ksprintf instead.
diff --git a/docs/stdlib/Stdlib/Queue/index.html b/docs/stdlib/Stdlib/Queue/index.html new file mode 100644 index 00000000..b526641f --- /dev/null +++ b/docs/stdlib/Stdlib/Queue/index.html @@ -0,0 +1,78 @@ + +Queue (docs.stdlib.Stdlib.Queue)

Module Stdlib.Queue

First-in first-out queues.

This module implements queues (FIFOs), with in-place modification. See the example section below.

Unsynchronized accesses

Unsynchronized accesses to a queue may lead to an invalid queue state. Thus, concurrent accesses to queues must be synchronized (for instance with a Mutex.t).

type !'a t

The type of queues containing elements of type 'a.

exception Empty

Raised when Queue.take or Queue.peek is applied to an empty queue.

val create : unit -> 'a t

Return a new queue, initially empty.

val add : 'a -> 'a t -> unit

add x q adds the element x at the end of the queue q.

val push : 'a -> 'a t -> unit

push is a synonym for add.

val take : 'a t -> 'a

take q removes and returns the first element in queue q, or raises Empty if the queue is empty.

val take_opt : 'a t -> 'a option

take_opt q removes and returns the first element in queue q, or returns None if the queue is empty.

  • since 4.08
val pop : 'a t -> 'a

pop is a synonym for take.

val peek : 'a t -> 'a

peek q returns the first element in queue q, without removing it from the queue, or raises Empty if the queue is empty.

val peek_opt : 'a t -> 'a option

peek_opt q returns the first element in queue q, without removing it from the queue, or returns None if the queue is empty.

  • since 4.08
val top : 'a t -> 'a

top is a synonym for peek.

val clear : 'a t -> unit

Discard all elements from a queue.

val copy : 'a t -> 'a t

Return a copy of the given queue.

val is_empty : 'a t -> bool

Return true if the given queue is empty, false otherwise.

val length : 'a t -> int

Return the number of elements in a queue.

val iter : ('a -> unit) -> 'a t -> unit

iter f q applies f in turn to all elements of q, from the least recently entered to the most recently entered. The queue itself is unchanged.

val fold : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc

fold f accu q is equivalent to List.fold_left f accu l, where l is the list of q's elements. The queue remains unchanged.

val transfer : 'a t -> 'a t -> unit

transfer q1 q2 adds all of q1's elements at the end of the queue q2, then clears q1. It is equivalent to the sequence iter (fun x -> add x q2) q1; clear q1, but runs in constant time.

Iterators

val to_seq : 'a t -> 'a Seq.t

Iterate on the queue, in front-to-back order. The behavior is not specified if the queue is modified during the iteration.

  • since 4.07
val add_seq : 'a t -> 'a Seq.t -> unit

Add the elements from a sequence to the end of the queue.

  • since 4.07
val of_seq : 'a Seq.t -> 'a t

Create a queue from a sequence.

  • since 4.07

Examples

Basic Example

A basic example:

# let q = Queue.create ()
+val q : '_weak1 Queue.t = <abstr>
+
+
+# Queue.push 1 q; Queue.push 2 q; Queue.push 3 q
+- : unit = ()
+
+# Queue.length q
+- : int = 3
+
+# Queue.pop q
+- : int = 1
+
+# Queue.pop q
+- : int = 2
+
+# Queue.pop q
+- : int = 3
+
+# Queue.pop q
+Exception: Stdlib.Queue.Empty.

Search Through a Graph

For a more elaborate example, a classic algorithmic use of queues is to implement a BFS (breadth-first search) through a graph.

 type graph = {
+   edges: (int, int list) Hashtbl.t
+ }
+
+(* Search in graph [g] using BFS, starting from node [start].
+   It returns the first node that satisfies [p], or [None] if
+   no node reachable from [start] satisfies [p].
+*)
+let search_for ~(g:graph) ~(start:int) (p:int -> bool) : int option =
+  let to_explore = Queue.create() in
+  let explored = Hashtbl.create 16 in
+
+  Queue.push start to_explore;
+  let rec loop () =
+    if Queue.is_empty to_explore then None
+    else
+      (* node to explore *)
+      let node = Queue.pop to_explore in
+      explore_node node
+
+  and explore_node node =
+    if not (Hashtbl.mem explored node) then (
+      if p node then Some node (* found *)
+      else (
+        Hashtbl.add explored node ();
+        let children =
+          Hashtbl.find_opt g.edges node
+          |> Option.value ~default:[]
+        in
+        List.iter (fun child -> Queue.push child to_explore) children;
+        loop()
+      )
+    ) else loop()
+  in
+  loop()
+
+(* a sample graph *)
+let my_graph: graph =
+  let edges =
+    List.to_seq [
+      1, [2;3];
+      2, [10; 11];
+      3, [4;5];
+      5, [100];
+      11, [0; 20];
+    ]
+    |> Hashtbl.of_seq
+  in {edges}
+
+# search_for ~g:my_graph ~start:1 (fun x -> x = 30)
+- : int option = None
+
+# search_for ~g:my_graph ~start:1 (fun x -> x >= 15)
+- : int option = Some 20
+
+# search_for ~g:my_graph ~start:1 (fun x -> x >= 50)
+- : int option = Some 100
diff --git a/docs/stdlib/Stdlib/Random/State/index.html b/docs/stdlib/Stdlib/Random/State/index.html new file mode 100644 index 00000000..dc2a20bf --- /dev/null +++ b/docs/stdlib/Stdlib/Random/State/index.html @@ -0,0 +1,2 @@ + +State (docs.stdlib.Stdlib.Random.State)

Module Random.State

type t

The type of PRNG states.

val make : int array -> t

Create a new state and initialize it with the given seed.

val make_self_init : unit -> t

Create a new state and initialize it with a random seed chosen in a system-dependent way. The seed is obtained as described in Random.self_init.

val copy : t -> t

Return a copy of the given state.

val bits : t -> int
val int : t -> int -> int
val full_int : t -> int -> int
val int32 : t -> Int32.t -> Int32.t
val nativeint : t -> Nativeint.t -> Nativeint.t
val int64 : t -> Int64.t -> Int64.t
val float : t -> float -> float
val bool : t -> bool
val bits32 : t -> Int32.t
val bits64 : t -> Int64.t
val nativebits : t -> Nativeint.t

These functions are the same as the basic functions, except that they use (and update) the given PRNG state instead of the default one.

val split : t -> t

Draw a fresh PRNG state from the given PRNG state. (The given PRNG state is modified.) The new PRNG is statistically independent from the given PRNG. Data can be drawn from both PRNGs, in any order, without risk of correlation. Both PRNGs can be split later, arbitrarily many times.

  • since 5.0
val to_binary_string : t -> string

Serializes the PRNG state into an immutable sequence of bytes. See of_binary_string for deserialization.

The string type is intended here for serialization only, the encoding is not human-readable and may not be printable.

Note that the serialization format may differ across OCaml versions.

  • since 5.1
val of_binary_string : string -> t

Deserializes a byte sequence obtained by calling to_binary_string. The resulting PRNG state will produce the same random numbers as the state that was passed as input to to_binary_string.

  • raises Failure

    if the input is not in the expected format.

    Note that the serialization format may differ across OCaml versions.

    Unlike the functions provided by the Marshal module, this function either produces a valid state or fails cleanly with a Failure exception. It can be safely used on user-provided, untrusted inputs.

  • since 5.1
diff --git a/docs/stdlib/Stdlib/Random/index.html b/docs/stdlib/Stdlib/Random/index.html new file mode 100644 index 00000000..34152d01 --- /dev/null +++ b/docs/stdlib/Stdlib/Random/index.html @@ -0,0 +1,2 @@ + +Random (docs.stdlib.Stdlib.Random)

Module Stdlib.Random

Pseudo-random number generators (PRNG).

With multiple domains, each domain has its own generator that evolves independently of the generators of other domains. When a domain is created, its generator is initialized by splitting the state of the generator associated with the parent domain.

In contrast, all threads within a domain share the same domain-local generator. Independent generators can be created with the Random.split function and used with the functions from the Random.State module.

Basic functions

val init : int -> unit

Initialize the domain-local generator, using the argument as a seed. The same seed will always yield the same sequence of numbers.

val full_init : int array -> unit

Same as Random.init but takes more data as seed.

val self_init : unit -> unit

Initialize the domain-local generator with a random seed chosen in a system-dependent way. If /dev/urandom is available on the host machine, it is used to provide a highly random initial seed. Otherwise, a less random seed is computed from system parameters (current time, process IDs, domain-local state).

val bits : unit -> int

Return 30 random bits in a nonnegative integer.

  • before 5.0

    used a different algorithm (affects all the following functions)

val int : int -> int

Random.int bound returns a random integer between 0 (inclusive) and bound (exclusive). bound must be greater than 0 and less than 230.

val full_int : int -> int

Random.full_int bound returns a random integer between 0 (inclusive) and bound (exclusive). bound may be any positive integer.

If bound is less than 230, Random.full_int bound is equal to Random.int bound. If bound is greater than 230 (on 64-bit systems or non-standard environments, such as JavaScript), Random.full_int returns a value, where Random.int raises Stdlib.Invalid_argument.

  • since 4.13
val int32 : Int32.t -> Int32.t

Random.int32 bound returns a random integer between 0 (inclusive) and bound (exclusive). bound must be greater than 0.

val nativeint : Nativeint.t -> Nativeint.t

Random.nativeint bound returns a random integer between 0 (inclusive) and bound (exclusive). bound must be greater than 0.

val int64 : Int64.t -> Int64.t

Random.int64 bound returns a random integer between 0 (inclusive) and bound (exclusive). bound must be greater than 0.

val float : float -> float

Random.float bound returns a random floating-point number between 0 and bound (inclusive). If bound is negative, the result is negative or zero. If bound is 0, the result is 0.

val bool : unit -> bool

Random.bool () returns true or false with probability 0.5 each.

val bits32 : unit -> Int32.t

Random.bits32 () returns 32 random bits as an integer between Int32.min_int and Int32.max_int.

  • since 4.14
val bits64 : unit -> Int64.t

Random.bits64 () returns 64 random bits as an integer between Int64.min_int and Int64.max_int.

  • since 4.14
val nativebits : unit -> Nativeint.t

Random.nativebits () returns 32 or 64 random bits (depending on the bit width of the platform) as an integer between Nativeint.min_int and Nativeint.max_int.

  • since 4.14

Advanced functions

The functions from module State manipulate the current state of the random generator explicitly. This allows using one or several deterministic PRNGs, even in a multi-threaded program, without interference from other parts of the program.

module State : sig ... end
val get_state : unit -> State.t

get_state() returns a fresh copy of the current state of the domain-local generator (which is used by the basic functions).

val set_state : State.t -> unit

set_state s updates the current state of the domain-local generator (which is used by the basic functions) by copying the state s into it.

val split : unit -> State.t

Draw a fresh PRNG state from the current state of the domain-local generator used by the default functions. (The state of the domain-local generator is modified.) See Random.State.split.

  • since 5.0
diff --git a/docs/stdlib/Stdlib/Result/index.html b/docs/stdlib/Stdlib/Result/index.html new file mode 100644 index 00000000..ac8ef48f --- /dev/null +++ b/docs/stdlib/Stdlib/Result/index.html @@ -0,0 +1,12 @@ + +Result (docs.stdlib.Stdlib.Result)

Module Stdlib.Result

Result values.

Result values handle computation results and errors in an explicit and declarative manner without resorting to exceptions.

  • since 4.08

Results

type ('a, 'e) t = ('a, 'e) result =
  1. | Ok of 'a
  2. | Error of 'e

The type for result values. Either a value Ok v or an error Error e.

val ok : 'a -> ('a, 'e) result

ok v is Ok v.

val error : 'e -> ('a, 'e) result

error e is Error e.

val value : ('a, 'e) result -> default:'a -> 'a

value r ~default is v if r is Ok v and default otherwise.

val get_ok : ('a, 'e) result -> 'a

get_ok r is v if r is Ok v and raise otherwise.

val get_error : ('a, 'e) result -> 'e

get_error r is e if r is Error e and raise otherwise.

val bind : ('a, 'e) result -> ('a -> ('b, 'e) result) -> ('b, 'e) result

bind r f is f v if r is Ok v and r if r is Error _.

val join : (('a, 'e) result, 'e) result -> ('a, 'e) result

join rr is r if rr is Ok r and rr if rr is Error _.

val map : ('a -> 'b) -> ('a, 'e) result -> ('b, 'e) result

map f r is Ok (f v) if r is Ok v and r if r is Error _.

val map_error : ('e -> 'f) -> ('a, 'e) result -> ('a, 'f) result

map_error f r is Error (f e) if r is Error e and r if r is Ok _.

val fold : ok:('a -> 'c) -> error:('e -> 'c) -> ('a, 'e) result -> 'c

fold ~ok ~error r is ok v if r is Ok v and error e if r is Error e.

val iter : ('a -> unit) -> ('a, 'e) result -> unit

iter f r is f v if r is Ok v and () otherwise.

val iter_error : ('e -> unit) -> ('a, 'e) result -> unit

iter_error f r is f e if r is Error e and () otherwise.

Predicates and comparisons

val is_ok : ('a, 'e) result -> bool

is_ok r is true if and only if r is Ok _.

val is_error : ('a, 'e) result -> bool

is_error r is true if and only if r is Error _.

val equal : + ok:('a -> 'a -> bool) -> + error:('e -> 'e -> bool) -> + ('a, 'e) result -> + ('a, 'e) result -> + bool

equal ~ok ~error r0 r1 tests equality of r0 and r1 using ok and error to respectively compare values wrapped by Ok _ and Error _.

val compare : + ok:('a -> 'a -> int) -> + error:('e -> 'e -> int) -> + ('a, 'e) result -> + ('a, 'e) result -> + int

compare ~ok ~error r0 r1 totally orders r0 and r1 using ok and error to respectively compare values wrapped by Ok _ and Error _. Ok _ values are smaller than Error _ values.

Converting

val to_option : ('a, 'e) result -> 'a option

to_option r is r as an option, mapping Ok v to Some v and Error _ to None.

val to_list : ('a, 'e) result -> 'a list

to_list r is [v] if r is Ok v and [] otherwise.

val to_seq : ('a, 'e) result -> 'a Seq.t

to_seq r is r as a sequence. Ok v is the singleton sequence containing v and Error _ is the empty sequence.

diff --git a/docs/stdlib/Stdlib/Scanf/Scanning/index.html b/docs/stdlib/Stdlib/Scanf/Scanning/index.html new file mode 100644 index 00000000..5bf73631 --- /dev/null +++ b/docs/stdlib/Stdlib/Scanf/Scanning/index.html @@ -0,0 +1,2 @@ + +Scanning (docs.stdlib.Stdlib.Scanf.Scanning)

Module Scanf.Scanning

type in_channel

The notion of input channel for the Scanf module: those channels provide all the machinery necessary to read from any source of characters, including a Stdlib.in_channel value. A Scanf.Scanning.in_channel value is also called a formatted input channel or equivalently a scanning buffer. The type Scanning.scanbuf below is an alias for Scanning.in_channel. Note that a Scanning.in_channel is not concurrency-safe: concurrent use may produce arbitrary values or exceptions.

  • since 3.12
type scanbuf = in_channel

The type of scanning buffers. A scanning buffer is the source from which a formatted input function gets characters. The scanning buffer holds the current state of the scan, plus a function to get the next char from the input, and a token buffer to store the string matched so far.

Note: a scanning action may often require to examine one character in advance; when this 'lookahead' character does not belong to the token read, it is stored back in the scanning buffer and becomes the next character yet to be read.

val stdin : in_channel

The standard input notion for the Scanf module. Scanning.stdin is the Scanning.in_channel formatted input channel attached to Stdlib.stdin.

Note: in the interactive system, when input is read from Stdlib.stdin, the newline character that triggers evaluation is part of the input; thus, the scanning specifications must properly skip this additional newline character (for instance, simply add a '\n' as the last character of the format string).

  • since 3.12
type file_name = string

A convenient alias to designate a file name.

  • since 4.00
val open_in : file_name -> in_channel

Scanning.open_in fname returns a Scanning.in_channel formatted input channel for bufferized reading in text mode from file fname.

Note: open_in returns a formatted input channel that efficiently reads characters in large chunks; in contrast, from_channel below returns formatted input channels that must read one character at a time, leading to a much slower scanning rate.

  • since 3.12
val open_in_bin : file_name -> in_channel

Scanning.open_in_bin fname returns a Scanning.in_channel formatted input channel for bufferized reading in binary mode from file fname.

  • since 3.12
val close_in : in_channel -> unit

Closes the Stdlib.in_channel associated with the given Scanning.in_channel formatted input channel.

  • since 3.12
val from_file : file_name -> in_channel

An alias for Scanning.open_in above.

val from_file_bin : string -> in_channel

An alias for Scanning.open_in_bin above.

val from_string : string -> in_channel

Scanning.from_string s returns a Scanning.in_channel formatted input channel which reads from the given string. Reading starts from the first character in the string. The end-of-input condition is set when the end of the string is reached.

val from_function : (unit -> char) -> in_channel

Scanning.from_function f returns a Scanning.in_channel formatted input channel with the given function as its reading method.

When scanning needs one more character, the given function is called.

When the function has no more character to provide, it must signal an end-of-input condition by raising the exception End_of_file.

val from_channel : in_channel -> in_channel

Scanning.from_channel ic returns a Scanning.in_channel formatted input channel which reads from the regular Stdlib.in_channel input channel ic argument. Reading starts at current reading position of ic.

val end_of_input : in_channel -> bool

Scanning.end_of_input ic tests the end-of-input condition of the given Scanning.in_channel formatted input channel.

val beginning_of_input : in_channel -> bool

Scanning.beginning_of_input ic tests the beginning of input condition of the given Scanning.in_channel formatted input channel.

val name_of_input : in_channel -> string

Scanning.name_of_input ic returns the name of the character source for the given Scanning.in_channel formatted input channel.

  • since 3.09
diff --git a/docs/stdlib/Stdlib/Scanf/index.html b/docs/stdlib/Stdlib/Scanf/index.html new file mode 100644 index 00000000..2ecc9601 --- /dev/null +++ b/docs/stdlib/Stdlib/Scanf/index.html @@ -0,0 +1,26 @@ + +Scanf (docs.stdlib.Stdlib.Scanf)

Module Stdlib.Scanf

Formatted input functions.

Introduction

Functional input with format strings

The module Scanf provides formatted input functions or scanners.

The formatted input functions can read from any kind of input, including strings, files, or anything that can return characters. The more general source of characters is named a formatted input channel (or scanning buffer) and has type Scanning.in_channel. The more general formatted input function reads from any scanning buffer and is named bscanf.

Generally speaking, the formatted input functions have 3 arguments:

  • the first argument is a source of characters for the input,
  • the second argument is a format string that specifies the values to read,
  • the third argument is a receiver function that is applied to the values read.

Hence, a typical call to the formatted input function Scanf.bscanf is bscanf ic fmt f, where:

  • ic is a source of characters (typically a formatted input channel with type Scanning.in_channel),
  • fmt is a format string (the same format strings as those used to print material with module Printf or Format),
  • f is a function that has as many arguments as the number of values to read in the input according to fmt.

A simple example

As suggested above, the expression bscanf ic "%d" f reads a decimal integer n from the source of characters ic and returns f n.

For instance,

  • if we use stdin as the source of characters (Scanning.stdin is the predefined formatted input channel that reads from standard input),
  • if we define the receiver f as let f x = x + 1,

then bscanf Scanning.stdin "%d" f reads an integer n from the standard input and returns f n (that is n + 1). Thus, if we evaluate bscanf stdin "%d" f, and then enter 41 at the keyboard, the result we get is 42.

Formatted input as a functional feature

The OCaml scanning facility is reminiscent of the corresponding C feature. However, it is also largely different, simpler, and yet more powerful: the formatted input functions are higher-order functionals and the parameter passing mechanism is just the regular function application not the variable assignment based mechanism which is typical for formatted input in imperative languages; the OCaml format strings also feature useful additions to easily define complex tokens; as expected within a functional programming language, the formatted input functions also support polymorphism, in particular arbitrary interaction with polymorphic user-defined scanners. Furthermore, the OCaml formatted input facility is fully type-checked at compile time.

Unsynchronized accesses

Unsynchronized accesses to a Scanning.in_channel may lead to an invalid Scanning.in_channel state. Thus, concurrent accesses to Scanning.in_channels must be synchronized (for instance with a Mutex.t).

Formatted input channel

module Scanning : sig ... end

Type of formatted input functions

type ('a, 'b, 'c, 'd) scanner = + ('a, Scanning.in_channel, 'b, 'c, 'a -> 'd, 'd) format6 -> + 'c

The type of formatted input scanners: ('a, 'b, 'c, 'd) scanner is the type of a formatted input function that reads from some formatted input channel according to some format string; more precisely, if scan is some formatted input function, then scan + ic fmt f applies f to all the arguments specified by format string fmt, when scan has read those arguments from the Scanning.in_channel formatted input channel ic.

For instance, the Scanf.scanf function below has type ('a, 'b, 'c, 'd) scanner, since it is a formatted input function that reads from Scanning.stdin: scanf fmt f applies f to the arguments specified by fmt, reading those arguments from Stdlib.stdin as expected.

If the format fmt has some %r indications, the corresponding formatted input functions must be provided before receiver function f. For instance, if read_elem is an input function for values of type t, then bscanf ic "%r;" read_elem f reads a value v of type t followed by a ';' character, and returns f v.

  • since 3.10
type ('a, 'b, 'c, 'd) scanner_opt = + ('a, Scanning.in_channel, 'b, 'c, 'a -> 'd option, 'd) format6 -> + 'c
exception Scan_failure of string

When the input can not be read according to the format string specification, formatted input functions typically raise exception Scan_failure.

The general formatted input function

val bscanf : Scanning.in_channel -> ('a, 'b, 'c, 'd) scanner

bscanf ic fmt r1 ... rN f reads characters from the Scanning.in_channel formatted input channel ic and converts them to values according to format string fmt. As a final step, receiver function f is applied to the values read and gives the result of the bscanf call.

For instance, if f is the function fun s i -> i + 1, then Scanf.sscanf "x = 1" "%s = %i" f returns 2.

Arguments r1 to rN are user-defined input functions that read the argument corresponding to the %r conversions specified in the format string.

val bscanf_opt : Scanning.in_channel -> ('a, 'b, 'c, 'd) scanner_opt

Same as Scanf.bscanf, but returns None in case of scanning failure.

  • since 5.0

Format string description

The format string is a character string which contains three types of objects:

  • plain characters, which are simply matched with the characters of the input (with a special case for space and line feed, see space),
  • conversion specifications, each of which causes reading and conversion of one argument for the function f (see conversion),
  • scanning indications to specify boundaries of tokens (see scanning indication).

The space character in format strings

As mentioned above, a plain character in the format string is just matched with the next character of the input; however, two characters are special exceptions to this rule: the space character (' ' or ASCII code 32) and the line feed character ('\n' or ASCII code 10). A space does not match a single space character, but any amount of 'whitespace' in the input. More precisely, a space inside the format string matches any number of tab, space, line feed and carriage return characters. Similarly, a line feed character in the format string matches either a single line feed or a carriage return followed by a line feed.

Matching any amount of whitespace, a space in the format string also matches no amount of whitespace at all; hence, the call bscanf ib + "Price = %d $" (fun p -> p) succeeds and returns 1 when reading an input with various whitespace in it, such as Price = 1 $, Price = 1 $, or even Price=1$.

Conversion specifications in format strings

Conversion specifications consist in the % character, followed by an optional flag, an optional field width, and followed by one or two conversion characters.

The conversion characters and their meanings are:

  • d: reads an optionally signed decimal integer (0-9+).
  • i: reads an optionally signed integer (usual input conventions for decimal (0-9+), hexadecimal (0x[0-9a-f]+ and 0X[0-9A-F]+), octal (0o[0-7]+), and binary (0b[0-1]+) notations are understood).
  • u: reads an unsigned decimal integer.
  • x or X: reads an unsigned hexadecimal integer ([0-9a-fA-F]+).
  • o: reads an unsigned octal integer ([0-7]+).
  • s: reads a string argument that spreads as much as possible, until the following bounding condition holds:

    • a whitespace has been found (see space),
    • a scanning indication (see scanning indication) has been encountered,
    • the end-of-input has been reached.

    Hence, this conversion always succeeds: it returns an empty string if the bounding condition holds when the scan begins.

  • S: reads a delimited string argument (delimiters and special escaped characters follow the lexical conventions of OCaml).
  • c: reads a single character. To test the current input character without reading it, specify a null field width, i.e. use specification %0c. Raise Invalid_argument, if the field width specification is greater than 1.
  • C: reads a single delimited character (delimiters and special escaped characters follow the lexical conventions of OCaml).
  • f, e, E, g, G: reads an optionally signed floating-point number in decimal notation, in the style dddd.ddd + e/E+-dd.
  • h, H: reads an optionally signed floating-point number in hexadecimal notation.
  • F: reads a floating point number according to the lexical conventions of OCaml (hence the decimal point is mandatory if the exponent part is not mentioned).
  • B: reads a boolean argument (true or false).
  • b: reads a boolean argument (for backward compatibility; do not use in new programs).
  • ld, li, lu, lx, lX, lo: reads an int32 argument to the format specified by the second letter for regular integers.
  • nd, ni, nu, nx, nX, no: reads a nativeint argument to the format specified by the second letter for regular integers.
  • Ld, Li, Lu, Lx, LX, Lo: reads an int64 argument to the format specified by the second letter for regular integers.
  • [ range ]: reads characters that matches one of the characters mentioned in the range of characters range (or not mentioned in it, if the range starts with ^). Reads a string that can be empty, if the next input character does not match the range. The set of characters from c1 to c2 (inclusively) is denoted by c1-c2. Hence, %[0-9] returns a string representing a decimal number or an empty string if no decimal digit is found; similarly, %[0-9a-f] returns a string of hexadecimal digits. If a closing bracket appears in a range, it must occur as the first character of the range (or just after the ^ in case of range negation); hence []] matches a ] character and [^]] matches any character that is not ]. Use %% and %@ to include a % or a @ in a range.
  • r: user-defined reader. Takes the next ri formatted input function and applies it to the scanning buffer ib to read the next argument. The input function ri must therefore have type Scanning.in_channel -> 'a and the argument read has type 'a.
  • { fmt %}: reads a format string argument. The format string read must have the same type as the format string specification fmt. For instance, "%{ %i %}" reads any format string that can read a value of type int; hence, if s is the string "fmt:\"number is %u\"", then Scanf.sscanf s "fmt: %{%i%}" succeeds and returns the format string "number is %u".
  • ( fmt %): scanning sub-format substitution. Reads a format string rf in the input, then goes on scanning with rf instead of scanning with fmt. The format string rf must have the same type as the format string specification fmt that it replaces. For instance, "%( %i %)" reads any format string that can read a value of type int. The conversion returns the format string read rf, and then a value read using rf. Hence, if s is the string "\"%4d\"1234.00", then Scanf.sscanf s "%(%i%)" (fun fmt i -> fmt, i) evaluates to ("%4d", 1234). This behaviour is not mere format substitution, since the conversion returns the format string read as additional argument. If you need pure format substitution, use special flag _ to discard the extraneous argument: conversion %_( fmt %) reads a format string rf and then behaves the same as format string rf. Hence, if s is the string "\"%4d\"1234.00", then Scanf.sscanf s "%_(%i%)" is simply equivalent to Scanf.sscanf "1234.00" "%4d".
  • l: returns the number of lines read so far.
  • n: returns the number of characters read so far.
  • N or L: returns the number of tokens read so far.
  • !: matches the end of input condition.
  • %: matches one % character in the input.
  • @: matches one @ character in the input.
  • ,: does nothing.

Following the % character that introduces a conversion, there may be the special flag _: the conversion that follows occurs as usual, but the resulting value is discarded. For instance, if f is the function fun i -> i + 1, and s is the string "x = 1", then Scanf.sscanf s "%_s = %i" f returns 2.

The field width is composed of an optional integer literal indicating the maximal width of the token to read. For instance, %6d reads an integer, having at most 6 decimal digits; %4f reads a float with at most 4 characters; and %8[\000-\255] returns the next 8 characters (or all the characters still available, if fewer than 8 characters are available in the input).

Notes:

  • as mentioned above, a %s conversion always succeeds, even if there is nothing to read in the input: in this case, it simply returns "".
  • in addition to the relevant digits, '_' characters may appear inside numbers (this is reminiscent to the usual OCaml lexical conventions). If stricter scanning is desired, use the range conversion facility instead of the number conversions.
  • the scanf facility is not intended for heavy duty lexical analysis and parsing. If it appears not expressive enough for your needs, several alternative exists: regular expressions (module Str), stream parsers, ocamllex-generated lexers, ocamlyacc-generated parsers.

Scanning indications in format strings

Scanning indications appear just after the string conversions %s and %[ range ] to delimit the end of the token. A scanning indication is introduced by a @ character, followed by some plain character c. It means that the string token should end just before the next matching c (which is skipped). If no c character is encountered, the string token spreads as much as possible. For instance, "%s@\t" reads a string up to the next tab character or to the end of input. If a @ character appears anywhere else in the format string, it is treated as a plain character.

Note:

  • As usual in format strings, % and @ characters must be escaped using %% and %@; this rule still holds within range specifications and scanning indications. For instance, format "%s@%%" reads a string up to the next % character, and format "%s@%@" reads a string up to the next @.
  • The scanning indications introduce slight differences in the syntax of Scanf format strings, compared to those used for the Printf module. However, the scanning indications are similar to those used in the Format module; hence, when producing formatted text to be scanned by Scanf.bscanf, it is wise to use printing functions from the Format module (or, if you need to use functions from Printf, banish or carefully double check the format strings that contain '@' characters).

Exceptions during scanning

Scanners may raise the following exceptions when the input cannot be read according to the format string:

  • Raise Failure if a conversion to a number is not possible.
  • Raise End_of_file if the end of input is encountered while some more characters are needed to read the current conversion specification.
  • Raise Invalid_argument if the format string is invalid.

Note:

  • as a consequence, scanning a %s conversion never raises exception End_of_file: if the end of input is reached the conversion succeeds and simply returns the characters read so far, or "" if none were ever read.

Specialised formatted input functions

val sscanf : string -> ('a, 'b, 'c, 'd) scanner

Same as Scanf.bscanf, but reads from the given string.

val sscanf_opt : string -> ('a, 'b, 'c, 'd) scanner_opt

Same as Scanf.sscanf, but returns None in case of scanning failure.

  • since 5.0
val scanf : ('a, 'b, 'c, 'd) scanner

Same as Scanf.bscanf, but reads from the predefined formatted input channel Scanf.Scanning.stdin that is connected to Stdlib.stdin.

val scanf_opt : ('a, 'b, 'c, 'd) scanner_opt

Same as Scanf.scanf, but returns None in case of scanning failure.

  • since 5.0
val kscanf : + Scanning.in_channel -> + (Scanning.in_channel -> exn -> 'd) -> + ('a, 'b, 'c, 'd) scanner

Same as Scanf.bscanf, but takes an additional function argument ef that is called in case of error: if the scanning process or some conversion fails, the scanning function aborts and calls the error handling function ef with the formatted input channel and the exception that aborted the scanning process as arguments.

val ksscanf : + string -> + (Scanning.in_channel -> exn -> 'd) -> + ('a, 'b, 'c, 'd) scanner

Same as Scanf.kscanf but reads from the given string.

  • since 4.02

Reading format strings from input

val bscanf_format : + Scanning.in_channel -> + ('a, 'b, 'c, 'd, 'e, 'f) format6 -> + (('a, 'b, 'c, 'd, 'e, 'f) format6 -> 'g) -> + 'g

bscanf_format ic fmt f reads a format string token from the formatted input channel ic, according to the given format string fmt, and applies f to the resulting format string value.

  • raises Scan_failure

    if the format string value read does not have the same type as fmt.

  • since 3.09
val sscanf_format : + string -> + ('a, 'b, 'c, 'd, 'e, 'f) format6 -> + (('a, 'b, 'c, 'd, 'e, 'f) format6 -> 'g) -> + 'g

Same as Scanf.bscanf_format, but reads from the given string.

  • since 3.09
val format_from_string : + string -> + ('a, 'b, 'c, 'd, 'e, 'f) format6 -> + ('a, 'b, 'c, 'd, 'e, 'f) format6

format_from_string s fmt converts a string argument to a format string, according to the given format string fmt.

  • raises Scan_failure

    if s, considered as a format string, does not have the same type as fmt.

  • since 3.10
val unescaped : string -> string

unescaped s return a copy of s with escape sequences (according to the lexical conventions of OCaml) replaced by their corresponding special characters. More precisely, Scanf.unescaped has the following property: for all string s, Scanf.unescaped (String.escaped s) = s.

Always return a copy of the argument, even if there is no escape sequence in the argument.

  • raises Scan_failure

    if s is not properly escaped (i.e. s has invalid escape sequences or special characters that are not properly escaped). For instance, Scanf.unescaped "\"" will fail.

  • since 4.00
diff --git a/docs/stdlib/Stdlib/Semaphore/Binary/index.html b/docs/stdlib/Stdlib/Semaphore/Binary/index.html new file mode 100644 index 00000000..9568f578 --- /dev/null +++ b/docs/stdlib/Stdlib/Semaphore/Binary/index.html @@ -0,0 +1,2 @@ + +Binary (docs.stdlib.Stdlib.Semaphore.Binary)

Module Semaphore.Binary

type t

The type of binary semaphores.

val make : bool -> t

make b returns a new binary semaphore. If b is true, the initial value of the semaphore is 1, meaning "available". If b is false, the initial value of the semaphore is 0, meaning "unavailable".

val release : t -> unit

release s sets the value of semaphore s to 1, putting it in the "available" state. If other threads are waiting on s, one of them is restarted.

val acquire : t -> unit

acquire s blocks the calling thread until the semaphore s has value 1 (is available), then atomically sets it to 0 and returns.

val try_acquire : t -> bool

try_acquire s immediately returns false if the semaphore s has value 0. If s has value 1, its value is atomically set to 0 and try_acquire s returns true.

diff --git a/docs/stdlib/Stdlib/Semaphore/Counting/index.html b/docs/stdlib/Stdlib/Semaphore/Counting/index.html new file mode 100644 index 00000000..3568998d --- /dev/null +++ b/docs/stdlib/Stdlib/Semaphore/Counting/index.html @@ -0,0 +1,2 @@ + +Counting (docs.stdlib.Stdlib.Semaphore.Counting)

Module Semaphore.Counting

type t

The type of counting semaphores.

val make : int -> t

make n returns a new counting semaphore, with initial value n. The initial value n must be nonnegative.

val release : t -> unit

release s increments the value of semaphore s. If other threads are waiting on s, one of them is restarted. If the current value of s is equal to max_int, the value of the semaphore is unchanged and a Sys_error exception is raised to signal overflow.

  • raises Sys_error

    if the value of the semaphore would overflow max_int

val acquire : t -> unit

acquire s blocks the calling thread until the value of semaphore s is not zero, then atomically decrements the value of s and returns.

val try_acquire : t -> bool

try_acquire s immediately returns false if the value of semaphore s is zero. Otherwise, the value of s is atomically decremented and try_acquire s returns true.

val get_value : t -> int

get_value s returns the current value of semaphore s. The current value can be modified at any time by concurrent release and acquire operations. Hence, the get_value operation is racy, and its result should only be used for debugging or informational messages.

diff --git a/docs/stdlib/Stdlib/Semaphore/index.html b/docs/stdlib/Stdlib/Semaphore/index.html new file mode 100644 index 00000000..ce6c3ae2 --- /dev/null +++ b/docs/stdlib/Stdlib/Semaphore/index.html @@ -0,0 +1,2 @@ + +Semaphore (docs.stdlib.Stdlib.Semaphore)

Module Stdlib.Semaphore

Semaphores

A semaphore is a thread synchronization device that can be used to control access to a shared resource.

Two flavors of semaphores are provided: counting semaphores and binary semaphores.

  • since 4.12

Counting semaphores

A counting semaphore is a counter that can be accessed concurrently by several threads. The typical use is to synchronize producers and consumers of a resource by counting how many units of the resource are available.

The two basic operations on semaphores are:

  • "release" (also called "V", "post", "up", and "signal"), which increments the value of the counter. This corresponds to producing one more unit of the shared resource and making it available to others.
  • "acquire" (also called "P", "wait", "down", and "pend"), which waits until the counter is greater than zero and decrements it. This corresponds to consuming one unit of the shared resource.
  • since 4.12
module Counting : sig ... end

Binary semaphores

Binary semaphores are a variant of counting semaphores where semaphores can only take two values, 0 and 1.

A binary semaphore can be used to control access to a single shared resource, with value 1 meaning "resource is available" and value 0 meaning "resource is unavailable".

The "release" operation of a binary semaphore sets its value to 1, and "acquire" waits until the value is 1 and sets it to 0.

A binary semaphore can be used instead of a mutex (see module Mutex) when the mutex discipline (of unlocking the mutex from the thread that locked it) is too restrictive. The "acquire" operation corresponds to locking the mutex, and the "release" operation to unlocking it, but "release" can be performed in a thread different than the one that performed the "acquire". Likewise, it is safe to release a binary semaphore that is already available.

  • since 4.12
module Binary : sig ... end
diff --git a/docs/stdlib/Stdlib/Seq/index.html b/docs/stdlib/Stdlib/Seq/index.html new file mode 100644 index 00000000..51205bc4 --- /dev/null +++ b/docs/stdlib/Stdlib/Seq/index.html @@ -0,0 +1,2 @@ + +Seq (docs.stdlib.Stdlib.Seq)

Module Stdlib.Seq

Sequences.

A sequence of type 'a Seq.t can be thought of as a delayed list, that is, a list whose elements are computed only when they are demanded by a consumer. This allows sequences to be produced and transformed lazily (one element at a time) rather than eagerly (all elements at once). This also allows constructing conceptually infinite sequences.

The type 'a Seq.t is defined as a synonym for unit -> 'a Seq.node. This is a function type: therefore, it is opaque. The consumer can query a sequence in order to request the next element (if there is one), but cannot otherwise inspect the sequence in any way.

Because it is opaque, the type 'a Seq.t does not reveal whether a sequence is:

  • persistent, which means that the sequence can be used as many times as desired, producing the same elements every time, just like an immutable list; or
  • ephemeral, which means that the sequence is not persistent. Querying an ephemeral sequence might have an observable side effect, such as incrementing a mutable counter. As a common special case, an ephemeral sequence can be affine, which means that it must be queried at most once.

It also does not reveal whether the elements of the sequence are:

  • pre-computed and stored in memory, which means that querying the sequence is cheap;
  • computed when first demanded and then stored in memory, which means that querying the sequence once can be expensive, but querying the same sequence again is cheap; or
  • re-computed every time they are demanded, which may or may not be cheap.

It is up to the programmer to keep these distinctions in mind so as to understand the time and space requirements of sequences.

For the sake of simplicity, most of the documentation that follows is written under the implicit assumption that the sequences at hand are persistent. We normally do not point out when or how many times each function is invoked, because that would be too verbose. For instance, in the description of map, we write: "if xs is the sequence x0; x1; ... then map f xs is the sequence f x0; f x1; ...". If we wished to be more explicit, we could point out that the transformation takes place on demand: that is, the elements of map f xs are computed only when they are demanded. In other words, the definition let ys = map f xs terminates immediately and does not invoke f. The function call f x0 takes place only when the first element of ys is demanded, via the function call ys(). Furthermore, calling ys() twice causes f x0 to be called twice as well. If one wishes for f to be applied at most once to each element of xs, even in scenarios where ys is queried more than once, then one should use let ys = memoize (map f xs).

As a general rule, the functions that build sequences, such as map, filter, scan, take, etc., produce sequences whose elements are computed only on demand. The functions that eagerly consume sequences, such as is_empty, find, length, iter, fold_left, etc., are the functions that force computation to take place.

When possible, we recommend using sequences rather than dispensers (functions of type unit -> 'a option that produce elements upon demand). Whereas sequences can be persistent or ephemeral, dispensers are always ephemeral, and are typically more difficult to work with than sequences. Two conversion functions, to_dispenser and of_dispenser, are provided.

  • since 4.07
type 'a t = unit -> 'a node

A sequence xs of type 'a t is a delayed list of elements of type 'a. Such a sequence is queried by performing a function application xs(). This function application returns a node, allowing the caller to determine whether the sequence is empty or nonempty, and in the latter case, to obtain its head and tail.

and +'a node =
  1. | Nil
  2. | Cons of 'a * 'a t

A node is either Nil, which means that the sequence is empty, or Cons (x, xs), which means that x is the first element of the sequence and that xs is the remainder of the sequence.

Consuming sequences

The functions in this section consume their argument, a sequence, either partially or completely:

  • is_empty and uncons consume the sequence down to depth 1. That is, they demand the first argument of the sequence, if there is one.
  • iter, fold_left, length, etc., consume the sequence all the way to its end. They terminate only if the sequence is finite.
  • for_all, exists, find, etc. consume the sequence down to a certain depth, which is a priori unpredictable.

Similarly, among the functions that consume two sequences, one can distinguish two groups:

  • iter2 and fold_left2 consume both sequences all the way to the end, provided the sequences have the same length.
  • for_all2, exists2, equal, compare consume the sequences down to a certain depth, which is a priori unpredictable.

The functions that consume two sequences can be applied to two sequences of distinct lengths: in that case, the excess elements in the longer sequence are ignored. (It may be the case that one excess element is demanded, even though this element is not used.)

None of the functions in this section is lazy. These functions are consumers: they force some computation to take place.

val is_empty : 'a t -> bool

is_empty xs determines whether the sequence xs is empty.

It is recommended that the sequence xs be persistent. Indeed, is_empty xs demands the head of the sequence xs, so, if xs is ephemeral, it may be the case that xs cannot be used any more after this call has taken place.

  • since 4.14
val uncons : 'a t -> ('a * 'a t) option

If xs is empty, then uncons xs is None.

If xs is nonempty, then uncons xs is Some (x, ys) where x is the head of the sequence and ys its tail.

  • since 4.14
val length : 'a t -> int

length xs is the length of the sequence xs.

The sequence xs must be finite.

  • since 4.14
val iter : ('a -> unit) -> 'a t -> unit

iter f xs invokes f x successively for every element x of the sequence xs, from left to right.

It terminates only if the sequence xs is finite.

val fold_left : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc

fold_left f _ xs invokes f _ x successively for every element x of the sequence xs, from left to right.

An accumulator of type 'a is threaded through the calls to f.

It terminates only if the sequence xs is finite.

val iteri : (int -> 'a -> unit) -> 'a t -> unit

iteri f xs invokes f i x successively for every element x located at index i in the sequence xs.

It terminates only if the sequence xs is finite.

iteri f xs is equivalent to iter (fun (i, x) -> f i x) (zip (ints 0) xs).

  • since 4.14
val fold_lefti : ('acc -> int -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc

fold_lefti f _ xs invokes f _ i x successively for every element x located at index i of the sequence xs.

An accumulator of type 'b is threaded through the calls to f.

It terminates only if the sequence xs is finite.

fold_lefti f accu xs is equivalent to fold_left (fun accu (i, x) -> f accu i x) accu (zip (ints 0) xs).

  • since 4.14
val for_all : ('a -> bool) -> 'a t -> bool

for_all p xs determines whether all elements x of the sequence xs satisfy p x.

The sequence xs must be finite.

  • since 4.14
val exists : ('a -> bool) -> 'a t -> bool

exists xs p determines whether at least one element x of the sequence xs satisfies p x.

The sequence xs must be finite.

  • since 4.14
val find : ('a -> bool) -> 'a t -> 'a option

find p xs returns Some x, where x is the first element of the sequence xs that satisfies p x, if there is such an element.

It returns None if there is no such element.

The sequence xs must be finite.

  • since 4.14
val find_index : ('a -> bool) -> 'a t -> int option

find_index p xs returns Some i, where i is the index of the first element of the sequence xs that satisfies p x, if there is such an element.

It returns None if there is no such element.

The sequence xs must be finite.

  • since 5.1
val find_map : ('a -> 'b option) -> 'a t -> 'b option

find_map f xs returns Some y, where x is the first element of the sequence xs such that f x = Some _, if there is such an element, and where y is defined by f x = Some y.

It returns None if there is no such element.

The sequence xs must be finite.

  • since 4.14
val find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option

Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.

The sequence xs must be finite.

  • since 5.1
val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit

iter2 f xs ys invokes f x y successively for every pair (x, y) of elements drawn synchronously from the sequences xs and ys.

If the sequences xs and ys have different lengths, then iteration stops as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.

Iteration terminates only if at least one of the sequences xs and ys is finite.

iter2 f xs ys is equivalent to iter (fun (x, y) -> f x y) (zip xs ys).

  • since 4.14
val fold_left2 : ('acc -> 'a -> 'b -> 'acc) -> 'acc -> 'a t -> 'b t -> 'acc

fold_left2 f _ xs ys invokes f _ x y successively for every pair (x, y) of elements drawn synchronously from the sequences xs and ys.

An accumulator of type 'a is threaded through the calls to f.

If the sequences xs and ys have different lengths, then iteration stops as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.

Iteration terminates only if at least one of the sequences xs and ys is finite.

fold_left2 f accu xs ys is equivalent to fold_left (fun accu (x, y) -> f accu x y) (zip xs ys).

  • since 4.14
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool

for_all2 p xs ys determines whether all pairs (x, y) of elements drawn synchronously from the sequences xs and ys satisfy p x y.

If the sequences xs and ys have different lengths, then iteration stops as soon as one sequence is exhausted; the excess elements in the other sequence are ignored. In particular, if xs or ys is empty, then for_all2 p xs ys is true. This is where for_all2 and equal differ: equal eq xs ys can be true only if xs and ys have the same length.

At least one of the sequences xs and ys must be finite.

for_all2 p xs ys is equivalent to for_all (fun b -> b) (map2 p xs ys).

  • since 4.14
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool

exists2 p xs ys determines whether some pair (x, y) of elements drawn synchronously from the sequences xs and ys satisfies p x y.

If the sequences xs and ys have different lengths, then iteration must stop as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.

At least one of the sequences xs and ys must be finite.

exists2 p xs ys is equivalent to exists (fun b -> b) (map2 p xs ys).

  • since 4.14
val equal : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool

Provided the function eq defines an equality on elements, equal eq xs ys determines whether the sequences xs and ys are pointwise equal.

At least one of the sequences xs and ys must be finite.

  • since 4.14
val compare : ('a -> 'b -> int) -> 'a t -> 'b t -> int

Provided the function cmp defines a preorder on elements, compare cmp xs ys compares the sequences xs and ys according to the lexicographic preorder.

For more details on comparison functions, see Array.sort.

At least one of the sequences xs and ys must be finite.

  • since 4.14

Constructing sequences

The functions in this section are lazy: that is, they return sequences whose elements are computed only when demanded.

val empty : 'a t

empty is the empty sequence. It has no elements. Its length is 0.

val return : 'a -> 'a t

return x is the sequence whose sole element is x. Its length is 1.

val cons : 'a -> 'a t -> 'a t

cons x xs is the sequence that begins with the element x, followed with the sequence xs.

Writing cons (f()) xs causes the function call f() to take place immediately. For this call to be delayed until the sequence is queried, one must instead write (fun () -> Cons(f(), xs)).

  • since 4.11
val init : int -> (int -> 'a) -> 'a t

init n f is the sequence f 0; f 1; ...; f (n-1).

n must be nonnegative.

If desired, the infinite sequence f 0; f 1; ... can be defined as map f (ints 0).

  • since 4.14
val unfold : ('b -> ('a * 'b) option) -> 'b -> 'a t

unfold constructs a sequence out of a step function and an initial state.

If f u is None then unfold f u is the empty sequence. If f u is Some (x, u') then unfold f u is the nonempty sequence cons x (unfold f u').

For example, unfold (function [] -> None | h :: t -> Some (h, t)) l is equivalent to List.to_seq l.

  • since 4.11
val repeat : 'a -> 'a t

repeat x is the infinite sequence where the element x is repeated indefinitely.

repeat x is equivalent to cycle (return x).

  • since 4.14
val forever : (unit -> 'a) -> 'a t

forever f is an infinite sequence where every element is produced (on demand) by the function call f().

For instance, forever Random.bool is an infinite sequence of random bits.

forever f is equivalent to map f (repeat ()).

  • since 4.14
val cycle : 'a t -> 'a t

cycle xs is the infinite sequence that consists of an infinite number of repetitions of the sequence xs.

If xs is an empty sequence, then cycle xs is empty as well.

Consuming (a prefix of) the sequence cycle xs once can cause the sequence xs to be consumed more than once. Therefore, xs must be persistent.

  • since 4.14
val iterate : ('a -> 'a) -> 'a -> 'a t

iterate f x is the infinite sequence whose elements are x, f x, f (f x), and so on.

In other words, it is the orbit of the function f, starting at x.

  • since 4.14

Transforming sequences

The functions in this section are lazy: that is, they return sequences whose elements are computed only when demanded.

val map : ('a -> 'b) -> 'a t -> 'b t

map f xs is the image of the sequence xs through the transformation f.

If xs is the sequence x0; x1; ... then map f xs is the sequence f x0; f x1; ....

val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t

mapi is analogous to map, but applies the function f to an index and an element.

mapi f xs is equivalent to map2 f (ints 0) xs.

  • since 4.14
val filter : ('a -> bool) -> 'a t -> 'a t

filter p xs is the sequence of the elements x of xs that satisfy p x.

In other words, filter p xs is the sequence xs, deprived of the elements x such that p x is false.

val filter_map : ('a -> 'b option) -> 'a t -> 'b t

filter_map f xs is the sequence of the elements y such that f x = Some y, where x ranges over xs.

filter_map f xs is equivalent to map Option.get (filter Option.is_some (map f xs)).

val scan : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b t

If xs is a sequence [x0; x1; x2; ...], then scan f a0 xs is a sequence of accumulators [a0; a1; a2; ...] where a1 is f a0 x0, a2 is f a1 x1, and so on.

Thus, scan f a0 xs is conceptually related to fold_left f a0 xs. However, instead of performing an eager iteration and immediately returning the final accumulator, it returns a sequence of accumulators.

For instance, scan (+) 0 transforms a sequence of integers into the sequence of its partial sums.

If xs has length n then scan f a0 xs has length n+1.

  • since 4.14
val take : int -> 'a t -> 'a t

take n xs is the sequence of the first n elements of xs.

If xs has fewer than n elements, then take n xs is equivalent to xs.

n must be nonnegative.

  • since 4.14
val drop : int -> 'a t -> 'a t

drop n xs is the sequence xs, deprived of its first n elements.

If xs has fewer than n elements, then drop n xs is empty.

n must be nonnegative.

drop is lazy: the first n+1 elements of the sequence xs are demanded only when the first element of drop n xs is demanded. For this reason, drop 1 xs is not equivalent to tail xs, which queries xs immediately.

  • since 4.14
val take_while : ('a -> bool) -> 'a t -> 'a t

take_while p xs is the longest prefix of the sequence xs where every element x satisfies p x.

  • since 4.14
val drop_while : ('a -> bool) -> 'a t -> 'a t

drop_while p xs is the sequence xs, deprived of the prefix take_while p xs.

  • since 4.14
val group : ('a -> 'a -> bool) -> 'a t -> 'a t t

Provided the function eq defines an equality on elements, group eq xs is the sequence of the maximal runs of adjacent duplicate elements of the sequence xs.

Every element of group eq xs is a nonempty sequence of equal elements.

The concatenation concat (group eq xs) is equal to xs.

Consuming group eq xs, and consuming the sequences that it contains, can cause xs to be consumed more than once. Therefore, xs must be persistent.

  • since 4.14
val memoize : 'a t -> 'a t

The sequence memoize xs has the same elements as the sequence xs.

Regardless of whether xs is ephemeral or persistent, memoize xs is persistent: even if it is queried several times, xs is queried at most once.

The construction of the sequence memoize xs internally relies on suspensions provided by the module Lazy. These suspensions are not thread-safe. Therefore, the sequence memoize xs must not be queried by multiple threads concurrently.

  • since 4.14
exception Forced_twice

This exception is raised when a sequence returned by once (or a suffix of it) is queried more than once.

  • since 4.14
val once : 'a t -> 'a t

The sequence once xs has the same elements as the sequence xs.

Regardless of whether xs is ephemeral or persistent, once xs is an ephemeral sequence: it can be queried at most once. If it (or a suffix of it) is queried more than once, then the exception Forced_twice is raised. This can be useful, while debugging or testing, to ensure that a sequence is consumed at most once.

  • raises Forced_twice

    if once xs, or a suffix of it, is queried more than once.

  • since 4.14
val transpose : 'a t t -> 'a t t

If xss is a matrix (a sequence of rows), then transpose xss is the sequence of the columns of the matrix xss.

The rows of the matrix xss are not required to have the same length.

The matrix xss is not required to be finite (in either direction).

The matrix xss must be persistent.

  • since 4.14

Combining sequences

val append : 'a t -> 'a t -> 'a t

append xs ys is the concatenation of the sequences xs and ys.

Its elements are the elements of xs, followed by the elements of ys.

  • since 4.11
val concat : 'a t t -> 'a t

If xss is a sequence of sequences, then concat xss is its concatenation.

If xss is the sequence xs0; xs1; ... then concat xss is the sequence xs0 @ xs1 @ ....

  • since 4.13
val flat_map : ('a -> 'b t) -> 'a t -> 'b t

flat_map f xs is equivalent to concat (map f xs).

val concat_map : ('a -> 'b t) -> 'a t -> 'b t

concat_map f xs is equivalent to concat (map f xs).

concat_map is an alias for flat_map.

  • since 4.13
val zip : 'a t -> 'b t -> ('a * 'b) t

zip xs ys is the sequence of pairs (x, y) drawn synchronously from the sequences xs and ys.

If the sequences xs and ys have different lengths, then the sequence ends as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.

zip xs ys is equivalent to map2 (fun a b -> (a, b)) xs ys.

  • since 4.14
val map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t

map2 f xs ys is the sequence of the elements f x y, where the pairs (x, y) are drawn synchronously from the sequences xs and ys.

If the sequences xs and ys have different lengths, then the sequence ends as soon as one sequence is exhausted; the excess elements in the other sequence are ignored.

map2 f xs ys is equivalent to map (fun (x, y) -> f x y) (zip xs ys).

  • since 4.14
val interleave : 'a t -> 'a t -> 'a t

interleave xs ys is the sequence that begins with the first element of xs, continues with the first element of ys, and so on.

When one of the sequences xs and ys is exhausted, interleave xs ys continues with the rest of the other sequence.

  • since 4.14
val sorted_merge : ('a -> 'a -> int) -> 'a t -> 'a t -> 'a t

If the sequences xs and ys are sorted according to the total preorder cmp, then sorted_merge cmp xs ys is the sorted sequence obtained by merging the sequences xs and ys.

For more details on comparison functions, see Array.sort.

  • since 4.14
val product : 'a t -> 'b t -> ('a * 'b) t

product xs ys is the Cartesian product of the sequences xs and ys.

For every element x of xs and for every element y of ys, the pair (x, y) appears once as an element of product xs ys.

The order in which the pairs appear is unspecified.

The sequences xs and ys are not required to be finite.

The sequences xs and ys must be persistent.

  • since 4.14
val map_product : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c t

The sequence map_product f xs ys is the image through f of the Cartesian product of the sequences xs and ys.

For every element x of xs and for every element y of ys, the element f x y appears once as an element of map_product f xs ys.

The order in which these elements appear is unspecified.

The sequences xs and ys are not required to be finite.

The sequences xs and ys must be persistent.

map_product f xs ys is equivalent to map (fun (x, y) -> f x y) (product xs ys).

  • since 4.14

Splitting a sequence into two sequences

val unzip : ('a * 'b) t -> 'a t * 'b t

unzip transforms a sequence of pairs into a pair of sequences.

unzip xs is equivalent to (map fst xs, map snd xs).

Querying either of the sequences returned by unzip xs causes xs to be queried. Therefore, querying both of them causes xs to be queried twice. Thus, xs must be persistent and cheap. If that is not the case, use unzip (memoize xs).

  • since 4.14
val split : ('a * 'b) t -> 'a t * 'b t

split is an alias for unzip.

  • since 4.14
val partition_map : ('a -> ('b, 'c) Either.t) -> 'a t -> 'b t * 'c t

partition_map f xs returns a pair of sequences (ys, zs), where:

  • ys is the sequence of the elements y such that f x = Left y, where x ranges over xs;
  • zs is the sequence of the elements z such that f x = Right z, where x ranges over xs.

partition_map f xs is equivalent to a pair of filter_map Either.find_left (map f xs) and filter_map Either.find_right (map f xs).

Querying either of the sequences returned by partition_map f xs causes xs to be queried. Therefore, querying both of them causes xs to be queried twice. Thus, xs must be persistent and cheap. If that is not the case, use partition_map f (memoize xs).

  • since 4.14
val partition : ('a -> bool) -> 'a t -> 'a t * 'a t

partition p xs returns a pair of the subsequence of the elements of xs that satisfy p and the subsequence of the elements of xs that do not satisfy p.

partition p xs is equivalent to filter p xs, filter (fun x -> not (p x)) xs.

Consuming both of the sequences returned by partition p xs causes xs to be consumed twice and causes the function f to be applied twice to each element of the list. Therefore, f should be pure and cheap. Furthermore, xs should be persistent and cheap. If that is not the case, use partition p (memoize xs).

  • since 4.14

Converting between sequences and dispensers

A dispenser is a representation of a sequence as a function of type unit -> 'a option. Every time this function is invoked, it returns the next element of the sequence. When there are no more elements, it returns None. A dispenser has mutable internal state, therefore is ephemeral: the sequence that it represents can be consumed at most once.

val of_dispenser : (unit -> 'a option) -> 'a t

of_dispenser it is the sequence of the elements produced by the dispenser it. It is an ephemeral sequence: it can be consumed at most once. If a persistent sequence is needed, use memoize (of_dispenser it).

  • since 4.14
val to_dispenser : 'a t -> unit -> 'a option

to_dispenser xs is a fresh dispenser on the sequence xs.

This dispenser has mutable internal state, which is not protected by a lock; so, it must not be used by several threads concurrently.

  • since 4.14

Sequences of integers

val ints : int -> int t

ints i is the infinite sequence of the integers beginning at i and counting up.

  • since 4.14
diff --git a/docs/stdlib/Stdlib/Set/Make/argument-1-Ord/index.html b/docs/stdlib/Stdlib/Set/Make/argument-1-Ord/index.html new file mode 100644 index 00000000..9206d28f --- /dev/null +++ b/docs/stdlib/Stdlib/Set/Make/argument-1-Ord/index.html @@ -0,0 +1,2 @@ + +Ord (docs.stdlib.Stdlib.Set.Make.Ord)

Parameter Make.Ord

type t

The type of the set elements.

val compare : t -> t -> int

A total ordering function over the set elements. This is a two-argument function f such that f e1 e2 is zero if the elements e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/Set/Make/index.html b/docs/stdlib/Stdlib/Set/Make/index.html new file mode 100644 index 00000000..27bff978 --- /dev/null +++ b/docs/stdlib/Stdlib/Set/Make/index.html @@ -0,0 +1,3 @@ + +Make (docs.stdlib.Stdlib.Set.Make)

Module Set.Make

Functor building an implementation of the set structure given a totally ordered type.

Parameters

module Ord : OrderedType

Signature

Sets

type elt = Ord.t

The type of the set elements.

type t

The type of sets.

val empty : t

The empty set.

val add : elt -> t -> t

add x s returns a set containing all elements of s, plus x. If x was already in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val singleton : elt -> t

singleton x returns the one-element set containing only x.

val remove : elt -> t -> t

remove x s returns a set containing all elements of s, except x. If x was not in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val union : t -> t -> t

Set union.

val inter : t -> t -> t

Set intersection.

val disjoint : t -> t -> bool

Test if two sets are disjoint.

  • since 4.08
val diff : t -> t -> t

Set difference: diff s1 s2 contains the elements of s1 that are not in s2.

val cardinal : t -> int

Return the number of elements of a set.

Elements

val elements : t -> elt list

Return the list of all elements of the given set. The returned list is sorted in increasing order with respect to the ordering Ord.compare, where Ord is the argument given to Set.Make.

val min_elt : t -> elt

Return the smallest element of the given set (with respect to the Ord.compare ordering), or raise Not_found if the set is empty.

val min_elt_opt : t -> elt option

Return the smallest element of the given set (with respect to the Ord.compare ordering), or None if the set is empty.

  • since 4.05
val max_elt : t -> elt

Same as min_elt, but returns the largest element of the given set.

val max_elt_opt : t -> elt option

Same as min_elt_opt, but returns the largest element of the given set.

  • since 4.05
val choose : t -> elt

Return one element of the given set, or raise Not_found if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

val choose_opt : t -> elt option

Return one element of the given set, or None if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

  • since 4.05

Searching

val find : elt -> t -> elt

find x s returns the element of s equal to x (according to Ord.compare), or raise Not_found if no such element exists.

  • since 4.01
val find_opt : elt -> t -> elt option

find_opt x s returns the element of s equal to x (according to Ord.compare), or None if no such element exists.

  • since 4.05
val find_first : (elt -> bool) -> t -> elt

find_first f s, where f is a monotonically increasing function, returns the lowest element e of s such that f e, or raises Not_found if no such element exists.

For example, find_first (fun e -> Ord.compare e x >= 0) s will return the first element e of s where Ord.compare e x >= 0 (intuitively: e >= x), or raise Not_found if x is greater than any element of s.

  • since 4.05
val find_first_opt : (elt -> bool) -> t -> elt option

find_first_opt f s, where f is a monotonically increasing function, returns an option containing the lowest element e of s such that f e, or None if no such element exists.

  • since 4.05
val find_last : (elt -> bool) -> t -> elt

find_last f s, where f is a monotonically decreasing function, returns the highest element e of s such that f e, or raises Not_found if no such element exists.

  • since 4.05
val find_last_opt : (elt -> bool) -> t -> elt option

find_last_opt f s, where f is a monotonically decreasing function, returns an option containing the highest element e of s such that f e, or None if no such element exists.

  • since 4.05

Traversing

val iter : (elt -> unit) -> t -> unit

iter f s applies f in turn to all elements of s. The elements of s are presented to f in increasing order with respect to the ordering over the type of the elements.

val fold : (elt -> 'acc -> 'acc) -> t -> 'acc -> 'acc

fold f s init computes (f xN ... (f x2 (f x1 init))...), where x1 ... xN are the elements of s, in increasing order.

Transforming

val map : (elt -> elt) -> t -> t

map f s is the set whose elements are f a0,f a1... f + aN, where a0,a1...aN are the elements of s.

The elements are passed to f in increasing order with respect to the ordering over the type of the elements.

If no element of s is changed by f, s is returned unchanged. (If each output of f is physically equal to its input, the returned set is physically equal to s.)

  • since 4.04
val filter : (elt -> bool) -> t -> t

filter f s returns the set of all elements in s that satisfy predicate f. If f satisfies every element in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val filter_map : (elt -> elt option) -> t -> t

filter_map f s returns the set of all v such that f x = Some v for some element x of s.

For example,

filter_map (fun n -> if n mod 2 = 0 then Some (n / 2) else None) s

is the set of halves of the even elements of s.

If no element of s is changed or dropped by f (if f x = Some x for each element x), then s is returned unchanged: the result of the function is then physically equal to s.

  • since 4.11
val partition : (elt -> bool) -> t -> t * t

partition f s returns a pair of sets (s1, s2), where s1 is the set of all the elements of s that satisfy the predicate f, and s2 is the set of all the elements of s that do not satisfy f.

val split : elt -> t -> t * bool * t

split x s returns a triple (l, present, r), where l is the set of elements of s that are strictly less than x; r is the set of elements of s that are strictly greater than x; present is false if s contains no element equal to x, or true if s contains an element equal to x.

Predicates and comparisons

val is_empty : t -> bool

Test whether a set is empty or not.

val mem : elt -> t -> bool

mem x s tests whether x belongs to the set s.

val equal : t -> t -> bool

equal s1 s2 tests whether the sets s1 and s2 are equal, that is, contain equal elements.

val compare : t -> t -> int

Total ordering between sets. Can be used as the ordering function for doing sets of sets.

val subset : t -> t -> bool

subset s1 s2 tests whether the set s1 is a subset of the set s2.

val for_all : (elt -> bool) -> t -> bool

for_all f s checks if all elements of the set satisfy the predicate f.

val exists : (elt -> bool) -> t -> bool

exists f s checks if at least one element of the set satisfies the predicate f.

Converting

val to_list : t -> elt list

to_list s is elements s.

  • since 5.1
val of_list : elt list -> t

of_list l creates a set from a list of elements. This is usually more efficient than folding add over the list, except perhaps for lists with many duplicated elements.

  • since 4.02
val to_seq_from : elt -> t -> elt Seq.t

to_seq_from x s iterates on a subset of the elements of s in ascending order, from x or above.

  • since 4.07
val to_seq : t -> elt Seq.t

Iterate on the whole set, in ascending order

  • since 4.07
val to_rev_seq : t -> elt Seq.t

Iterate on the whole set, in descending order

  • since 4.12
val add_seq : elt Seq.t -> t -> t

Add the given elements to the set, in order.

  • since 4.07
val of_seq : elt Seq.t -> t

Build a set from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/Set/index.html b/docs/stdlib/Stdlib/Set/index.html new file mode 100644 index 00000000..4016f6a7 --- /dev/null +++ b/docs/stdlib/Stdlib/Set/index.html @@ -0,0 +1,13 @@ + +Set (docs.stdlib.Stdlib.Set)

Module Stdlib.Set

Sets over ordered types.

This module implements the set data structure, given a total ordering function over the set elements. All operations over sets are purely applicative (no side-effects). The implementation uses balanced binary trees, and is therefore reasonably efficient: insertion and membership take time logarithmic in the size of the set, for instance.

The Make functor constructs implementations for any type, given a compare function. For instance:

module IntPairs =
+  struct
+    type t = int * int
+    let compare (x0,y0) (x1,y1) =
+      match Stdlib.compare x0 x1 with
+          0 -> Stdlib.compare y0 y1
+        | c -> c
+  end
+
+module PairsSet = Set.Make(IntPairs)
+
+let m = PairsSet.(empty |> add (2,3) |> add (5,7) |> add (11,13))

This creates a new module PairsSet, with a new type PairsSet.t of sets of int * int.

module type OrderedType = sig ... end

Input signature of the functor Make.

module type S = sig ... end

Output signature of the functor Make.

module Make (Ord : OrderedType) : S with type elt = Ord.t

Functor building an implementation of the set structure given a totally ordered type.

diff --git a/docs/stdlib/Stdlib/Set/module-type-OrderedType/index.html b/docs/stdlib/Stdlib/Set/module-type-OrderedType/index.html new file mode 100644 index 00000000..29e67b99 --- /dev/null +++ b/docs/stdlib/Stdlib/Set/module-type-OrderedType/index.html @@ -0,0 +1,2 @@ + +OrderedType (docs.stdlib.Stdlib.Set.OrderedType)

Module type Set.OrderedType

Input signature of the functor Make.

type t

The type of the set elements.

val compare : t -> t -> int

A total ordering function over the set elements. This is a two-argument function f such that f e1 e2 is zero if the elements e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2. Example: a suitable ordering function is the generic structural comparison function Stdlib.compare.

diff --git a/docs/stdlib/Stdlib/Set/module-type-S/index.html b/docs/stdlib/Stdlib/Set/module-type-S/index.html new file mode 100644 index 00000000..6cdb3dda --- /dev/null +++ b/docs/stdlib/Stdlib/Set/module-type-S/index.html @@ -0,0 +1,3 @@ + +S (docs.stdlib.Stdlib.Set.S)

Module type Set.S

Output signature of the functor Make.

Sets

type elt

The type of the set elements.

type t

The type of sets.

val empty : t

The empty set.

val add : elt -> t -> t

add x s returns a set containing all elements of s, plus x. If x was already in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val singleton : elt -> t

singleton x returns the one-element set containing only x.

val remove : elt -> t -> t

remove x s returns a set containing all elements of s, except x. If x was not in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val union : t -> t -> t

Set union.

val inter : t -> t -> t

Set intersection.

val disjoint : t -> t -> bool

Test if two sets are disjoint.

  • since 4.08
val diff : t -> t -> t

Set difference: diff s1 s2 contains the elements of s1 that are not in s2.

val cardinal : t -> int

Return the number of elements of a set.

Elements

val elements : t -> elt list

Return the list of all elements of the given set. The returned list is sorted in increasing order with respect to the ordering Ord.compare, where Ord is the argument given to Set.Make.

val min_elt : t -> elt

Return the smallest element of the given set (with respect to the Ord.compare ordering), or raise Not_found if the set is empty.

val min_elt_opt : t -> elt option

Return the smallest element of the given set (with respect to the Ord.compare ordering), or None if the set is empty.

  • since 4.05
val max_elt : t -> elt

Same as min_elt, but returns the largest element of the given set.

val max_elt_opt : t -> elt option

Same as min_elt_opt, but returns the largest element of the given set.

  • since 4.05
val choose : t -> elt

Return one element of the given set, or raise Not_found if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

val choose_opt : t -> elt option

Return one element of the given set, or None if the set is empty. Which element is chosen is unspecified, but equal elements will be chosen for equal sets.

  • since 4.05

Searching

val find : elt -> t -> elt

find x s returns the element of s equal to x (according to Ord.compare), or raise Not_found if no such element exists.

  • since 4.01
val find_opt : elt -> t -> elt option

find_opt x s returns the element of s equal to x (according to Ord.compare), or None if no such element exists.

  • since 4.05
val find_first : (elt -> bool) -> t -> elt

find_first f s, where f is a monotonically increasing function, returns the lowest element e of s such that f e, or raises Not_found if no such element exists.

For example, find_first (fun e -> Ord.compare e x >= 0) s will return the first element e of s where Ord.compare e x >= 0 (intuitively: e >= x), or raise Not_found if x is greater than any element of s.

  • since 4.05
val find_first_opt : (elt -> bool) -> t -> elt option

find_first_opt f s, where f is a monotonically increasing function, returns an option containing the lowest element e of s such that f e, or None if no such element exists.

  • since 4.05
val find_last : (elt -> bool) -> t -> elt

find_last f s, where f is a monotonically decreasing function, returns the highest element e of s such that f e, or raises Not_found if no such element exists.

  • since 4.05
val find_last_opt : (elt -> bool) -> t -> elt option

find_last_opt f s, where f is a monotonically decreasing function, returns an option containing the highest element e of s such that f e, or None if no such element exists.

  • since 4.05

Traversing

val iter : (elt -> unit) -> t -> unit

iter f s applies f in turn to all elements of s. The elements of s are presented to f in increasing order with respect to the ordering over the type of the elements.

val fold : (elt -> 'acc -> 'acc) -> t -> 'acc -> 'acc

fold f s init computes (f xN ... (f x2 (f x1 init))...), where x1 ... xN are the elements of s, in increasing order.

Transforming

val map : (elt -> elt) -> t -> t

map f s is the set whose elements are f a0,f a1... f + aN, where a0,a1...aN are the elements of s.

The elements are passed to f in increasing order with respect to the ordering over the type of the elements.

If no element of s is changed by f, s is returned unchanged. (If each output of f is physically equal to its input, the returned set is physically equal to s.)

  • since 4.04
val filter : (elt -> bool) -> t -> t

filter f s returns the set of all elements in s that satisfy predicate f. If f satisfies every element in s, s is returned unchanged (the result of the function is then physically equal to s).

  • before 4.03

    Physical equality was not ensured.

val filter_map : (elt -> elt option) -> t -> t

filter_map f s returns the set of all v such that f x = Some v for some element x of s.

For example,

filter_map (fun n -> if n mod 2 = 0 then Some (n / 2) else None) s

is the set of halves of the even elements of s.

If no element of s is changed or dropped by f (if f x = Some x for each element x), then s is returned unchanged: the result of the function is then physically equal to s.

  • since 4.11
val partition : (elt -> bool) -> t -> t * t

partition f s returns a pair of sets (s1, s2), where s1 is the set of all the elements of s that satisfy the predicate f, and s2 is the set of all the elements of s that do not satisfy f.

val split : elt -> t -> t * bool * t

split x s returns a triple (l, present, r), where l is the set of elements of s that are strictly less than x; r is the set of elements of s that are strictly greater than x; present is false if s contains no element equal to x, or true if s contains an element equal to x.

Predicates and comparisons

val is_empty : t -> bool

Test whether a set is empty or not.

val mem : elt -> t -> bool

mem x s tests whether x belongs to the set s.

val equal : t -> t -> bool

equal s1 s2 tests whether the sets s1 and s2 are equal, that is, contain equal elements.

val compare : t -> t -> int

Total ordering between sets. Can be used as the ordering function for doing sets of sets.

val subset : t -> t -> bool

subset s1 s2 tests whether the set s1 is a subset of the set s2.

val for_all : (elt -> bool) -> t -> bool

for_all f s checks if all elements of the set satisfy the predicate f.

val exists : (elt -> bool) -> t -> bool

exists f s checks if at least one element of the set satisfies the predicate f.

Converting

val to_list : t -> elt list

to_list s is elements s.

  • since 5.1
val of_list : elt list -> t

of_list l creates a set from a list of elements. This is usually more efficient than folding add over the list, except perhaps for lists with many duplicated elements.

  • since 4.02
val to_seq_from : elt -> t -> elt Seq.t

to_seq_from x s iterates on a subset of the elements of s in ascending order, from x or above.

  • since 4.07
val to_seq : t -> elt Seq.t

Iterate on the whole set, in ascending order

  • since 4.07
val to_rev_seq : t -> elt Seq.t

Iterate on the whole set, in descending order

  • since 4.12
val add_seq : elt Seq.t -> t -> t

Add the given elements to the set, in order.

  • since 4.07
val of_seq : elt Seq.t -> t

Build a set from the given bindings

  • since 4.07
diff --git a/docs/stdlib/Stdlib/Stack/index.html b/docs/stdlib/Stdlib/Stack/index.html new file mode 100644 index 00000000..6aa957f1 --- /dev/null +++ b/docs/stdlib/Stdlib/Stack/index.html @@ -0,0 +1,2 @@ + +Stack (docs.stdlib.Stdlib.Stack)

Module Stdlib.Stack

Last-in first-out stacks.

This module implements stacks (LIFOs), with in-place modification.

Unsynchronized accesses

Unsynchronized accesses to a stack may lead to an invalid queue state. Thus, concurrent accesses to stacks must be synchronized (for instance with a Mutex.t).

type !'a t

The type of stacks containing elements of type 'a.

exception Empty

Raised when Stack.pop or Stack.top is applied to an empty stack.

val create : unit -> 'a t

Return a new stack, initially empty.

val push : 'a -> 'a t -> unit

push x s adds the element x at the top of stack s.

val pop : 'a t -> 'a

pop s removes and returns the topmost element in stack s, or raises Empty if the stack is empty.

val pop_opt : 'a t -> 'a option

pop_opt s removes and returns the topmost element in stack s, or returns None if the stack is empty.

  • since 4.08
val drop : 'a t -> unit

drop s removes the topmost element in stack s, or raises Empty if the stack is empty.

  • since 5.1
val top : 'a t -> 'a

top s returns the topmost element in stack s, or raises Empty if the stack is empty.

val top_opt : 'a t -> 'a option

top_opt s returns the topmost element in stack s, or None if the stack is empty.

  • since 4.08
val clear : 'a t -> unit

Discard all elements from a stack.

val copy : 'a t -> 'a t

Return a copy of the given stack.

val is_empty : 'a t -> bool

Return true if the given stack is empty, false otherwise.

val length : 'a t -> int

Return the number of elements in a stack. Time complexity O(1)

val iter : ('a -> unit) -> 'a t -> unit

iter f s applies f in turn to all elements of s, from the element at the top of the stack to the element at the bottom of the stack. The stack itself is unchanged.

val fold : ('acc -> 'a -> 'acc) -> 'acc -> 'a t -> 'acc

fold f accu s is (f (... (f (f accu x1) x2) ...) xn) where x1 is the top of the stack, x2 the second element, and xn the bottom element. The stack is unchanged.

  • since 4.03

Stacks and Sequences

val to_seq : 'a t -> 'a Seq.t

Iterate on the stack, top to bottom. It is safe to modify the stack during iteration.

  • since 4.07
val add_seq : 'a t -> 'a Seq.t -> unit

Add the elements from the sequence on the top of the stack.

  • since 4.07
val of_seq : 'a Seq.t -> 'a t

Create a stack from the sequence.

  • since 4.07
diff --git a/docs/stdlib/Stdlib/StdLabels/index.html b/docs/stdlib/Stdlib/StdLabels/index.html new file mode 100644 index 00000000..9f9fc215 --- /dev/null +++ b/docs/stdlib/Stdlib/StdLabels/index.html @@ -0,0 +1,6 @@ + +StdLabels (docs.stdlib.Stdlib.StdLabels)

Module Stdlib.StdLabels

Standard labeled libraries.

This meta-module provides versions of the Array, Bytes, List and String modules where function arguments are systematically labeled. It is intended to be opened at the top of source files, as shown below.

open StdLabels
+
+let to_upper = String.map ~f:Char.uppercase_ascii
+let seq len = List.init ~f:(fun i -> i) ~len
+let everything = Array.create_matrix ~dimx:42 ~dimy:42 42
module Array = ArrayLabels
module Bytes = BytesLabels
module List = ListLabels
module String = StringLabels
diff --git a/docs/stdlib/Stdlib/String/index.html b/docs/stdlib/Stdlib/String/index.html new file mode 100644 index 00000000..e1eec548 --- /dev/null +++ b/docs/stdlib/Stdlib/String/index.html @@ -0,0 +1,6 @@ + +String (docs.stdlib.Stdlib.String)

Module Stdlib.String

Strings.

A string s of length n is an indexable and immutable sequence of n bytes. For historical reasons these bytes are referred to as characters.

The semantics of string functions is defined in terms of indices and positions. These are depicted and described as follows.

positions  0   1   2   3   4    n-1    n
+           +---+---+---+---+     +-----+
+  indices  | 0 | 1 | 2 | 3 | ... | n-1 |
+           +---+---+---+---+     +-----+
  • An index i of s is an integer in the range [0;n-1]. It represents the ith byte (character) of s which can be accessed using the constant time string indexing operator s.[i].
  • A position i of s is an integer in the range [0;n]. It represents either the point at the beginning of the string, or the point between two indices, or the point at the end of the string. The ith byte index is between position i and i+1.

Two integers start and len are said to define a valid substring of s if len >= 0 and start, start+len are positions of s.

Unicode text. Strings being arbitrary sequences of bytes, they can hold any kind of textual encoding. However the recommended encoding for storing Unicode text in OCaml strings is UTF-8. This is the encoding used by Unicode escapes in string literals. For example the string "\u{1F42B}" is the UTF-8 encoding of the Unicode character U+1F42B.

Past mutability. Before OCaml 4.02, strings used to be modifiable in place like Bytes.t mutable sequences of bytes. OCaml 4 had various compiler flags and configuration options to support the transition period from mutable to immutable strings. Those options are no longer available, and strings are now always immutable.

The labeled version of this module can be used as described in the StdLabels module.

Strings

type t = string

The type for strings.

val make : int -> char -> string

make n c is a string of length n with each index holding the character c.

val init : int -> (int -> char) -> string

init n f is a string of length n with index i holding the character f i (called in increasing index order).

  • since 4.02
val empty : string

The empty string.

  • since 4.13
val length : string -> int

length s is the length (number of bytes/characters) of s.

val get : string -> int -> char

get s i is the character at index i in s. This is the same as writing s.[i].

val of_bytes : bytes -> string

Return a new string that contains the same bytes as the given byte sequence.

  • since 4.13
val to_bytes : string -> bytes

Return a new byte sequence that contains the same bytes as the given string.

  • since 4.13
val blit : string -> int -> bytes -> int -> int -> unit

Same as Bytes.blit_string which should be preferred.

Concatenating

Note. The Stdlib.(^) binary operator concatenates two strings.

val concat : string -> string list -> string

concat sep ss concatenates the list of strings ss, inserting the separator string sep between each.

val cat : string -> string -> string

cat s1 s2 concatenates s1 and s2 (s1 ^ s2).

  • since 4.13

Predicates and comparisons

val equal : t -> t -> bool

equal s0 s1 is true if and only if s0 and s1 are character-wise equal.

  • since 4.03 (4.05 in StringLabels)
val compare : t -> t -> int

compare s0 s1 sorts s0 and s1 in lexicographical order. compare behaves like Stdlib.compare on strings but may be more efficient.

val starts_with : prefix:string -> string -> bool

starts_with ~prefix s is true if and only if s starts with prefix.

  • since 4.13
val ends_with : suffix:string -> string -> bool

ends_with ~suffix s is true if and only if s ends with suffix.

  • since 4.13
val contains_from : string -> int -> char -> bool

contains_from s start c is true if and only if c appears in s after position start.

val rcontains_from : string -> int -> char -> bool

rcontains_from s stop c is true if and only if c appears in s before position stop+1.

val contains : string -> char -> bool

contains s c is String.contains_from s 0 c.

Extracting substrings

val sub : string -> int -> int -> string

sub s pos len is a string of length len, containing the substring of s that starts at position pos and has length len.

val split_on_char : char -> string -> string list

split_on_char sep s is the list of all (possibly empty) substrings of s that are delimited by the character sep.

The function's result is specified by the following invariants:

  • The list is not empty.
  • Concatenating its elements using sep as a separator returns a string equal to the input (concat (make 1 sep) + (split_on_char sep s) = s).
  • No string in the result contains the sep character.
  • since 4.04 (4.05 in StringLabels)

Transforming

val map : (char -> char) -> string -> string

map f s is the string resulting from applying f to all the characters of s in increasing order.

  • since 4.00
val mapi : (int -> char -> char) -> string -> string

mapi f s is like map but the index of the character is also passed to f.

  • since 4.02
val fold_left : ('acc -> char -> 'acc) -> 'acc -> string -> 'acc

fold_left f x s computes f (... (f (f x s.[0]) s.[1]) ...) s.[n-1], where n is the length of the string s.

  • since 4.13
val fold_right : (char -> 'acc -> 'acc) -> string -> 'acc -> 'acc

fold_right f s x computes f s.[0] (f s.[1] ( ... (f s.[n-1] x) ...)), where n is the length of the string s.

  • since 4.13
val for_all : (char -> bool) -> string -> bool

for_all p s checks if all characters in s satisfy the predicate p.

  • since 4.13
val exists : (char -> bool) -> string -> bool

exists p s checks if at least one character of s satisfies the predicate p.

  • since 4.13
val trim : string -> string

trim s is s without leading and trailing whitespace. Whitespace characters are: ' ', '\x0C' (form feed), '\n', '\r', and '\t'.

  • since 4.00
val escaped : string -> string

escaped s is s with special characters represented by escape sequences, following the lexical conventions of OCaml.

All characters outside the US-ASCII printable range [0x20;0x7E] are escaped, as well as backslash (0x2F) and double-quote (0x22).

The function Scanf.unescaped is a left inverse of escaped, i.e. Scanf.unescaped (escaped s) = s for any string s (unless escaped s fails).

val uppercase_ascii : string -> string

uppercase_ascii s is s with all lowercase letters translated to uppercase, using the US-ASCII character set.

  • since 4.03 (4.05 in StringLabels)
val lowercase_ascii : string -> string

lowercase_ascii s is s with all uppercase letters translated to lowercase, using the US-ASCII character set.

  • since 4.03 (4.05 in StringLabels)
val capitalize_ascii : string -> string

capitalize_ascii s is s with the first character set to uppercase, using the US-ASCII character set.

  • since 4.03 (4.05 in StringLabels)
val uncapitalize_ascii : string -> string

uncapitalize_ascii s is s with the first character set to lowercase, using the US-ASCII character set.

  • since 4.03 (4.05 in StringLabels)

Traversing

val iter : (char -> unit) -> string -> unit

iter f s applies function f in turn to all the characters of s. It is equivalent to f s.[0]; f s.[1]; ...; f s.[length s - 1]; ().

val iteri : (int -> char -> unit) -> string -> unit

iteri is like iter, but the function is also given the corresponding character index.

  • since 4.00

Searching

val index_from : string -> int -> char -> int

index_from s i c is the index of the first occurrence of c in s after position i.

  • raises Not_found

    if c does not occur in s after position i.

val index_from_opt : string -> int -> char -> int option

index_from_opt s i c is the index of the first occurrence of c in s after position i (if any).

  • since 4.05
val rindex_from : string -> int -> char -> int

rindex_from s i c is the index of the last occurrence of c in s before position i+1.

  • raises Not_found

    if c does not occur in s before position i+1.

val rindex_from_opt : string -> int -> char -> int option

rindex_from_opt s i c is the index of the last occurrence of c in s before position i+1 (if any).

  • since 4.05
val index : string -> char -> int

index s c is String.index_from s 0 c.

val index_opt : string -> char -> int option

index_opt s c is String.index_from_opt s 0 c.

  • since 4.05
val rindex : string -> char -> int

rindex s c is String.rindex_from s (length s - 1) c.

val rindex_opt : string -> char -> int option

rindex_opt s c is String.rindex_from_opt s (length s - 1) c.

  • since 4.05

Strings and Sequences

val to_seq : t -> char Seq.t

to_seq s is a sequence made of the string's characters in increasing order. In "unsafe-string" mode, modifications of the string during iteration will be reflected in the sequence.

  • since 4.07
val to_seqi : t -> (int * char) Seq.t

to_seqi s is like to_seq but also tuples the corresponding index.

  • since 4.07
val of_seq : char Seq.t -> t

of_seq s is a string made of the sequence's characters.

  • since 4.07

UTF decoding and validations

  • since 4.14

UTF-8

val get_utf_8_uchar : t -> int -> Uchar.utf_decode

get_utf_8_uchar b i decodes an UTF-8 character at index i in b.

val is_valid_utf_8 : t -> bool

is_valid_utf_8 b is true if and only if b contains valid UTF-8 data.

UTF-16BE

val get_utf_16be_uchar : t -> int -> Uchar.utf_decode

get_utf_16be_uchar b i decodes an UTF-16BE character at index i in b.

val is_valid_utf_16be : t -> bool

is_valid_utf_16be b is true if and only if b contains valid UTF-16BE data.

UTF-16LE

val get_utf_16le_uchar : t -> int -> Uchar.utf_decode

get_utf_16le_uchar b i decodes an UTF-16LE character at index i in b.

val is_valid_utf_16le : t -> bool

is_valid_utf_16le b is true if and only if b contains valid UTF-16LE data.

Binary decoding of integers

The functions in this section binary decode integers from strings.

All following functions raise Invalid_argument if the characters needed at index i to decode the integer are not available.

Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order. Native-endian encoding is either little-endian or big-endian depending on Sys.big_endian.

32-bit and 64-bit integers are represented by the int32 and int64 types, which can be interpreted either as signed or unsigned numbers.

8-bit and 16-bit integers are represented by the int type, which has more bits than the binary encoding. These extra bits are sign-extended (or zero-extended) for functions which decode 8-bit or 16-bit integers and represented them with int values.

val get_uint8 : string -> int -> int

get_uint8 b i is b's unsigned 8-bit integer starting at character index i.

  • since 4.13
val get_int8 : string -> int -> int

get_int8 b i is b's signed 8-bit integer starting at character index i.

  • since 4.13
val get_uint16_ne : string -> int -> int

get_uint16_ne b i is b's native-endian unsigned 16-bit integer starting at character index i.

  • since 4.13
val get_uint16_be : string -> int -> int

get_uint16_be b i is b's big-endian unsigned 16-bit integer starting at character index i.

  • since 4.13
val get_uint16_le : string -> int -> int

get_uint16_le b i is b's little-endian unsigned 16-bit integer starting at character index i.

  • since 4.13
val get_int16_ne : string -> int -> int

get_int16_ne b i is b's native-endian signed 16-bit integer starting at character index i.

  • since 4.13
val get_int16_be : string -> int -> int

get_int16_be b i is b's big-endian signed 16-bit integer starting at character index i.

  • since 4.13
val get_int16_le : string -> int -> int

get_int16_le b i is b's little-endian signed 16-bit integer starting at character index i.

  • since 4.13
val get_int32_ne : string -> int -> int32

get_int32_ne b i is b's native-endian 32-bit integer starting at character index i.

  • since 4.13
val hash : t -> int

An unseeded hash function for strings, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.0
val seeded_hash : int -> t -> int

A seeded hash function for strings, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.0
val get_int32_be : string -> int -> int32

get_int32_be b i is b's big-endian 32-bit integer starting at character index i.

  • since 4.13
val get_int32_le : string -> int -> int32

get_int32_le b i is b's little-endian 32-bit integer starting at character index i.

  • since 4.13
val get_int64_ne : string -> int -> int64

get_int64_ne b i is b's native-endian 64-bit integer starting at character index i.

  • since 4.13
val get_int64_be : string -> int -> int64

get_int64_be b i is b's big-endian 64-bit integer starting at character index i.

  • since 4.13
val get_int64_le : string -> int -> int64

get_int64_le b i is b's little-endian 64-bit integer starting at character index i.

  • since 4.13
diff --git a/docs/stdlib/Stdlib/StringLabels/index.html b/docs/stdlib/Stdlib/StringLabels/index.html new file mode 100644 index 00000000..24c467a2 --- /dev/null +++ b/docs/stdlib/Stdlib/StringLabels/index.html @@ -0,0 +1,12 @@ + +StringLabels (docs.stdlib.Stdlib.StringLabels)

Module Stdlib.StringLabels

Strings.

A string s of length n is an indexable and immutable sequence of n bytes. For historical reasons these bytes are referred to as characters.

The semantics of string functions is defined in terms of indices and positions. These are depicted and described as follows.

positions  0   1   2   3   4    n-1    n
+           +---+---+---+---+     +-----+
+  indices  | 0 | 1 | 2 | 3 | ... | n-1 |
+           +---+---+---+---+     +-----+
  • An index i of s is an integer in the range [0;n-1]. It represents the ith byte (character) of s which can be accessed using the constant time string indexing operator s.[i].
  • A position i of s is an integer in the range [0;n]. It represents either the point at the beginning of the string, or the point between two indices, or the point at the end of the string. The ith byte index is between position i and i+1.

Two integers start and len are said to define a valid substring of s if len >= 0 and start, start+len are positions of s.

Unicode text. Strings being arbitrary sequences of bytes, they can hold any kind of textual encoding. However the recommended encoding for storing Unicode text in OCaml strings is UTF-8. This is the encoding used by Unicode escapes in string literals. For example the string "\u{1F42B}" is the UTF-8 encoding of the Unicode character U+1F42B.

Past mutability. Before OCaml 4.02, strings used to be modifiable in place like Bytes.t mutable sequences of bytes. OCaml 4 had various compiler flags and configuration options to support the transition period from mutable to immutable strings. Those options are no longer available, and strings are now always immutable.

The labeled version of this module can be used as described in the StdLabels module.

Strings

type t = string

The type for strings.

val make : int -> char -> string

make n c is a string of length n with each index holding the character c.

val init : int -> f:(int -> char) -> string

init n ~f is a string of length n with index i holding the character f i (called in increasing index order).

  • since 4.02
val empty : string

The empty string.

  • since 4.13
val length : string -> int

length s is the length (number of bytes/characters) of s.

val get : string -> int -> char

get s i is the character at index i in s. This is the same as writing s.[i].

val of_bytes : bytes -> string

Return a new string that contains the same bytes as the given byte sequence.

  • since 4.13
val to_bytes : string -> bytes

Return a new byte sequence that contains the same bytes as the given string.

  • since 4.13
val blit : + src:string -> + src_pos:int -> + dst:bytes -> + dst_pos:int -> + len:int -> + unit

Same as Bytes.blit_string which should be preferred.

Concatenating

Note. The Stdlib.(^) binary operator concatenates two strings.

val concat : sep:string -> string list -> string

concat ~sep ss concatenates the list of strings ss, inserting the separator string sep between each.

val cat : string -> string -> string

cat s1 s2 concatenates s1 and s2 (s1 ^ s2).

  • since 4.13

Predicates and comparisons

val equal : t -> t -> bool

equal s0 s1 is true if and only if s0 and s1 are character-wise equal.

  • since 4.05
val compare : t -> t -> int

compare s0 s1 sorts s0 and s1 in lexicographical order. compare behaves like Stdlib.compare on strings but may be more efficient.

val starts_with : prefix:string -> string -> bool

starts_with ~prefix s is true if and only if s starts with prefix.

  • since 4.13
val ends_with : suffix:string -> string -> bool

ends_with ~suffix s is true if and only if s ends with suffix.

  • since 4.13
val contains_from : string -> int -> char -> bool

contains_from s start c is true if and only if c appears in s after position start.

val rcontains_from : string -> int -> char -> bool

rcontains_from s stop c is true if and only if c appears in s before position stop+1.

val contains : string -> char -> bool

contains s c is String.contains_from s 0 c.

Extracting substrings

val sub : string -> pos:int -> len:int -> string

sub s ~pos ~len is a string of length len, containing the substring of s that starts at position pos and has length len.

val split_on_char : sep:char -> string -> string list

split_on_char ~sep s is the list of all (possibly empty) substrings of s that are delimited by the character sep.

The function's result is specified by the following invariants:

  • The list is not empty.
  • Concatenating its elements using sep as a separator returns a string equal to the input (concat (make 1 sep) + (split_on_char sep s) = s).
  • No string in the result contains the sep character.
  • since 4.05

Transforming

val map : f:(char -> char) -> string -> string

map f s is the string resulting from applying f to all the characters of s in increasing order.

  • since 4.00
val mapi : f:(int -> char -> char) -> string -> string

mapi ~f s is like map but the index of the character is also passed to f.

  • since 4.02
val fold_left : f:('acc -> char -> 'acc) -> init:'acc -> string -> 'acc

fold_left f x s computes f (... (f (f x s.[0]) s.[1]) ...) s.[n-1], where n is the length of the string s.

  • since 4.13
val fold_right : f:(char -> 'acc -> 'acc) -> string -> init:'acc -> 'acc

fold_right f s x computes f s.[0] (f s.[1] ( ... (f s.[n-1] x) ...)), where n is the length of the string s.

  • since 4.13
val for_all : f:(char -> bool) -> string -> bool

for_all p s checks if all characters in s satisfy the predicate p.

  • since 4.13
val exists : f:(char -> bool) -> string -> bool

exists p s checks if at least one character of s satisfies the predicate p.

  • since 4.13
val trim : string -> string

trim s is s without leading and trailing whitespace. Whitespace characters are: ' ', '\x0C' (form feed), '\n', '\r', and '\t'.

  • since 4.00
val escaped : string -> string

escaped s is s with special characters represented by escape sequences, following the lexical conventions of OCaml.

All characters outside the US-ASCII printable range [0x20;0x7E] are escaped, as well as backslash (0x2F) and double-quote (0x22).

The function Scanf.unescaped is a left inverse of escaped, i.e. Scanf.unescaped (escaped s) = s for any string s (unless escaped s fails).

val uppercase_ascii : string -> string

uppercase_ascii s is s with all lowercase letters translated to uppercase, using the US-ASCII character set.

  • since 4.05
val lowercase_ascii : string -> string

lowercase_ascii s is s with all uppercase letters translated to lowercase, using the US-ASCII character set.

  • since 4.05
val capitalize_ascii : string -> string

capitalize_ascii s is s with the first character set to uppercase, using the US-ASCII character set.

  • since 4.05
val uncapitalize_ascii : string -> string

uncapitalize_ascii s is s with the first character set to lowercase, using the US-ASCII character set.

  • since 4.05

Traversing

val iter : f:(char -> unit) -> string -> unit

iter ~f s applies function f in turn to all the characters of s. It is equivalent to f s.[0]; f s.[1]; ...; f s.[length s - 1]; ().

val iteri : f:(int -> char -> unit) -> string -> unit

iteri is like iter, but the function is also given the corresponding character index.

  • since 4.00

Searching

val index_from : string -> int -> char -> int

index_from s i c is the index of the first occurrence of c in s after position i.

  • raises Not_found

    if c does not occur in s after position i.

val index_from_opt : string -> int -> char -> int option

index_from_opt s i c is the index of the first occurrence of c in s after position i (if any).

  • since 4.05
val rindex_from : string -> int -> char -> int

rindex_from s i c is the index of the last occurrence of c in s before position i+1.

  • raises Not_found

    if c does not occur in s before position i+1.

val rindex_from_opt : string -> int -> char -> int option

rindex_from_opt s i c is the index of the last occurrence of c in s before position i+1 (if any).

  • since 4.05
val index : string -> char -> int

index s c is String.index_from s 0 c.

val index_opt : string -> char -> int option

index_opt s c is String.index_from_opt s 0 c.

  • since 4.05
val rindex : string -> char -> int

rindex s c is String.rindex_from s (length s - 1) c.

val rindex_opt : string -> char -> int option

rindex_opt s c is String.rindex_from_opt s (length s - 1) c.

  • since 4.05

Strings and Sequences

val to_seq : t -> char Seq.t

to_seq s is a sequence made of the string's characters in increasing order. In "unsafe-string" mode, modifications of the string during iteration will be reflected in the sequence.

  • since 4.07
val to_seqi : t -> (int * char) Seq.t

to_seqi s is like to_seq but also tuples the corresponding index.

  • since 4.07
val of_seq : char Seq.t -> t

of_seq s is a string made of the sequence's characters.

  • since 4.07

UTF decoding and validations

  • since 4.14

UTF-8

val get_utf_8_uchar : t -> int -> Uchar.utf_decode

get_utf_8_uchar b i decodes an UTF-8 character at index i in b.

val is_valid_utf_8 : t -> bool

is_valid_utf_8 b is true if and only if b contains valid UTF-8 data.

UTF-16BE

val get_utf_16be_uchar : t -> int -> Uchar.utf_decode

get_utf_16be_uchar b i decodes an UTF-16BE character at index i in b.

val is_valid_utf_16be : t -> bool

is_valid_utf_16be b is true if and only if b contains valid UTF-16BE data.

UTF-16LE

val get_utf_16le_uchar : t -> int -> Uchar.utf_decode

get_utf_16le_uchar b i decodes an UTF-16LE character at index i in b.

val is_valid_utf_16le : t -> bool

is_valid_utf_16le b is true if and only if b contains valid UTF-16LE data.

Binary decoding of integers

The functions in this section binary decode integers from strings.

All following functions raise Invalid_argument if the characters needed at index i to decode the integer are not available.

Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order. Native-endian encoding is either little-endian or big-endian depending on Sys.big_endian.

32-bit and 64-bit integers are represented by the int32 and int64 types, which can be interpreted either as signed or unsigned numbers.

8-bit and 16-bit integers are represented by the int type, which has more bits than the binary encoding. These extra bits are sign-extended (or zero-extended) for functions which decode 8-bit or 16-bit integers and represented them with int values.

val get_uint8 : string -> int -> int

get_uint8 b i is b's unsigned 8-bit integer starting at character index i.

  • since 4.13
val get_int8 : string -> int -> int

get_int8 b i is b's signed 8-bit integer starting at character index i.

  • since 4.13
val get_uint16_ne : string -> int -> int

get_uint16_ne b i is b's native-endian unsigned 16-bit integer starting at character index i.

  • since 4.13
val get_uint16_be : string -> int -> int

get_uint16_be b i is b's big-endian unsigned 16-bit integer starting at character index i.

  • since 4.13
val get_uint16_le : string -> int -> int

get_uint16_le b i is b's little-endian unsigned 16-bit integer starting at character index i.

  • since 4.13
val get_int16_ne : string -> int -> int

get_int16_ne b i is b's native-endian signed 16-bit integer starting at character index i.

  • since 4.13
val get_int16_be : string -> int -> int

get_int16_be b i is b's big-endian signed 16-bit integer starting at character index i.

  • since 4.13
val get_int16_le : string -> int -> int

get_int16_le b i is b's little-endian signed 16-bit integer starting at character index i.

  • since 4.13
val get_int32_ne : string -> int -> int32

get_int32_ne b i is b's native-endian 32-bit integer starting at character index i.

  • since 4.13
val hash : t -> int

An unseeded hash function for strings, with the same output value as Hashtbl.hash. This function allows this module to be passed as argument to the functor Hashtbl.Make.

  • since 5.0
val seeded_hash : int -> t -> int

A seeded hash function for strings, with the same output value as Hashtbl.seeded_hash. This function allows this module to be passed as argument to the functor Hashtbl.MakeSeeded.

  • since 5.0
val get_int32_be : string -> int -> int32

get_int32_be b i is b's big-endian 32-bit integer starting at character index i.

  • since 4.13
val get_int32_le : string -> int -> int32

get_int32_le b i is b's little-endian 32-bit integer starting at character index i.

  • since 4.13
val get_int64_ne : string -> int -> int64

get_int64_ne b i is b's native-endian 64-bit integer starting at character index i.

  • since 4.13
val get_int64_be : string -> int -> int64

get_int64_be b i is b's big-endian 64-bit integer starting at character index i.

  • since 4.13
val get_int64_le : string -> int -> int64

get_int64_le b i is b's little-endian 64-bit integer starting at character index i.

  • since 4.13
diff --git a/docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-1-Immediate/index.html b/docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-1-Immediate/index.html new file mode 100644 index 00000000..027e043b --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-1-Immediate/index.html @@ -0,0 +1,2 @@ + +Immediate (docs.stdlib.Stdlib.Sys.Immediate64.Make.Immediate)

Parameter Make.Immediate

type t
diff --git a/docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-2-Non_immediate/index.html b/docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-2-Non_immediate/index.html new file mode 100644 index 00000000..414004df --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/Immediate64/Make/argument-2-Non_immediate/index.html @@ -0,0 +1,2 @@ + +Non_immediate (docs.stdlib.Stdlib.Sys.Immediate64.Make.Non_immediate)

Parameter Make.Non_immediate

type t
diff --git a/docs/stdlib/Stdlib/Sys/Immediate64/Make/index.html b/docs/stdlib/Stdlib/Sys/Immediate64/Make/index.html new file mode 100644 index 00000000..c1a16281 --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/Immediate64/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.Sys.Immediate64.Make)

Module Immediate64.Make

Parameters

Signature

type t
type 'a repr =
  1. | Immediate : Immediate.t repr
  2. | Non_immediate : Non_immediate.t repr
val repr : t repr
diff --git a/docs/stdlib/Stdlib/Sys/Immediate64/index.html b/docs/stdlib/Stdlib/Sys/Immediate64/index.html new file mode 100644 index 00000000..f0f5a800 --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/Immediate64/index.html @@ -0,0 +1,5 @@ + +Immediate64 (docs.stdlib.Stdlib.Sys.Immediate64)

Module Sys.Immediate64

This module allows to define a type t with the immediate64 attribute. This attribute means that the type is immediate on 64 bit architectures. On other architectures, it might or might not be immediate.

  • since 4.10
module type Non_immediate = sig ... end
module type Immediate = sig ... end
module Make + (Immediate : Immediate) + (Non_immediate : Non_immediate) : + sig ... end
diff --git a/docs/stdlib/Stdlib/Sys/Immediate64/module-type-Immediate/index.html b/docs/stdlib/Stdlib/Sys/Immediate64/module-type-Immediate/index.html new file mode 100644 index 00000000..0c79032c --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/Immediate64/module-type-Immediate/index.html @@ -0,0 +1,2 @@ + +Immediate (docs.stdlib.Stdlib.Sys.Immediate64.Immediate)

Module type Immediate64.Immediate

type t
diff --git a/docs/stdlib/Stdlib/Sys/Immediate64/module-type-Non_immediate/index.html b/docs/stdlib/Stdlib/Sys/Immediate64/module-type-Non_immediate/index.html new file mode 100644 index 00000000..10a489ad --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/Immediate64/module-type-Non_immediate/index.html @@ -0,0 +1,2 @@ + +Non_immediate (docs.stdlib.Stdlib.Sys.Immediate64.Non_immediate)

Module type Immediate64.Non_immediate

type t
diff --git a/docs/stdlib/Stdlib/Sys/index.html b/docs/stdlib/Stdlib/Sys/index.html new file mode 100644 index 00000000..52935e57 --- /dev/null +++ b/docs/stdlib/Stdlib/Sys/index.html @@ -0,0 +1,4 @@ + +Sys (docs.stdlib.Stdlib.Sys)

Module Stdlib.Sys

System interface.

Every function in this module raises Sys_error with an informative message when the underlying system call signal an error.

val argv : string array

The command line arguments given to the process. The first element is the command name used to invoke the program. The following elements are the command-line arguments given to the program.

val executable_name : string

The name of the file containing the executable currently running. This name may be absolute or relative to the current directory, depending on the platform and whether the program was compiled to bytecode or a native executable.

val file_exists : string -> bool

Test if a file with the given name exists.

val is_directory : string -> bool

Returns true if the given name refers to a directory, false if it refers to another kind of file.

  • raises Sys_error

    if no file exists with the given name.

  • since 3.10
val is_regular_file : string -> bool

Returns true if the given name refers to a regular file, false if it refers to another kind of file.

  • raises Sys_error

    if no file exists with the given name.

  • since 5.1
val remove : string -> unit

Remove the given file name from the file system.

val rename : string -> string -> unit

Rename a file or directory. rename oldpath newpath renames the file or directory called oldpath, giving it newpath as its new name, moving it between (parent) directories if needed. If a file named newpath already exists, its contents will be replaced with those of oldpath. Depending on the operating system, the metadata (permissions, owner, etc) of newpath can either be preserved or be replaced by those of oldpath.

  • since 4.06 concerning the "replace existing file" behavior
val getenv : string -> string

Return the value associated to a variable in the process environment.

val getenv_opt : string -> string option

Return the value associated to a variable in the process environment or None if the variable is unbound.

  • since 4.05
val command : string -> int

Execute the given shell command and return its exit code.

The argument of Sys.command is generally the name of a command followed by zero, one or several arguments, separated by whitespace. The given argument is interpreted by a shell: either the Windows shell cmd.exe for the Win32 ports of OCaml, or the POSIX shell sh for other ports. It can contain shell builtin commands such as echo, and also special characters such as file redirections > and <, which will be honored by the shell.

Conversely, whitespace or special shell characters occurring in command names or in their arguments must be quoted or escaped so that the shell does not interpret them. The quoting rules vary between the POSIX shell and the Windows shell. The Filename.quote_command performs the appropriate quoting given a command name, a list of arguments, and optional file redirections.

val time : unit -> float

Return the processor time, in seconds, used by the program since the beginning of execution.

val chdir : string -> unit

Change the current working directory of the process.

val mkdir : string -> int -> unit

Create a directory with the given permissions.

  • since 4.12
val rmdir : string -> unit

Remove an empty directory.

  • since 4.12
val getcwd : unit -> string

Return the current working directory of the process.

val readdir : string -> string array

Return the names of all files present in the given directory. Names denoting the current directory and the parent directory ("." and ".." in Unix) are not returned. Each string in the result is a file name rather than a complete path. There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order.

val interactive : bool ref

This reference is initially set to false in standalone programs and to true if the code is being executed under the interactive toplevel system ocaml.

  • alert unsynchronized_access The interactive status is a mutable global state.
val os_type : string

Operating system currently executing the OCaml program. One of

  • "Unix" (for all Unix versions, including Linux and Mac OS X),
  • "Win32" (for MS-Windows, OCaml compiled with MSVC++ or MinGW-w64),
  • "Cygwin" (for MS-Windows, OCaml compiled with Cygwin).
type backend_type =
  1. | Native
  2. | Bytecode
  3. | Other of string

Currently, the official distribution only supports Native and Bytecode, but it can be other backends with alternative compilers, for example, javascript.

  • since 4.04
val backend_type : backend_type

Backend type currently executing the OCaml program.

  • since 4.04
val unix : bool

True if Sys.os_type = "Unix".

  • since 4.01
val win32 : bool

True if Sys.os_type = "Win32".

  • since 4.01
val cygwin : bool

True if Sys.os_type = "Cygwin".

  • since 4.01
val word_size : int

Size of one word on the machine currently executing the OCaml program, in bits: 32 or 64.

val int_size : int

Size of int, in bits. It is 31 (resp. 63) when using OCaml on a 32-bit (resp. 64-bit) platform. It may differ for other implementations, e.g. it can be 32 bits when compiling to JavaScript.

  • since 4.03
val big_endian : bool

Whether the machine currently executing the Caml program is big-endian.

  • since 4.00
val max_string_length : int

Maximum length of strings and byte sequences.

val max_array_length : int

Maximum length of a normal array (i.e. any array whose elements are not of type float). The maximum length of a float array is max_floatarray_length if OCaml was configured with --enable-flat-float-array and max_array_length if configured with --disable-flat-float-array.

val max_floatarray_length : int

Maximum length of a floatarray. This is also the maximum length of a float array when OCaml is configured with --enable-flat-float-array.

val runtime_variant : unit -> string

Return the name of the runtime variant the program is running on. This is normally the argument given to -runtime-variant at compile time, but for byte-code it can be changed after compilation.

  • since 4.03
val runtime_parameters : unit -> string

Return the value of the runtime parameters, in the same format as the contents of the OCAMLRUNPARAM environment variable.

  • since 4.03

Signal handling

type signal_behavior =
  1. | Signal_default
  2. | Signal_ignore
  3. | Signal_handle of int -> unit

What to do when receiving a signal:

  • Signal_default: take the default behavior (usually: abort the program)
  • Signal_ignore: ignore the signal
  • Signal_handle f: call function f, giving it the signal number as argument.
val signal : int -> signal_behavior -> signal_behavior

Set the behavior of the system on receipt of a given signal. The first argument is the signal number. Return the behavior previously associated with the signal. If the signal number is invalid (or not available on your system), an Invalid_argument exception is raised.

val set_signal : int -> signal_behavior -> unit

Same as Sys.signal but return value is ignored.

Signal numbers for the standard POSIX signals.

val sigabrt : int

Abnormal termination

val sigalrm : int

Timeout

val sigfpe : int

Arithmetic exception

val sighup : int

Hangup on controlling terminal

val sigill : int

Invalid hardware instruction

val sigint : int

Interactive interrupt (ctrl-C)

val sigkill : int

Termination (cannot be ignored)

val sigpipe : int

Broken pipe

val sigquit : int

Interactive termination

val sigsegv : int

Invalid memory reference

val sigterm : int

Termination

val sigusr1 : int

Application-defined signal 1

val sigusr2 : int

Application-defined signal 2

val sigchld : int

Child process terminated

val sigcont : int

Continue

val sigstop : int

Stop

val sigtstp : int

Interactive stop

val sigttin : int

Terminal read from background process

val sigttou : int

Terminal write from background process

val sigvtalrm : int

Timeout in virtual time

val sigprof : int

Profiling interrupt

val sigbus : int

Bus error

  • since 4.03
val sigpoll : int

Pollable event

  • since 4.03
val sigsys : int

Bad argument to routine

  • since 4.03
val sigtrap : int

Trace/breakpoint trap

  • since 4.03
val sigurg : int

Urgent condition on socket

  • since 4.03
val sigxcpu : int

Timeout in cpu time

  • since 4.03
val sigxfsz : int

File size limit exceeded

  • since 4.03
exception Break

Exception raised on interactive interrupt if Sys.catch_break is on.

val catch_break : bool -> unit

catch_break governs whether interactive interrupt (ctrl-C) terminates the program or raises the Break exception. Call catch_break true to enable raising Break, and catch_break false to let the system terminate the program on user interrupt.

val ocaml_version : string

ocaml_version is the version of OCaml. It is a string of the form "major.minor[.patchlevel][(+|~)additional-info]", where major, minor, and patchlevel are integers, and additional-info is an arbitrary string. The [.patchlevel] part was absent before version 3.08.0 and became mandatory from 3.08.0 onwards. The [(+|~)additional-info] part may be absent.

val development_version : bool

true if this is a development version, false otherwise.

  • since 4.14
type extra_prefix =
  1. | Plus
  2. | Tilde
    (*
    • since 4.14
    *)
type extra_info = extra_prefix * string
  • since 4.14
type ocaml_release_info = {
  1. major : int;
  2. minor : int;
  3. patchlevel : int;
  4. extra : extra_info option;
}
  • since 4.14
val ocaml_release : ocaml_release_info

ocaml_release is the version of OCaml.

  • since 4.14
val enable_runtime_warnings : bool -> unit

Control whether the OCaml runtime system can emit warnings on stderr. Currently, the only supported warning is triggered when a channel created by open_* functions is finalized without being closed. Runtime warnings are disabled by default.

  • since 4.03
  • alert unsynchronized_access The status of runtime warnings is a mutable global state.
val runtime_warnings_enabled : unit -> bool

Return whether runtime warnings are currently enabled.

  • since 4.03
  • alert unsynchronized_access The status of runtime warnings is a mutable global state.

Optimization

val opaque_identity : 'a -> 'a

For the purposes of optimization, opaque_identity behaves like an unknown (and thus possibly side-effecting) function.

At runtime, opaque_identity disappears altogether.

A typical use of this function is to prevent pure computations from being optimized away in benchmarking loops. For example:

for _round = 1 to 100_000 do
+  ignore (Sys.opaque_identity (my_pure_computation ()))
+done
  • since 4.03
module Immediate64 : sig ... end

This module allows to define a type t with the immediate64 attribute. This attribute means that the type is immediate on 64 bit architectures. On other architectures, it might or might not be immediate.

diff --git a/docs/stdlib/Stdlib/Type/Id/index.html b/docs/stdlib/Stdlib/Type/Id/index.html new file mode 100644 index 00000000..4adc5398 --- /dev/null +++ b/docs/stdlib/Stdlib/Type/Id/index.html @@ -0,0 +1,40 @@ + +Id (docs.stdlib.Stdlib.Type.Id)

Module Type.Id

Type identifiers.

A type identifier is a value that denotes a type. Given two type identifiers, they can be tested for equality to prove they denote the same type. Note that:

  • Unequal identifiers do not imply unequal types: a given type can be denoted by more than one identifier.
  • Type identifiers can be marshalled, but they get a new, distinct, identity on unmarshalling, so the equalities are lost.

See an example of use.

Type identifiers

type !'a t

The type for identifiers for type 'a.

val make : unit -> 'a t

make () is a new type identifier.

val uid : 'a t -> int

uid id is a runtime unique identifier for id.

val provably_equal : 'a t -> 'b t -> ('a, 'b) eq option

provably_equal i0 i1 is Some Equal if identifier i0 is equal to i1 and None otherwise.

Example

The following shows how type identifiers can be used to implement a simple heterogeneous key-value dictionary. In contrast to Stdlib.Map values whose keys map to a single, homogeneous type of values, this dictionary can associate a different type of value to each key.

(** Heterogeneous dictionaries. *)
+module Dict : sig
+  type t
+  (** The type for dictionaries. *)
+
+  type 'a key
+  (** The type for keys binding values of type ['a]. *)
+
+  val key : unit -> 'a key
+  (** [key ()] is a new dictionary key. *)
+
+  val empty : t
+  (** [empty] is the empty dictionary. *)
+
+  val add : 'a key -> 'a -> t -> t
+  (** [add k v d] is [d] with [k] bound to [v]. *)
+
+  val remove : 'a key -> t -> t
+  (** [remove k d] is [d] with the last binding of [k] removed. *)
+
+  val find : 'a key -> t -> 'a option
+  (** [find k d] is the binding of [k] in [d], if any. *)
+end = struct
+  type 'a key = 'a Type.Id.t
+  type binding = B : 'a key * 'a -> binding
+  type t = (int * binding) list
+
+  let key () = Type.Id.make ()
+  let empty = []
+  let add k v d = (Type.Id.uid k, B (k, v)) :: d
+  let remove k d = List.remove_assoc (Type.Id.uid k) d
+  let find : type a. a key -> t -> a option = fun k d ->
+    match List.assoc_opt (Type.Id.uid k) d with
+    | None -> None
+    | Some (B (k', v)) ->
+        match Type.Id.provably_equal k k' with
+        | Some Type.Equal -> Some v
+        | None -> assert false
+end
diff --git a/docs/stdlib/Stdlib/Type/index.html b/docs/stdlib/Stdlib/Type/index.html new file mode 100644 index 00000000..da292d71 --- /dev/null +++ b/docs/stdlib/Stdlib/Type/index.html @@ -0,0 +1,2 @@ + +Type (docs.stdlib.Stdlib.Type)

Module Stdlib.Type

Type introspection.

  • since 5.1

Type equality witness

type (_, _) eq =
  1. | Equal : ('a, 'a) eq

The purpose of eq is to represent type equalities that may not otherwise be known by the type checker (e.g. because they may depend on dynamic data).

A value of type (a, b) eq represents the fact that types a and b are equal.

If one has a value eq : (a, b) eq that proves types a and b are equal, one can use it to convert a value of type a to a value of type b by pattern matching on Equal:

let cast (type a) (type b) (Equal : (a, b) Type.eq) (a : a) : b = a

At runtime, this function simply returns its second argument unchanged.

Type identifiers

module Id : sig ... end

Type identifiers.

diff --git a/docs/stdlib/Stdlib/Uchar/index.html b/docs/stdlib/Stdlib/Uchar/index.html new file mode 100644 index 00000000..6ab86782 --- /dev/null +++ b/docs/stdlib/Stdlib/Uchar/index.html @@ -0,0 +1,2 @@ + +Uchar (docs.stdlib.Stdlib.Uchar)

Module Stdlib.Uchar

Unicode characters.

  • since 4.03
type t

The type for Unicode characters.

A value of this type represents a Unicode scalar value which is an integer in the ranges 0x0000...0xD7FF or 0xE000...0x10FFFF.

val min : t

min is U+0000.

val max : t

max is U+10FFFF.

val bom : t

bom is U+FEFF, the byte order mark (BOM) character.

  • since 4.06
val rep : t

rep is U+FFFD, the replacement character.

  • since 4.06
val succ : t -> t

succ u is the scalar value after u in the set of Unicode scalar values.

val pred : t -> t

pred u is the scalar value before u in the set of Unicode scalar values.

val is_valid : int -> bool

is_valid n is true if and only if n is a Unicode scalar value (i.e. in the ranges 0x0000...0xD7FF or 0xE000...0x10FFFF).

val of_int : int -> t

of_int i is i as a Unicode character.

val to_int : t -> int

to_int u is u as an integer.

val is_char : t -> bool

is_char u is true if and only if u is a latin1 OCaml character.

val of_char : char -> t

of_char c is c as a Unicode character.

val to_char : t -> char

to_char u is u as an OCaml latin1 character.

val equal : t -> t -> bool

equal u u' is u = u'.

val compare : t -> t -> int

compare u u' is Stdlib.compare u u'.

val hash : t -> int

hash u associates a non-negative integer to u.

UTF codecs tools

  • since 4.14
type utf_decode

The type for UTF decode results. Values of this type represent the result of a Unicode Transformation Format decoding attempt.

val utf_decode_is_valid : utf_decode -> bool

utf_decode_is_valid d is true if and only if d holds a valid decode.

val utf_decode_uchar : utf_decode -> t

utf_decode_uchar d is the Unicode character decoded by d if utf_decode_is_valid d is true and Uchar.rep otherwise.

val utf_decode_length : utf_decode -> int

utf_decode_length d is the number of elements from the source that were consumed by the decode d. This is always strictly positive and smaller or equal to 4. The kind of source elements depends on the actual decoder; for the decoders of the standard library this function always returns a length in bytes.

val utf_decode : int -> t -> utf_decode

utf_decode n u is a valid UTF decode for u that consumed n elements from the source for decoding. n must be positive and smaller or equal to 4 (this is not checked by the module).

val utf_decode_invalid : int -> utf_decode

utf_decode_invalid n is an invalid UTF decode that consumed n elements from the source to error. n must be positive and smaller or equal to 4 (this is not checked by the module). The resulting decode has rep as the decoded Unicode character.

val utf_8_byte_length : t -> int

utf_8_byte_length u is the number of bytes needed to encode u in UTF-8.

val utf_16_byte_length : t -> int

utf_16_byte_length u is the number of bytes needed to encode u in UTF-16.

diff --git a/docs/stdlib/Stdlib/Unit/index.html b/docs/stdlib/Stdlib/Unit/index.html new file mode 100644 index 00000000..265ffdb0 --- /dev/null +++ b/docs/stdlib/Stdlib/Unit/index.html @@ -0,0 +1,2 @@ + +Unit (docs.stdlib.Stdlib.Unit)

Module Stdlib.Unit

Unit values.

  • since 4.08

The unit type

type t = unit =
  1. | ()

The unit type.

The constructor () is included here so that it has a path, but it is not intended to be used in user-defined data types.

val equal : t -> t -> bool

equal u1 u2 is true.

val compare : t -> t -> int

compare u1 u2 is 0.

val to_string : t -> string

to_string b is "()".

diff --git a/docs/stdlib/Stdlib/Weak/Make/argument-1-H/index.html b/docs/stdlib/Stdlib/Weak/Make/argument-1-H/index.html new file mode 100644 index 00000000..b8713748 --- /dev/null +++ b/docs/stdlib/Stdlib/Weak/Make/argument-1-H/index.html @@ -0,0 +1,2 @@ + +H (docs.stdlib.Stdlib.Weak.Make.H)

Parameter Make.H

type t

The type of the hashtable keys.

val equal : t -> t -> bool

The equality predicate used to compare keys.

val hash : t -> int

A hashing function on keys. It must be such that if two keys are equal according to equal, then they have identical hash values as computed by hash. Examples: suitable (equal, hash) pairs for arbitrary key types include

  • ((=), hash) for comparing objects by structure (provided objects do not contain floats)
  • ((fun x y -> compare x y = 0), hash) for comparing objects by structure and handling Stdlib.nan correctly
  • ((==), hash) for comparing objects by physical equality (e.g. for mutable or cyclic objects).
diff --git a/docs/stdlib/Stdlib/Weak/Make/index.html b/docs/stdlib/Stdlib/Weak/Make/index.html new file mode 100644 index 00000000..04e7a361 --- /dev/null +++ b/docs/stdlib/Stdlib/Weak/Make/index.html @@ -0,0 +1,2 @@ + +Make (docs.stdlib.Stdlib.Weak.Make)

Module Weak.Make

Functor building an implementation of the weak hash set structure. H.equal can't be the physical equality, since only shallow copies of the elements in the set are given to it.

Parameters

Signature

type data = H.t

The type of the elements stored in the table.

type t

The type of tables that contain elements of type data. Note that weak hash sets cannot be marshaled using Stdlib.output_value or the functions of the Marshal module.

val create : int -> t

create n creates a new empty weak hash set, of initial size n. The table will grow as needed.

val clear : t -> unit

Remove all elements from the table.

val merge : t -> data -> data

merge t x returns an instance of x found in t if any, or else adds x to t and return x.

val add : t -> data -> unit

add t x adds x to t. If there is already an instance of x in t, it is unspecified which one will be returned by subsequent calls to find and merge.

val remove : t -> data -> unit

remove t x removes from t one instance of x. Does nothing if there is no instance of x in t.

val find : t -> data -> data

find t x returns an instance of x found in t.

  • raises Not_found

    if there is no such element.

val find_opt : t -> data -> data option

find_opt t x returns an instance of x found in t or None if there is no such element.

  • since 4.05
val find_all : t -> data -> data list

find_all t x returns a list of all the instances of x found in t.

val mem : t -> data -> bool

mem t x returns true if there is at least one instance of x in t, false otherwise.

val iter : (data -> unit) -> t -> unit

iter f t calls f on each element of t, in some unspecified order. It is not specified what happens if f tries to change t itself.

val fold : (data -> 'acc -> 'acc) -> t -> 'acc -> 'acc

fold f t init computes (f d1 (... (f dN init))) where d1 ... dN are the elements of t in some unspecified order. It is not specified what happens if f tries to change t itself.

val count : t -> int

Count the number of elements in the table. count t gives the same result as fold (fun _ n -> n+1) t 0 but does not delay the deallocation of the dead elements.

val stats : t -> int * int * int * int * int * int

Return statistics on the table. The numbers are, in order: table length, number of entries, sum of bucket lengths, smallest bucket length, median bucket length, biggest bucket length.

diff --git a/docs/stdlib/Stdlib/Weak/index.html b/docs/stdlib/Stdlib/Weak/index.html new file mode 100644 index 00000000..ab758bb9 --- /dev/null +++ b/docs/stdlib/Stdlib/Weak/index.html @@ -0,0 +1,2 @@ + +Weak (docs.stdlib.Stdlib.Weak)

Module Stdlib.Weak

Arrays of weak pointers and hash sets of weak pointers.

Low-level functions

type !'a t

The type of arrays of weak pointers (weak arrays). A weak pointer is a value that the garbage collector may erase whenever the value is not used any more (through normal pointers) by the program. Note that finalisation functions are run before the weak pointers are erased, because the finalisation functions can make values alive again (before 4.03 the finalisation functions were run after).

A weak pointer is said to be full if it points to a value, empty if the value was erased by the GC.

Notes:

  • Integers are not allocated and cannot be stored in weak arrays.
  • Weak arrays cannot be marshaled using Stdlib.output_value nor the functions of the Marshal module.
val create : int -> 'a t

Weak.create n returns a new weak array of length n. All the pointers are initially empty.

val length : 'a t -> int

Weak.length ar returns the length (number of elements) of ar.

val set : 'a t -> int -> 'a option -> unit

Weak.set ar n (Some el) sets the nth cell of ar to be a (full) pointer to el; Weak.set ar n None sets the nth cell of ar to empty.

val get : 'a t -> int -> 'a option

Weak.get ar n returns None if the nth cell of ar is empty, Some x (where x is the value) if it is full.

val get_copy : 'a t -> int -> 'a option

Weak.get_copy ar n returns None if the nth cell of ar is empty, Some x (where x is a (shallow) copy of the value) if it is full. In addition to pitfalls with mutable values, the interesting difference with get is that get_copy does not prevent the incremental GC from erasing the value in its current cycle (get may delay the erasure to the next GC cycle).

val check : 'a t -> int -> bool

Weak.check ar n returns true if the nth cell of ar is full, false if it is empty. Note that even if Weak.check ar n returns true, a subsequent Weak.get ar n can return None.

val fill : 'a t -> int -> int -> 'a option -> unit

Weak.fill ar ofs len el sets to el all pointers of ar from ofs to ofs + len - 1.

val blit : 'a t -> int -> 'a t -> int -> int -> unit

Weak.blit ar1 off1 ar2 off2 len copies len weak pointers from ar1 (starting at off1) to ar2 (starting at off2). It works correctly even if ar1 and ar2 are the same.

  • raises Invalid_argument

    if off1 and len do not designate a valid subarray of ar1, or if off2 and len do not designate a valid subarray of ar2.

Weak hash sets

A weak hash set is a hashed set of values. Each value may magically disappear from the set when it is not used by the rest of the program any more. This is normally used to share data structures without inducing memory leaks. Weak hash sets are defined on values from a Hashtbl.HashedType module; the equal relation and hash function are taken from that module. We will say that v is an instance of x if equal x v is true.

The equal relation must be able to work on a shallow copy of the values and give the same result as with the values themselves.

Unsynchronized accesses

Unsynchronized accesses to weak hash sets are a programming error. Unsynchronized accesses to a weak hash set may lead to an invalid weak hash set state. Thus, concurrent accesses to weak hash sets must be synchronized (for instance with a Mutex.t).

module type S = sig ... end

The output signature of the functor Weak.Make.

module Make (H : Hashtbl.HashedType) : S with type data = H.t

Functor building an implementation of the weak hash set structure. H.equal can't be the physical equality, since only shallow copies of the elements in the set are given to it.

diff --git a/docs/stdlib/Stdlib/Weak/module-type-S/index.html b/docs/stdlib/Stdlib/Weak/module-type-S/index.html new file mode 100644 index 00000000..f1fe9834 --- /dev/null +++ b/docs/stdlib/Stdlib/Weak/module-type-S/index.html @@ -0,0 +1,2 @@ + +S (docs.stdlib.Stdlib.Weak.S)

Module type Weak.S

The output signature of the functor Weak.Make.

type data

The type of the elements stored in the table.

type t

The type of tables that contain elements of type data. Note that weak hash sets cannot be marshaled using Stdlib.output_value or the functions of the Marshal module.

val create : int -> t

create n creates a new empty weak hash set, of initial size n. The table will grow as needed.

val clear : t -> unit

Remove all elements from the table.

val merge : t -> data -> data

merge t x returns an instance of x found in t if any, or else adds x to t and return x.

val add : t -> data -> unit

add t x adds x to t. If there is already an instance of x in t, it is unspecified which one will be returned by subsequent calls to find and merge.

val remove : t -> data -> unit

remove t x removes from t one instance of x. Does nothing if there is no instance of x in t.

val find : t -> data -> data

find t x returns an instance of x found in t.

  • raises Not_found

    if there is no such element.

val find_opt : t -> data -> data option

find_opt t x returns an instance of x found in t or None if there is no such element.

  • since 4.05
val find_all : t -> data -> data list

find_all t x returns a list of all the instances of x found in t.

val mem : t -> data -> bool

mem t x returns true if there is at least one instance of x in t, false otherwise.

val iter : (data -> unit) -> t -> unit

iter f t calls f on each element of t, in some unspecified order. It is not specified what happens if f tries to change t itself.

val fold : (data -> 'acc -> 'acc) -> t -> 'acc -> 'acc

fold f t init computes (f d1 (... (f dN init))) where d1 ... dN are the elements of t in some unspecified order. It is not specified what happens if f tries to change t itself.

val count : t -> int

Count the number of elements in the table. count t gives the same result as fold (fun _ n -> n+1) t 0 but does not delay the deallocation of the dead elements.

val stats : t -> int * int * int * int * int * int

Return statistics on the table. The numbers are, in order: table length, number of entries, sum of bucket lengths, smallest bucket length, median bucket length, biggest bucket length.

diff --git a/docs/stdlib/Stdlib/index.html b/docs/stdlib/Stdlib/index.html new file mode 100644 index 00000000..450d1196 --- /dev/null +++ b/docs/stdlib/Stdlib/index.html @@ -0,0 +1,8 @@ + +Stdlib (docs.stdlib.Stdlib)

Module Stdlib

The OCaml Standard library.

This module is automatically opened at the beginning of each compilation. All components of this module can therefore be referred by their short name, without prefixing them by Stdlib.

In particular, it provides the basic operations over the built-in types (numbers, booleans, byte sequences, strings, exceptions, references, lists, arrays, input-output channels, ...) and the standard library modules.

Exceptions

val raise : exn -> 'a

Raise the given exception value

val raise_notrace : exn -> 'a

A faster version raise which does not record the backtrace.

  • since 4.02
val invalid_arg : string -> 'a

Raise exception Invalid_argument with the given string.

val failwith : string -> 'a

Raise exception Failure with the given string.

exception Exit

The Exit exception is not raised by any library function. It is provided for use in your programs.

exception Match_failure of string * int * int

Exception raised when none of the cases of a pattern-matching apply. The arguments are the location of the match keyword in the source code (file name, line number, column number).

exception Assert_failure of string * int * int

Exception raised when an assertion fails. The arguments are the location of the assert keyword in the source code (file name, line number, column number).

exception Invalid_argument of string

Exception raised by library functions to signal that the given arguments do not make sense. The string gives some information to the programmer. As a general rule, this exception should not be caught, it denotes a programming error and the code should be modified not to trigger it.

exception Failure of string

Exception raised by library functions to signal that they are undefined on the given arguments. The string is meant to give some information to the programmer; you must not pattern match on the string literal because it may change in future versions (use Failure _ instead).

exception Not_found

Exception raised by search functions when the desired object could not be found.

exception Out_of_memory

Exception raised by the garbage collector when there is insufficient memory to complete the computation. (Not reliable for allocations on the minor heap.)

exception Stack_overflow

Exception raised by the bytecode interpreter when the evaluation stack reaches its maximal size. This often indicates infinite or excessively deep recursion in the user's program.

Before 4.10, it was not fully implemented by the native-code compiler.

exception Sys_error of string

Exception raised by the input/output functions to report an operating system error. The string is meant to give some information to the programmer; you must not pattern match on the string literal because it may change in future versions (use Sys_error _ instead).

exception End_of_file

Exception raised by input functions to signal that the end of file has been reached.

exception Division_by_zero

Exception raised by integer division and remainder operations when their second argument is zero.

exception Sys_blocked_io

A special case of Sys_error raised when no I/O is possible on a non-blocking I/O channel.

exception Undefined_recursive_module of string * int * int

Exception raised when an ill-founded recursive module definition is evaluated. The arguments are the location of the definition in the source code (file name, line number, column number).

Comparisons

val (=) : 'a -> 'a -> bool

e1 = e2 tests for structural equality of e1 and e2. Mutable structures (e.g. references and arrays) are equal if and only if their current contents are structurally equal, even if the two mutable objects are not the same physical object. Equality between functional values raises Invalid_argument. Equality between cyclic data structures may not terminate. Left-associative operator, see Ocaml_operators for more information.

val (<>) : 'a -> 'a -> bool

Negation of Stdlib.(=). Left-associative operator, see Ocaml_operators for more information.

val (<) : 'a -> 'a -> bool

See Stdlib.(>=). Left-associative operator, see Ocaml_operators for more information.

val (>) : 'a -> 'a -> bool

See Stdlib.(>=). Left-associative operator, see Ocaml_operators for more information.

val (<=) : 'a -> 'a -> bool

See Stdlib.(>=). Left-associative operator, see Ocaml_operators for more information.

val (>=) : 'a -> 'a -> bool

Structural ordering functions. These functions coincide with the usual orderings over integers, characters, strings, byte sequences and floating-point numbers, and extend them to a total ordering over all types. The ordering is compatible with ( = ). As in the case of ( = ), mutable structures are compared by contents. Comparison between functional values raises Invalid_argument. Comparison between cyclic structures may not terminate. Left-associative operator, see Ocaml_operators for more information.

val compare : 'a -> 'a -> int

compare x y returns 0 if x is equal to y, a negative integer if x is less than y, and a positive integer if x is greater than y. The ordering implemented by compare is compatible with the comparison predicates =, < and > defined above, with one difference on the treatment of the float value Stdlib.nan. Namely, the comparison predicates treat nan as different from any other float value, including itself; while compare treats nan as equal to itself and less than any other float value. This treatment of nan ensures that compare defines a total ordering relation.

compare applied to functional values may raise Invalid_argument. compare applied to cyclic structures may not terminate.

The compare function can be used as the comparison function required by the Set.Make and Map.Make functors, as well as the List.sort and Array.sort functions.

val min : 'a -> 'a -> 'a

Return the smaller of the two arguments. The result is unspecified if one of the arguments contains the float value nan.

val max : 'a -> 'a -> 'a

Return the greater of the two arguments. The result is unspecified if one of the arguments contains the float value nan.

val (==) : 'a -> 'a -> bool

e1 == e2 tests for physical equality of e1 and e2. On mutable types such as references, arrays, byte sequences, records with mutable fields and objects with mutable instance variables, e1 == e2 is true if and only if physical modification of e1 also affects e2. On non-mutable types, the behavior of ( == ) is implementation-dependent; however, it is guaranteed that e1 == e2 implies compare e1 e2 = 0. Left-associative operator, see Ocaml_operators for more information.

val (!=) : 'a -> 'a -> bool

Negation of Stdlib.(==). Left-associative operator, see Ocaml_operators for more information.

Boolean operations

val not : bool -> bool

The boolean negation.

val (&&) : bool -> bool -> bool

The boolean 'and'. Evaluation is sequential, left-to-right: in e1 && e2, e1 is evaluated first, and if it returns false, e2 is not evaluated at all. Right-associative operator, see Ocaml_operators for more information.

val (||) : bool -> bool -> bool

The boolean 'or'. Evaluation is sequential, left-to-right: in e1 || e2, e1 is evaluated first, and if it returns true, e2 is not evaluated at all. Right-associative operator, see Ocaml_operators for more information.

Debugging

val __LOC__ : string

__LOC__ returns the location at which this expression appears in the file currently being parsed by the compiler, with the standard error format of OCaml: "File %S, line %d, characters %d-%d".

  • since 4.02
val __FILE__ : string

__FILE__ returns the name of the file currently being parsed by the compiler.

  • since 4.02
val __LINE__ : int

__LINE__ returns the line number at which this expression appears in the file currently being parsed by the compiler.

  • since 4.02
val __MODULE__ : string

__MODULE__ returns the module name of the file being parsed by the compiler.

  • since 4.02
val __POS__ : string * int * int * int

__POS__ returns a tuple (file,lnum,cnum,enum), corresponding to the location at which this expression appears in the file currently being parsed by the compiler. file is the current filename, lnum the line number, cnum the character position in the line and enum the last character position in the line.

  • since 4.02
val __FUNCTION__ : string

__FUNCTION__ returns the name of the current function or method, including any enclosing modules or classes.

  • since 4.12
val __LOC_OF__ : 'a -> string * 'a

__LOC_OF__ expr returns a pair (loc, expr) where loc is the location of expr in the file currently being parsed by the compiler, with the standard error format of OCaml: "File %S, line %d, characters %d-%d".

  • since 4.02
val __LINE_OF__ : 'a -> int * 'a

__LINE_OF__ expr returns a pair (line, expr), where line is the line number at which the expression expr appears in the file currently being parsed by the compiler.

  • since 4.02
val __POS_OF__ : 'a -> (string * int * int * int) * 'a

__POS_OF__ expr returns a pair (loc,expr), where loc is a tuple (file,lnum,cnum,enum) corresponding to the location at which the expression expr appears in the file currently being parsed by the compiler. file is the current filename, lnum the line number, cnum the character position in the line and enum the last character position in the line.

  • since 4.02

Composition operators

val (|>) : 'a -> ('a -> 'b) -> 'b

Reverse-application operator: x |> f |> g is exactly equivalent to g (f (x)). Left-associative operator, see Ocaml_operators for more information.

  • since 4.01
val (@@) : ('a -> 'b) -> 'a -> 'b

Application operator: g @@ f @@ x is exactly equivalent to g (f (x)). Right-associative operator, see Ocaml_operators for more information.

  • since 4.01

Integer arithmetic

Integers are Sys.int_size bits wide. All operations are taken modulo 2Sys.int_size. They do not fail on overflow.

val (~-) : int -> int

Unary negation. You can also write - e instead of ~- e. Unary operator, see Ocaml_operators for more information.

val (~+) : int -> int

Unary addition. You can also write + e instead of ~+ e. Unary operator, see Ocaml_operators for more information.

  • since 3.12
val succ : int -> int

succ x is x + 1.

val pred : int -> int

pred x is x - 1.

val (+) : int -> int -> int

Integer addition. Left-associative operator, see Ocaml_operators for more information.

val (-) : int -> int -> int

Integer subtraction. Left-associative operator, , see Ocaml_operators for more information.

val (*) : int -> int -> int

Integer multiplication. Left-associative operator, see Ocaml_operators for more information.

val (/) : int -> int -> int

Integer division. Integer division rounds the real quotient of its arguments towards zero. More precisely, if x >= 0 and y > 0, x / y is the greatest integer less than or equal to the real quotient of x by y. Moreover, (- x) / y = x / (- y) = - (x / y). Left-associative operator, see Ocaml_operators for more information.

val (mod) : int -> int -> int

Integer remainder. If y is not zero, the result of x mod y satisfies the following properties: x = (x / y) * y + x mod y and abs(x mod y) <= abs(y) - 1. If y = 0, x mod y raises Division_by_zero. Note that x mod y is negative only if x < 0. Left-associative operator, see Ocaml_operators for more information.

val abs : int -> int

abs x is the absolute value of x. On min_int this is min_int itself and thus remains negative.

val max_int : int

The greatest representable integer.

val min_int : int

The smallest representable integer.

Bitwise operations

val (land) : int -> int -> int

Bitwise logical and. Left-associative operator, see Ocaml_operators for more information.

val (lor) : int -> int -> int

Bitwise logical or. Left-associative operator, see Ocaml_operators for more information.

val (lxor) : int -> int -> int

Bitwise logical exclusive or. Left-associative operator, see Ocaml_operators for more information.

val lnot : int -> int

Bitwise logical negation.

val (lsl) : int -> int -> int

n lsl m shifts n to the left by m bits. The result is unspecified if m < 0 or m > Sys.int_size. Right-associative operator, see Ocaml_operators for more information.

val (lsr) : int -> int -> int

n lsr m shifts n to the right by m bits. This is a logical shift: zeroes are inserted regardless of the sign of n. The result is unspecified if m < 0 or m > Sys.int_size. Right-associative operator, see Ocaml_operators for more information.

val (asr) : int -> int -> int

n asr m shifts n to the right by m bits. This is an arithmetic shift: the sign bit of n is replicated. The result is unspecified if m < 0 or m > Sys.int_size. Right-associative operator, see Ocaml_operators for more information.

Floating-point arithmetic

OCaml's floating-point numbers follow the IEEE 754 standard, using double precision (64 bits) numbers. Floating-point operations never raise an exception on overflow, underflow, division by zero, etc. Instead, special IEEE numbers are returned as appropriate, such as infinity for 1.0 /. 0.0, neg_infinity for -1.0 /. 0.0, and nan ('not a number') for 0.0 /. 0.0. These special numbers then propagate through floating-point computations as expected: for instance, 1.0 /. infinity is 0.0, basic arithmetic operations (+., -., *., /.) with nan as an argument return nan, ...

val (~-.) : float -> float

Unary negation. You can also write -. e instead of ~-. e. Unary operator, see Ocaml_operators for more information.

val (~+.) : float -> float

Unary addition. You can also write +. e instead of ~+. e. Unary operator, see Ocaml_operators for more information.

  • since 3.12
val (+.) : float -> float -> float

Floating-point addition. Left-associative operator, see Ocaml_operators for more information.

val (-.) : float -> float -> float

Floating-point subtraction. Left-associative operator, see Ocaml_operators for more information.

val (*.) : float -> float -> float

Floating-point multiplication. Left-associative operator, see Ocaml_operators for more information.

val (/.) : float -> float -> float

Floating-point division. Left-associative operator, see Ocaml_operators for more information.

val (**) : float -> float -> float

Exponentiation. Right-associative operator, see Ocaml_operators for more information.

val sqrt : float -> float

Square root.

val exp : float -> float

Exponential.

val log : float -> float

Natural logarithm.

val log10 : float -> float

Base 10 logarithm.

val expm1 : float -> float

expm1 x computes exp x -. 1.0, giving numerically-accurate results even if x is close to 0.0.

  • since 3.12
val log1p : float -> float

log1p x computes log(1.0 +. x) (natural logarithm), giving numerically-accurate results even if x is close to 0.0.

  • since 3.12
val cos : float -> float

Cosine. Argument is in radians.

val sin : float -> float

Sine. Argument is in radians.

val tan : float -> float

Tangent. Argument is in radians.

val acos : float -> float

Arc cosine. The argument must fall within the range [-1.0, 1.0]. Result is in radians and is between 0.0 and pi.

val asin : float -> float

Arc sine. The argument must fall within the range [-1.0, 1.0]. Result is in radians and is between -pi/2 and pi/2.

val atan : float -> float

Arc tangent. Result is in radians and is between -pi/2 and pi/2.

val atan2 : float -> float -> float

atan2 y x returns the arc tangent of y /. x. The signs of x and y are used to determine the quadrant of the result. Result is in radians and is between -pi and pi.

val hypot : float -> float -> float

hypot x y returns sqrt(x *. x + y *. y), that is, the length of the hypotenuse of a right-angled triangle with sides of length x and y, or, equivalently, the distance of the point (x,y) to origin. If one of x or y is infinite, returns infinity even if the other is nan.

  • since 4.00
val cosh : float -> float

Hyperbolic cosine. Argument is in radians.

val sinh : float -> float

Hyperbolic sine. Argument is in radians.

val tanh : float -> float

Hyperbolic tangent. Argument is in radians.

val acosh : float -> float

Hyperbolic arc cosine. The argument must fall within the range [1.0, inf]. Result is in radians and is between 0.0 and inf.

  • since 4.13
val asinh : float -> float

Hyperbolic arc sine. The argument and result range over the entire real line. Result is in radians.

  • since 4.13
val atanh : float -> float

Hyperbolic arc tangent. The argument must fall within the range [-1.0, 1.0]. Result is in radians and ranges over the entire real line.

  • since 4.13
val ceil : float -> float

Round above to an integer value. ceil f returns the least integer value greater than or equal to f. The result is returned as a float.

val floor : float -> float

Round below to an integer value. floor f returns the greatest integer value less than or equal to f. The result is returned as a float.

val abs_float : float -> float

abs_float f returns the absolute value of f.

val copysign : float -> float -> float

copysign x y returns a float whose absolute value is that of x and whose sign is that of y. If x is nan, returns nan. If y is nan, returns either x or -. x, but it is not specified which.

  • since 4.00
val mod_float : float -> float -> float

mod_float a b returns the remainder of a with respect to b. The returned value is a -. n *. b, where n is the quotient a /. b rounded towards zero to an integer.

val frexp : float -> float * int

frexp f returns the pair of the significant and the exponent of f. When f is zero, the significant x and the exponent n of f are equal to zero. When f is non-zero, they are defined by f = x *. 2 ** n and 0.5 <= x < 1.0.

val ldexp : float -> int -> float

ldexp x n returns x *. 2 ** n.

val modf : float -> float * float

modf f returns the pair of the fractional and integral part of f.

val float : int -> float
val float_of_int : int -> float

Convert an integer to floating-point.

val truncate : float -> int
val int_of_float : float -> int

Truncate the given floating-point number to an integer. The result is unspecified if the argument is nan or falls outside the range of representable integers.

val infinity : float

Positive infinity.

val neg_infinity : float

Negative infinity.

val nan : float

A special floating-point value denoting the result of an undefined operation such as 0.0 /. 0.0. Stands for 'not a number'. Any floating-point operation with nan as argument returns nan as result, unless otherwise specified in IEEE 754 standard. As for floating-point comparisons, =, <, <=, > and >= return false and <> returns true if one or both of their arguments is nan.

nan is a quiet NaN since 5.1; it was a signaling NaN before.

val max_float : float

The largest positive finite value of type float.

val min_float : float

The smallest positive, non-zero, non-denormalized value of type float.

val epsilon_float : float

The difference between 1.0 and the smallest exactly representable floating-point number greater than 1.0.

type fpclass =
  1. | FP_normal
    (*

    Normal number, none of the below

    *)
  2. | FP_subnormal
    (*

    Number very close to 0.0, has reduced precision

    *)
  3. | FP_zero
    (*

    Number is 0.0 or -0.0

    *)
  4. | FP_infinite
    (*

    Number is positive or negative infinity

    *)
  5. | FP_nan
    (*

    Not a number: result of an undefined operation

    *)

The five classes of floating-point numbers, as determined by the Stdlib.classify_float function.

val classify_float : float -> fpclass

Return the class of the given floating-point number: normal, subnormal, zero, infinite, or not a number.

String operations

More string operations are provided in module String.

val (^) : string -> string -> string

String concatenation. Right-associative operator, see Ocaml_operators for more information.

Character operations

More character operations are provided in module Char.

val int_of_char : char -> int

Return the ASCII code of the argument.

val char_of_int : int -> char

Return the character with the given ASCII code.

Unit operations

val ignore : 'a -> unit

Discard the value of its argument and return (). For instance, ignore(f x) discards the result of the side-effecting function f. It is equivalent to f x; (), except that the latter may generate a compiler warning; writing ignore(f x) instead avoids the warning.

String conversion functions

val string_of_bool : bool -> string

Return the string representation of a boolean. As the returned values may be shared, the user should not modify them directly.

val bool_of_string_opt : string -> bool option

Convert the given string to a boolean.

Return None if the string is not "true" or "false".

  • since 4.05
val bool_of_string : string -> bool

Same as Stdlib.bool_of_string_opt, but raise Invalid_argument "bool_of_string" instead of returning None.

val string_of_int : int -> string

Return the string representation of an integer, in decimal.

val int_of_string_opt : string -> int option

Convert the given string to an integer. The string is read in decimal (by default, or if the string begins with 0u), in hexadecimal (if it begins with 0x or 0X), in octal (if it begins with 0o or 0O), or in binary (if it begins with 0b or 0B).

The 0u prefix reads the input as an unsigned integer in the range [0, 2*max_int+1]. If the input exceeds max_int it is converted to the signed integer min_int + input - max_int - 1.

The _ (underscore) character can appear anywhere in the string and is ignored.

Return None if the given string is not a valid representation of an integer, or if the integer represented exceeds the range of integers representable in type int.

  • since 4.05
val int_of_string : string -> int

Same as Stdlib.int_of_string_opt, but raise Failure "int_of_string" instead of returning None.

val string_of_float : float -> string

Return a string representation of a floating-point number.

This conversion can involve a loss of precision. For greater control over the manner in which the number is printed, see Printf.

val float_of_string_opt : string -> float option

Convert the given string to a float. The string is read in decimal (by default) or in hexadecimal (marked by 0x or 0X).

The format of decimal floating-point numbers is [-] dd.ddd (e|E) [+|-] dd , where d stands for a decimal digit.

The format of hexadecimal floating-point numbers is [-] 0(x|X) hh.hhh (p|P) [+|-] dd , where h stands for an hexadecimal digit and d for a decimal digit.

In both cases, at least one of the integer and fractional parts must be given; the exponent part is optional.

The _ (underscore) character can appear anywhere in the string and is ignored.

Depending on the execution platforms, other representations of floating-point numbers can be accepted, but should not be relied upon.

Return None if the given string is not a valid representation of a float.

  • since 4.05
val float_of_string : string -> float

Same as Stdlib.float_of_string_opt, but raise Failure "float_of_string" instead of returning None.

Pair operations

val fst : ('a * 'b) -> 'a

Return the first component of a pair.

val snd : ('a * 'b) -> 'b

Return the second component of a pair.

List operations

More list operations are provided in module List.

val (@) : 'a list -> 'a list -> 'a list

l0 @ l1 appends l1 to l0. Same function as List.append. Right-associative operator, see Ocaml_operators for more information.

  • since 5.1 this function is tail-recursive.

Input/output

Note: all input/output functions can raise Sys_error when the system calls they invoke fail.

type in_channel

The type of input channel.

type out_channel

The type of output channel.

val stdin : in_channel

The standard input for the process.

val stdout : out_channel

The standard output for the process.

val stderr : out_channel

The standard error output for the process.

Output functions on standard output

val print_char : char -> unit

Print a character on standard output.

val print_string : string -> unit

Print a string on standard output.

val print_bytes : bytes -> unit

Print a byte sequence on standard output.

  • since 4.02
val print_int : int -> unit

Print an integer, in decimal, on standard output.

val print_float : float -> unit

Print a floating-point number, in decimal, on standard output.

The conversion of the number to a string uses string_of_float and can involve a loss of precision.

val print_endline : string -> unit

Print a string, followed by a newline character, on standard output and flush standard output.

val print_newline : unit -> unit

Print a newline character on standard output, and flush standard output. This can be used to simulate line buffering of standard output.

Output functions on standard error

val prerr_char : char -> unit

Print a character on standard error.

val prerr_string : string -> unit

Print a string on standard error.

val prerr_bytes : bytes -> unit

Print a byte sequence on standard error.

  • since 4.02
val prerr_int : int -> unit

Print an integer, in decimal, on standard error.

val prerr_float : float -> unit

Print a floating-point number, in decimal, on standard error.

The conversion of the number to a string uses string_of_float and can involve a loss of precision.

val prerr_endline : string -> unit

Print a string, followed by a newline character on standard error and flush standard error.

val prerr_newline : unit -> unit

Print a newline character on standard error, and flush standard error.

Input functions on standard input

val read_line : unit -> string

Flush standard output, then read characters from standard input until a newline character is encountered.

Return the string of all characters read, without the newline character at the end.

  • raises End_of_file

    if the end of the file is reached at the beginning of line.

val read_int_opt : unit -> int option

Flush standard output, then read one line from standard input and convert it to an integer.

Return None if the line read is not a valid representation of an integer.

  • since 4.05
val read_int : unit -> int

Same as Stdlib.read_int_opt, but raise Failure "int_of_string" instead of returning None.

val read_float_opt : unit -> float option

Flush standard output, then read one line from standard input and convert it to a floating-point number.

Return None if the line read is not a valid representation of a floating-point number.

  • since 4.05
val read_float : unit -> float

Same as Stdlib.read_float_opt, but raise Failure "float_of_string" instead of returning None.

General output functions

type open_flag =
  1. | Open_rdonly
    (*

    open for reading.

    *)
  2. | Open_wronly
    (*

    open for writing.

    *)
  3. | Open_append
    (*

    open for appending: always write at end of file.

    *)
  4. | Open_creat
    (*

    create the file if it does not exist.

    *)
  5. | Open_trunc
    (*

    empty the file if it already exists.

    *)
  6. | Open_excl
    (*

    fail if Open_creat and the file already exists.

    *)
  7. | Open_binary
    (*

    open in binary mode (no conversion).

    *)
  8. | Open_text
    (*

    open in text mode (may perform conversions).

    *)
  9. | Open_nonblock
    (*

    open in non-blocking mode.

    *)
val open_out : string -> out_channel

Open the named file for writing, and return a new output channel on that file, positioned at the beginning of the file. The file is truncated to zero length if it already exists. It is created if it does not already exists.

val open_out_bin : string -> out_channel

Same as Stdlib.open_out, but the file is opened in binary mode, so that no translation takes place during writes. On operating systems that do not distinguish between text mode and binary mode, this function behaves like Stdlib.open_out.

val open_out_gen : open_flag list -> int -> string -> out_channel

open_out_gen mode perm filename opens the named file for writing, as described above. The extra argument mode specifies the opening mode. The extra argument perm specifies the file permissions, in case the file must be created. Stdlib.open_out and Stdlib.open_out_bin are special cases of this function.

val flush : out_channel -> unit

Flush the buffer associated with the given output channel, performing all pending writes on that channel. Interactive programs must be careful about flushing standard output and standard error at the right time.

val flush_all : unit -> unit

Flush all open output channels; ignore errors.

val output_char : out_channel -> char -> unit

Write the character on the given output channel.

val output_string : out_channel -> string -> unit

Write the string on the given output channel.

val output_bytes : out_channel -> bytes -> unit

Write the byte sequence on the given output channel.

  • since 4.02
val output : out_channel -> bytes -> int -> int -> unit

output oc buf pos len writes len characters from byte sequence buf, starting at offset pos, to the given output channel oc.

val output_substring : out_channel -> string -> int -> int -> unit

Same as output but take a string as argument instead of a byte sequence.

  • since 4.02
val output_byte : out_channel -> int -> unit

Write one 8-bit integer (as the single character with that code) on the given output channel. The given integer is taken modulo 256.

val output_binary_int : out_channel -> int -> unit

Write one integer in binary format (4 bytes, big-endian) on the given output channel. The given integer is taken modulo 232. The only reliable way to read it back is through the Stdlib.input_binary_int function. The format is compatible across all machines for a given version of OCaml.

val output_value : out_channel -> 'a -> unit

Write the representation of a structured value of any type to a channel. Circularities and sharing inside the value are detected and preserved. The object can be read back, by the function Stdlib.input_value. See the description of module Marshal for more information. Stdlib.output_value is equivalent to Marshal.to_channel with an empty list of flags.

val seek_out : out_channel -> int -> unit

seek_out chan pos sets the current writing position to pos for channel chan. This works only for regular files. On files of other kinds (such as terminals, pipes and sockets), the behavior is unspecified.

val pos_out : out_channel -> int

Return the current writing position for the given channel. Does not work on channels opened with the Open_append flag (returns unspecified results). For files opened in text mode under Windows, the returned position is approximate (owing to end-of-line conversion); in particular, saving the current position with pos_out, then going back to this position using seek_out will not work. For this programming idiom to work reliably and portably, the file must be opened in binary mode.

val out_channel_length : out_channel -> int

Return the size (number of characters) of the regular file on which the given channel is opened. If the channel is opened on a file that is not a regular file, the result is meaningless.

val close_out : out_channel -> unit

Close the given channel, flushing all buffered write operations. Output functions raise a Sys_error exception when they are applied to a closed output channel, except close_out and flush, which do nothing when applied to an already closed channel. Note that close_out may raise Sys_error if the operating system signals an error when flushing or closing.

val close_out_noerr : out_channel -> unit

Same as close_out, but ignore all errors.

val set_binary_mode_out : out_channel -> bool -> unit

set_binary_mode_out oc true sets the channel oc to binary mode: no translations take place during output. set_binary_mode_out oc false sets the channel oc to text mode: depending on the operating system, some translations may take place during output. For instance, under Windows, end-of-lines will be translated from \n to \r\n. This function has no effect under operating systems that do not distinguish between text mode and binary mode.

General input functions

val open_in : string -> in_channel

Open the named file for reading, and return a new input channel on that file, positioned at the beginning of the file.

val open_in_bin : string -> in_channel

Same as Stdlib.open_in, but the file is opened in binary mode, so that no translation takes place during reads. On operating systems that do not distinguish between text mode and binary mode, this function behaves like Stdlib.open_in.

val open_in_gen : open_flag list -> int -> string -> in_channel

open_in_gen mode perm filename opens the named file for reading, as described above. The extra arguments mode and perm specify the opening mode and file permissions. Stdlib.open_in and Stdlib.open_in_bin are special cases of this function.

val input_char : in_channel -> char

Read one character from the given input channel.

  • raises End_of_file

    if there are no more characters to read.

val input_line : in_channel -> string

Read characters from the given input channel, until a newline character is encountered. Return the string of all characters read, without the newline character at the end.

  • raises End_of_file

    if the end of the file is reached at the beginning of line.

val input : in_channel -> bytes -> int -> int -> int

input ic buf pos len reads up to len characters from the given channel ic, storing them in byte sequence buf, starting at character number pos. It returns the actual number of characters read, between 0 and len (inclusive). A return value of 0 means that the end of file was reached. A return value between 0 and len exclusive means that not all requested len characters were read, either because no more characters were available at that time, or because the implementation found it convenient to do a partial read; input must be called again to read the remaining characters, if desired. (See also Stdlib.really_input for reading exactly len characters.) Exception Invalid_argument "input" is raised if pos and len do not designate a valid range of buf.

val really_input : in_channel -> bytes -> int -> int -> unit

really_input ic buf pos len reads len characters from channel ic, storing them in byte sequence buf, starting at character number pos.

  • raises End_of_file

    if the end of file is reached before len characters have been read.

val really_input_string : in_channel -> int -> string

really_input_string ic len reads len characters from channel ic and returns them in a new string.

  • raises End_of_file

    if the end of file is reached before len characters have been read.

  • since 4.02
val input_byte : in_channel -> int

Same as Stdlib.input_char, but return the 8-bit integer representing the character.

val input_binary_int : in_channel -> int

Read an integer encoded in binary format (4 bytes, big-endian) from the given input channel. See Stdlib.output_binary_int.

  • raises End_of_file

    if the end of file was reached while reading the integer.

val input_value : in_channel -> 'a

Read the representation of a structured value, as produced by Stdlib.output_value, and return the corresponding value. This function is identical to Marshal.from_channel; see the description of module Marshal for more information, in particular concerning the lack of type safety.

val seek_in : in_channel -> int -> unit

seek_in chan pos sets the current reading position to pos for channel chan. This works only for regular files. On files of other kinds, the behavior is unspecified.

val pos_in : in_channel -> int

Return the current reading position for the given channel. For files opened in text mode under Windows, the returned position is approximate (owing to end-of-line conversion); in particular, saving the current position with pos_in, then going back to this position using seek_in will not work. For this programming idiom to work reliably and portably, the file must be opened in binary mode.

val in_channel_length : in_channel -> int

Return the size (number of characters) of the regular file on which the given channel is opened. If the channel is opened on a file that is not a regular file, the result is meaningless. The returned size does not take into account the end-of-line translations that can be performed when reading from a channel opened in text mode.

val close_in : in_channel -> unit

Close the given channel. Input functions raise a Sys_error exception when they are applied to a closed input channel, except close_in, which does nothing when applied to an already closed channel.

val close_in_noerr : in_channel -> unit

Same as close_in, but ignore all errors.

val set_binary_mode_in : in_channel -> bool -> unit

set_binary_mode_in ic true sets the channel ic to binary mode: no translations take place during input. set_binary_mode_out ic false sets the channel ic to text mode: depending on the operating system, some translations may take place during input. For instance, under Windows, end-of-lines will be translated from \r\n to \n. This function has no effect under operating systems that do not distinguish between text mode and binary mode.

Operations on large files

module LargeFile : sig ... end

Operations on large files. This sub-module provides 64-bit variants of the channel functions that manipulate file positions and file sizes. By representing positions and sizes by 64-bit integers (type int64) instead of regular integers (type int), these alternate functions allow operating on files whose sizes are greater than max_int.

References

type 'a ref = {
  1. mutable contents : 'a;
}

The type of references (mutable indirection cells) containing a value of type 'a.

val ref : 'a -> 'a ref

Return a fresh reference containing the given value.

val (!) : 'a ref -> 'a

!r returns the current contents of reference r. Equivalent to fun r -> r.contents. Unary operator, see Ocaml_operators for more information.

val (:=) : 'a ref -> 'a -> unit

r := a stores the value of a in reference r. Equivalent to fun r v -> r.contents <- v. Right-associative operator, see Ocaml_operators for more information.

val incr : int ref -> unit

Increment the integer contained in the given reference. Equivalent to fun r -> r := succ !r.

val decr : int ref -> unit

Decrement the integer contained in the given reference. Equivalent to fun r -> r := pred !r.

Result type

type ('a, 'b) result =
  1. | Ok of 'a
  2. | Error of 'b
  • since 4.03

Operations on format strings

Format strings are character strings with special lexical conventions that defines the functionality of formatted input/output functions. Format strings are used to read data with formatted input functions from module Scanf and to print data with formatted output functions from modules Printf and Format.

Format strings are made of three kinds of entities:

  • conversions specifications, introduced by the special character '%' followed by one or more characters specifying what kind of argument to read or print,
  • formatting indications, introduced by the special character '@' followed by one or more characters specifying how to read or print the argument,
  • plain characters that are regular characters with usual lexical conventions. Plain characters specify string literals to be read in the input or printed in the output.

There is an additional lexical rule to escape the special characters '%' and '@' in format strings: if a special character follows a '%' character, it is treated as a plain character. In other words, "%%" is considered as a plain '%' and "%@" as a plain '@'.

For more information about conversion specifications and formatting indications available, read the documentation of modules Scanf, Printf and Format.

Format strings have a general and highly polymorphic type ('a, 'b, 'c, 'd, 'e, 'f) format6. The two simplified types, format and format4 below are included for backward compatibility with earlier releases of OCaml.

The meaning of format string type parameters is as follows:

  • 'a is the type of the parameters of the format for formatted output functions (printf-style functions); 'a is the type of the values read by the format for formatted input functions (scanf-style functions).
  • 'b is the type of input source for formatted input functions and the type of output target for formatted output functions. For printf-style functions from module Printf, 'b is typically out_channel; for printf-style functions from module Format, 'b is typically Format.formatter; for scanf-style functions from module Scanf, 'b is typically Scanf.Scanning.in_channel.

Type argument 'b is also the type of the first argument given to user's defined printing functions for %a and %t conversions, and user's defined reading functions for %r conversion.

  • 'c is the type of the result of the %a and %t printing functions, and also the type of the argument transmitted to the first argument of kprintf-style functions or to the kscanf-style functions.
  • 'd is the type of parameters for the scanf-style functions.
  • 'e is the type of the receiver function for the scanf-style functions.
  • 'f is the final result type of a formatted input/output function invocation: for the printf-style functions, it is typically unit; for the scanf-style functions, it is typically the result type of the receiver function.
type ('a, 'b, 'c, 'd, 'e, 'f) format6 = + ('a, 'b, 'c, 'd, 'e, 'f) CamlinternalFormatBasics.format6
type ('a, 'b, 'c, 'd) format4 = ('a, 'b, 'c, 'c, 'c, 'd) format6
type ('a, 'b, 'c) format = ('a, 'b, 'c, 'c) format4
val string_of_format : ('a, 'b, 'c, 'd, 'e, 'f) format6 -> string

Converts a format string into a string.

val format_of_string : + ('a, 'b, 'c, 'd, 'e, 'f) format6 -> + ('a, 'b, 'c, 'd, 'e, 'f) format6

format_of_string s returns a format string read from the string literal s. Note: format_of_string can not convert a string argument that is not a literal. If you need this functionality, use the more general Scanf.format_from_string function.

val (^^) : + ('a, 'b, 'c, 'd, 'e, 'f) format6 -> + ('f, 'b, 'c, 'e, 'g, 'h) format6 -> + ('a, 'b, 'c, 'd, 'g, 'h) format6

f1 ^^ f2 catenates format strings f1 and f2. The result is a format string that behaves as the concatenation of format strings f1 and f2: in case of formatted output, it accepts arguments from f1, then arguments from f2; in case of formatted input, it returns results from f1, then results from f2. Right-associative operator, see Ocaml_operators for more information.

Program termination

val exit : int -> 'a

Terminate the process, returning the given status code to the operating system: usually 0 to indicate no errors, and a small positive integer to indicate failure. All open output channels are flushed with flush_all. The callbacks registered with Domain.at_exit are called followed by those registered with Stdlib.at_exit.

An implicit exit 0 is performed each time a program terminates normally. An implicit exit 2 is performed if the program terminates early because of an uncaught exception.

val at_exit : (unit -> unit) -> unit

Register the given function to be called at program termination time. The functions registered with at_exit will be called when the program does any of the following:

  • executes Stdlib.exit
  • terminates, either normally or because of an uncaught exception
  • executes the C function caml_shutdown. The functions are called in 'last in, first out' order: the function most recently added with at_exit is called first.

Standard library modules

module Arg : sig ... end

Parsing of command line arguments.

module Array : sig ... end

Array operations.

module ArrayLabels : sig ... end

Array operations.

module Atomic : sig ... end

Atomic references.

module Bigarray : sig ... end

Large, multi-dimensional, numerical arrays.

module Bool : sig ... end

Boolean values.

module Buffer : sig ... end

Extensible buffers.

module Bytes : sig ... end

Byte sequence operations.

module BytesLabels : sig ... end

Byte sequence operations.

module Callback : sig ... end

Registering OCaml values with the C runtime.

module Char : sig ... end

Character operations.

module Complex : sig ... end

Complex numbers.

module Condition : sig ... end

Condition variables.

module Digest : sig ... end

MD5 message digest.

module Domain : sig ... end
module Effect : sig ... end
module Either : sig ... end

Either type.

module Ephemeron : sig ... end

Ephemerons and weak hash tables.

module Filename : sig ... end

Operations on file names.

module Float : sig ... end

Floating-point arithmetic.

module Format : sig ... end

Pretty-printing.

module Fun : sig ... end

Function manipulation.

module Gc : sig ... end

Memory management control and statistics; finalised values.

module Hashtbl : sig ... end

Hash tables and hash functions.

module In_channel : sig ... end

Input channels.

module Int : sig ... end

Integer values.

module Int32 : sig ... end

32-bit integers.

module Int64 : sig ... end

64-bit integers.

module Lazy : sig ... end

Deferred computations.

module Lexing : sig ... end

The run-time library for lexers generated by ocamllex.

module List : sig ... end

List operations.

module ListLabels : sig ... end

List operations.

module Map : sig ... end

Association tables over ordered types.

module Marshal : sig ... end

Marshaling of data structures.

module MoreLabels : sig ... end

Extra labeled libraries.

module Mutex : sig ... end

Locks for mutual exclusion.

module Nativeint : sig ... end

Processor-native integers.

module Obj : sig ... end

Operations on internal representations of values.

module Oo : sig ... end

Operations on objects

module Option : sig ... end

Option values.

module Out_channel : sig ... end

Output channels.

module Parsing : sig ... end

The run-time library for parsers generated by ocamlyacc.

module Printexc : sig ... end

Facilities for printing exceptions and inspecting current call stack.

module Printf : sig ... end

Formatted output functions.

module Queue : sig ... end

First-in first-out queues.

module Random : sig ... end

Pseudo-random number generators (PRNG).

module Result : sig ... end

Result values.

module Scanf : sig ... end

Formatted input functions.

module Semaphore : sig ... end

Semaphores

module Seq : sig ... end

Sequences.

module Set : sig ... end

Sets over ordered types.

module Stack : sig ... end

Last-in first-out stacks.

module StdLabels : sig ... end

Standard labeled libraries.

module String : sig ... end

Strings.

module StringLabels : sig ... end

Strings.

module Sys : sig ... end

System interface.

module Type : sig ... end

Type introspection.

module Uchar : sig ... end

Unicode characters.

module Unit : sig ... end

Unit values.

module Weak : sig ... end

Arrays of weak pointers and hash sets of weak pointers.

diff --git a/docs/stdlib/index.html b/docs/stdlib/index.html new file mode 100644 index 00000000..4e0dfcfc --- /dev/null +++ b/docs/stdlib/index.html @@ -0,0 +1,2 @@ + +stdlib (docs.stdlib)

Packages located relative to stdlib

Libraries

The following libraries are found in this directory.

  • stdlib

Modules

The following is a list of all of the modules found at this filesystem path.