diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-05 01:47:19 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-16 17:29:57 +0100 |
commit | 8da8c7d337123b28fdeb539a283d00732118712e (patch) | |
tree | 74096a23b9e2f64a7e25ec1e8d4d3b1d8934842e /libphobos/src/std | |
parent | c5e2c3dd6afcf9b152df72b30e205b0180c0afd5 (diff) | |
download | gcc-8da8c7d337123b28fdeb539a283d00732118712e.zip gcc-8da8c7d337123b28fdeb539a283d00732118712e.tar.gz gcc-8da8c7d337123b28fdeb539a283d00732118712e.tar.bz2 |
d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
D front-end changes:
- Import dmd v2.103.0-beta.1.
- Using `alias this' for classes has been deprecated.
- The feature `-fpreview=dip25` is now enabled by default.
- The compile-time traits `isVirtualFunction' and
`getVirtualFunctions' have been deprecated.
D runtime changes:
- Import druntime v2.103.0-beta.1.
Phobos changes:
- Import phobos v2.103.0-beta.1.
- Updated unicode grapheme walking updated to conform to Unicode
version 15.
- Improved friendliness of error messages when instantiating
`std.algorithm.iteration.joiner' and
`std.algorithm.sorting.sort' with wrong inputs.
gcc/d/ChangeLog:
* dmd/MERGE: Merge upstream dmd 4ca4140e58.
* dmd/VERSION: Bump version to v2.103.0-beta.1.
* Make-lang.in (D_FRONTEND_OBJS): Add d/errorsink.o.
* d-ctfloat.cc (CTFloat::sprint): Update signature for new front-end
interface.
* d-frontend.cc (getTypeInfoType): Likewise.
* d-lang.cc (d_handle_option): Remove handling of -fpreview=dip25 and
-frevert=dip25.
(d_post_options): Remove enabling of sealed references language
feature when scoped pointers is enabled.
* d-tree.h (create_typeinfo): Update signature.
* decl.cc (DeclVisitor::finish_vtable): Update for new front-end
interface.
(DeclVisitor::visit (VarDeclaration *)): Likewise.
(DeclVisitor::visit (FuncDeclaration *)): Check skipCodegen to see if
front-end explicitly requested not to generate code.
* expr.cc (ExprVisitor::visit (NewExp *)): Update for new front-end
interface.
* lang.opt (fpreview=dip25): Remove.
(frevert=dip25): Remove.
* modules.cc (layout_moduleinfo_fields): Update for new front-end
interface.
(layout_moduleinfo): Likewise.
* runtime.def (NEWCLASS): Remove.
* toir.cc (IRVisitor::visit (IfStatement *)): Don't generate IR for if
statement list when condition is `__ctfe'.
* typeinfo.cc (create_typeinfo): Add generate parameter.
* types.cc (layout_aggregate_members): Update for new front-end
interface.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime 4ca4140e58.
* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/factory.d.
* libdruntime/Makefile.in: Regenerate.
* src/MERGE: Merge upstream phobos 454dff14d.
* testsuite/libphobos.hash/test_hash.d: Update test.
* testsuite/libphobos.shared/finalize.d: Update test.
* libdruntime/core/factory.d: New file.
gcc/testsuite/ChangeLog:
* gdc.dg/torture/simd23084.d: New test.
* gdc.dg/torture/simd23085.d: New test.
* gdc.dg/torture/simd23218.d: New test.
Diffstat (limited to 'libphobos/src/std')
24 files changed, 1250 insertions, 520 deletions
diff --git a/libphobos/src/std/algorithm/iteration.d b/libphobos/src/std/algorithm/iteration.d index 967d2a6..8236076 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -2969,10 +2969,24 @@ iterated from the back to the front, the separator will still be consumed from front to back, even if it is a bidirectional range too. */ auto joiner(RoR, Separator)(RoR r, Separator sep) -if (isInputRange!RoR && isInputRange!(ElementType!RoR) - && isForwardRange!Separator - && is(ElementType!Separator : ElementType!(ElementType!RoR))) { + static assert(isInputRange!RoR, "The type of RoR '", RoR.stringof + , " must be an InputRange (isInputRange!", RoR.stringof, ")."); + static assert(isInputRange!(ElementType!RoR), "The ElementyType of RoR '" + , ElementType!(RoR).stringof, "' must be an InputRange " + , "(isInputRange!(ElementType!(", RoR.stringof , ")))."); + static assert(isForwardRange!Separator, "The type of the Seperator '" + , Seperator.stringof, "' must be a ForwardRange (isForwardRange!(" + , Seperator.stringof, "))."); + static assert(is(ElementType!Separator : ElementType!(ElementType!RoR)) + , "The type of the elements of the separator range does not match " + , "the type of the elements that are joined. Separator type '" + , ElementType!(Separator).stringof, "' is not implicitly" + , "convertible to range element type '" + , ElementType!(ElementType!RoR).stringof, "' (is(ElementType!" + , Separator.stringof, " : ElementType!(ElementType!", RoR.stringof + , ")))."); + static struct Result { private RoR _items; diff --git a/libphobos/src/std/algorithm/package.d b/libphobos/src/std/algorithm/package.d index 6aacd51..71bd1d9 100644 --- a/libphobos/src/std/algorithm/package.d +++ b/libphobos/src/std/algorithm/package.d @@ -103,6 +103,7 @@ $(TR $(SUBREF sorting, multiSort) $(SUBREF sorting, nextEvenPermutation) $(SUBREF sorting, nextPermutation) + $(SUBREF sorting, nthPermutation) $(SUBREF sorting, partialSort) $(SUBREF sorting, partition) $(SUBREF sorting, partition3) diff --git a/libphobos/src/std/algorithm/sorting.d b/libphobos/src/std/algorithm/sorting.d index ddb80b8..c5b085d 100644 --- a/libphobos/src/std/algorithm/sorting.d +++ b/libphobos/src/std/algorithm/sorting.d @@ -1922,14 +1922,8 @@ See_Also: $(REF binaryFun, std,functional) */ SortedRange!(Range, less) -sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, - Range)(Range r) -if (((ss == SwapStrategy.unstable && (hasSwappableElements!Range || - hasAssignableElements!Range)) || - (ss != SwapStrategy.unstable && hasAssignableElements!Range)) && - isRandomAccessRange!Range && - hasSlicing!Range && - hasLength!Range) +sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range) +(Range r) /+ Unstable sorting uses the quicksort algorithm, which uses swapAt, which either uses swap(...), requiring swappable elements, or just swaps using assignment. @@ -1937,21 +1931,46 @@ if (((ss == SwapStrategy.unstable && (hasSwappableElements!Range || requiring assignable elements. +/ { import std.range : assumeSorted; - alias lessFun = binaryFun!(less); - alias LessRet = typeof(lessFun(r.front, r.front)); // instantiate lessFun - static if (is(LessRet == bool)) + static if (ss == SwapStrategy.unstable) { - static if (ss == SwapStrategy.unstable) - quickSortImpl!(lessFun)(r, r.length); - else //use Tim Sort for semistable & stable - TimSortImpl!(lessFun, Range).sort(r, null); - - assert(isSorted!lessFun(r), "Failed to sort range of type " ~ Range.stringof); + static assert(hasSwappableElements!Range || hasAssignableElements!Range, + "When using SwapStrategy.unstable, the passed Range '" + ~ Range.stringof ~ "' must" + ~ " either fulfill hasSwappableElements, or" + ~ " hasAssignableElements, both were not the case"); } else { - static assert(false, "Invalid predicate passed to sort: " ~ less.stringof); + static assert(hasAssignableElements!Range, "When using a SwapStrategy" + ~ " != unstable, the" + ~ " passed Range '" ~ Range.stringof ~ "' must fulfill" + ~ " hasAssignableElements, which it did not"); } + + static assert(isRandomAccessRange!Range, "The passed Range '" + ~ Range.stringof ~ "' must be a Random AccessRange " + ~ "(isRandomAccessRange)"); + + static assert(hasSlicing!Range, "The passed Range '" + ~ Range.stringof ~ "' must allow Slicing (hasSlicing)"); + + static assert(hasLength!Range, "The passed Range '" + ~ Range.stringof ~ "' must have a length (hasLength)"); + + alias lessFun = binaryFun!(less); + alias LessRet = typeof(lessFun(r.front, r.front)); // instantiate lessFun + + static assert(is(LessRet == bool), "The return type of the template" + ~ " argument 'less' when used with the binaryFun!less template" + ~ " must be a bool. This is not the case, the returned type is '" + ~ LessRet.stringof ~ "'"); + + static if (ss == SwapStrategy.unstable) + quickSortImpl!(lessFun)(r, r.length); + else //use Tim Sort for semistable & stable + TimSortImpl!(lessFun, Range).sort(r, null); + + assert(isSorted!lessFun(r), "Failed to sort range of type " ~ Range.stringof); return assumeSorted!less(r); } @@ -2599,8 +2618,16 @@ private template TimSortImpl(alias pred, R) //Test for overflow if (newSize < minCapacity) newSize = minCapacity; - if (__ctfe) temp.length = newSize; - else temp = () @trusted { return uninitializedArray!(T[])(newSize); }(); + // can't use `temp.length` if there's no default constructor + static if (__traits(compiles, { T defaultConstructed; cast(void) defaultConstructed; })) + { + if (__ctfe) temp.length = newSize; + else temp = () @trusted { return uninitializedArray!(T[])(newSize); }(); + } + else + { + temp = () @trusted { return uninitializedArray!(T[])(newSize); }(); + } } return temp; } @@ -3037,6 +3064,18 @@ private template TimSortImpl(alias pred, R) sort!(cmp, SwapStrategy.stable)(makeArray(minMerge + 5)); } +// https://issues.dlang.org/show_bug.cgi?id=23668 +@safe unittest +{ + static struct S + { + int opCmp(const S) const { return 1; } + @disable this(); + } + S[] array; + array.sort!("a < b", SwapStrategy.stable); +} + // schwartzSort /** Alternative sorting method that should be used when comparing keys involves an diff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d index daa103a..4584dcc 100644 --- a/libphobos/src/std/array.d +++ b/libphobos/src/std/array.d @@ -170,7 +170,7 @@ if (isIterable!Range && !isAutodecodableString!Range && !isInfinite!Range) /// ditto ForeachType!(typeof((*Range).init))[] array(Range)(Range r) -if (is(Range : U*, U) && isIterable!U && !isAutodecodableString!Range && !isInfinite!Range) +if (is(Range == U*, U) && isIterable!U && !isAutodecodableString!Range && !isInfinite!Range) { return array(*r); } @@ -2294,22 +2294,6 @@ if (isInputRange!RoR && } } -// https://issues.dlang.org/show_bug.cgi?id=10895 -@safe unittest -{ - static class A - { - string name; - alias name this; - this(string name) { this.name = name; } - } - auto a = [new A(`foo`)]; - assert(a[0].length == 3); - auto temp = join(a, " "); - assert(a[0].length == 3); - assert(temp.length == 3); -} - // https://issues.dlang.org/show_bug.cgi?id=14230 @safe unittest { diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d index 559f8da..b84a676 100644 --- a/libphobos/src/std/bitmanip.d +++ b/libphobos/src/std/bitmanip.d @@ -89,22 +89,21 @@ private template createAccessors( } else { - enum ulong - maskAllElse = ((~0uL) >> (64 - len)) << offset, - signBitCheck = 1uL << (len - 1); + enum ulong maskAllElse = ((~0uL) >> (64 - len)) << offset; + enum TSize = 8 * T.sizeof; + enum SignShift = TSize - len; static if (T.min < 0) { enum long minVal = -(1uL << (len - 1)); enum ulong maxVal = (1uL << (len - 1)) - 1; - alias UT = Unsigned!(T); - enum UT extendSign = cast(UT)~((~0uL) >> (64 - len)); + enum RightShiftOp = ">>="; } else { enum ulong minVal = 0; enum ulong maxVal = (~0uL) >> (64 - len); - enum extendSign = 0; + enum RightShiftOp = ">>>="; } static if (is(T == bool)) @@ -121,15 +120,11 @@ private template createAccessors( else { // getter - enum createAccessors = "@property "~T.stringof~" "~name~"() @safe pure nothrow @nogc const { auto result = " - ~"("~store~" & " - ~ myToString(maskAllElse) ~ ") >>" - ~ myToString(offset) ~ ";" - ~ (T.min < 0 - ? "if (result >= " ~ myToString(signBitCheck) - ~ ") result |= " ~ myToString(extendSign) ~ ";" - : "") - ~ " return cast("~T.stringof~") result;}\n" + enum createAccessors = "@property "~T.stringof~" "~name~"() @safe pure nothrow @nogc const {" + ~ "auto result = cast("~T.stringof~") (" ~ store ~ " >>" ~ myToString(offset) ~ ");" + ~ "result <<= " ~ myToString(SignShift) ~ ";" + ~ "result " ~ RightShiftOp ~ myToString(SignShift) ~ ";" + ~ " return result;}\n" // setter ~"@property void "~name~"("~T.stringof~" v) @safe pure nothrow @nogc { " ~"assert(v >= "~name~`_min, "Value is smaller than the minimum value of bitfield '`~name~`'"); ` diff --git a/libphobos/src/std/concurrency.d b/libphobos/src/std/concurrency.d index 323926a..7fe52ba 100644 --- a/libphobos/src/std/concurrency.d +++ b/libphobos/src/std/concurrency.d @@ -46,7 +46,7 @@ * * This is a low-level messaging API upon which more structured or restrictive * APIs may be built. The general idea is that every messageable entity is - * represented by a common handle type called a Tid, which allows messages to + * represented by a common handle type called a `Tid`, which allows messages to * be sent to logical threads that are executing in both the current process * and in external processes using the same interface. This is an important * aspect of scalability because it allows the components of a program to be @@ -55,11 +55,11 @@ * * A logical thread is an execution context that has its own stack and which * runs asynchronously to other logical threads. These may be preemptively - * scheduled kernel threads, fibers (cooperative user-space threads), or some - * other concept with similar behavior. + * scheduled kernel threads, $(MREF_ALTTEXT fibers, core, thread, fiber) + * (cooperative user-space threads), or some other concept with similar behavior. * * The type of concurrency used when logical threads are created is determined - * by the Scheduler selected at initialization time. The default behavior is + * by the $(LREF Scheduler) selected at initialization time. The default behavior is * currently to create a new kernel thread per call to spawn, but other * schedulers are available that multiplex fibers across the main thread or * use some combination of the two approaches. @@ -274,7 +274,7 @@ static ~this() // Exceptions /** - * Thrown on calls to `receiveOnly` if a message other than the type + * Thrown on calls to $(LREF receiveOnly) if a message other than the type * the receiving thread expected is sent. */ class MessageMismatch : Exception @@ -287,7 +287,7 @@ class MessageMismatch : Exception } /** - * Thrown on calls to `receive` if the thread that spawned the receiving + * Thrown on calls to $(LREF receive) if the thread that spawned the receiving * thread has terminated and no more messages exist. */ class OwnerTerminated : Exception @@ -354,7 +354,7 @@ class MailboxFull : Exception } /** - * Thrown when a Tid is missing, e.g. when `ownerTid` doesn't + * Thrown when a `Tid` is missing, e.g. when $(LREF ownerTid) doesn't * find an owner thread. */ class TidMissingException : Exception @@ -384,11 +384,11 @@ private: public: /** - * Generate a convenient string for identifying this Tid. This is only - * useful to see if Tid's that are currently executing are the same or + * Generate a convenient string for identifying this `Tid`. This is only + * useful to see if `Tid`'s that are currently executing are the same or * different, e.g. for logging and debugging. It is potentially possible - * that a Tid executed in the future will have the same toString() output - * as another Tid that has already terminated. + * that a `Tid` executed in the future will have the same `toString()` output + * as another `Tid` that has already terminated. */ void toString(W)(ref W w) const { @@ -420,7 +420,7 @@ public: } /** - * Returns: The $(LREF Tid) of the caller's thread. + * Returns: The `Tid` of the caller's thread. */ @property Tid thisTid() @safe { @@ -437,7 +437,7 @@ public: } /** - * Return the Tid of the thread which spawned the caller's thread. + * Return the `Tid` of the thread which spawned the caller's thread. * * Throws: A `TidMissingException` exception if * there is no owner thread. @@ -493,7 +493,7 @@ private template isSpawnable(F, T...) } /** - * Starts fn(args) in a new logical thread. + * Starts `fn(args)` in a new logical thread. * * Executes the supplied function in a new logical thread represented by * `Tid`. The calling thread is designated as the owner of the new thread. @@ -506,7 +506,7 @@ private template isSpawnable(F, T...) * args = Arguments to the function. * * Returns: - * A Tid representing the new logical thread. + * A `Tid` representing the new logical thread. * * Notes: * `args` must not have unshared aliasing. In other words, all arguments @@ -573,16 +573,16 @@ if (isSpawnable!(F, T)) } /** - * Starts fn(args) in a logical thread and will receive a LinkTerminated + * Starts `fn(args)` in a logical thread and will receive a `LinkTerminated` * message when the operation terminates. * * Executes the supplied function in a new logical thread represented by - * Tid. This new thread is linked to the calling thread so that if either - * it or the calling thread terminates a LinkTerminated message will be sent - * to the other, causing a LinkTerminated exception to be thrown on receive(). - * The owner relationship from spawn() is preserved as well, so if the link + * `Tid`. This new thread is linked to the calling thread so that if either + * it or the calling thread terminates a `LinkTerminated` message will be sent + * to the other, causing a `LinkTerminated` exception to be thrown on `receive()`. + * The owner relationship from `spawn()` is preserved as well, so if the link * between threads is broken, owner termination will still result in an - * OwnerTerminated exception to be thrown on receive(). + * `OwnerTerminated` exception to be thrown on `receive()`. * * Params: * fn = The function to execute. @@ -1021,7 +1021,7 @@ do enum OnCrowding { block, /// Wait until room is available. - throwException, /// Throw a MailboxFull exception. + throwException, /// Throw a $(LREF MailboxFull) exception. ignore /// Abort the send and return. } @@ -1178,13 +1178,13 @@ bool unregister(string name) } /** - * Gets the Tid associated with name. + * Gets the `Tid` associated with name. * * Params: * name = The name to locate within the registry. * * Returns: - * The associated Tid or Tid.init if name is not registered. + * The associated `Tid` or `Tid.init` if name is not registered. */ Tid locate(string name) { @@ -1199,7 +1199,7 @@ Tid locate(string name) /** * Encapsulates all implementation-level data needed for scheduling. * - * When defining a Scheduler, an instance of this struct must be associated + * When defining a $(LREF Scheduler), an instance of this struct must be associated * with each logical thread. It contains all implementation-level information * needed by the internal API. */ @@ -1210,11 +1210,11 @@ struct ThreadInfo Tid owner; /** - * Gets a thread-local instance of ThreadInfo. + * Gets a thread-local instance of `ThreadInfo`. * - * Gets a thread-local instance of ThreadInfo, which should be used as the + * Gets a thread-local instance of `ThreadInfo`, which should be used as the * default instance when info is requested for a thread not created by the - * Scheduler. + * `Scheduler`. */ static @property ref thisInfo() nothrow { @@ -1253,15 +1253,15 @@ struct ThreadInfo } /** - * A Scheduler controls how threading is performed by spawn. + * A `Scheduler` controls how threading is performed by spawn. * - * Implementing a Scheduler allows the concurrency mechanism used by this + * Implementing a `Scheduler` allows the concurrency mechanism used by this * module to be customized according to different needs. By default, a call * to spawn will create a new kernel thread that executes the supplied routine - * and terminates when finished. But it is possible to create Schedulers that - * reuse threads, that multiplex Fibers (coroutines) across a single thread, - * or any number of other approaches. By making the choice of Scheduler a - * user-level option, std.concurrency may be used for far more types of + * and terminates when finished. But it is possible to create `Scheduler`s that + * reuse threads, that multiplex `Fiber`s (coroutines) across a single thread, + * or any number of other approaches. By making the choice of `Scheduler` a + * user-level option, `std.concurrency` may be used for far more types of * application than if this behavior were predefined. * * Example: @@ -1280,25 +1280,25 @@ struct ThreadInfo * --- * * Some schedulers have a dispatching loop that must run if they are to work - * properly, so for the sake of consistency, when using a scheduler, start() - * must be called within main(). This yields control to the scheduler and + * properly, so for the sake of consistency, when using a scheduler, `start()` + * must be called within `main()`. This yields control to the scheduler and * will ensure that any spawned threads are executed in an expected manner. */ interface Scheduler { /** - * Spawns the supplied op and starts the Scheduler. + * Spawns the supplied op and starts the `Scheduler`. * * This is intended to be called at the start of the program to yield all - * scheduling to the active Scheduler instance. This is necessary for + * scheduling to the active `Scheduler` instance. This is necessary for * schedulers that explicitly dispatch threads rather than simply relying * on the operating system to do so, and so start should always be called - * within main() to begin normal program execution. + * within `main()` to begin normal program execution. * * Params: * op = A wrapper for whatever the main thread would have done in the * absence of a custom scheduler. It will be automatically executed - * via a call to spawn by the Scheduler. + * via a call to spawn by the `Scheduler`. */ void start(void delegate() op); @@ -1307,8 +1307,8 @@ interface Scheduler * * This routine is called by spawn. It is expected to instantiate a new * logical thread and run the supplied operation. This thread must call - * thisInfo.cleanup() when the thread terminates if the scheduled thread - * is not a kernel thread--all kernel threads will have their ThreadInfo + * `thisInfo.cleanup()` when the thread terminates if the scheduled thread + * is not a kernel thread--all kernel threads will have their `ThreadInfo` * cleaned up automatically by a thread-local destructor. * * Params: @@ -1329,36 +1329,36 @@ interface Scheduler void yield() nothrow; /** - * Returns an appropriate ThreadInfo instance. + * Returns an appropriate `ThreadInfo` instance. * - * Returns an instance of ThreadInfo specific to the logical thread that + * Returns an instance of `ThreadInfo` specific to the logical thread that * is calling this routine or, if the calling thread was not create by - * this scheduler, returns ThreadInfo.thisInfo instead. + * this scheduler, returns `ThreadInfo.thisInfo` instead. */ @property ref ThreadInfo thisInfo() nothrow; /** - * Creates a Condition variable analog for signaling. + * Creates a `Condition` variable analog for signaling. * - * Creates a new Condition variable analog which is used to check for and + * Creates a new `Condition` variable analog which is used to check for and * to signal the addition of messages to a thread's message queue. Like * yield, some schedulers may need to define custom behavior so that calls - * to Condition.wait() yield to another thread when no new messages are + * to `Condition.wait()` yield to another thread when no new messages are * available instead of blocking. * * Params: - * m = The Mutex that will be associated with this condition. It will be + * m = The `Mutex` that will be associated with this condition. It will be * locked prior to any operation on the condition, and so in some - * cases a Scheduler may need to hold this reference and unlock the + * cases a `Scheduler` may need to hold this reference and unlock the * mutex before yielding execution to another logical thread. */ Condition newCondition(Mutex m) nothrow; } /** - * An example Scheduler using kernel threads. + * An example `Scheduler` using kernel threads. * - * This is an example Scheduler that mirrors the default scheduling behavior + * This is an example `Scheduler` that mirrors the default scheduling behavior * of creating one kernel thread per call to spawn. It is fully functional * and may be instantiated and used, but is not a necessary part of the * default functioning of this module. @@ -1392,8 +1392,8 @@ class ThreadScheduler : Scheduler } /** - * Returns ThreadInfo.thisInfo, since it is a thread-local instance of - * ThreadInfo, which is the correct behavior for this scheduler. + * Returns `ThreadInfo.thisInfo`, since it is a thread-local instance of + * `ThreadInfo`, which is the correct behavior for this scheduler. */ @property ref ThreadInfo thisInfo() nothrow { @@ -1401,7 +1401,7 @@ class ThreadScheduler : Scheduler } /** - * Creates a new Condition variable. No custom behavior is needed here. + * Creates a new `Condition` variable. No custom behavior is needed here. */ Condition newCondition(Mutex m) nothrow { @@ -1410,15 +1410,15 @@ class ThreadScheduler : Scheduler } /** - * An example Scheduler using Fibers. + * An example `Scheduler` using $(MREF_ALTTEXT `Fiber`s, core, thread, fiber). * - * This is an example scheduler that creates a new Fiber per call to spawn + * This is an example scheduler that creates a new `Fiber` per call to spawn * and multiplexes the execution of all fibers within the main thread. */ class FiberScheduler : Scheduler { /** - * This creates a new Fiber for the supplied op and then starts the + * This creates a new `Fiber` for the supplied op and then starts the * dispatcher. */ void start(void delegate() op) @@ -1428,7 +1428,7 @@ class FiberScheduler : Scheduler } /** - * This created a new Fiber for the supplied op and adds it to the + * This created a new `Fiber` for the supplied op and adds it to the * dispatch list. */ void spawn(void delegate() op) nothrow @@ -1438,8 +1438,8 @@ class FiberScheduler : Scheduler } /** - * If the caller is a scheduled Fiber, this yields execution to another - * scheduled Fiber. + * If the caller is a scheduled `Fiber`, this yields execution to another + * scheduled `Fiber`. */ void yield() nothrow { @@ -1451,11 +1451,11 @@ class FiberScheduler : Scheduler } /** - * Returns an appropriate ThreadInfo instance. + * Returns an appropriate `ThreadInfo` instance. * - * Returns a ThreadInfo instance specific to the calling Fiber if the - * Fiber was created by this dispatcher, otherwise it returns - * ThreadInfo.thisInfo. + * Returns a `ThreadInfo` instance specific to the calling `Fiber` if the + * `Fiber` was created by this dispatcher, otherwise it returns + * `ThreadInfo.thisInfo`. */ @property ref ThreadInfo thisInfo() nothrow { @@ -1467,10 +1467,10 @@ class FiberScheduler : Scheduler } /** - * Returns a Condition analog that yields when wait or notify is called. + * Returns a `Condition` analog that yields when wait or notify is called. * * Bug: - * For the default implementation, `notifyAll`will behave like `notify`. + * For the default implementation, `notifyAll` will behave like `notify`. * * Params: * m = A `Mutex` to use for locking if the condition needs to be waited on @@ -1485,7 +1485,7 @@ class FiberScheduler : Scheduler protected: /** - * Creates a new Fiber which calls the given delegate. + * Creates a new `Fiber` which calls the given delegate. * * Params: * op = The delegate the fiber should call @@ -1505,7 +1505,7 @@ protected: } /** - * Fiber which embeds a ThreadInfo + * `Fiber` which embeds a `ThreadInfo` */ static class InfoFiber : Fiber { @@ -1650,10 +1650,10 @@ private: } /** - * Sets the Scheduler behavior within the program. + * Sets the `Scheduler` behavior within the program. * - * This variable sets the Scheduler behavior within this program. Typically, - * when setting a Scheduler, scheduler.start() should be called in main. This + * This variable sets the `Scheduler` behavior within this program. Typically, + * when setting a `Scheduler`, `scheduler.start()` should be called in `main`. This * routine will not return until program execution is complete. */ __gshared Scheduler scheduler; @@ -1661,8 +1661,8 @@ __gshared Scheduler scheduler; // Generator /** - * If the caller is a Fiber and is not a Generator, this function will call - * scheduler.yield() or Fiber.yield(), as appropriate. + * If the caller is a `Fiber` and is not a $(LREF Generator), this function will call + * `scheduler.yield()` or `Fiber.yield()`, as appropriate. */ void yield() nothrow { @@ -1684,8 +1684,9 @@ private interface IsGenerator {} /** - * A Generator is a Fiber that periodically returns values of type T to the - * caller via yield. This is represented as an InputRange. + * A Generator is a $(MREF_ALTTEXT Fiber, core, thread, fiber) + * that periodically returns values of type `T` to the + * caller via `yield`. This is represented as an InputRange. */ class Generator(T) : Fiber, IsGenerator, InputRange!T @@ -1829,7 +1830,7 @@ class Generator(T) : /** * Returns the most recently generated value without executing a * copy contructor. Will not compile for element types defining a - * postblit, because Generator does not return by reference. + * postblit, because `Generator` does not return by reference. */ final T moveFront() { diff --git a/libphobos/src/std/container/binaryheap.d b/libphobos/src/std/container/binaryheap.d index 7ff14fc..0fd3452 100644 --- a/libphobos/src/std/container/binaryheap.d +++ b/libphobos/src/std/container/binaryheap.d @@ -597,3 +597,43 @@ BinaryHeap!(Store, less) heapify(alias less = "a < b", Store)(Store s, heap.insert(6); assert(equal(heap, [6, 5])); } + +/** +Example for unintuitive behaviour +It is important not to use the Store after a Heap has been instantiated from +it, at least in the cases of Dynamic Arrays. For example, inserting a new element +in a Heap, which is using a Dyamic Array as a Store, will cause a reallocation of +the Store, if the Store is already full. The Heap will not point anymore to the +original Dyamic Array, but point to a new Dynamic Array. + */ + +// https://issues.dlang.org/show_bug.cgi?id=18333 +@system unittest +{ + import std.stdio; + import std.algorithm.comparison : equal; + import std.container.binaryheap; + + int[] a = [ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 ]; + auto h = heapify(a); + + // Internal representation of Binary Heap tree + assert(a.equal([16, 14, 10, 8, 7, 9, 3, 2, 4, 1])); + + h.replaceFront(30); + // Value 16 was replaced by 30 + assert(a.equal([30, 14, 10, 8, 7, 9, 3, 2, 4, 1])); + + // Making changes to the Store will be seen in the Heap + a[0] = 40; + assert(h.front() == 40); + + // Inserting a new element will reallocate the Store, leaving + // the original Store unchanged. + h.insert(20); + assert(a.equal([40, 14, 10, 8, 7, 9, 3, 2, 4, 1])); + + // Making changes to the original Store will not affect the Heap anymore + a[0] = 60; + assert(h.front() == 40); +} diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d index b699a8e..6ffc0f7 100644 --- a/libphobos/src/std/exception.d +++ b/libphobos/src/std/exception.d @@ -1069,9 +1069,9 @@ as the language is free to assume objects don't have internal pointers */ bool doesPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @nogc @trusted pure nothrow if (__traits(isRef, source) || isDynamicArray!S || - is(S : U*, U) || is(S == class)) + is(S == U*, U) || is(S == class)) { - static if (is(S : U*, U) || is(S == class) || is(S == interface)) + static if (is(S == U*, U) || is(S == class) || is(S == interface)) { const m = *cast(void**) &source; const b = cast(void*) ⌖ @@ -1115,9 +1115,9 @@ bool doesPointTo(S, T)(auto ref const shared S source, ref const shared T target /// ditto bool mayPointTo(S, T, Tdummy=void)(auto ref const S source, ref const T target) @trusted pure nothrow if (__traits(isRef, source) || isDynamicArray!S || - is(S : U*, U) || is(S == class)) + is(S == U*, U) || is(S == class)) { - static if (is(S : U*, U) || is(S == class) || is(S == interface)) + static if (is(S == U*, U) || is(S == class) || is(S == interface)) { const m = *cast(void**) &source; const b = cast(void*) ⌖ @@ -1533,21 +1533,6 @@ version (StdUnittest) assert( doesPointTo(cast(int*) s, i)); assert(!doesPointTo(cast(int*) s, j)); } -@safe unittest //more alias this opCast -{ - void* p; - class A - { - void* opCast(T)() if (is(T == void*)) - { - return p; - } - alias foo = opCast!(void*); - alias foo this; - } - assert(!doesPointTo(A.init, p)); - assert(!mayPointTo(A.init, p)); -} /+ Returns true if the field at index `i` in ($D T) shares its address with another field. diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index d031096..b7bd3fc 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -1575,7 +1575,7 @@ private void setTimesImpl(scope const(char)[] names, scope const(FSChar)* namez, const ta = SysTimeToFILETIME(accessTime); const tm = SysTimeToFILETIME(modificationTime); alias defaults = - AliasSeq!(GENERIC_WRITE, + AliasSeq!(FILE_WRITE_ATTRIBUTES, 0, null, OPEN_EXISTING, @@ -1664,6 +1664,16 @@ private void setTimesImpl(scope const(char)[] names, scope const(FSChar)* namez, rmdirRecurse(newdir); } +// https://issues.dlang.org/show_bug.cgi?id=23683 +@safe unittest +{ + scope(exit) deleteme.remove; + import std.stdio : File; + auto f = File(deleteme, "wb"); + SysTime time = SysTime(DateTime(2018, 10, 4, 0, 0, 30)); + setTimes(deleteme, time, time); +} + /++ Returns the time that the given file was last modified. @@ -4930,7 +4940,10 @@ alias DirIterator = _DirIterator!dip1000Enabled; $(LREF DirEntry). Throws: - $(LREF FileException) if the directory does not exist. + $(UL + $(LI $(LREF FileException) if the $(B path) directory does not exist or read permission is denied.) + $(LI $(LREF FileException) if $(B mode) is not `shallow` and a subdirectory cannot be read.) + ) Example: -------------------- @@ -4971,7 +4984,25 @@ auto dFiles = dirEntries("","*.{d,di}",SpanMode.depth); foreach (d; dFiles) writeln(d.name); -------------------- - +/ +To handle subdirectories with denied read permission, use `SpanMode.shallow`: +--- +void scan(string path) +{ + foreach (DirEntry entry; dirEntries(path, SpanMode.shallow)) + { + try + { + writeln(entry.name); + if (entry.isDir) + scan(entry.name); + } + catch (FileException fe) { continue; } // ignore + } +} + +scan(""); +--- ++/ // For some reason, doing the same alias-to-a-template trick as with DirIterator // does not work here. diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d index 32c82995..7f127c0 100644 --- a/libphobos/src/std/format/internal/write.d +++ b/libphobos/src/std/format/internal/write.d @@ -50,27 +50,6 @@ if (is(BooleanTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) @safe unittest { - class C1 - { - bool val; - alias val this; - this(bool v){ val = v; } - } - - class C2 { - bool val; - alias val this; - this(bool v){ val = v; } - override string toString() const { return "C"; } - } - - () @trusted { - formatTest(new C1(false), "false"); - formatTest(new C1(true), "true"); - formatTest(new C2(false), "C"); - formatTest(new C2(true), "C"); - } (); - struct S1 { bool val; @@ -411,26 +390,6 @@ private uint baseOfSpec(in char spec) @safe pure @safe unittest { - class C1 - { - long val; - alias val this; - this(long v){ val = v; } - } - - class C2 - { - long val; - alias val this; - this(long v){ val = v; } - override string toString() const { return "C"; } - } - - () @trusted { - formatTest(new C1(10), "10"); - formatTest(new C2(10), "C"); - } (); - struct S1 { long val; @@ -709,26 +668,6 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) { formatTest(2.25, "2.25"); - class C1 - { - double val; - alias val this; - this(double v){ val = v; } - } - - class C2 - { - double val; - alias val this; - this(double v){ val = v; } - override string toString() const { return "C"; } - } - - () @trusted { - formatTest(new C1(2.25), "2.25"); - formatTest(new C2(2.25), "C"); - } (); - struct S1 { double val; @@ -1078,26 +1017,6 @@ if (is(CharTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) @safe unittest { - class C1 - { - char val; - alias val this; - this(char v){ val = v; } - } - - class C2 - { - char val; - alias val this; - this(char v){ val = v; } - override string toString() const { return "C"; } - } - - () @trusted { - formatTest(new C1('c'), "c"); - formatTest(new C2('c'), "C"); - } (); - struct S1 { char val; @@ -1165,26 +1084,6 @@ if (is(StringTypeOf!T) && !is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToSt @safe unittest { - // Test for bug 5371 for classes - class C1 - { - const string var; - alias var this; - this(string s){ var = s; } - } - - class C2 - { - string var; - alias var this; - this(string s){ var = s; } - } - - () @trusted { - formatTest(new C1("c1"), "c1"); - formatTest(new C2("c2"), "c2"); - } (); - // Test for bug 5371 for structs struct S1 { @@ -1204,16 +1103,6 @@ if (is(StringTypeOf!T) && !is(StaticArrayTypeOf!T) && !is(T == enum) && !hasToSt @safe unittest { - class C3 - { - string val; - alias val this; - this(string s){ val = s; } - override string toString() const { return "C"; } - } - - () @trusted { formatTest(new C3("c3"), "C"); } (); - struct S3 { string val; alias val this; @@ -1436,36 +1325,6 @@ if (is(DynamicArrayTypeOf!T) && !is(StringTypeOf!T) && !is(T == enum) && !hasToS formatTest(S!0b101([0, 1, 2]), "S"); // Test for bug 7628 formatTest(S!0b110([0, 1, 2]), "S"); formatTest(S!0b111([0, 1, 2]), "S"); - - class C(uint flags) - { - int[] arr; - static if (flags & 1) - alias arr this; - - this(int[] a) { arr = a; } - - static if (flags & 2) - { - @property bool empty() const { return arr.length == 0; } - @property int front() const { return arr[0] * 2; } - void popFront() { arr = arr[1 .. $]; } - } - - static if (flags & 4) - override string toString() const { return "C"; } - } - - () @trusted { - formatTest(new C!0b000([0, 1, 2]), (new C!0b000([])).toString()); - formatTest(new C!0b001([0, 1, 2]), "[0, 1, 2]"); // Test for bug 7628 - formatTest(new C!0b010([0, 1, 2]), "[0, 2, 4]"); - formatTest(new C!0b011([0, 1, 2]), "[0, 2, 4]"); - formatTest(new C!0b100([0, 1, 2]), "C"); - formatTest(new C!0b101([0, 1, 2]), "C"); // Test for bug 7628 - formatTest(new C!0b110([0, 1, 2]), "C"); - formatTest(new C!0b111([0, 1, 2]), "C"); - } (); } @safe unittest @@ -1901,26 +1760,6 @@ if (is(AssocArrayTypeOf!T) && !is(T == enum) && !hasToString!(T, Char)) @safe unittest { - class C1 - { - int[char] val; - alias val this; - this(int[char] v){ val = v; } - } - - class C2 - { - int[char] val; - alias val this; - this(int[char] v){ val = v; } - override string toString() const { return "C"; } - } - - () @trusted { - formatTest(new C1(['c':1, 'd':2]), [`['c':1, 'd':2]`, `['d':2, 'c':1]`]); - formatTest(new C2(['c':1, 'd':2]), "C"); - } (); - struct S1 { int[char] val; @@ -1990,7 +1829,8 @@ enum HasToStringResult customPutWriterFormatSpec, } -private enum hasPreviewIn = !is(typeof(mixin(q{(in ref int a) => a}))); +private alias DScannerBug895 = int[256]; +private immutable bool hasPreviewIn = ((in DScannerBug895 a) { return __traits(isRef, a); })(DScannerBug895.init); template hasToString(T, Char) { @@ -3167,18 +3007,6 @@ if (isPointer!T && !is(T == enum) && !hasToString!(T, Char)) formatTest(q, "FFEECCAA"); } -// https://issues.dlang.org/show_bug.cgi?id=8186 -@system unittest -{ - class B - { - int* a; - this() { a = new int; } - alias a this; - } - formatTest(B.init, "null"); -} - // https://issues.dlang.org/show_bug.cgi?id=9336 @system pure unittest { diff --git a/libphobos/src/std/format/read.d b/libphobos/src/std/format/read.d index 144fa8c..da9d0dc 100644 --- a/libphobos/src/std/format/read.d +++ b/libphobos/src/std/format/read.d @@ -303,8 +303,23 @@ uint formattedRead(alias fmt, Range, Args...)(auto ref Range r, auto ref Args ar if (isSomeString!(typeof(fmt))) { import std.format : checkFormatException; + import std.meta : staticMap; + import std.typecons : Tuple; + - alias e = checkFormatException!(fmt, Args); + // formattedRead supports std.typecons.Tuple + // however, checkFormatException does not + // this means that all std.typecons.Tuple's types in Args must be unwrapped + // and passed to checkFormatException + template Flatten(T) + { + static if (is(T : Tuple!Args, Args...)) + alias Flatten = Args; + else + alias Flatten = T; + } + + alias e = checkFormatException!(fmt, staticMap!(Flatten, Args)); static assert(!e, e); return .formattedRead(r, fmt, args); } @@ -361,6 +376,20 @@ if (isSomeString!(typeof(fmt))) assert(t[0] == 1 && t[1] == 2.125); } +// https://issues.dlang.org/show_bug.cgi?id=23600 +@safe pure unittest +{ + import std.typecons : Tuple, tuple; + + string h, w; + Tuple!(int, float) t; + + assert("hello 1 2.34 world".formattedRead!"%s %d %f %s"(h, t, w) == 3); + assert(h == "hello"); + assert(t == tuple(1, 2.34f)); + assert(w == "world"); +} + @safe unittest { import std.math.operations : isClose; diff --git a/libphobos/src/std/getopt.d b/libphobos/src/std/getopt.d index c85247f..42aeb40 100644 --- a/libphobos/src/std/getopt.d +++ b/libphobos/src/std/getopt.d @@ -558,7 +558,7 @@ private template optionValidator(A...) import std.format : format; enum fmt = "getopt validator: %s (at position %d)"; - enum isReceiver(T) = is(T : U*, U) || (is(T == function)) || (is(T == delegate)); + enum isReceiver(T) = is(T == U*, U) || (is(T == function)) || (is(T == delegate)); enum isOptionStr(T) = isSomeString!T || isSomeChar!T; auto validator() diff --git a/libphobos/src/std/internal/unicode_grapheme.d b/libphobos/src/std/internal/unicode_grapheme.d index d7b2c29..093ebd1 100644 --- a/libphobos/src/std/internal/unicode_grapheme.d +++ b/libphobos/src/std/internal/unicode_grapheme.d @@ -22,10 +22,16 @@ static if (size_t.sizeof == 4) enum hangulLVTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0x80], [ 0x100, 0x80, 0xa00], [ 0x0, 0x20100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006, 0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006, 0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006, 0x80001, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x10000001, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x10, 0x1000000, 0x100000, 0x10000, 0x1000, 0x100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); //832 bytes enum hangulLVTTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0x80], [ 0x100, 0x80, 0xa00], [ 0x0, 0x20100, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006, 0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006, 0x20001, 0x40003, 0x60005, 0x10007, 0x30002, 0x50004, 0x70006, 0x80001, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xeffffffe, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xffffffef, 0xfeffffff, 0xffefffff, 0xfffeffff, 0xffffefff, 0xfffffeff, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); -//1920 bytes -enum mcTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0xc0], [ 0x100, 0x100, 0x2400], [ 0x2020100, 0x2020302, 0x5020204, 0x2060202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x60000, 0x7, 0x0, 0x0, 0x80000, 0x90000, 0xb000a, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf000e, 0x110010, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x130012, 0x150014, 0x170016, 0x190018, 0x1b001a, 0x1c, 0x1e001d, 0x20001f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x210000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xc8000000, 0xde01, 0x0, 0xc, 0xc0000000, 0x801981, 0x0, 0x8, 0xc0000000, 0x1, 0x0, 0x8, 0xc0000000, 0x1a01, 0x0, 0xc, 0x40000000, 0x801981, 0x0, 0x0, 0xc0000000, 0x801dc6, 0x0, 0xe, 0x0, 0x1e, 0x0, 0xc, 0x40000000, 0x600d9f, 0x80000, 0xc, 0xc0000000, 0x801dc1, 0x0, 0xc, 0x0, 0xff038000, 0xc0000, 0x0, 0xc0000000, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19021800, 0xc00000, 0x3f9c, 0x1c009f98, 0x0, 0x0, 0x0, 0x200000, 0x100000, 0x0, 0x0, 0x0, 0xc0400000, 0x1bf, 0x0, 0x0, 0x1fb0e78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6000000, 0x0, 0xa00000, 0x7e01a, 0x0, 0x0, 0x0, 0x0, 0x10, 0xe8200000, 0x1b, 0x0, 0x4, 0x4c2, 0x0, 0xc5c80, 0x0, 0x300ff0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800002, 0x0, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x3, 0xfff00000, 0xf, 0x0, 0x0, 0x0, 0xc0000, 0x0, 0x8, 0xcc300000, 0x1, 0x0, 0x0, 0x198000, 0x2000, 0x28000000, 0x0, 0x0, 0x0, 0x20c800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16d8, 0x5, 0x0, 0x0, 0x0, 0x4, 0x1870000, 0x0, 0x0, 0x0, 0x1000, 0x60, 0x0, 0x4, 0x80380000, 0x4001, 0x0, 0x0, 0x2c7000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xc, 0xc0000000, 0x80399e, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe00000, 0x23, 0x0, 0x0, 0x7a070000, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f038000, 0x0, 0x0, 0x0, 0x58070000, 0x0, 0x0, 0x0, 0x40d000, 0x0, 0x0, 0x0, 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1007000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21bf0000, 0x5, 0x0, 0x0, 0x0, 0xf00e0000, 0x10, 0x0, 0x2000000, 0x1800000, 0x0, 0x800000, 0x0, 0x0, 0x0, 0x0, 0x40008000, 0x0, 0x0, 0x0, 0x120200, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x587c00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x600000, 0x8, 0xc0300000, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffe0000, 0xffffffff, 0xff, 0x0, 0x0, 0x30000, 0x0, 0x0, 0x0, 0x7e060, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); -//3456 bytes -enum graphemeExtendTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0x110], [ 0x100, 0x1a0, 0x4a00], [ 0x2020100, 0x4020302, 0x7020605, 0xa090802, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x202020b, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xb000a, 0xd000c, 0xe, 0xf0000, 0x0, 0x100000, 0x120011, 0x140013, 0x160015, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x190018, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1d001c, 0x1f001e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x220021, 0x230000, 0x250024, 0x0, 0x0, 0x0, 0x26, 0x270000, 0x290028, 0x2b002a, 0x2d002c, 0x2f002e, 0x310030, 0x330032, 0x34, 0x360035, 0x380037, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b003a, 0x0, 0x3c0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e0000, 0x3f0000, 0x40, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x3b0042, 0x43, 0x44, 0x0, 0x460045, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x480047, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffe0000, 0xbfffffff, 0xb6, 0x0, 0x7ff0000, 0x0, 0xfffff800, 0x10000, 0x0, 0x0, 0x9fc00000, 0x3d9f, 0x20000, 0xffff0000, 0x7ff, 0x0, 0x0, 0x1ffc0, 0x0, 0x200ff800, 0xfbc00000, 0x3eef, 0xe000000, 0x0, 0xff000000, 0x0, 0xfffffc00, 0xfffffffb, 0x7, 0x14000000, 0xfe21fe, 0xc, 0x2, 0x50000000, 0x80201e, 0x4000000c, 0x6, 0x10000000, 0x23986, 0x230000, 0x6, 0x10000000, 0x21be, 0xfc00000c, 0x2, 0xd0000000, 0xe0201e, 0xc, 0x4, 0x40000000, 0x802001, 0x0, 0x11, 0xd0000000, 0x603dc1, 0xc, 0x2, 0x90000000, 0x603044, 0xc, 0x3, 0x58000000, 0x80201e, 0xc, 0x2, 0x0, 0x805c8400, 0x0, 0x0, 0x7f20000, 0x7f80, 0x0, 0x0, 0x1ff20000, 0x7f00, 0x0, 0x3000000, 0x2a00000, 0x0, 0x7ffe0000, 0xfeffe0df, 0x1fffffff, 0x40, 0x0, 0x0, 0x66fde000, 0xc3000000, 0x1e0001, 0x20002064, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c0000, 0xc0000, 0xc0000, 0xc0000, 0x0, 0x3fb00000, 0x200ffe40, 0x0, 0xb800, 0x0, 0x0, 0x0, 0x60, 0x200, 0x0, 0x0, 0x0, 0xe040187, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9800000, 0x0, 0x7f400000, 0x9ff81fe5, 0x0, 0xffff0000, 0x7fff, 0x0, 0xf, 0x17f00000, 0x4, 0xff800, 0x3, 0x3b3c, 0x0, 0x3a340, 0x0, 0xcff000, 0x0, 0x0, 0x0, 0x0, 0xfff70000, 0x31021fd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000, 0x1ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38000, 0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0xffffffff, 0x0, 0xfc00, 0x0, 0x0, 0x6000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff78000, 0xc0000000, 0x0, 0x0, 0x30000, 0x844, 0x1060, 0x0, 0x0, 0x0, 0x0, 0x30, 0x8003ffff, 0x0, 0x3fc0, 0x3ff80, 0x0, 0x7, 0x33c80000, 0x0, 0x20, 0x0, 0x667e00, 0x1008, 0x10000000, 0x0, 0xc19d0000, 0x2, 0x403000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2120, 0x40000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x7c00000, 0x0, 0x0, 0x0, 0x0, 0xf06e, 0x87000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1800, 0x0, 0xe0000000, 0x0, 0x0, 0x1ffc0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x2, 0xff000000, 0x7f, 0x80190000, 0x3, 0x6780000, 0x4, 0x0, 0x7, 0x1fef80, 0x0, 0x80000, 0x3, 0x7fc00000, 0x9e00, 0x0, 0x0, 0x40d38000, 0x2, 0x0, 0x0, 0x0, 0x80000000, 0x7f8, 0x3, 0x58000000, 0x800001, 0x1f1fc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff000000, 0x4000005c, 0x0, 0x0, 0xa5f90000, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb03c8000, 0x30000001, 0x0, 0x0, 0xa7f80000, 0x1, 0x0, 0x0, 0xbf2800, 0x0, 0x0, 0xe0000000, 0xfbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6ff8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58010000, 0x8, 0x0, 0x0, 0x0, 0xcf00000, 0x1, 0x7fe, 0x79f80000, 0xe7e0080, 0x0, 0x37ffc00, 0x0, 0x0, 0x0, 0x0, 0xbf7f0000, 0x0, 0x0, 0xfffc0000, 0x6dfcff, 0x0, 0x0, 0x0, 0xb47e0000, 0xbf, 0x0, 0xa30000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x180000, 0x3, 0x7c00000, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f0000, 0x0, 0x7f0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000, 0x0, 0x78000, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x60000000, 0x0, 0x0, 0x0, 0xffffffff, 0xffff3fff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf807c3a0, 0xfe7, 0x3c00, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xf87fffff, 0xffffffff, 0x201fff, 0xf8000010, 0xfffe, 0x0, 0x0, 0xf9ffff7f, 0x7db, 0x0, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000, 0x0, 0xf000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f0000, 0x0, 0x0, 0x0, 0x7f0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//896 bytes +enum prependTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0x80], [ 0x100, 0x80, 0xc00], [ 0x1010100, 0x1010101, 0x1010102, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20001, 0x3, 0x0, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60005, 0x0, 0x0, 0x0, 0x70000, 0x8, 0x90000, 0xa0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30000, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x80000000, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000, 0x0, 0x0, 0x3f0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//1280 bytes +enum controlTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0xd0], [ 0x100, 0x120, 0xe00], [ 0x2020100, 0x3020202, 0x2020402, 0x2060502, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020207, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x10001, 0x10001, 0x10002, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10003, 0x10001, 0x10001, 0x10001, 0x10004, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x60005, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10007, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10008, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x90001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0xb000a, 0xc000c, 0xc000c, 0xc000c, 0xc000c, 0xc000c, 0xc000c, 0xc000c, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0xffffdbff, 0x0, 0x0, 0x80000000, 0xffffffff, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc800, 0x7f00, 0x0, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfff0000, 0x0, 0xffff0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f80000, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//1856 bytes +enum spacingMarkTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0xb0], [ 0x100, 0xe0, 0x2400], [ 0x1010100, 0x1010201, 0x4010103, 0x1050101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x70006, 0x8, 0x0, 0x0, 0x90000, 0xa0000, 0xc000b, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf000e, 0x110010, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x130012, 0x150014, 0x170016, 0x190018, 0x1b001a, 0x1c, 0x1e001d, 0x20001f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x210000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xc8000000, 0xde01, 0x0, 0xc, 0x80000000, 0x1981, 0x0, 0x8, 0xc0000000, 0x1, 0x0, 0x8, 0xc0000000, 0x1a01, 0x0, 0xc, 0x0, 0x1981, 0x0, 0x0, 0x80000000, 0x1dc6, 0x0, 0xe, 0x0, 0x1e, 0x0, 0xc, 0x40000000, 0xd9b, 0x80000, 0xc, 0x80000000, 0x1dc1, 0x0, 0xc, 0x0, 0x7f030000, 0xc0000, 0x0, 0x80000, 0x0, 0x0, 0x0, 0x80000, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18020000, 0xc00000, 0x0, 0x10, 0x0, 0x0, 0x0, 0x200000, 0x100000, 0x0, 0x0, 0x0, 0xc0400000, 0x1bf, 0x0, 0x0, 0x1fb0e78, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6000000, 0x0, 0xa00000, 0x7e000, 0x0, 0x0, 0x0, 0x0, 0x10, 0xe8000000, 0x1b, 0x0, 0x4, 0x4c2, 0x0, 0xc5c80, 0x0, 0x300ff0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800002, 0x0, 0x98, 0x0, 0x0, 0x3, 0xfff00000, 0xf, 0x0, 0x0, 0x0, 0xc0000, 0x0, 0x8, 0xcc300000, 0x1, 0x0, 0x0, 0x198000, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x20c800, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16d8, 0x5, 0x0, 0x0, 0x0, 0x4, 0x1870000, 0x0, 0x0, 0x0, 0x1000, 0x60, 0x0, 0x4, 0x80380000, 0x4001, 0x0, 0x0, 0x2c7000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xc, 0x80000000, 0x399e, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe00000, 0x23, 0x0, 0x0, 0x5a060000, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f030000, 0x0, 0x0, 0x0, 0x58070000, 0x0, 0x0, 0x0, 0x40d000, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1007000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21be0000, 0x5, 0x0, 0x0, 0x0, 0xf00e0000, 0x10, 0x0, 0x2000000, 0x1800000, 0x0, 0x800000, 0x0, 0x0, 0x0, 0x0, 0x40008000, 0x0, 0x0, 0x0, 0x120200, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x587c00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x600000, 0x8, 0xc0300000, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffe0000, 0xffffffff, 0xff, 0x0, 0x0, 0x30000, 0x0, 0x0, 0x0, 0x2040, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//3488 bytes +enum graphemeExtendTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0x110], [ 0x100, 0x1a0, 0x4b00], [ 0x2020100, 0x4020302, 0x7020605, 0xa090802, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x202020b, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x30002, 0x50004, 0x70006, 0x90008, 0xb000a, 0xd000c, 0xe, 0xf0000, 0x0, 0x100000, 0x120011, 0x140013, 0x160015, 0x0, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x190018, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x1d001c, 0x1f001e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000, 0x0, 0x220021, 0x230000, 0x250024, 0x0, 0x0, 0x0, 0x26, 0x270000, 0x290028, 0x2b002a, 0x2d002c, 0x2f002e, 0x310030, 0x330032, 0x34, 0x360035, 0x380037, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b003a, 0x0, 0x3c0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e0000, 0x3f0000, 0x40, 0x0, 0x0, 0x0, 0x41, 0x0, 0x0, 0x3b0042, 0x43, 0x44, 0x0, 0x460045, 0x0, 0x0, 0x0, 0x0, 0x470000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x490048, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfffe0000, 0xbfffffff, 0xb6, 0x0, 0x7ff0000, 0x0, 0xfffff800, 0x10000, 0x0, 0x0, 0x9fc00000, 0x3d9f, 0x20000, 0xffff0000, 0x7ff, 0x0, 0x0, 0x1ffc0, 0x0, 0x200ff800, 0xfbc00000, 0x3eef, 0xe000000, 0x0, 0xff000000, 0x0, 0xfffffc00, 0xfffffffb, 0x7, 0x14000000, 0xfe21fe, 0xc, 0x2, 0x50000000, 0x80201e, 0x4000000c, 0x6, 0x10000000, 0x23986, 0x230000, 0x6, 0x10000000, 0x21be, 0xfc00000c, 0x2, 0xd0000000, 0xe0201e, 0xc, 0x4, 0x40000000, 0x802001, 0x0, 0x11, 0xd0000000, 0x603dc1, 0xc, 0x2, 0x90000000, 0x603044, 0xc, 0x3, 0x58000000, 0x80201e, 0xc, 0x2, 0x0, 0x805c8400, 0x0, 0x0, 0x7f20000, 0x7f80, 0x0, 0x0, 0x1ff20000, 0x7f00, 0x0, 0x3000000, 0x2a00000, 0x0, 0x7ffe0000, 0xfeffe0df, 0x1fffffff, 0x40, 0x0, 0x0, 0x66fde000, 0xc3000000, 0x1e0001, 0x20002064, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1c0000, 0xc0000, 0xc0000, 0xc0000, 0x0, 0x3fb00000, 0x200ffe40, 0x0, 0xb800, 0x0, 0x0, 0x0, 0x60, 0x200, 0x0, 0x0, 0x0, 0xe040187, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9800000, 0x0, 0x7f400000, 0x9ff81fe5, 0x0, 0xffff0000, 0x7fff, 0x0, 0xf, 0x17f00000, 0x4, 0xff800, 0x3, 0x3b3c, 0x0, 0x3a340, 0x0, 0xcff000, 0x0, 0x0, 0x0, 0x0, 0xfff70000, 0x31021fd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff0000, 0x1ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38000, 0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0x0, 0xffffffff, 0x0, 0xfc00, 0x0, 0x0, 0x6000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3ff78000, 0xc0000000, 0x0, 0x0, 0x30000, 0x844, 0x1060, 0x0, 0x0, 0x0, 0x0, 0x30, 0x8003ffff, 0x0, 0x3fc0, 0x3ff80, 0x0, 0x7, 0x33c80000, 0x0, 0x20, 0x0, 0x667e00, 0x1008, 0x10000000, 0x0, 0xc19d0000, 0x2, 0x403000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2120, 0x40000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x7c00000, 0x0, 0x0, 0x0, 0x0, 0xf06e, 0x87000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x0, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1800, 0x0, 0xe0000000, 0x0, 0x0, 0x1ffc0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x2, 0xff000000, 0x7f, 0x80190000, 0x3, 0x6780000, 0x4, 0x0, 0x7, 0x1fef80, 0x0, 0x80000, 0x3, 0x7fc00000, 0x9e00, 0x0, 0x0, 0x40d38000, 0x2, 0x0, 0x0, 0x0, 0x80000000, 0x7f8, 0x3, 0x58000000, 0x800001, 0x1f1fc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff000000, 0x4000005c, 0x0, 0x0, 0xa5f90000, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb03c8000, 0x30000001, 0x0, 0x0, 0xa7f80000, 0x1, 0x0, 0x0, 0xbf2800, 0x0, 0x0, 0xe0000000, 0xfbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6ff8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x58010000, 0x8, 0x0, 0x0, 0x0, 0xcf00000, 0x1, 0x7fe, 0x79f80000, 0xe7e0080, 0x0, 0x37ffc00, 0x0, 0x0, 0x0, 0x0, 0xbf7f0000, 0x0, 0x0, 0xfffc0000, 0x6dfcff, 0x0, 0x0, 0x0, 0xb47e0000, 0xbf, 0x0, 0xa30000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x180000, 0x3, 0x7c00000, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3fff81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f0000, 0x0, 0x7f0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000, 0x0, 0x78000, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x60000000, 0x0, 0x0, 0x0, 0xffffffff, 0xffff3fff, 0x7f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf807c3a0, 0xfe7, 0x3c00, 0x0, 0x0, 0x0, 0x0, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xf87fffff, 0xffffffff, 0x201fff, 0xf8000010, 0xfffe, 0x0, 0x0, 0xf9ffff7f, 0x7db, 0x0, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000, 0x0, 0xf000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f0000, 0x0, 0x0, 0x0, 0x7f0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8000000, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//1344 bytes +enum Extended_PictographicTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x40, 0x90], [ 0x100, 0xa0, 0x1800], [ 0x2020100, 0x2020202, 0x2020202, 0x3020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x2020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x30002, 0x40001, 0x60005, 0x80007, 0x90001, 0xa0001, 0x10001, 0x10001, 0x1000b, 0x1000c, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0xe000d, 0x10000f, 0x11000d, 0x130012, 0x150014, 0x1000d, 0xd000d, 0x16000d, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4200, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000, 0x200, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000004, 0x0, 0x0, 0x3f00000, 0x600, 0x0, 0x0, 0xc000000, 0x100, 0x0, 0x0, 0x100, 0x0, 0x8000, 0x70ffe00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400c00, 0x1, 0x78000000, 0xfff7ffbf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff003f, 0xffffffff, 0xffffffff, 0xffffffff, 0x2057ff3f, 0x180102, 0xb85090, 0xf8, 0xe00000, 0x80010002, 0x0, 0x0, 0x0, 0x300000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x180000e0, 0x0, 0x210000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20010000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2800000, 0x0, 0x0, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xe000, 0x8000, 0x0, 0xc003f000, 0x7fe4000, 0xffffe000, 0xffffffff, 0x3f, 0x400fffe, 0xf7fc8000, 0xfffffe00, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7ffffff, 0xffffffff, 0x3fffffff, 0xffffffc0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffff, 0x0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0, 0x0, 0x0, 0xfff00000, 0x0, 0x0, 0xffe00000, 0xffffffff, 0xf000, 0x0, 0xfc00ff00, 0x0, 0xff00, 0xffffc000, 0xffffffff, 0xffffffff, 0xfffff000, 0xf7ffffff, 0xffffffbf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); } @@ -36,10 +42,16 @@ static if (size_t.sizeof == 8) enum hangulLVTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x40], [ 0x100, 0x80, 0xa00], [ 0x2010000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000300020001, 0x1000700060005, 0x5000400030002, 0x2000100070006, 0x6000500040003, 0x3000200010007, 0x7000600050004, 0x4000300020001, 0x1000700060005, 0x5000400030002, 0x8000100070006, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000010000001, 0x1000000100000, 0x10000001000, 0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100, 0x100000010000001, 0x1000000100000, 0x10000001000, 0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100, 0x100000010000001, 0x1000000100000, 0x10000001000, 0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100, 0x100000010000001, 0x1000000100000, 0x10000001000, 0x1000000100000010, 0x10000001000000, 0x100000010000, 0x1000000100, 0x10000001000000, 0x100000010000, 0x100, 0x0, 0x0, 0x0, 0x0, 0x0]); //832 bytes enum hangulLVTTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x40], [ 0x100, 0x80, 0xa00], [ 0x2010000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000300020001, 0x1000700060005, 0x5000400030002, 0x2000100070006, 0x6000500040003, 0x3000200010007, 0x7000600050004, 0x4000300020001, 0x1000700060005, 0x5000400030002, 0x8000100070006, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfeffffffeffffffe, 0xfffeffffffefffff, 0xfffffeffffffefff, 0xeffffffeffffffef, 0xffeffffffeffffff, 0xffffeffffffeffff, 0xffffffeffffffeff, 0xfeffffffeffffffe, 0xfffeffffffefffff, 0xfffffeffffffefff, 0xeffffffeffffffef, 0xffeffffffeffffff, 0xffffeffffffeffff, 0xffffffeffffffeff, 0xfeffffffeffffffe, 0xfffeffffffefffff, 0xfffffeffffffefff, 0xeffffffeffffffef, 0xffeffffffeffffff, 0xffffeffffffeffff, 0xffffffeffffffeff, 0xfeffffffeffffffe, 0xfffeffffffefffff, 0xfffffeffffffefff, 0xeffffffeffffffef, 0xffeffffffeffffff, 0xffffeffffffeffff, 0xffffffeffffffeff, 0xffeffffffeffffff, 0xffffeffffffeffff, 0xffffffeff, 0x0, 0x0, 0x0, 0x0, 0x0]); -//1920 bytes -enum mcTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x60], [ 0x100, 0x100, 0x2400], [ 0x202030202020100, 0x206020205020204, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3000200010000, 0x6000000050004, 0x7, 0x8000000000000, 0xb000a00090000, 0xc, 0x0, 0x0, 0x0, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x110010000f000e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15001400130012, 0x19001800170016, 0x1c001b001a, 0x20001f001e001d, 0x0, 0x0, 0x0, 0x21000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc800000000000008, 0xde01, 0xc00000000000000c, 0x801981, 0xc000000000000008, 0x1, 0xc000000000000008, 0x1a01, 0x400000000000000c, 0x801981, 0xc000000000000000, 0x801dc6, 0xe, 0x1e, 0x400000000000000c, 0x8000000600d9f, 0xc00000000000000c, 0x801dc1, 0xc, 0xc0000ff038000, 0xc000000000000000, 0x8000000000000000, 0x0, 0x0, 0x1902180000000000, 0x3f9c00c00000, 0x1c009f98, 0x0, 0x10000000200000, 0x0, 0xc040000000000000, 0x1bf, 0x1fb0e7800000000, 0x0, 0x0, 0x0, 0x6000000, 0x7e01a00a00000, 0x0, 0x0, 0xe820000000000010, 0x1b, 0x4c200000004, 0xc5c8000000000, 0x300ff000000000, 0x0, 0x0, 0x80000200000000, 0xc00000000000, 0x0, 0x0, 0x0, 0x9800000000, 0x0, 0xfff0000000000003, 0xf, 0x0, 0xc0000, 0xcc30000000000008, 0x1, 0x19800000000000, 0x2800000000002000, 0x0, 0x20c80000000000, 0x0, 0x0, 0x0, 0x16d800000000, 0x5, 0x0, 0x187000000000004, 0x0, 0x100000000000, 0x60, 0x8038000000000004, 0x4001, 0x2c700000000000, 0x0, 0x0, 0x700000000, 0xc00000000000000c, 0xc0080399e, 0x0, 0x0, 0xe0000000000000, 0x23, 0x7a07000000000000, 0x2, 0x0, 0x0, 0x4f03800000000000, 0x0, 0x5807000000000000, 0x0, 0x40d00000000000, 0x0, 0x4300000000, 0x0, 0x0, 0x0, 0x100700000000000, 0x0, 0x0, 0x0, 0x21bf000000000000, 0x5, 0x0, 0x10f00e0000, 0x200000000000000, 0x1800000, 0x800000, 0x0, 0x4000800000000000, 0x0, 0x12020000000000, 0x0, 0x0, 0x0, 0x587c00, 0x0, 0x0, 0x0, 0x0, 0x60000000000000, 0xc030000000000008, 0x2, 0x0, 0x0, 0x0, 0xfffffffffffe0000, 0xff, 0x3000000000000, 0x0, 0x7e06000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); -//3456 bytes -enum graphemeExtendTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x88], [ 0x100, 0x1a0, 0x4a00], [ 0x402030202020100, 0xa09080207020605, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x20202020202020b, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000, 0x5000400030002, 0x9000800070006, 0xd000c000b000a, 0xf00000000000e, 0x10000000000000, 0x14001300120011, 0x160015, 0x17, 0x0, 0x0, 0x190018, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b00000000, 0x1f001e001d001c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000, 0x22002100000000, 0x25002400230000, 0x0, 0x2600000000, 0x29002800270000, 0x2d002c002b002a, 0x310030002f002e, 0x3400330032, 0x38003700360035, 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x3b003a00000000, 0x3c000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x3e000000000000, 0x40003f0000, 0x0, 0x4100000000, 0x0, 0x43003b0042, 0x44, 0x460045, 0x0, 0x0, 0x0, 0x0, 0x0, 0x480047, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0, 0x0, 0x0, 0xbffffffffffe0000, 0xb6, 0x7ff0000, 0x10000fffff800, 0x0, 0x3d9f9fc00000, 0xffff000000020000, 0x7ff, 0x1ffc000000000, 0x200ff80000000000, 0x3eeffbc00000, 0xe000000, 0xff000000, 0xfffffffbfffffc00, 0x1400000000000007, 0xc00fe21fe, 0x5000000000000002, 0x4000000c0080201e, 0x1000000000000006, 0x23000000023986, 0x1000000000000006, 0xfc00000c000021be, 0xd000000000000002, 0xc00e0201e, 0x4000000000000004, 0x802001, 0xd000000000000011, 0xc00603dc1, 0x9000000000000002, 0xc00603044, 0x5800000000000003, 0xc0080201e, 0x2, 0x805c8400, 0x7f2000000000000, 0x7f80, 0x1ff2000000000000, 0x7f00, 0x2a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x40, 0x66fde00000000000, 0x1e0001c3000000, 0x20002064, 0x0, 0x0, 0xe0000000, 0x0, 0x0, 0xc0000001c0000, 0xc0000000c0000, 0x3fb0000000000000, 0x200ffe40, 0xb800, 0x0, 0x20000000060, 0x0, 0xe04018700000000, 0x0, 0x0, 0x0, 0x9800000, 0x9ff81fe57f400000, 0xffff000000000000, 0x7fff, 0x17f000000000000f, 0xff80000000004, 0x3b3c00000003, 0x3a34000000000, 0xcff00000000000, 0x0, 0x0, 0x31021fdfff70000, 0x0, 0x0, 0x0, 0xffffffffffffffff, 0x1000, 0x0, 0x0, 0x1ffffffff0000, 0x0, 0x0, 0x0, 0x3800000000000, 0x0, 0x8000000000000000, 0x0, 0xffffffff00000000, 0xfc0000000000, 0x0, 0x6000000, 0x0, 0x0, 0x3ff7800000000000, 0xc0000000, 0x3000000000000, 0x106000000844, 0x0, 0x0, 0x8003ffff00000030, 0x3fc000000000, 0x3ff80, 0x33c8000000000007, 0x2000000000, 0x667e0000000000, 0x1000000000001008, 0xc19d000000000000, 0x40300000000002, 0x0, 0x0, 0x0, 0x212000000000, 0x40000000, 0x0, 0x0, 0x0, 0xffff0000ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0x100000000, 0x0, 0x7c0000000000000, 0x0, 0x0, 0x870000000000f06e, 0x0, 0x0, 0x6000000000, 0xf000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x180000000000, 0xe000000000000000, 0x0, 0x1ffc0, 0x3c, 0x0, 0xff00000000000002, 0x801900000000007f, 0x678000000000003, 0x4, 0x1fef8000000007, 0x8000000000000, 0x7fc0000000000003, 0x9e00, 0x40d3800000000000, 0x2, 0x0, 0x7f880000000, 0x5800000000000003, 0x1f1fc000800001, 0x0, 0x0, 0xff00000000000000, 0x4000005c, 0xa5f9000000000000, 0xd, 0x0, 0x0, 0xb03c800000000000, 0x30000001, 0xa7f8000000000000, 0x1, 0xbf280000000000, 0x0, 0xfbce0000000, 0x0, 0x0, 0x0, 0x6ff800000000000, 0x0, 0x0, 0x0, 0x5801000000000000, 0x8, 0x0, 0x10cf00000, 0x79f80000000007fe, 0xe7e0080, 0x37ffc00, 0x0, 0xbf7f000000000000, 0x0, 0x6dfcfffffc0000, 0x0, 0xb47e000000000000, 0xbf, 0xa30000, 0x0, 0x0, 0x0, 0x0, 0x18000000000000, 0x7c0000000000003, 0x5, 0x0, 0x0, 0x0, 0x3fff81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f000000000000, 0x7f000000000000, 0x0, 0x0, 0x0, 0x0, 0x8000, 0x78000, 0x1000000000, 0x0, 0x0, 0x60000000, 0x0, 0xffff3fffffffffff, 0x7f, 0x0, 0x0, 0x0, 0xf807c3a000000000, 0x3c0000000fe7, 0x0, 0x0, 0x1c, 0x0, 0x0, 0xf87fffffffffffff, 0x201fffffffffff, 0xfffef8000010, 0x0, 0x7dbf9ffff7f, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x400000000000, 0xf00000000000, 0x0, 0x0, 0x0, 0xf00000000000, 0x0, 0x0, 0x0, 0x7f0000, 0x0, 0x7f0, 0x0, 0x0, 0xffffffff00000000, 0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0]); +//896 bytes +enum prependTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x40], [ 0x100, 0x80, 0xc00], [ 0x101010101010100, 0x101010101010102, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000100000000, 0x3, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60005, 0x0, 0x800070000, 0xa000000090000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x0, 0x20000000, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30000, 0x400000000, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000, 0x2000, 0x0, 0x0, 0x0, 0xc, 0x8000000000000000, 0x2, 0x0, 0x0, 0x400000000000000, 0x0, 0x3f0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//1280 bytes +enum controlTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x68], [ 0x100, 0x120, 0xe00], [ 0x302020202020100, 0x206050202020402, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020207, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000100010000, 0x1000200010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010003, 0x1000100010001, 0x1000100010004, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x6000500010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010007, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010008, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100090001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0xc000c000b000a, 0xc000c000c000c, 0xc000c000c000c, 0xc000c000c000c, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0xffffdbff, 0x8000000000000000, 0x2000ffffffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000, 0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x0, 0x7f000000c800, 0xffff00000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0xfff000000000000, 0xffff000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf00000000, 0x0, 0x0, 0x7f8000000000000, 0x0, 0x0, 0xffffffff, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0, 0x0, 0xffff000000000000, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0, 0x0, 0x0]); +//1856 bytes +enum spacingMarkTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x58], [ 0x100, 0xe0, 0x2400], [ 0x101020101010100, 0x105010104010103, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x101010101010101, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3000200010000, 0x7000600050004, 0x8, 0x9000000000000, 0xc000b000a0000, 0xd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x110010000f000e, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15001400130012, 0x19001800170016, 0x1c001b001a, 0x20001f001e001d, 0x0, 0x0, 0x0, 0x21000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x220000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc800000000000008, 0xde01, 0x800000000000000c, 0x1981, 0xc000000000000008, 0x1, 0xc000000000000008, 0x1a01, 0xc, 0x1981, 0x8000000000000000, 0x1dc6, 0xe, 0x1e, 0x400000000000000c, 0x8000000000d9b, 0x800000000000000c, 0x1dc1, 0xc, 0xc00007f030000, 0x8000000000000, 0x0, 0x8000000000000, 0x0, 0xc000000000000000, 0x8000000000000000, 0x0, 0x0, 0x1802000000000000, 0xc00000, 0x10, 0x0, 0x10000000200000, 0x0, 0xc040000000000000, 0x1bf, 0x1fb0e7800000000, 0x0, 0x0, 0x0, 0x6000000, 0x7e00000a00000, 0x0, 0x0, 0xe800000000000010, 0x1b, 0x4c200000004, 0xc5c8000000000, 0x300ff000000000, 0x0, 0x0, 0x80000200000000, 0x9800000000, 0x0, 0xfff0000000000003, 0xf, 0x0, 0xc0000, 0xcc30000000000008, 0x1, 0x19800000000000, 0x2000, 0x0, 0x20c80000000000, 0x0, 0x0, 0x0, 0x16d800000000, 0x5, 0x0, 0x187000000000004, 0x0, 0x100000000000, 0x60, 0x8038000000000004, 0x4001, 0x2c700000000000, 0x0, 0x0, 0x700000000, 0x800000000000000c, 0xc0000399e, 0x0, 0x0, 0xe0000000000000, 0x23, 0x5a06000000000000, 0x2, 0x0, 0x0, 0x4f03000000000000, 0x0, 0x5807000000000000, 0x0, 0x40d00000000000, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x100700000000000, 0x0, 0x0, 0x0, 0x21be000000000000, 0x5, 0x0, 0x10f00e0000, 0x200000000000000, 0x1800000, 0x800000, 0x0, 0x4000800000000000, 0x0, 0x12020000000000, 0x0, 0x0, 0x0, 0x587c00, 0x0, 0x0, 0x0, 0x0, 0x60000000000000, 0xc030000000000008, 0x2, 0x0, 0x0, 0x0, 0xfffffffffffe0000, 0xff, 0x3000000000000, 0x0, 0x204000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]); +//3488 bytes +enum graphemeExtendTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x88], [ 0x100, 0x1a0, 0x4b00], [ 0x402030202020100, 0xa09080207020605, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x20202020202020b, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000, 0x5000400030002, 0x9000800070006, 0xd000c000b000a, 0xf00000000000e, 0x10000000000000, 0x14001300120011, 0x160015, 0x17, 0x0, 0x0, 0x190018, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b00000000, 0x1f001e001d001c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000, 0x22002100000000, 0x25002400230000, 0x0, 0x2600000000, 0x29002800270000, 0x2d002c002b002a, 0x310030002f002e, 0x3400330032, 0x38003700360035, 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0x0, 0x3b003a00000000, 0x3c000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3d, 0x0, 0x0, 0x0, 0x3e000000000000, 0x40003f0000, 0x0, 0x4100000000, 0x0, 0x43003b0042, 0x44, 0x460045, 0x0, 0x47000000000000, 0x0, 0x0, 0x0, 0x490048, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0, 0x3f8, 0x0, 0x0, 0x0, 0xbffffffffffe0000, 0xb6, 0x7ff0000, 0x10000fffff800, 0x0, 0x3d9f9fc00000, 0xffff000000020000, 0x7ff, 0x1ffc000000000, 0x200ff80000000000, 0x3eeffbc00000, 0xe000000, 0xff000000, 0xfffffffbfffffc00, 0x1400000000000007, 0xc00fe21fe, 0x5000000000000002, 0x4000000c0080201e, 0x1000000000000006, 0x23000000023986, 0x1000000000000006, 0xfc00000c000021be, 0xd000000000000002, 0xc00e0201e, 0x4000000000000004, 0x802001, 0xd000000000000011, 0xc00603dc1, 0x9000000000000002, 0xc00603044, 0x5800000000000003, 0xc0080201e, 0x2, 0x805c8400, 0x7f2000000000000, 0x7f80, 0x1ff2000000000000, 0x7f00, 0x2a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, 0x40, 0x66fde00000000000, 0x1e0001c3000000, 0x20002064, 0x0, 0x0, 0xe0000000, 0x0, 0x0, 0xc0000001c0000, 0xc0000000c0000, 0x3fb0000000000000, 0x200ffe40, 0xb800, 0x0, 0x20000000060, 0x0, 0xe04018700000000, 0x0, 0x0, 0x0, 0x9800000, 0x9ff81fe57f400000, 0xffff000000000000, 0x7fff, 0x17f000000000000f, 0xff80000000004, 0x3b3c00000003, 0x3a34000000000, 0xcff00000000000, 0x0, 0x0, 0x31021fdfff70000, 0x0, 0x0, 0x0, 0xffffffffffffffff, 0x1000, 0x0, 0x0, 0x1ffffffff0000, 0x0, 0x0, 0x0, 0x3800000000000, 0x0, 0x8000000000000000, 0x0, 0xffffffff00000000, 0xfc0000000000, 0x0, 0x6000000, 0x0, 0x0, 0x3ff7800000000000, 0xc0000000, 0x3000000000000, 0x106000000844, 0x0, 0x0, 0x8003ffff00000030, 0x3fc000000000, 0x3ff80, 0x33c8000000000007, 0x2000000000, 0x667e0000000000, 0x1000000000001008, 0xc19d000000000000, 0x40300000000002, 0x0, 0x0, 0x0, 0x212000000000, 0x40000000, 0x0, 0x0, 0x0, 0xffff0000ffff, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0000000, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0x100000000, 0x0, 0x7c0000000000000, 0x0, 0x0, 0x870000000000f06e, 0x0, 0x0, 0x6000000000, 0xf000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x180000000000, 0xe000000000000000, 0x0, 0x1ffc0, 0x3c, 0x0, 0xff00000000000002, 0x801900000000007f, 0x678000000000003, 0x4, 0x1fef8000000007, 0x8000000000000, 0x7fc0000000000003, 0x9e00, 0x40d3800000000000, 0x2, 0x0, 0x7f880000000, 0x5800000000000003, 0x1f1fc000800001, 0x0, 0x0, 0xff00000000000000, 0x4000005c, 0xa5f9000000000000, 0xd, 0x0, 0x0, 0xb03c800000000000, 0x30000001, 0xa7f8000000000000, 0x1, 0xbf280000000000, 0x0, 0xfbce0000000, 0x0, 0x0, 0x0, 0x6ff800000000000, 0x0, 0x0, 0x0, 0x5801000000000000, 0x8, 0x0, 0x10cf00000, 0x79f80000000007fe, 0xe7e0080, 0x37ffc00, 0x0, 0xbf7f000000000000, 0x0, 0x6dfcfffffc0000, 0x0, 0xb47e000000000000, 0xbf, 0xa30000, 0x0, 0x0, 0x0, 0x0, 0x18000000000000, 0x7c0000000000003, 0x5, 0x0, 0x0, 0x0, 0x3fff81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f000000000000, 0x7f000000000000, 0x0, 0x0, 0x0, 0x0, 0x8000, 0x78000, 0x1000000000, 0x0, 0x0, 0x60000000, 0x0, 0xffff3fffffffffff, 0x7f, 0x0, 0x0, 0x0, 0xf807c3a000000000, 0x3c0000000fe7, 0x0, 0x0, 0x1c, 0x0, 0x0, 0xf87fffffffffffff, 0x201fffffffffff, 0xfffef8000010, 0x0, 0x7dbf9ffff7f, 0x0, 0x8000, 0x0, 0x0, 0x0, 0x400000000000, 0xf00000000000, 0x0, 0x0, 0x0, 0xf00000000000, 0x0, 0x0, 0x0, 0x7f0000, 0x0, 0x7f0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf800000000000000, 0xffffffff00000000, 0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffff, 0x0, 0x0, 0x0, 0x0]); +//1344 bytes +enum Extended_PictographicTrieEntries = TrieEntry!(bool, 8, 5, 8)([ 0x0, 0x20, 0x48], [ 0x100, 0xa0, 0x1800], [ 0x202020202020100, 0x302020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x202020202020202, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000100010000, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x4000100030002, 0x8000700060005, 0xa000100090001, 0x1000100010001, 0x1000c0001000b, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x10000f000e000d, 0x1300120011000d, 0x1000d00150014, 0x16000d000d000d, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x1000100010001, 0x0, 0x0, 0x420000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000, 0x200, 0x0, 0x0, 0x200000400000000, 0x0, 0x60003f00000, 0x0, 0x1000c000000, 0x0, 0x100, 0x70ffe0000008000, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x400c0000000000, 0x7800000000000001, 0xfffffffffff7ffbf, 0xffffffffffffffff, 0xffffffffffff003f, 0xffffffffffffffff, 0x1801022057ff3f, 0xf800b85090, 0x8001000200e00000, 0x0, 0x30000000000000, 0x0, 0x0, 0x0, 0x180000e0, 0x210000, 0x0, 0x0, 0x2001000000000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2800000, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x80000000e000, 0xc003f00000000000, 0xffffe00007fe4000, 0x3fffffffff, 0xf7fc80000400fffe, 0xfffffffffffffe00, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x7ffffffffffffff, 0x3fffffffffffffff, 0xffffffffffffffc0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0xfff0000000000000, 0x0, 0xffffffffffe00000, 0xf000, 0xfc00ff00, 0xffffc0000000ff00, 0xffffffffffffffff, 0xf7fffffffffff000, 0xffffffffffffffbf, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x3fffffffffffffff, 0x0, 0x0, 0x0, 0x0]); } diff --git a/libphobos/src/std/math/exponential.d b/libphobos/src/std/math/exponential.d index 66f4b8a..fd1ff24 100644 --- a/libphobos/src/std/math/exponential.d +++ b/libphobos/src/std/math/exponential.d @@ -39,7 +39,8 @@ static import core.stdc.math; version (DigitalMars) { - version = INLINE_YL2X; // x87 has opcodes for these + version (OSX) { } // macOS 13 (M1) has issues emulating instruction + else version = INLINE_YL2X; // x87 has opcodes for these } version (D_InlineAsm_X86) version = InlineAsm_X86_Any; @@ -2862,7 +2863,7 @@ float ldexp(float n, int exp) @safe pure nothrow @nogc { return core.math.ldex private { - // Coefficients shared across log(), log2(), log10(). + // Coefficients shared across log(), log2(), log10(), log1p(). template LogCoeffs(T) { import std.math : floatTraits, RealFormat; @@ -3022,6 +3023,25 @@ private alias log2Q = logQ; // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) + static immutable double[7] logp1P = [ + 2.0039553499201281259648E1, + 5.7112963590585538103336E1, + 6.0949667980987787057556E1, + 2.9911919328553073277375E1, + 6.5787325942061044846969E0, + 4.9854102823193375972212E-1, + 4.5270000862445199635215E-5, + ]; + static immutable double[7] logp1Q = [ + 1.0000000000000000000000E0, + 6.0118660497603843919306E1, + 2.1642788614495947685003E2, + 3.0909872225312059774938E2, + 2.2176239823732856465394E2, + 8.3047565967967209469434E1, + 1.5062909083469192043167E1, + ]; + static immutable double[7] log10P = [ 1.98892446572874072159E1, 5.67349287391754285487E1, @@ -3070,6 +3090,26 @@ private 7.0376836292E-2, ]; + // Coefficients for log(1 + x) = x - x^^2/2 + x^^3 P(x)/Q(x) + static immutable float[7] logp1P = [ + 2.0039553499E1, + 5.7112963590E1, + 6.0949667980E1, + 2.9911919328E1, + 6.5787325942E0, + 4.9854102823E-1, + 4.5270000862E-5, + ]; + static immutable float[7] logp1Q = [ + 1.00000000000E0, + 6.01186604976E1, + 2.16427886144E2, + 3.09098722253E2, + 2.21762398237E2, + 8.30475659679E1, + 1.50629090834E1, + ]; + // log2 and log10 uses the same coefficients as log. alias log2P = logP; alias log10P = logP; @@ -3135,7 +3175,7 @@ real log(ulong x) @safe pure nothrow @nogc { return log(cast(real) x); } assert(feqrel(log(E), 1) >= real.mant_dig - 1); } -private T logImpl(T)(T x) @safe pure nothrow @nogc +private T logImpl(T, bool LOG1P = false)(T x) @safe pure nothrow @nogc { import std.math.constants : SQRT1_2; import std.math.algebraic : poly; @@ -3145,6 +3185,12 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc alias coeffs = LogCoeffs!T; alias F = floatTraits!T; + static if (LOG1P) + { + const T xm1 = x; + x = x + 1.0; + } + static if (F.realFormat == RealFormat.ieeeExtended || F.realFormat == RealFormat.ieeeExtended53 || F.realFormat == RealFormat.ieeeQuadruple) @@ -3219,11 +3265,28 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc if (x < SQRT1_2) { exp -= 1; - x = 2.0 * x - 1.0; + static if (LOG1P) + { + if (exp != 0) + x = 2.0 * x - 1.0; + else + x = xm1; + } + else + x = 2.0 * x - 1.0; + } else { - x = x - 1.0; + static if (LOG1P) + { + if (exp != 0) + x = x - 1.0; + else + x = xm1; + } + else + x = x - 1.0; } z = x * x; static if (F.realFormat == RealFormat.ieeeSingle) @@ -3241,6 +3304,84 @@ private T logImpl(T)(T x) @safe pure nothrow @nogc return z; } +@safe @nogc nothrow unittest +{ + import std.math : floatTraits, RealFormat; + import std.meta : AliasSeq; + + static void testLog(T)(T[2][] vals) + { + import std.math.operations : isClose; + import std.math.traits : isNaN; + foreach (ref pair; vals) + { + if (isNaN(pair[1])) + assert(isNaN(log(pair[0]))); + else + assert(isClose(log(pair[0]), pair[1])); + } + } + static foreach (F; AliasSeq!(float, double, real)) + {{ + F[2][24] vals = [ + [F(1), F(0x0p+0)], [F(2), F(0x1.62e42fefa39ef358p-1)], + [F(4), F(0x1.62e42fefa39ef358p+0)], [F(8), F(0x1.0a2b23f3bab73682p+1)], + [F(16), F(0x1.62e42fefa39ef358p+1)], [F(32), F(0x1.bb9d3beb8c86b02ep+1)], + [F(64), F(0x1.0a2b23f3bab73682p+2)], [F(128), F(0x1.3687a9f1af2b14ecp+2)], + [F(256), F(0x1.62e42fefa39ef358p+2)], [F(512), F(0x1.8f40b5ed9812d1c2p+2)], + [F(1024), F(0x1.bb9d3beb8c86b02ep+2)], [F(2048), F(0x1.e7f9c1e980fa8e98p+2)], + [F(3), F(0x1.193ea7aad030a976p+0)], [F(5), F(0x1.9c041f7ed8d336bp+0)], + [F(7), F(0x1.f2272ae325a57546p+0)], [F(15), F(0x1.5aa16394d481f014p+1)], + [F(17), F(0x1.6aa6bc1fa7f79cfp+1)], [F(31), F(0x1.b78ce48912b59f12p+1)], + [F(33), F(0x1.bf8d8f4d5b8d1038p+1)], [F(63), F(0x1.09291e8e3181b20ep+2)], + [F(65), F(0x1.0b292939429755ap+2)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(10000), F(0x1.26bb1bbb5551582ep+3)], + ]; + testLog(vals); + }} + { + float[2][16] vals = [ + [float.nan, float.nan],[-float.nan, float.nan], + [float.infinity, float.infinity], [-float.infinity, float.nan], + [float.min_normal, -0x1.5d58ap+6f], [-float.min_normal, float.nan], + [float.max, 0x1.62e43p+6f], [-float.max, float.nan], + [float.min_normal / 2, -0x1.601e68p+6f], [-float.min_normal / 2, float.nan], + [float.max / 2, 0x1.601e68p+6f], [-float.max / 2, float.nan], + [float.min_normal / 3, -0x1.61bd9ap+6f], [-float.min_normal / 3, float.nan], + [float.max / 3, 0x1.5e7f36p+6f], [-float.max / 3, float.nan], + ]; + testLog(vals); + } + { + double[2][16] vals = [ + [double.nan, double.nan],[-double.nan, double.nan], + [double.infinity, double.infinity], [-double.infinity, double.nan], + [double.min_normal, -0x1.6232bdd7abcd2p+9], [-double.min_normal, double.nan], + [double.max, 0x1.62e42fefa39efp+9], [-double.max, double.nan], + [double.min_normal / 2, -0x1.628b76e3a7b61p+9], [-double.min_normal / 2, double.nan], + [double.max / 2, 0x1.628b76e3a7b61p+9], [-double.max / 2, double.nan], + [double.min_normal / 3, -0x1.62bf5d2b81354p+9], [-double.min_normal / 3, double.nan], + [double.max / 3, 0x1.6257909bce36ep+9], [-double.max / 3, double.nan], + ]; + testLog(vals); + } + alias F = floatTraits!real; + static if (F.realFormat == RealFormat.ieeeExtended || F.realFormat == RealFormat.ieeeQuadruple) + {{ + real[2][16] vals = [ + [real.nan, real.nan],[-real.nan, real.nan], + [real.infinity, real.infinity], [-real.infinity, real.nan], + [real.min_normal, -0x1.62d918ce2421d66p+13L], [-real.min_normal, real.nan], + [real.max, 0x1.62e42fefa39ef358p+13L], [-real.max, real.nan], + [real.min_normal / 2, -0x1.62dea45ee3e064dcp+13L], [-real.min_normal / 2, real.nan], + [real.max / 2, 0x1.62dea45ee3e064dcp+13L], [-real.max / 2, real.nan], + [real.min_normal / 3, -0x1.62e1e2c3617857e6p+13L], [-real.min_normal / 3, real.nan], + [real.max / 3, 0x1.62db65fa664871d2p+13L], [-real.max / 3, real.nan], + ]; + testLog(vals); + }} +} + /************************************** * Calculate the base-10 logarithm of x. * @@ -3296,6 +3437,14 @@ real log10(ulong x) @safe pure nothrow @nogc { return log10(cast(real) x); } assert(fabs(log10(1000.0L) - 3) < .000001); } +@safe pure nothrow @nogc unittest +{ + import std.math.algebraic : fabs; + + assert(fabs(log10(1000.0) - 3) < .000001); + assert(fabs(log10(1000.0f) - 3) < .000001); +} + private T log10Impl(T)(T x) @safe pure nothrow @nogc { import std.math.constants : SQRT1_2; @@ -3404,6 +3553,84 @@ Ldone: return z; } +@safe @nogc nothrow unittest +{ + import std.math : floatTraits, RealFormat; + import std.meta : AliasSeq; + + static void testLog10(T)(T[2][] vals) + { + import std.math.operations : isClose; + import std.math.traits : isNaN; + foreach (ref pair; vals) + { + if (isNaN(pair[1])) + assert(isNaN(log10(pair[0]))); + else + assert(isClose(log10(pair[0]), pair[1])); + } + } + static foreach (F; AliasSeq!(float, double, real)) + {{ + F[2][24] vals = [ + [F(1), F(0x0p+0)], [F(2), F(0x1.34413509f79fef32p-2)], + [F(4), F(0x1.34413509f79fef32p-1)], [F(8), F(0x1.ce61cf8ef36fe6cap-1)], + [F(16), F(0x1.34413509f79fef32p+0)], [F(32), F(0x1.8151824c7587eafep+0)], + [F(64), F(0x1.ce61cf8ef36fe6cap+0)], [F(128), F(0x1.0db90e68b8abf14cp+1)], + [F(256), F(0x1.34413509f79fef32p+1)], [F(512), F(0x1.5ac95bab3693ed18p+1)], + [F(1024), F(0x1.8151824c7587eafep+1)], [F(2048), F(0x1.a7d9a8edb47be8e4p+1)], + [F(3), F(0x1.e8927964fd5fd08cp-2)], [F(5), F(0x1.65df657b04300868p-1)], + [F(7), F(0x1.b0b0b0b78cc3f296p-1)], [F(15), F(0x1.2d145116c16ff856p+0)], + [F(17), F(0x1.3afeb354b7d9731ap+0)], [F(31), F(0x1.7dc9e145867e62eap+0)], + [F(33), F(0x1.84bd545e4baeddp+0)], [F(63), F(0x1.cca1950e4511e192p+0)], + [F(65), F(0x1.d01b16f9433cf7b8p+0)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(10000), F(0x1p+2)], + ]; + testLog10(vals); + }} + { + float[2][16] vals = [ + [float.nan, float.nan],[-float.nan, float.nan], + [float.infinity, float.infinity], [-float.infinity, float.nan], + [float.min_normal, -0x1.2f703p+5f], [-float.min_normal, float.nan], + [float.max, 0x1.344136p+5f], [-float.max, float.nan], + [float.min_normal / 2, -0x1.31d8b2p+5f], [-float.min_normal / 2, float.nan], + [float.max / 2, 0x1.31d8b2p+5f], [-float.max / 2, float.nan], + [float.min_normal / 3, -0x1.334156p+5f], [-float.min_normal / 3, float.nan], + [float.max / 3, 0x1.30701p+5f], [-float.max / 3, float.nan], + ]; + testLog10(vals); + } + { + double[2][16] vals = [ + [double.nan, double.nan],[-double.nan, double.nan], + [double.infinity, double.infinity], [-double.infinity, double.nan], + [double.min_normal, -0x1.33a7146f72a42p+8], [-double.min_normal, double.nan], + [double.max, 0x1.34413509f79ffp+8], [-double.max, double.nan], + [double.min_normal / 2, -0x1.33f424bcb522p+8], [-double.min_normal / 2, double.nan], + [double.max / 2, 0x1.33f424bcb522p+8], [-double.max / 2, double.nan], + [double.min_normal / 3, -0x1.3421390dcbe37p+8], [-double.min_normal / 3, double.nan], + [double.max / 3, 0x1.33c7106b9e609p+8], [-double.max / 3, double.nan], + ]; + testLog10(vals); + } + alias F = floatTraits!real; + static if (F.realFormat == RealFormat.ieeeExtended || F.realFormat == RealFormat.ieeeQuadruple) + {{ + real[2][16] vals = [ + [real.nan, real.nan],[-real.nan, real.nan], + [real.infinity, real.infinity], [-real.infinity, real.nan], + [real.min_normal, -0x1.343793004f503232p+12L], [-real.min_normal, real.nan], + [real.max, 0x1.34413509f79fef32p+12L], [-real.max, real.nan], + [real.min_normal / 2, -0x1.343c6405237810b2p+12L], [-real.min_normal / 2, real.nan], + [real.max / 2, 0x1.343c6405237810b2p+12L], [-real.max / 2, real.nan], + [real.min_normal / 3, -0x1.343f354a34e427bp+12L], [-real.min_normal / 3, real.nan], + [real.max / 3, 0x1.343992c0120bf9b2p+12L], [-real.max / 3, real.nan], + ]; + testLog10(vals); + }} +} + /** * Calculates the natural logarithm of 1 + x. * @@ -3476,6 +3703,9 @@ real log1p(ulong x) @safe pure nothrow @nogc { return log1p(cast(real) x); } private T log1pImpl(T)(T x) @safe pure nothrow @nogc { import std.math.traits : isNaN, isInfinity, signbit; + import std.math.algebraic : poly; + import std.math.constants : SQRT1_2, SQRT2; + import std.math : floatTraits, RealFormat; // Special cases. if (isNaN(x) || x == 0.0) @@ -3487,7 +3717,104 @@ private T log1pImpl(T)(T x) @safe pure nothrow @nogc if (x < -1.0) return T.nan; - return logImpl(x + 1.0); + alias F = floatTraits!T; + static if (F.realFormat == RealFormat.ieeeSingle || + F.realFormat == RealFormat.ieeeDouble) + { + // When the input is within the range 1/sqrt(2) <= x+1 <= sqrt(2), compute + // log1p inline. Forwarding to log() would otherwise result in inaccuracies. + const T xp1 = x + 1.0; + if (xp1 >= SQRT1_2 && xp1 <= SQRT2) + { + alias coeffs = LogCoeffs!T; + + T px = poly(x, coeffs.logp1P); + T qx = poly(x, coeffs.logp1Q); + const T xx = x * x; + qx = x + ((cast(T) -0.5) * xx + x * (xx * px / qx)); + return qx; + } + } + + return logImpl!(T, true)(x); +} + +@safe @nogc nothrow unittest +{ + import std.math : floatTraits, RealFormat; + import std.meta : AliasSeq; + + static void testLog1p(T)(T[2][] vals) + { + import std.math.operations : isClose; + import std.math.traits : isNaN; + foreach (ref pair; vals) + { + if (isNaN(pair[1])) + assert(isNaN(log1p(pair[0]))); + else + assert(isClose(log1p(pair[0]), pair[1])); + } + } + static foreach (F; AliasSeq!(float, double, real)) + {{ + F[2][24] vals = [ + [F(1), F(0x1.62e42fefa39ef358p-1)], [F(2), F(0x1.193ea7aad030a976p+0)], + [F(4), F(0x1.9c041f7ed8d336bp+0)], [F(8), F(0x1.193ea7aad030a976p+1)], + [F(16), F(0x1.6aa6bc1fa7f79cfp+1)], [F(32), F(0x1.bf8d8f4d5b8d1038p+1)], + [F(64), F(0x1.0b292939429755ap+2)], [F(128), F(0x1.37072a9b5b6cb31p+2)], + [F(256), F(0x1.63241004e9010ad8p+2)], [F(512), F(0x1.8f60adf041bde2a8p+2)], + [F(1024), F(0x1.bbad39ebe1cc08b6p+2)], [F(2048), F(0x1.e801c1698ba4395cp+2)], + [F(3), F(0x1.62e42fefa39ef358p+0)], [F(5), F(0x1.cab0bfa2a2002322p+0)], + [F(7), F(0x1.0a2b23f3bab73682p+1)], [F(15), F(0x1.62e42fefa39ef358p+1)], + [F(17), F(0x1.71f7b3a6b918664cp+1)], [F(31), F(0x1.bb9d3beb8c86b02ep+1)], + [F(33), F(0x1.c35fc81b90df59c6p+1)], [F(63), F(0x1.0a2b23f3bab73682p+2)], + [F(65), F(0x1.0c234da4a23a6686p+2)], [F(-0), F(-0x0p+0)], [F(0), F(0x0p+0)], + [F(10000), F(0x1.26bbed6fbd84182ep+3)], + ]; + testLog1p(vals); + }} + { + float[2][16] vals = [ + [float.nan, float.nan],[-float.nan, float.nan], + [float.infinity, float.infinity], [-float.infinity, float.nan], + [float.min_normal, 0x1p-126f], [-float.min_normal, -0x1p-126f], + [float.max, 0x1.62e43p+6f], [-float.max, float.nan], + [float.min_normal / 2, 0x0.8p-126f], [-float.min_normal / 2, -0x0.8p-126f], + [float.max / 2, 0x1.601e68p+6f], [-float.max / 2, float.nan], + [float.min_normal / 3, 0x0.555556p-126f], [-float.min_normal / 3, -0x0.555556p-126f], + [float.max / 3, 0x1.5e7f36p+6f], [-float.max / 3, float.nan], + ]; + testLog1p(vals); + } + { + double[2][16] vals = [ + [double.nan, double.nan],[-double.nan, double.nan], + [double.infinity, double.infinity], [-double.infinity, double.nan], + [double.min_normal, 0x1p-1022], [-double.min_normal, -0x1p-1022], + [double.max, 0x1.62e42fefa39efp+9], [-double.max, double.nan], + [double.min_normal / 2, 0x0.8p-1022], [-double.min_normal / 2, -0x0.8p-1022], + [double.max / 2, 0x1.628b76e3a7b61p+9], [-double.max / 2, double.nan], + [double.min_normal / 3, 0x0.5555555555555p-1022], [-double.min_normal / 3, -0x0.5555555555555p-1022], + [double.max / 3, 0x1.6257909bce36ep+9], [-double.max / 3, double.nan], + ]; + testLog1p(vals); + } + alias F = floatTraits!real; + static if (F.realFormat == RealFormat.ieeeExtended || F.realFormat == RealFormat.ieeeQuadruple) + {{ + real[2][16] vals = [ + [real.nan, real.nan],[-real.nan, real.nan], + [real.infinity, real.infinity], [-real.infinity, real.nan], + [real.min_normal, 0x1p-16382L], [-real.min_normal, -0x1p-16382L], + [real.max, 0x1.62e42fefa39ef358p+13L], [-real.max, real.nan], + [real.min_normal / 2, 0x0.8p-16382L], [-real.min_normal / 2, -0x0.8p-16382L], + [real.max / 2, 0x1.62dea45ee3e064dcp+13L], [-real.max / 2, real.nan], + [real.min_normal / 3, 0x0.5555555555555556p-16382L], [-real.min_normal / 3, -0x0.5555555555555556p-16382L], + [real.max / 3, 0x1.62db65fa664871d2p+13L], [-real.max / 3, real.nan], + ]; + testLog1p(vals); + }} } /*************************************** @@ -3635,6 +3962,84 @@ Ldone: return z; } +@safe @nogc nothrow unittest +{ + import std.math : floatTraits, RealFormat; + import std.meta : AliasSeq; + + static void testLog2(T)(T[2][] vals) + { + import std.math.operations : isClose; + import std.math.traits : isNaN; + foreach (ref pair; vals) + { + if (isNaN(pair[1])) + assert(isNaN(log2(pair[0]))); + else + assert(isClose(log2(pair[0]), pair[1])); + } + } + static foreach (F; AliasSeq!(float, double, real)) + {{ + F[2][24] vals = [ + [F(1), F(0x0p+0)], [F(2), F(0x1p+0)], + [F(4), F(0x1p+1)], [F(8), F(0x1.8p+1)], + [F(16), F(0x1p+2)], [F(32), F(0x1.4p+2)], + [F(64), F(0x1.8p+2)], [F(128), F(0x1.cp+2)], + [F(256), F(0x1p+3)], [F(512), F(0x1.2p+3)], + [F(1024), F(0x1.4p+3)], [F(2048), F(0x1.6p+3)], + [F(3), F(0x1.95c01a39fbd687ap+0)], [F(5), F(0x1.2934f0979a3715fcp+1)], + [F(7), F(0x1.675767f54042cd9ap+1)], [F(15), F(0x1.f414fdb4982259ccp+1)], + [F(17), F(0x1.0598fdbeb244c5ap+2)], [F(31), F(0x1.3d118d66c4d4e554p+2)], + [F(33), F(0x1.42d75a6eb1dfb0e6p+2)], [F(63), F(0x1.7e8bc1179e0caa9cp+2)], + [F(65), F(0x1.816e79685c2d2298p+2)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(10000), F(0x1.a934f0979a3715fcp+3)], + ]; + testLog2(vals); + }} + { + float[2][16] vals = [ + [float.nan, float.nan],[-float.nan, float.nan], + [float.infinity, float.infinity], [-float.infinity, float.nan], + [float.min_normal, -0x1.f8p+6f], [-float.min_normal, float.nan], + [float.max, 0x1p+7f], [-float.max, float.nan], + [float.min_normal / 2, -0x1.fcp+6f], [-float.min_normal / 2, float.nan], + [float.max / 2, 0x1.fcp+6f], [-float.max / 2, float.nan], + [float.min_normal / 3, -0x1.fe57p+6f], [-float.min_normal / 3, float.nan], + [float.max / 3, 0x1.f9a9p+6f], [-float.max / 3, float.nan], + ]; + testLog2(vals); + } + { + double[2][16] vals = [ + [double.nan, double.nan],[-double.nan, double.nan], + [double.infinity, double.infinity], [-double.infinity, double.nan], + [double.min_normal, -0x1.ffp+9], [-double.min_normal, double.nan], + [double.max, 0x1p+10], [-double.max, double.nan], + [double.min_normal / 2, -0x1.ff8p+9], [-double.min_normal / 2, double.nan], + [double.max / 2, 0x1.ff8p+9], [-double.max / 2, double.nan], + [double.min_normal / 3, -0x1.ffcae00d1cfdfp+9], [-double.min_normal / 3, double.nan], + [double.max / 3, 0x1.ff351ff2e3021p+9], [-double.max / 3, double.nan], + ]; + testLog2(vals); + } + alias F = floatTraits!real; + static if (F.realFormat == RealFormat.ieeeExtended || F.realFormat == RealFormat.ieeeQuadruple) + {{ + real[2][16] vals = [ + [real.nan, real.nan],[-real.nan, real.nan], + [real.infinity, real.infinity], [-real.infinity, real.nan], + [real.min_normal, -0x1.fffp+13L], [-real.min_normal, real.nan], + [real.max, 0x1p+14L], [-real.max, real.nan], + [real.min_normal / 2, -0x1.fff8p+13L], [-real.min_normal / 2, real.nan], + [real.max / 2, 0x1.fff8p+13L], [-real.max / 2, real.nan], + [real.min_normal / 3, -0x1.fffcae00d1cfdeb4p+13L], [-real.min_normal / 3, real.nan], + [real.max / 3, 0x1.fff351ff2e30214cp+13L], [-real.max / 3, real.nan], + ]; + testLog2(vals); + }} +} + /***************************************** * Extracts the exponent of x as a signed integral value. * @@ -3754,6 +4159,84 @@ private T logbImpl(T)(T x) @trusted pure nothrow @nogc return ilogb(x); } +@safe @nogc nothrow unittest +{ + import std.math : floatTraits, RealFormat; + import std.meta : AliasSeq; + + static void testLogb(T)(T[2][] vals) + { + import std.math.operations : isClose; + import std.math.traits : isNaN; + foreach (ref pair; vals) + { + if (isNaN(pair[1])) + assert(isNaN(logb(pair[0]))); + else + assert(isClose(logb(pair[0]), pair[1])); + } + } + static foreach (F; AliasSeq!(float, double, real)) + {{ + F[2][24] vals = [ + [F(1), F(0x0p+0)], [F(2), F(0x1p+0)], + [F(4), F(0x1p+1)], [F(8), F(0x1.8p+1)], + [F(16), F(0x1p+2)], [F(32), F(0x1.4p+2)], + [F(64), F(0x1.8p+2)], [F(128), F(0x1.cp+2)], + [F(256), F(0x1p+3)], [F(512), F(0x1.2p+3)], + [F(1024), F(0x1.4p+3)], [F(2048), F(0x1.6p+3)], + [F(3), F(0x1p+0)], [F(5), F(0x1p+1)], + [F(7), F(0x1p+1)], [F(15), F(0x1.8p+1)], + [F(17), F(0x1p+2)], [F(31), F(0x1p+2)], + [F(33), F(0x1.4p+2)], [F(63), F(0x1.4p+2)], + [F(65), F(0x1.8p+2)], [F(-0), -F.infinity], [F(0), -F.infinity], + [F(10000), F(0x1.ap+3)], + ]; + testLogb(vals); + }} + { + float[2][16] vals = [ + [float.nan, float.nan],[-float.nan, float.nan], + [float.infinity, float.infinity], [-float.infinity, float.infinity], + [float.min_normal, -0x1.f8p+6f], [-float.min_normal, -0x1.f8p+6f], + [float.max, 0x1.fcp+6f], [-float.max, 0x1.fcp+6f], + [float.min_normal / 2, -0x1.fcp+6f], [-float.min_normal / 2, -0x1.fcp+6f], + [float.max / 2, 0x1.f8p+6f], [-float.max / 2, 0x1.f8p+6f], + [float.min_normal / 3, -0x1p+7f], [-float.min_normal / 3, -0x1p+7f], + [float.max / 3, 0x1.f8p+6f], [-float.max / 3, 0x1.f8p+6f], + ]; + testLogb(vals); + } + { + double[2][16] vals = [ + [double.nan, double.nan],[-double.nan, double.nan], + [double.infinity, double.infinity], [-double.infinity, double.infinity], + [double.min_normal, -0x1.ffp+9], [-double.min_normal, -0x1.ffp+9], + [double.max, 0x1.ff8p+9], [-double.max, 0x1.ff8p+9], + [double.min_normal / 2, -0x1.ff8p+9], [-double.min_normal / 2, -0x1.ff8p+9], + [double.max / 2, 0x1.ffp+9], [-double.max / 2, 0x1.ffp+9], + [double.min_normal / 3, -0x1p+10], [-double.min_normal / 3, -0x1p+10], + [double.max / 3, 0x1.ffp+9], [-double.max / 3, 0x1.ffp+9], + ]; + testLogb(vals); + } + alias F = floatTraits!real; + static if (F.realFormat == RealFormat.ieeeExtended || F.realFormat == RealFormat.ieeeQuadruple) + {{ + real[2][16] vals = [ + [real.nan, real.nan],[-real.nan, real.nan], + [real.infinity, real.infinity], [-real.infinity, real.infinity], + [real.min_normal, -0x1.fffp+13L], [-real.min_normal, -0x1.fffp+13L], + [real.max, 0x1.fff8p+13L], [-real.max, 0x1.fff8p+13L], + [real.min_normal / 2, -0x1.fff8p+13L], [-real.min_normal / 2, -0x1.fff8p+13L], + [real.max / 2, 0x1.fffp+13L], [-real.max / 2, 0x1.fffp+13L], + [real.min_normal / 3, -0x1p+14L], [-real.min_normal / 3, -0x1p+14L], + [real.max / 3, 0x1.fffp+13L], [-real.max / 3, 0x1.fffp+13L], + ]; + testLogb(vals); + }} +} + /************************************* * Efficiently calculates x * 2$(SUPERSCRIPT n). * diff --git a/libphobos/src/std/net/curl.d b/libphobos/src/std/net/curl.d index 8745bbd..42a34b9 100644 --- a/libphobos/src/std/net/curl.d +++ b/libphobos/src/std/net/curl.d @@ -2171,7 +2171,7 @@ private mixin template Protocol() * * Example: * ---- - * import std.net.curl, std.stdio; + * import std.net.curl, std.stdio, std.conv; * auto client = HTTP("dlang.org"); * client.onReceive = (ubyte[] data) * { @@ -2817,7 +2817,7 @@ struct HTTP * * Example: * ---- - * import std.net.curl, std.stdio; + * import std.net.curl, std.stdio, std.conv; * auto client = HTTP("dlang.org"); * client.onReceive = (ubyte[] data) * { @@ -3054,7 +3054,7 @@ struct HTTP * * Example: * ---- - * import std.net.curl, std.stdio; + * import std.net.curl, std.stdio, std.conv; * auto http = HTTP("http://www.mydomain.com"); * http.onReceive = (ubyte[] data) { writeln(to!(const(char)[])(data)); return data.length; }; * http.postData = [1,2,3,4,5]; @@ -3073,7 +3073,7 @@ struct HTTP * * Example: * ---- - * import std.net.curl, std.stdio; + * import std.net.curl, std.stdio, std.conv; * auto http = HTTP("http://www.mydomain.com"); * http.onReceive = (ubyte[] data) { writeln(to!(const(char)[])(data)); return data.length; }; * http.postData = "The quick...."; @@ -3145,7 +3145,7 @@ struct HTTP * * Example: * ---- - * import std.net.curl, std.stdio; + * import std.net.curl, std.stdio, std.conv; * auto http = HTTP("dlang.org"); * http.onReceive = (ubyte[] data) { writeln(to!(const(char)[])(data)); return data.length; }; * http.onReceiveHeader = (in char[] key, in char[] value) { writeln(key, " = ", value); }; @@ -4551,7 +4551,7 @@ struct Curl * * Example: * ---- - * import std.net.curl, std.stdio; + * import std.net.curl, std.stdio, std.conv; * Curl curl; * curl.initialize(); * curl.set(CurlOption.url, "http://dlang.org"); diff --git a/libphobos/src/std/process.d b/libphobos/src/std/process.d index 3eaa283..494910f 100644 --- a/libphobos/src/std/process.d +++ b/libphobos/src/std/process.d @@ -2505,7 +2505,7 @@ version (Windows) import std.exception : collectException; import std.typecons : tuple; - TestScript prog = ":Loop\ngoto Loop;"; + TestScript prog = ":Loop\r\n" ~ "goto Loop"; auto pid = spawnProcess(prog.path); // Doesn't block longer than one second @@ -3658,7 +3658,7 @@ string escapeShellCommand(scope const(char[])[] args...) @safe pure { args : ["foo bar", "hello"], windows : `"foo bar" hello`, - posix : `'foo bar' 'hello'` + posix : `'foo bar' hello` }, { args : ["foo bar", "hello world"], @@ -3668,20 +3668,34 @@ string escapeShellCommand(scope const(char[])[] args...) @safe pure { args : ["foo bar", "hello", "world"], windows : `"foo bar" hello world`, - posix : `'foo bar' 'hello' 'world'` + posix : `'foo bar' hello world` }, { args : ["foo bar", `'"^\`], windows : `"foo bar" ^"'\^"^^\\^"`, posix : `'foo bar' ''\''"^\'` }, + { + args : ["foo bar", ""], + windows : `"foo bar" ^"^"`, + posix : `'foo bar' ''` + }, + { + args : ["foo bar", "2"], + windows : `"foo bar" ^"2^"`, + posix : `'foo bar' '2'` + }, ]; foreach (test; tests) + { + auto actual = escapeShellCommand(test.args); version (Windows) - assert(escapeShellCommand(test.args) == test.windows); + string expected = test.windows; else - assert(escapeShellCommand(test.args) == test.posix ); + string expected = test.posix; + assert(actual == expected, "\nExpected: " ~ expected ~ "\nGot: " ~ actual); + } } private string escapeShellCommandString(return scope string command) @safe pure @@ -3922,6 +3936,37 @@ private char[] escapePosixArgumentImpl(alias allocator)(scope const(char)[] arg) @safe nothrow if (is(typeof(allocator(size_t.init)[0] = char.init))) { + bool needQuoting = { + import std.ascii : isAlphaNum, isDigit; + import std.algorithm.comparison : among; + + // Empty arguments need to be specified as '' + if (arg.length == 0) + return true; + // Arguments ending with digits need to be escaped, + // to disambiguate with 1>file redirection syntax + if (isDigit(arg[$-1])) + return true; + + // Obtained using: + // for n in $(seq 1 255) ; do + // c=$(printf \\$(printf "%o" $n)) + // q=$(/bin/printf '%q' "$c") + // if [[ "$q" == "$c" ]] ; then printf "%s, " "'$c'" ; fi + // done + // printf '\n' + foreach (char c; arg) + if (!isAlphaNum(c) && !c.among('%', '+', ',', '-', '.', '/', ':', '@', ']', '_')) + return true; + return false; + }(); + if (!needQuoting) + { + auto buf = allocator(arg.length); + buf[] = arg; + return buf; + } + // '\'' means: close quoted part of argument, append an escaped // single quote, and reopen quotes @@ -3995,6 +4040,11 @@ version (unittest_burnin) // Then, test this module with: // rdmd --main -unittest -version=unittest_burnin process.d + import std.file : readText, remove; + import std.format : format; + import std.path : absolutePath; + import std.random : uniform; + auto helper = absolutePath("std_process_unittest_helper"); assert(executeShell(helper ~ " hello").output.split("\0")[1..$] == ["hello"], "Helper malfunction"); diff --git a/libphobos/src/std/range/primitives.d b/libphobos/src/std/range/primitives.d index cdab401..748fde3 100644 --- a/libphobos/src/std/range/primitives.d +++ b/libphobos/src/std/range/primitives.d @@ -171,9 +171,9 @@ Returns: */ enum bool isInputRange(R) = is(typeof(R.init) == R) - && is(ReturnType!((R r) => r.empty) == bool) + && is(typeof((R r) { return r.empty; } (R.init)) == bool) && (is(typeof((return ref R r) => r.front)) || is(typeof(ref (return ref R r) => r.front))) - && !is(ReturnType!((R r) => r.front) == void) + && !is(typeof((R r) { return r.front; } (R.init)) == void) && is(typeof((R r) => r.popFront)); /// @@ -998,7 +998,7 @@ See_Also: The header of $(MREF std,range) for tutorials on ranges. */ enum bool isForwardRange(R) = isInputRange!R - && is(ReturnType!((R r) => r.save) == R); + && is(typeof((R r) { return r.save; } (R.init)) == R); /// @safe unittest @@ -1041,7 +1041,7 @@ See_Also: */ enum bool isBidirectionalRange(R) = isForwardRange!R && is(typeof((R r) => r.popBack)) - && is(ReturnType!((R r) => r.back) == ElementType!R); + && is(typeof((R r) { return r.back; } (R.init)) == ElementType!R); /// @safe unittest @@ -1674,8 +1674,8 @@ The following expression must be true for `hasSlicing` to be `true`: ---- isForwardRange!R - && !isNarrowString!R - && is(ReturnType!((R r) => r[1 .. 1].length) == size_t) + && !(isAutodecodableString!R && !isAggregateType!R) + && is(typeof((R r) { return r[1 .. 1].length; } (R.init)) == size_t) && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R) && (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R)) && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R @@ -1688,7 +1688,7 @@ The following expression must be true for `hasSlicing` to be `true`: */ enum bool hasSlicing(R) = isForwardRange!R && !(isAutodecodableString!R && !isAggregateType!R) - && is(ReturnType!((R r) => r[1 .. 1].length) == size_t) + && is(typeof((R r) { return r[1 .. 1].length; } (R.init)) == size_t) && (is(typeof(lvalueOf!R[1 .. 1]) == R) || isInfinite!R) && (!is(typeof(lvalueOf!R[0 .. $])) || is(typeof(lvalueOf!R[0 .. $]) == R)) && (!is(typeof(lvalueOf!R[0 .. $])) || isInfinite!R diff --git a/libphobos/src/std/regex/internal/parser.d b/libphobos/src/std/regex/internal/parser.d index 448bb99..ab2b297 100644 --- a/libphobos/src/std/regex/internal/parser.d +++ b/libphobos/src/std/regex/internal/parser.d @@ -1010,12 +1010,14 @@ if (isForwardRange!R && is(ElementType!R : dchar)) // @trusted void error(string msg) { - import std.array : appender; - import std.format.write : formattedWrite; - auto app = appender!string(); - formattedWrite(app, "%s\nPattern with error: `%s` <--HERE-- `%s`", - msg, origin[0..$-pat.length], pat); - throw new RegexException(app.data); + import std.conv : text; + string app = msg; + app ~= "\nPattern with error: `"; + app ~= origin[0..$-pat.length].text; + app ~= "` <--HERE-- `"; + app ~= pat.text; + app ~= "`"; + throw new RegexException(app); } alias Char = BasicElementOf!R; diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d index 593052e..3359c8e 100644 --- a/libphobos/src/std/socket.d +++ b/libphobos/src/std/socket.d @@ -802,10 +802,14 @@ class InternetHost { string getHostNameFromInt = ih.name.dup; - assert(ih.getHostByAddr(ia.toAddrString())); - string getHostNameFromStr = ih.name.dup; + // This randomly fails in the compiler test suite + //assert(ih.getHostByAddr(ia.toAddrString())); - assert(getHostNameFromInt == getHostNameFromStr); + if (ih.getHostByAddr(ia.toAddrString())) + { + string getHostNameFromStr = ih.name.dup; + assert(getHostNameFromInt == getHostNameFromStr); + } } } diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index 802aa128..92e4906 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -1374,8 +1374,9 @@ Throws: `Exception` if the file is not opened. } /** -Calls $(HTTP cplusplus.com/reference/clibrary/cstdio/ftell.html, ftell) for the -managed file handle. +Calls $(HTTP cplusplus.com/reference/cstdio/ftell.html, ftell) +for the managed file handle, which returns the current value of +the position indicator of the file handle. Throws: `Exception` if the file is not opened. `ErrnoException` if the call to `ftell` fails. diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d index e5f305b..bbbca69 100644 --- a/libphobos/src/std/traits.d +++ b/libphobos/src/std/traits.d @@ -10,6 +10,7 @@ * $(TR $(TH Category) $(TH Templates)) * $(TR $(TD Symbol Name traits) $(TD * $(LREF fullyQualifiedName) + * $(LREF mangledName) * $(LREF moduleName) * $(LREF packageName) * )) @@ -67,9 +68,7 @@ * $(LREF isCovariantWith) * $(LREF isImplicitlyConvertible) * )) - * $(TR $(TD SomethingTypeOf) $(TD - * $(LREF rvalueOf) - * $(LREF lvalueOf) + * $(TR $(TD Type Constructors) $(TD * $(LREF InoutOf) * $(LREF ConstOf) * $(LREF SharedOf) @@ -138,7 +137,8 @@ * $(LREF Promoted) * )) * $(TR $(TD Misc) $(TD - * $(LREF mangledName) + * $(LREF lvalueOf) + * $(LREF rvalueOf) * $(LREF Select) * $(LREF select) * )) @@ -889,7 +889,7 @@ private template fqnType(T, ); } } - else static if (is(T : U*, U)) + else static if (is(T == U*, U)) { enum fqnType = chain!( fqnType!(U, qualifiers) ~ "*" @@ -986,6 +986,10 @@ private template fqnType(T, * or a class with an `opCall`. Please note that $(D_KEYWORD ref) * is not part of a type, but the attribute of the function * (see template $(LREF functionAttributes)). + * + * $(NOTE To reduce template instantiations, consider instead using + * $(D typeof(() { return func(args); } ())) if the argument types are known or + * $(D static if (is(typeof(func) Ret == return))) if only that basic test is needed.) */ template ReturnType(alias func) if (isCallable!func) @@ -2302,7 +2306,7 @@ if (isCallable!func) int test(int); int test() @property; } - alias ov = __traits(getVirtualFunctions, Overloads, "test"); + alias ov = __traits(getVirtualMethods, Overloads, "test"); alias F_ov0 = FunctionTypeOf!(ov[0]); alias F_ov1 = FunctionTypeOf!(ov[1]); alias F_ov2 = FunctionTypeOf!(ov[2]); @@ -3925,7 +3929,7 @@ template hasStaticMember(T, string member) { static if (__traits(hasMember, T, member)) { - static if (is(T : V*, V)) + static if (is(T == V*, V)) alias U = V; else alias U = T; @@ -4529,7 +4533,7 @@ if (is(C == class) || is(C == interface)) static if (__traits(hasMember, Node, name) && __traits(compiles, __traits(getMember, Node, name))) { // Get all overloads in sight (not hidden). - alias inSight = __traits(getVirtualFunctions, Node, name); + alias inSight = __traits(getVirtualMethods, Node, name); // And collect all overloads in ancestor classes to reveal hidden // methods. The result may contain duplicates. @@ -5297,7 +5301,8 @@ enum isLvalueAssignable(Lhs, Rhs = Lhs) = __traits(compiles, { lvalueOf!Lhs = lv static assert(!isAssignable!S5); // `-preview=in` is enabled - static if (!is(typeof(mixin(q{(in ref int a) => a})))) + alias DScannerBug895 = int[256]; + static if (((in DScannerBug895 a) { return __traits(isRef, a); })(DScannerBug895.init)) { struct S6 { void opAssign(in S5); } @@ -6066,7 +6071,7 @@ template StringTypeOf(T) static assert(is(Q!T[] == StringTypeOf!( SubTypeOf!(Q!T[]) ))); alias Str = Q!T[]; - class C(S) { S val; alias val this; } + struct C(S) { S val; alias val this; } static assert(is(StringTypeOf!(C!Str) == Str)); }} } @@ -7481,24 +7486,10 @@ Params: Returns: A `bool` */ -template isSomeFunction(alias T) -{ - static if (is(typeof(& T) U : U*) && is(U == function) || is(typeof(& T) U == delegate)) - { - // T is a (nested) function symbol. - enum bool isSomeFunction = true; - } - else static if (is(T W) || is(typeof(T) W)) - { - // T is an expression or a type. Take the type of it and examine. - static if (is(W F : F*) && is(F == function)) - enum bool isSomeFunction = true; // function pointer - else - enum bool isSomeFunction = is(W == function) || is(W == delegate); - } - else - enum bool isSomeFunction = false; -} +enum bool isSomeFunction(alias T) = + is(T == return) || + is(typeof(T) == return) || + is(typeof(&T) == return); // @property /// @safe unittest @@ -7513,17 +7504,16 @@ template isSomeFunction(alias T) auto c = new C; auto fp = &func; auto dg = &c.method; - real val; static assert( isSomeFunction!func); static assert( isSomeFunction!prop); static assert( isSomeFunction!(C.method)); static assert( isSomeFunction!(C.prop)); static assert( isSomeFunction!(c.prop)); - static assert( isSomeFunction!(c.prop)); static assert( isSomeFunction!fp); static assert( isSomeFunction!dg); + real val; static assert(!isSomeFunction!int); static assert(!isSomeFunction!val); } @@ -7969,7 +7959,7 @@ has both opApply and a range interface. */ template ForeachType(T) { - alias ForeachType = ReturnType!(typeof( + alias ForeachType = typeof( (inout int x = 0) { foreach (elem; T.init) @@ -7977,7 +7967,7 @@ template ForeachType(T) return elem; } assert(0); - })); + }()); } /// diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index 25cf9e0..bde8439 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -3160,12 +3160,6 @@ struct Nullable(T) } /// ditto - inout(typeof(this)) opIndex() inout - { - return this; - } - - /// ditto inout(typeof(this)) opIndex(size_t[2] dim) inout in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0]) { @@ -3192,6 +3186,74 @@ struct Nullable(T) { return get(); } + + /** + * Converts `Nullable` to a range. Works even when the contained type is `immutable`. + */ + auto opSlice(this This)() + { + static struct NullableRange + { + private This value; + + // starts out true if value is null + private bool empty_; + + @property bool empty() const @safe pure nothrow + { + return empty_; + } + + void popFront() @safe pure nothrow + { + empty_ = true; + } + + alias popBack = popFront; + + @property ref inout(typeof(value.get())) front() inout @safe pure nothrow + { + return value.get(); + } + + alias back = front; + + @property inout(typeof(this)) save() inout + { + return this; + } + + size_t[2] opSlice(size_t dim : 0)(size_t from, size_t to) const + { + return [from, to]; + } + + @property size_t length() const @safe pure nothrow + { + return !empty; + } + + alias opDollar(size_t dim : 0) = length; + + ref inout(typeof(value.get())) opIndex(size_t index) inout @safe pure nothrow + in (index < length) + { + return value.get(); + } + + inout(typeof(this)) opIndex(size_t[2] dim) inout + in (dim[0] <= length && dim[1] <= length && dim[1] >= dim[0]) + { + return (dim[0] == 0 && dim[1] == 1) ? this : this.init; + } + + auto opIndex() inout + { + return this; + } + } + return NullableRange(this, isNull); + } } /// ditto @@ -3774,6 +3836,34 @@ auto nullable(T)(T t) assert(hasLvalueElements!(Nullable!int)); } +// https://issues.dlang.org/show_bug.cgi?id=23640 +@safe pure nothrow unittest +{ + import std.algorithm.comparison : equal; + import std.range : only; + import std.range.primitives : hasLength, hasSlicing, + isRandomAccessRange; + static immutable struct S { int[] array; } + auto value = S([42]); + alias ImmutableNullable = immutable Nullable!S; + auto a = ImmutableNullable(value)[]; + alias Range = typeof(a); + assert(isRandomAccessRange!Range); + assert(hasLength!Range); + assert(hasSlicing!Range); + assert(!a.empty); + assert(a.front == value); + assert(a.back == value); + assert(a[0] == value); + assert(a.equal(only(value))); + assert(a[0 .. $].equal(only(value))); + Range b = a.save(); + assert(!b.empty); + b.popFront(); + assert(!a.empty); + assert(b.empty); +} + /** Just like `Nullable!T`, except that the null state is defined as a particular value. For example, $(D Nullable!(uint, uint.max)) is an diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d index 5c0659e..e2a0de7 100644 --- a/libphobos/src/std/uni/package.d +++ b/libphobos/src/std/uni/package.d @@ -712,6 +712,8 @@ import std.traits : isConvertibleToString, isIntegral, isSomeChar, isSomeString, Unqual, isDynamicArray; // debug = std_uni; +import std.internal.unicode_tables; // generated file + debug(std_uni) import std.stdio; // writefln, writeln private: @@ -6962,23 +6964,192 @@ private: enum EMPTY_CASE_TRIE = ushort.max;// from what gen_uni uses internally -// control - '\r' -enum controlSwitch = ` - case '\u0000':..case '\u0008':case '\u000E':..case '\u001F':case '\u007F':.. - case '\u0084':case '\u0086':..case '\u009F': case '\u0009':..case '\u000C': case '\u0085': -`; // TODO: redo the most of hangul stuff algorithmically in case of Graphemes too -// kill unrolled switches +// Use combined trie instead of checking for '\r' | '\n' | ccTrie, +// or extend | '\u200D' separately private static bool isRegionalIndicator(dchar ch) @safe pure @nogc nothrow { return ch >= '\U0001F1E6' && ch <= '\U0001F1FF'; } +// Our grapheme decoder is a state machine, this is list of all possible +// states before each code point. +private enum GraphemeState +{ + Start, + CR, + RI, + L, + V, + LVT, + Emoji, + EmojiZWJ, + Prepend, + End +} + +// Message values whether end of grapheme is reached +private enum TransformRes +{ + // No, unless the source range ends here + // (GB2 - break at end of text, unless text is empty) + goOn, + redo, // Run last character again with new state + retInclude, // Yes, after the just iterated character + retExclude // Yes, before the just iterated character +} + +// The logic of the grapheme decoding is all here +// GB# means Grapheme Breaking rule number # - see Unicode standard annex #29 +// Note, getting GB1 (break at start of text, unless text is empty) right +// relies on the user starting grapheme walking from beginning of the text, and +// not attempting to walk an empty text. +private enum TransformRes + function(ref GraphemeState, dchar) @safe pure nothrow @nogc [] graphemeTransforms = +[ + GraphemeState.Start: (ref state, ch) + { + // GB4. Break after controls. + if (graphemeControlTrie[ch] || ch == '\n') + return TransformRes.retInclude; + + with (GraphemeState) state = + ch == '\r' ? CR : + isRegionalIndicator(ch) ? RI : + isHangL(ch) ? L : + hangLV[ch] || isHangV(ch) ? V : + hangLVT[ch] || isHangT(ch) ? LVT : + prependTrie[ch] ? Prepend : + xpictoTrie[ch] ? Emoji : + End; + + // No matter what we encountered, we always include the + // first code point in the grapheme. + return TransformRes.goOn; + }, + + // GB3, GB4. Do not break between a CR and LF. + // Otherwise, break after controls. + GraphemeState.CR: (ref state, ch) => ch == '\n' ? + TransformRes.retInclude : + TransformRes.retExclude, + + // GB12 - GB13. Do not break within emoji flag sequences. + // That is, do not break between regional indicator (RI) symbols if + // there is an odd number of RI characters before the break point. + // This state applies if one and only one RI code point has been + // encountered. + GraphemeState.RI: (ref state, ch) + { + state = GraphemeState.End; + + return isRegionalIndicator(ch) ? + TransformRes.goOn : + TransformRes.redo; + }, + + // GB6. Do not break Hangul syllable sequences. + GraphemeState.L: (ref state, ch) + { + if (isHangL(ch)) + return TransformRes.goOn; + else if (isHangV(ch) || hangLV[ch]) + { + state = GraphemeState.V; + return TransformRes.goOn; + } + else if (hangLVT[ch]) + { + state = GraphemeState.LVT; + return TransformRes.goOn; + } + + state = GraphemeState.End; + return TransformRes.redo; + }, + + // GB7. Do not break Hangul syllable sequences. + GraphemeState.V: (ref state, ch) + { + if (isHangV(ch)) + return TransformRes.goOn; + else if (isHangT(ch)) + { + state = GraphemeState.LVT; + return TransformRes.goOn; + } + + state = GraphemeState.End; + return TransformRes.redo; + }, + + // GB8. Do not break Hangul syllable sequences. + GraphemeState.LVT: (ref state, ch) + { + if (isHangT(ch)) + return TransformRes.goOn; + + state = GraphemeState.End; + return TransformRes.redo; + }, + + // GB11. Do not break within emoji modifier sequences or emoji + // zwj sequences. This state applies when the last code point was + // NOT a ZWJ. + GraphemeState.Emoji: (ref state, ch) + { + if (graphemeExtendTrie[ch]) + return TransformRes.goOn; + + static assert(!graphemeExtendTrie['\u200D']); + + if (ch == '\u200D') + { + state = GraphemeState.EmojiZWJ; + return TransformRes.goOn; + } + + state = GraphemeState.End; + // There might still be spacing marks are + // at the end, which are not allowed in + // middle of emoji sequences + return TransformRes.redo; + }, + + // GB11. Do not break within emoji modifier sequences or emoji + // zwj sequences. This state applies when the last code point was + // a ZWJ. + GraphemeState.EmojiZWJ: (ref state, ch) + { + state = GraphemeState.Emoji; + if (xpictoTrie[ch]) + return TransformRes.goOn; + return TransformRes.redo; + }, + + // GB9b. Do not break after Prepend characters. + GraphemeState.Prepend: (ref state, ch) + { + // GB5. Break before controls. + if (graphemeControlTrie[ch] || ch == '\r' || ch == '\n') + return TransformRes.retExclude; + + state = GraphemeState.Start; + return TransformRes.redo; + }, + + // GB9, GB9a. Do not break before extending characters, ZWJ + // or SpacingMarks. + // GB999. Otherwise, break everywhere. + GraphemeState.End: (ref state, ch) + => !graphemeExtendTrie[ch] && !spacingMarkTrie[ch] && ch != '\u200D' ? + TransformRes.retExclude : + TransformRes.goOn +]; + template genericDecodeGrapheme(bool getValue) { - alias graphemeExtend = graphemeExtendTrie; - alias spacingMark = mcTrie; static if (getValue) alias Value = Grapheme; else @@ -6986,115 +7157,44 @@ template genericDecodeGrapheme(bool getValue) Value genericDecodeGrapheme(Input)(ref Input range) { - import std.internal.unicode_tables : isHangL, isHangT, isHangV; // generated file - enum GraphemeState { - Start, - CR, - RI, - L, - V, - LVT - } static if (getValue) Grapheme grapheme; auto state = GraphemeState.Start; - enum eat = q{ - static if (getValue) - grapheme ~= ch; - range.popFront(); - }; - dchar ch; + assert(!range.empty, "Attempting to decode grapheme from an empty " ~ Input.stringof); + outer: while (!range.empty) { ch = range.front; - final switch (state) with(GraphemeState) + + rerun: + final switch (graphemeTransforms[state](state, ch)) + with(TransformRes) { - case Start: - mixin(eat); - if (ch == '\r') - state = CR; - else if (isRegionalIndicator(ch)) - state = RI; - else if (isHangL(ch)) - state = L; - else if (hangLV[ch] || isHangV(ch)) - state = V; - else if (hangLVT[ch]) - state = LVT; - else if (isHangT(ch)) - state = LVT; - else - { - switch (ch) - { - mixin(controlSwitch); - goto L_End; - default: - goto L_End_Extend; - } - } - break; - case CR: - if (ch == '\n') - mixin(eat); - goto L_End_Extend; - case RI: - if (isRegionalIndicator(ch)) - mixin(eat); - goto L_End_Extend; - case L: - if (isHangL(ch)) - mixin(eat); - else if (isHangV(ch) || hangLV[ch]) - { - state = V; - mixin(eat); - } - else if (hangLVT[ch]) - { - state = LVT; - mixin(eat); - } - else - goto L_End_Extend; - break; - case V: - if (isHangV(ch)) - mixin(eat); - else if (isHangT(ch)) - { - state = LVT; - mixin(eat); - } - else - goto L_End_Extend; - break; - case LVT: - if (isHangT(ch)) - { - mixin(eat); - } - else - goto L_End_Extend; - break; + case goOn: + static if (getValue) + grapheme ~= ch; + range.popFront(); + continue; + + case redo: + goto rerun; + + case retInclude: + static if (getValue) + grapheme ~= ch; + range.popFront(); + break outer; + + case retExclude: + break outer; } } - L_End_Extend: - while (!range.empty) - { - ch = range.front; - // extend & spacing marks - if (!graphemeExtend[ch] && !spacingMark[ch]) - break; - mixin(eat); - } - L_End: + static if (getValue) return grapheme; } - } public: // Public API continues @@ -7143,6 +7243,31 @@ if (is(C : dchar)) static assert(c2 == 3); // \u0301 has 2 UTF-8 code units } +// TODO: make this @nogc. Probably no big deal since the state machine is +// already GC-free. +@safe pure nothrow unittest +{ + // grinning face ~ emoji modifier fitzpatrick type-5 ~ grinning face + assert(graphemeStride("\U0001F600\U0001f3FE\U0001F600"d, 0) == 2); + // skier ~ female sign ~ '€' + assert(graphemeStride("\u26F7\u2640€"d, 0) == 1); + // skier ~ emoji modifier fitzpatrick type-5 ~ female sign ~ '€' + assert(graphemeStride("\u26F7\U0001f3FE\u2640€"d, 0) == 2); + // skier ~ zero-width joiner ~ female sign ~ '€' + assert(graphemeStride("\u26F7\u200D\u2640€"d, 0) == 3); + // skier ~ emoji modifier fitzpatrick type-5 ~ zero-width joiner + // ~ female sign ~ '€' + assert(graphemeStride("\u26F7\U0001f3FE\u200D\u2640€"d, 0) == 4); + // skier ~ zero-width joiner ~ '€' + assert(graphemeStride("\u26F7\u200D€"d, 0) == 2); + //'€' ~ zero-width joiner ~ skier + assert(graphemeStride("€\u200D\u26F7"d, 0) == 2); + // Kaithi number sign ~ Devanagari digit four ~ Devanagari digit two + assert(graphemeStride("\U000110BD\u096A\u0968"d, 0) == 2); + // Kaithi number sign ~ null + assert(graphemeStride("\U000110BD\0"d, 0) == 1); +} + /++ Reads one full grapheme cluster from an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of dchar `inp`. @@ -7285,6 +7410,13 @@ private static @safe struct InputRangeString assert(nonForwardRange.walkLength == 4); } +// Issue 23474 +@safe pure unittest +{ + import std.range.primitives : walkLength; + assert(byGrapheme("\r\u0308").walkLength == 2); +} + /++ $(P Lazily transform a range of $(LREF Grapheme)s to a range of code points.) @@ -10530,8 +10662,6 @@ private: @safe pure nothrow @nogc @property { - import std.internal.unicode_tables; // generated file - // It's important to use auto return here, so that the compiler // only runs semantic on the return type if the function gets // used. Also these are functions rather than templates to not @@ -10578,10 +10708,10 @@ private: } //grapheme breaking algorithm tables - auto mcTrie() + auto spacingMarkTrie() { - import std.internal.unicode_grapheme : mcTrieEntries; - static immutable res = asTrie(mcTrieEntries); + import std.internal.unicode_grapheme : spacingMarkTrieEntries; + static immutable res = asTrie(spacingMarkTrieEntries); return res; } @@ -10606,6 +10736,27 @@ private: return res; } + auto prependTrie() + { + import std.internal.unicode_grapheme : prependTrieEntries; + static immutable res = asTrie(prependTrieEntries); + return res; + } + + auto graphemeControlTrie() + { + import std.internal.unicode_grapheme : controlTrieEntries; + static immutable res = asTrie(controlTrieEntries); + return res; + } + + auto xpictoTrie() + { + import std.internal.unicode_grapheme : Extended_PictographicTrieEntries; + static immutable res = asTrie(Extended_PictographicTrieEntries); + return res; + } + // tables below are used for composition/decomposition auto combiningClassTrie() { diff --git a/libphobos/src/std/utf.d b/libphobos/src/std/utf.d index 7a0556d..3eef5cb 100644 --- a/libphobos/src/std/utf.d +++ b/libphobos/src/std/utf.d @@ -3136,7 +3136,7 @@ private T toUTFImpl(T, S)(scope S s) collection cycle and cause a nasty bug when the C code tries to use it. +/ template toUTFz(P) -if (is(P : C*, C) && isSomeChar!C) +if (is(P == C*, C) && isSomeChar!C) { P toUTFz(S)(S str) @safe pure if (isSomeString!S) |