// Written in the D programming language.

/++
    $(P The $(D std.uni) module provides an implementation
    of fundamental Unicode algorithms and data structures.
    This doesn't include UTF encoding and decoding primitives,
    see $(REF decode, std,_utf) and $(REF encode, std,_utf) in $(MREF std, utf)
    for this functionality. )

$(SCRIPT inhibitQuickIndex = 1;)
$(BOOKTABLE,
$(TR $(TH Category) $(TH Functions))
$(TR $(TD Decode) $(TD
    $(LREF byCodePoint)
    $(LREF byGrapheme)
    $(LREF decodeGrapheme)
    $(LREF graphemeStride)
))
$(TR $(TD Comparison) $(TD
    $(LREF icmp)
    $(LREF sicmp)
))
$(TR $(TD Classification) $(TD
    $(LREF isAlpha)
    $(LREF isAlphaNum)
    $(LREF isCodepointSet)
    $(LREF isControl)
    $(LREF isFormat)
    $(LREF isGraphical)
    $(LREF isIntegralPair)
    $(LREF isMark)
    $(LREF isNonCharacter)
    $(LREF isNumber)
    $(LREF isPrivateUse)
    $(LREF isPunctuation)
    $(LREF isSpace)
    $(LREF isSurrogate)
    $(LREF isSurrogateHi)
    $(LREF isSurrogateLo)
    $(LREF isSymbol)
    $(LREF isWhite)
))
$(TR $(TD Normalization) $(TD
    $(LREF NFC)
    $(LREF NFD)
    $(LREF NFKD)
    $(LREF NormalizationForm)
    $(LREF normalize)
))
$(TR $(TD Decompose) $(TD
    $(LREF decompose)
    $(LREF decomposeHangul)
    $(LREF UnicodeDecomposition)
))
$(TR $(TD Compose) $(TD
    $(LREF compose)
    $(LREF composeJamo)
))
$(TR $(TD Sets) $(TD
    $(LREF CodepointInterval)
    $(LREF CodepointSet)
    $(LREF InversionList)
    $(LREF unicode)
))
$(TR $(TD Trie) $(TD
    $(LREF codepointSetTrie)
    $(LREF CodepointSetTrie)
    $(LREF codepointTrie)
    $(LREF CodepointTrie)
    $(LREF toTrie)
    $(LREF toDelegate)
))
$(TR $(TD Casing) $(TD
    $(LREF asCapitalized)
    $(LREF asLowerCase)
    $(LREF asUpperCase)
    $(LREF isLower)
    $(LREF isUpper)
    $(LREF toLower)
    $(LREF toLowerInPlace)
    $(LREF toUpper)
    $(LREF toUpperInPlace)
))
$(TR $(TD Utf8Matcher) $(TD
    $(LREF isUtfMatcher)
    $(LREF MatcherConcept)
    $(LREF utfMatcher)
))
$(TR $(TD Separators) $(TD
    $(LREF lineSep)
    $(LREF nelSep)
    $(LREF paraSep)
))
$(TR $(TD Building blocks) $(TD
    $(LREF allowedIn)
    $(LREF combiningClass)
    $(LREF Grapheme)
))
)

    $(P All primitives listed operate on Unicode characters and
        sets of characters. For functions which operate on ASCII characters
        and ignore Unicode $(CHARACTERS), see $(MREF std, ascii).
        For definitions of Unicode $(CHARACTER), $(CODEPOINT) and other terms
        used throughout this module see the $(S_LINK Terminology, terminology) section
        below.
    )
    $(P The focus of this module is the core needs of developing Unicode-aware
        applications. To that effect it provides the following optimized primitives:
    )
    $(UL
        $(LI Character classification by category and common properties:
            $(LREF isAlpha), $(LREF isWhite) and others.
        )
        $(LI
            Case-insensitive string comparison ($(LREF sicmp), $(LREF icmp)).
        )
        $(LI
            Converting text to any of the four normalization forms via $(LREF normalize).
        )
        $(LI
            Decoding ($(LREF decodeGrapheme))  and iteration ($(LREF byGrapheme), $(LREF graphemeStride))
            by user-perceived characters, that is by $(LREF Grapheme) clusters.
        )
        $(LI
            Decomposing and composing of individual character(s) according to canonical
            or compatibility rules, see $(LREF compose) and $(LREF decompose),
            including the specific version for Hangul syllables $(LREF composeJamo)
            and $(LREF decomposeHangul).
        )
    )
    $(P It's recognized that an application may need further enhancements
        and extensions, such as less commonly known algorithms,
        or tailoring existing ones for region specific needs. To help users
        with building any extra functionality beyond the core primitives,
        the module provides:
    )
    $(UL
        $(LI
            $(LREF CodepointSet), a type for easy manipulation of sets of characters.
            Besides the typical set algebra it provides an unusual feature:
            a D source code generator for detection of $(CODEPOINTS) in this set.
            This is a boon for meta-programming parser frameworks,
            and is used internally to power classification in small
            sets like $(LREF isWhite).
        )
        $(LI
            A way to construct optimal packed multi-stage tables also known as a
            special case of $(LINK2 https://en.wikipedia.org/wiki/Trie, Trie).
            The functions $(LREF codepointTrie), $(LREF codepointSetTrie)
            construct custom tries that map dchar to value.
            The end result is a fast and predictable $(BIGOH 1) lookup that powers
            functions like $(LREF isAlpha) and $(LREF combiningClass),
            but for user-defined data sets.
        )
        $(LI
            A useful technique for Unicode-aware parsers that perform
            character classification of encoded $(CODEPOINTS)
            is to avoid unnecassary decoding at all costs.
            $(LREF utfMatcher) provides an improvement over the usual workflow
            of decode-classify-process, combining the decoding and classification
            steps. By extracting necessary bits directly from encoded
            $(S_LINK Code unit, code units) matchers achieve
            significant performance improvements. See $(LREF MatcherConcept) for
            the common interface of UTF matchers.
        )
        $(LI
            Generally useful building blocks for customized normalization:
            $(LREF combiningClass) for querying combining class
            and $(LREF allowedIn) for testing the Quick_Check
            property of a given normalization form.
        )
        $(LI
            Access to a large selection of commonly used sets of $(CODEPOINTS).
            $(S_LINK Unicode properties, Supported sets) include Script,
            Block and General Category. The exact contents of a set can be
            observed in the CLDR utility, on the
            $(HTTP www.unicode.org/cldr/utility/properties.jsp, property index) page
            of the Unicode website.
            See $(LREF unicode) for easy and (optionally) compile-time checked set
            queries.
        )
    )
    $(SECTION Synopsis)
    ---
    import std.uni;
    void main()
    {
        // initialize code point sets using script/block or property name
        // now 'set' contains code points from both scripts.
        auto set = unicode("Cyrillic") | unicode("Armenian");
        // same thing but simpler and checked at compile-time
        auto ascii = unicode.ASCII;
        auto currency = unicode.Currency_Symbol;

        // easy set ops
        auto a = set & ascii;
        assert(a.empty); // as it has no intersection with ascii
        a = set | ascii;
        auto b = currency - a; // subtract all ASCII, Cyrillic and Armenian

        // some properties of code point sets
        assert(b.length > 45); // 46 items in Unicode 6.1, even more in 6.2
        // testing presence of a code point in a set
        // is just fine, it is O(logN)
        assert(!b['$']);
        assert(!b['\u058F']); // Armenian dram sign
        assert(b['¥']);

        // building fast lookup tables, these guarantee O(1) complexity
        // 1-level Trie lookup table essentially a huge bit-set ~262Kb
        auto oneTrie = toTrie!1(b);
        // 2-level far more compact but typically slightly slower
        auto twoTrie = toTrie!2(b);
        // 3-level even smaller, and a bit slower yet
        auto threeTrie = toTrie!3(b);
        assert(oneTrie['£']);
        assert(twoTrie['£']);
        assert(threeTrie['£']);

        // build the trie with the most sensible trie level
        // and bind it as a functor
        auto cyrillicOrArmenian = toDelegate(set);
        auto balance = find!(cyrillicOrArmenian)("Hello ընկեր!");
        assert(balance == "ընկեր!");
        // compatible with bool delegate(dchar)
        bool delegate(dchar) bindIt = cyrillicOrArmenian;

        // Normalization
        string s = "Plain ascii (and not only), is always normalized!";
        assert(s is normalize(s));// is the same string

        string nonS = "A\u0308ffin"; // A ligature
        auto nS = normalize(nonS); // to NFC, the W3C endorsed standard
        assert(nS == "Äffin");
        assert(nS != nonS);
        string composed = "Äffin";

        assert(normalize!NFD(composed) == "A\u0308ffin");
        // to NFKD, compatibility decomposition useful for fuzzy matching/searching
        assert(normalize!NFKD("2¹⁰") == "210");
    }
    ---
    $(SECTION Terminology
    )
    $(P The following is a list of important Unicode notions
    and definitions. Any conventions used specifically in this
    module alone are marked as such. The descriptions are based on the formal
    definition as found in $(HTTP www.unicode.org/versions/Unicode6.2.0/ch03.pdf,
    chapter three of The Unicode Standard Core Specification.)
    )
    $(P $(DEF Abstract character) A unit of information used for the organization,
        control, or representation of textual data.
        Note that:
        $(UL
            $(LI When representing data, the nature of that data
                is generally symbolic as opposed to some other
                kind of data (for example, visual).
            )
             $(LI An abstract character has no concrete form
                and should not be confused with a $(S_LINK Glyph, glyph).
            )
            $(LI An abstract character does not necessarily
                correspond to what a user thinks of as a “character”
                and should not be confused with a $(LREF Grapheme).
            )
            $(LI The abstract characters encoded (see Encoded character)
                are known as Unicode abstract characters.
            )
            $(LI Abstract characters not directly
                encoded by the Unicode Standard can often be
                represented by the use of combining character sequences.
            )
        )
    )
    $(P $(DEF Canonical decomposition)
        The decomposition of a character or character sequence
        that results from recursively applying the canonical
        mappings found in the Unicode Character Database
        and these described in Conjoining Jamo Behavior
        (section 12 of
        $(HTTP www.unicode.org/uni2book/ch03.pdf, Unicode Conformance)).
    )
    $(P $(DEF Canonical composition)
        The precise definition of the Canonical composition
        is the algorithm as specified in $(HTTP www.unicode.org/uni2book/ch03.pdf,
        Unicode Conformance) section 11.
        Informally it's the process that does the reverse of the canonical
        decomposition with the addition of certain rules
        that e.g. prevent legacy characters from appearing in the composed result.
    )
    $(P $(DEF Canonical equivalent)
        Two character sequences are said to be canonical equivalents if
        their full canonical decompositions are identical.
    )
    $(P $(DEF Character) Typically differs by context.
        For the purpose of this documentation the term $(I character)
        implies $(I encoded character), that is, a code point having
        an assigned abstract character (a symbolic meaning).
    )
    $(P $(DEF Code point) Any value in the Unicode codespace;
        that is, the range of integers from 0 to 10FFFF (hex).
        Not all code points are assigned to encoded characters.
    )
    $(P $(DEF Code unit) The minimal bit combination that can represent
        a unit of encoded text for processing or interchange.
        Depending on the encoding this could be:
        8-bit code units in the UTF-8 ($(D char)),
        16-bit code units in the UTF-16 ($(D wchar)),
        and 32-bit code units in the UTF-32 ($(D dchar)).
        $(I Note that in UTF-32, a code unit is a code point
        and is represented by the D $(D dchar) type.)
    )
    $(P $(DEF Combining character) A character with the General Category
        of Combining Mark(M).
        $(UL
            $(LI All characters with non-zero canonical combining class
            are combining characters, but the reverse is not the case:
            there are combining characters with a zero combining class.
            )
            $(LI These characters are not normally used in isolation
            unless they are being described. They include such characters
            as accents, diacritics, Hebrew points, Arabic vowel signs,
            and Indic matras.
            )
        )
    )
    $(P $(DEF Combining class)
        A numerical value used by the Unicode Canonical Ordering Algorithm
        to determine which sequences of combining marks are to be
        considered canonically equivalent and  which are not.
    )
    $(P $(DEF Compatibility decomposition)
        The decomposition of a character or character sequence that results
        from recursively applying both the compatibility mappings and
        the canonical mappings found in the Unicode Character Database, and those
        described in Conjoining Jamo Behavior no characters
        can be further decomposed.
    )
    $(P $(DEF Compatibility equivalent)
        Two character sequences are said to be compatibility
        equivalents if their full compatibility decompositions are identical.
    )
    $(P $(DEF Encoded character) An association (or mapping)
        between an abstract character and a code point.
    )
    $(P $(DEF Glyph) The actual, concrete image of a glyph representation
        having been rasterized or otherwise imaged onto some display surface.
    )
    $(P $(DEF Grapheme base) A character with the property
        Grapheme_Base, or any standard Korean syllable block.
    )
    $(P $(DEF Grapheme cluster) Defined as the text between
        grapheme boundaries  as specified by Unicode Standard Annex #29,
        $(HTTP www.unicode.org/reports/tr29/, Unicode text segmentation).
        Important general properties of a grapheme:
        $(UL
            $(LI The grapheme cluster represents a horizontally segmentable
            unit of text, consisting of some grapheme base (which may
            consist of a Korean syllable) together with any number of
            nonspacing marks applied to it.
            )
            $(LI  A grapheme cluster typically starts with a grapheme base
            and then extends across any subsequent sequence of nonspacing marks.
            A grapheme cluster is most directly relevant to text rendering and
            processes such as cursor placement and text selection in editing,
            but may also be relevant to comparison and searching.
            )
            $(LI For many processes, a grapheme cluster behaves as if it was a
            single character with the same properties as its grapheme base.
            Effectively, nonspacing marks apply $(I graphically) to the base,
            but do not change its properties.
            )
        )
        $(P This module defines a number of primitives that work with graphemes:
        $(LREF Grapheme), $(LREF decodeGrapheme) and $(LREF graphemeStride).
        All of them are using $(I extended grapheme) boundaries
        as defined in the aforementioned standard annex.
        )
    )
    $(P $(DEF Nonspacing mark) A combining character with the
        General Category of Nonspacing Mark (Mn) or Enclosing Mark (Me).
    )
    $(P $(DEF Spacing mark) A combining character that is not a nonspacing mark.
    )
    $(SECTION Normalization
    )
    $(P The concepts of $(S_LINK Canonical equivalent, canonical equivalent)
        or $(S_LINK Compatibility equivalent, compatibility equivalent)
        characters in the Unicode Standard make it necessary to have a full, formal
        definition of equivalence for Unicode strings.
        String equivalence is determined by a process called normalization,
        whereby strings are converted into forms which are compared
        directly for identity. This is the primary goal of the normalization process,
        see the function $(LREF normalize) to convert into any of
        the four defined forms.
    )
    $(P A very important attribute of the Unicode Normalization Forms
        is that they must remain stable between versions of the Unicode Standard.
        A Unicode string normalized to a particular Unicode Normalization Form
        in one version of the standard is guaranteed to remain in that Normalization
        Form for implementations of future versions of the standard.
    )
    $(P The Unicode Standard specifies four normalization forms.
        Informally, two of these forms are defined by maximal decomposition
        of equivalent sequences, and two of these forms are defined
        by maximal $(I composition) of equivalent sequences.
            $(UL
            $(LI Normalization Form D (NFD): The $(S_LINK Canonical decomposition,
                canonical decomposition) of a character sequence.)
            $(LI Normalization Form KD (NFKD): The $(S_LINK Compatibility decomposition,
                compatibility decomposition) of a character sequence.)
            $(LI Normalization Form C (NFC): The canonical composition of the
                $(S_LINK Canonical decomposition, canonical decomposition)
                of a coded character sequence.)
            $(LI Normalization Form KC (NFKC): The canonical composition
            of the $(S_LINK Compatibility decomposition,
                compatibility decomposition) of a character sequence)
            )
    )
    $(P The choice of the normalization form depends on the particular use case.
        NFC is the best form for general text, since it's more compatible with
        strings converted from legacy encodings. NFKC is the preferred form for
        identifiers, especially where there are security concerns. NFD and NFKD
        are the most useful for internal processing.
    )
    $(SECTION Construction of lookup tables
    )
    $(P The Unicode standard describes a set of algorithms that
        depend on having the ability to quickly look up various properties
        of a code point. Given the the codespace of about 1 million $(CODEPOINTS),
        it is not a trivial task to provide a space-efficient solution for
        the multitude of properties.
    )
    $(P Common approaches such as hash-tables or binary search over
        sorted code point intervals (as in $(LREF InversionList)) are insufficient.
        Hash-tables have enormous memory footprint and binary search
        over intervals is not fast enough for some heavy-duty algorithms.
    )
    $(P The recommended solution (see Unicode Implementation Guidelines)
        is using multi-stage tables that are an implementation of the
        $(HTTP en.wikipedia.org/wiki/Trie, Trie) data structure with integer
        keys and a fixed number of stages. For the remainder of the section
        this will be called a fixed trie. The following describes a particular
        implementation that is aimed for the speed of access at the expense
        of ideal size savings.
    )
    $(P Taking a 2-level Trie as an example the principle of operation is as follows.
        Split the number of bits in a key (code point, 21 bits) into 2 components
        (e.g. 15 and 8).  The first is the number of bits in the index of the trie
         and the other is number of bits in each page of the trie.
        The layout of the trie is then an array of size 2^^bits-of-index followed
        an array of memory chunks of size 2^^bits-of-page/bits-per-element.
    )
    $(P The number of pages is variable (but not less then 1)
        unlike the number of entries in the index. The slots of the index
        all have to contain a number of a page that is present. The lookup is then
        just a couple of operations - slice the upper bits,
        lookup an index for these, take a page at this index and use
        the lower bits as an offset within this page.

        Assuming that pages are laid out consequently
        in one array at $(D pages), the pseudo-code is:
    )
    ---
    auto elemsPerPage = (2 ^^ bits_per_page) / Value.sizeOfInBits;
    pages[index[n >> bits_per_page]][n & (elemsPerPage - 1)];
    ---
    $(P Where if $(D elemsPerPage) is a power of 2 the whole process is
        a handful of simple instructions and 2 array reads. Subsequent levels
        of the trie are introduced by recursing on this notion - the index array
        is treated as values. The number of bits in index is then again
        split into 2 parts, with pages over 'current-index' and the new 'upper-index'.
    )

    $(P For completeness a level 1 trie is simply an array.
        The current implementation takes advantage of bit-packing values
        when the range is known to be limited in advance (such as $(D bool)).
        See also $(LREF BitPacked) for enforcing it manually.
        The major size advantage however comes from the fact
        that multiple $(B identical pages on every level are merged) by construction.
    )
    $(P The process of constructing a trie is more involved and is hidden from
        the user in a form of the convenience functions $(LREF codepointTrie),
        $(LREF codepointSetTrie) and the even more convenient $(LREF toTrie).
        In general a set or built-in AA with $(D dchar) type
        can be turned into a trie. The trie object in this module
        is read-only (immutable); it's effectively frozen after construction.
    )
    $(SECTION Unicode properties
    )
    $(P This is a full list of Unicode properties accessible through $(LREF unicode)
        with specific helpers per category nested within. Consult the
        $(HTTP www.unicode.org/cldr/utility/properties.jsp, CLDR utility)
        when in doubt about the contents of a particular set.
    )
    $(P General category sets listed below are only accessible with the
        $(LREF unicode) shorthand accessor.)
        $(BOOKTABLE $(B General category ),
             $(TR $(TH Abb.) $(TH Long form)
                $(TH Abb.) $(TH Long form)$(TH Abb.) $(TH Long form))
            $(TR $(TD L) $(TD Letter)
                $(TD Cn) $(TD Unassigned)  $(TD Po) $(TD Other_Punctuation))
            $(TR $(TD Ll) $(TD Lowercase_Letter)
                $(TD Co) $(TD Private_Use) $(TD Ps) $(TD Open_Punctuation))
            $(TR $(TD Lm) $(TD Modifier_Letter)
                $(TD Cs) $(TD Surrogate)   $(TD S) $(TD Symbol))
            $(TR $(TD Lo) $(TD Other_Letter)
                $(TD N) $(TD Number)  $(TD Sc) $(TD Currency_Symbol))
            $(TR $(TD Lt) $(TD Titlecase_Letter)
              $(TD Nd) $(TD Decimal_Number)  $(TD Sk) $(TD Modifier_Symbol))
            $(TR $(TD Lu) $(TD Uppercase_Letter)
              $(TD Nl) $(TD Letter_Number)   $(TD Sm) $(TD Math_Symbol))
            $(TR $(TD M) $(TD Mark)
              $(TD No) $(TD Other_Number)    $(TD So) $(TD Other_Symbol))
            $(TR $(TD Mc) $(TD Spacing_Mark)
              $(TD P) $(TD Punctuation) $(TD Z) $(TD Separator))
            $(TR $(TD Me) $(TD Enclosing_Mark)
              $(TD Pc) $(TD Connector_Punctuation)   $(TD Zl) $(TD Line_Separator))
            $(TR $(TD Mn) $(TD Nonspacing_Mark)
              $(TD Pd) $(TD Dash_Punctuation)    $(TD Zp) $(TD Paragraph_Separator))
            $(TR $(TD C) $(TD Other)
              $(TD Pe) $(TD Close_Punctuation) $(TD Zs) $(TD Space_Separator))
            $(TR $(TD Cc) $(TD Control) $(TD Pf)
              $(TD Final_Punctuation)   $(TD -) $(TD Any))
            $(TR $(TD Cf) $(TD Format)
              $(TD Pi) $(TD Initial_Punctuation) $(TD -) $(TD ASCII))
    )
    $(P Sets for other commonly useful properties that are
        accessible with $(LREF unicode):)
        $(BOOKTABLE $(B Common binary properties),
            $(TR $(TH Name) $(TH Name) $(TH Name))
            $(TR $(TD Alphabetic)  $(TD Ideographic) $(TD Other_Uppercase))
            $(TR $(TD ASCII_Hex_Digit) $(TD IDS_Binary_Operator) $(TD Pattern_Syntax))
            $(TR $(TD Bidi_Control)    $(TD ID_Start)    $(TD Pattern_White_Space))
            $(TR $(TD Cased)   $(TD IDS_Trinary_Operator)    $(TD Quotation_Mark))
            $(TR $(TD Case_Ignorable)  $(TD Join_Control)    $(TD Radical))
            $(TR $(TD Dash)    $(TD Logical_Order_Exception) $(TD Soft_Dotted))
            $(TR $(TD Default_Ignorable_Code_Point)    $(TD Lowercase)   $(TD STerm))
            $(TR $(TD Deprecated)  $(TD Math)    $(TD Terminal_Punctuation))
            $(TR $(TD Diacritic)   $(TD Noncharacter_Code_Point) $(TD Unified_Ideograph))
            $(TR $(TD Extender)    $(TD Other_Alphabetic)    $(TD Uppercase))
            $(TR $(TD Grapheme_Base)   $(TD Other_Default_Ignorable_Code_Point)  $(TD Variation_Selector))
            $(TR $(TD Grapheme_Extend) $(TD Other_Grapheme_Extend)   $(TD White_Space))
            $(TR $(TD Grapheme_Link)   $(TD Other_ID_Continue)   $(TD XID_Continue))
            $(TR $(TD Hex_Digit)   $(TD Other_ID_Start)  $(TD XID_Start))
            $(TR $(TD Hyphen)  $(TD Other_Lowercase) )
            $(TR $(TD ID_Continue) $(TD Other_Math)  )
    )
    $(P Below is the table with block names accepted by $(LREF unicode.block).
        Note that the shorthand version $(LREF unicode) requires "In"
        to be prepended to the names of blocks so as to disambiguate
        scripts and blocks.
    )
    $(BOOKTABLE $(B Blocks),
        $(TR $(TD Aegean Numbers)    $(TD Ethiopic Extended) $(TD Mongolian))
        $(TR $(TD Alchemical Symbols)    $(TD Ethiopic Extended-A)   $(TD Musical Symbols))
        $(TR $(TD Alphabetic Presentation Forms) $(TD Ethiopic Supplement)   $(TD Myanmar))
        $(TR $(TD Ancient Greek Musical Notation)    $(TD General Punctuation)   $(TD Myanmar Extended-A))
        $(TR $(TD Ancient Greek Numbers) $(TD Geometric Shapes)  $(TD New Tai Lue))
        $(TR $(TD Ancient Symbols)   $(TD Georgian)  $(TD NKo))
        $(TR $(TD Arabic)    $(TD Georgian Supplement)   $(TD Number Forms))
        $(TR $(TD Arabic Extended-A) $(TD Glagolitic)    $(TD Ogham))
        $(TR $(TD Arabic Mathematical Alphabetic Symbols)    $(TD Gothic)    $(TD Ol Chiki))
        $(TR $(TD Arabic Presentation Forms-A)   $(TD Greek and Coptic)  $(TD Old Italic))
        $(TR $(TD Arabic Presentation Forms-B)   $(TD Greek Extended)    $(TD Old Persian))
        $(TR $(TD Arabic Supplement) $(TD Gujarati)  $(TD Old South Arabian))
        $(TR $(TD Armenian)  $(TD Gurmukhi)  $(TD Old Turkic))
        $(TR $(TD Arrows)    $(TD Halfwidth and Fullwidth Forms) $(TD Optical Character Recognition))
        $(TR $(TD Avestan)   $(TD Hangul Compatibility Jamo) $(TD Oriya))
        $(TR $(TD Balinese)  $(TD Hangul Jamo)   $(TD Osmanya))
        $(TR $(TD Bamum) $(TD Hangul Jamo Extended-A)    $(TD Phags-pa))
        $(TR $(TD Bamum Supplement)  $(TD Hangul Jamo Extended-B)    $(TD Phaistos Disc))
        $(TR $(TD Basic Latin)   $(TD Hangul Syllables)  $(TD Phoenician))
        $(TR $(TD Batak) $(TD Hanunoo)   $(TD Phonetic Extensions))
        $(TR $(TD Bengali)   $(TD Hebrew)    $(TD Phonetic Extensions Supplement))
        $(TR $(TD Block Elements)    $(TD High Private Use Surrogates)   $(TD Playing Cards))
        $(TR $(TD Bopomofo)  $(TD High Surrogates)   $(TD Private Use Area))
        $(TR $(TD Bopomofo Extended) $(TD Hiragana)  $(TD Rejang))
        $(TR $(TD Box Drawing)   $(TD Ideographic Description Characters)    $(TD Rumi Numeral Symbols))
        $(TR $(TD Brahmi)    $(TD Imperial Aramaic)  $(TD Runic))
        $(TR $(TD Braille Patterns)  $(TD Inscriptional Pahlavi) $(TD Samaritan))
        $(TR $(TD Buginese)  $(TD Inscriptional Parthian)    $(TD Saurashtra))
        $(TR $(TD Buhid) $(TD IPA Extensions)    $(TD Sharada))
        $(TR $(TD Byzantine Musical Symbols) $(TD Javanese)  $(TD Shavian))
        $(TR $(TD Carian)    $(TD Kaithi)    $(TD Sinhala))
        $(TR $(TD Chakma)    $(TD Kana Supplement)   $(TD Small Form Variants))
        $(TR $(TD Cham)  $(TD Kanbun)    $(TD Sora Sompeng))
        $(TR $(TD Cherokee)  $(TD Kangxi Radicals)   $(TD Spacing Modifier Letters))
        $(TR $(TD CJK Compatibility) $(TD Kannada)   $(TD Specials))
        $(TR $(TD CJK Compatibility Forms)   $(TD Katakana)  $(TD Sundanese))
        $(TR $(TD CJK Compatibility Ideographs)  $(TD Katakana Phonetic Extensions)  $(TD Sundanese Supplement))
        $(TR $(TD CJK Compatibility Ideographs Supplement)   $(TD Kayah Li)  $(TD Superscripts and Subscripts))
        $(TR $(TD CJK Radicals Supplement)   $(TD Kharoshthi)    $(TD Supplemental Arrows-A))
        $(TR $(TD CJK Strokes)   $(TD Khmer) $(TD Supplemental Arrows-B))
        $(TR $(TD CJK Symbols and Punctuation)   $(TD Khmer Symbols) $(TD Supplemental Mathematical Operators))
        $(TR $(TD CJK Unified Ideographs)    $(TD Lao)   $(TD Supplemental Punctuation))
        $(TR $(TD CJK Unified Ideographs Extension A)    $(TD Latin-1 Supplement)    $(TD Supplementary Private Use Area-A))
        $(TR $(TD CJK Unified Ideographs Extension B)    $(TD Latin Extended-A)  $(TD Supplementary Private Use Area-B))
        $(TR $(TD CJK Unified Ideographs Extension C)    $(TD Latin Extended Additional) $(TD Syloti Nagri))
        $(TR $(TD CJK Unified Ideographs Extension D)    $(TD Latin Extended-B)  $(TD Syriac))
        $(TR $(TD Combining Diacritical Marks)   $(TD Latin Extended-C)  $(TD Tagalog))
        $(TR $(TD Combining Diacritical Marks for Symbols)   $(TD Latin Extended-D)  $(TD Tagbanwa))
        $(TR $(TD Combining Diacritical Marks Supplement)    $(TD Lepcha)    $(TD Tags))
        $(TR $(TD Combining Half Marks)  $(TD Letterlike Symbols)    $(TD Tai Le))
        $(TR $(TD Common Indic Number Forms) $(TD Limbu) $(TD Tai Tham))
        $(TR $(TD Control Pictures)  $(TD Linear B Ideograms)    $(TD Tai Viet))
        $(TR $(TD Coptic)    $(TD Linear B Syllabary)    $(TD Tai Xuan Jing Symbols))
        $(TR $(TD Counting Rod Numerals) $(TD Lisu)  $(TD Takri))
        $(TR $(TD Cuneiform) $(TD Low Surrogates)    $(TD Tamil))
        $(TR $(TD Cuneiform Numbers and Punctuation) $(TD Lycian)    $(TD Telugu))
        $(TR $(TD Currency Symbols)  $(TD Lydian)    $(TD Thaana))
        $(TR $(TD Cypriot Syllabary) $(TD Mahjong Tiles) $(TD Thai))
        $(TR $(TD Cyrillic)  $(TD Malayalam) $(TD Tibetan))
        $(TR $(TD Cyrillic Extended-A)   $(TD Mandaic)   $(TD Tifinagh))
        $(TR $(TD Cyrillic Extended-B)   $(TD Mathematical Alphanumeric Symbols) $(TD Transport And Map Symbols))
        $(TR $(TD Cyrillic Supplement)   $(TD Mathematical Operators)    $(TD Ugaritic))
        $(TR $(TD Deseret)   $(TD Meetei Mayek)  $(TD Unified Canadian Aboriginal Syllabics))
        $(TR $(TD Devanagari)    $(TD Meetei Mayek Extensions)   $(TD Unified Canadian Aboriginal Syllabics Extended))
        $(TR $(TD Devanagari Extended)   $(TD Meroitic Cursive)  $(TD Vai))
        $(TR $(TD Dingbats)  $(TD Meroitic Hieroglyphs)  $(TD Variation Selectors))
        $(TR $(TD Domino Tiles)  $(TD Miao)  $(TD Variation Selectors Supplement))
        $(TR $(TD Egyptian Hieroglyphs)  $(TD Miscellaneous Mathematical Symbols-A)  $(TD Vedic Extensions))
        $(TR $(TD Emoticons) $(TD Miscellaneous Mathematical Symbols-B)  $(TD Vertical Forms))
        $(TR $(TD Enclosed Alphanumerics)    $(TD Miscellaneous Symbols) $(TD Yijing Hexagram Symbols))
        $(TR $(TD Enclosed Alphanumeric Supplement)  $(TD Miscellaneous Symbols and Arrows)  $(TD Yi Radicals))
        $(TR $(TD Enclosed CJK Letters and Months)   $(TD Miscellaneous Symbols And Pictographs) $(TD Yi Syllables))
        $(TR $(TD Enclosed Ideographic Supplement)   $(TD Miscellaneous Technical)   )
        $(TR $(TD Ethiopic)  $(TD Modifier Tone Letters) )
    )
    $(P Below is the table with script names accepted by $(LREF unicode.script)
        and by the shorthand version $(LREF unicode):)
        $(BOOKTABLE $(B Scripts),
            $(TR $(TD Arabic)  $(TD Hanunoo) $(TD Old_Italic))
            $(TR $(TD Armenian)    $(TD Hebrew)  $(TD Old_Persian))
            $(TR $(TD Avestan) $(TD Hiragana)    $(TD Old_South_Arabian))
            $(TR $(TD Balinese)    $(TD Imperial_Aramaic)    $(TD Old_Turkic))
            $(TR $(TD Bamum)   $(TD Inherited)   $(TD Oriya))
            $(TR $(TD Batak)   $(TD Inscriptional_Pahlavi)   $(TD Osmanya))
            $(TR $(TD Bengali) $(TD Inscriptional_Parthian)  $(TD Phags_Pa))
            $(TR $(TD Bopomofo)    $(TD Javanese)    $(TD Phoenician))
            $(TR $(TD Brahmi)  $(TD Kaithi)  $(TD Rejang))
            $(TR $(TD Braille) $(TD Kannada) $(TD Runic))
            $(TR $(TD Buginese)    $(TD Katakana)    $(TD Samaritan))
            $(TR $(TD Buhid)   $(TD Kayah_Li)    $(TD Saurashtra))
            $(TR $(TD Canadian_Aboriginal) $(TD Kharoshthi)  $(TD Sharada))
            $(TR $(TD Carian)  $(TD Khmer)   $(TD Shavian))
            $(TR $(TD Chakma)  $(TD Lao) $(TD Sinhala))
            $(TR $(TD Cham)    $(TD Latin)   $(TD Sora_Sompeng))
            $(TR $(TD Cherokee)    $(TD Lepcha)  $(TD Sundanese))
            $(TR $(TD Common)  $(TD Limbu)   $(TD Syloti_Nagri))
            $(TR $(TD Coptic)  $(TD Linear_B)    $(TD Syriac))
            $(TR $(TD Cuneiform)   $(TD Lisu)    $(TD Tagalog))
            $(TR $(TD Cypriot) $(TD Lycian)  $(TD Tagbanwa))
            $(TR $(TD Cyrillic)    $(TD Lydian)  $(TD Tai_Le))
            $(TR $(TD Deseret) $(TD Malayalam)   $(TD Tai_Tham))
            $(TR $(TD Devanagari)  $(TD Mandaic) $(TD Tai_Viet))
            $(TR $(TD Egyptian_Hieroglyphs)    $(TD Meetei_Mayek)    $(TD Takri))
            $(TR $(TD Ethiopic)    $(TD Meroitic_Cursive)    $(TD Tamil))
            $(TR $(TD Georgian)    $(TD Meroitic_Hieroglyphs)    $(TD Telugu))
            $(TR $(TD Glagolitic)  $(TD Miao)    $(TD Thaana))
            $(TR $(TD Gothic)  $(TD Mongolian)   $(TD Thai))
            $(TR $(TD Greek)   $(TD Myanmar) $(TD Tibetan))
            $(TR $(TD Gujarati)    $(TD New_Tai_Lue) $(TD Tifinagh))
            $(TR $(TD Gurmukhi)    $(TD Nko) $(TD Ugaritic))
            $(TR $(TD Han) $(TD Ogham)   $(TD Vai))
            $(TR $(TD Hangul)  $(TD Ol_Chiki)    $(TD Yi))
    )
    $(P Below is the table of names accepted by $(LREF unicode.hangulSyllableType).)
        $(BOOKTABLE $(B Hangul syllable type),
            $(TR $(TH Abb.) $(TH Long form))
            $(TR $(TD L)   $(TD Leading_Jamo))
            $(TR $(TD LV)  $(TD LV_Syllable))
            $(TR $(TD LVT) $(TD LVT_Syllable) )
            $(TR $(TD T)   $(TD Trailing_Jamo))
            $(TR $(TD V)   $(TD Vowel_Jamo))
    )
    References:
        $(HTTP www.digitalmars.com/d/ascii-table.html, ASCII Table),
        $(HTTP en.wikipedia.org/wiki/Unicode, Wikipedia),
        $(HTTP www.unicode.org, The Unicode Consortium),
        $(HTTP www.unicode.org/reports/tr15/, Unicode normalization forms),
        $(HTTP www.unicode.org/reports/tr29/, Unicode text segmentation)
        $(HTTP www.unicode.org/uni2book/ch05.pdf,
            Unicode Implementation Guidelines)
        $(HTTP www.unicode.org/uni2book/ch03.pdf,
            Unicode Conformance)
    Trademarks:
        Unicode(tm) is a trademark of Unicode, Inc.

    Copyright: Copyright 2013 -
    License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
    Authors:   Dmitry Olshansky
    Source:    $(PHOBOSSRC std/_uni.d)
    Standards: $(HTTP www.unicode.org/versions/Unicode6.2.0/, Unicode v6.2)

Macros:

SECTION = <h3><a id="$1">$0</a></h3>
DEF = <div><a id="$1"><i>$0</i></a></div>
S_LINK = <a href="#$1">$+</a>
CODEPOINT = $(S_LINK Code point, code point)
CODEPOINTS = $(S_LINK Code point, code points)
CHARACTER = $(S_LINK Character, character)
CHARACTERS = $(S_LINK Character, characters)
CLUSTER = $(S_LINK Grapheme cluster, grapheme cluster)
+/
module std.uni;

import std.meta; // AliasSeq
import std.range.primitives; // back, ElementEncodingType, ElementType, empty,
    // front, isForwardRange, isInputRange, isRandomAccessRange, popFront, put,
    // save
import std.traits; // isConvertibleToString, isIntegral, isSomeChar,
    // isSomeString, Unqual
import std.exception;// : enforce;
import core.memory; //: pureMalloc, pureRealloc, pureFree;
import core.exception; // : onOutOfMemoryError;
static import std.ascii;
// debug = std_uni;

debug(std_uni) import std.stdio; // writefln, writeln

private:

version (unittest)
{
private:
    struct TestAliasedString
    {
        string get() @safe @nogc pure nothrow { return _s; }
        alias get this;
        @disable this(this);
        string _s;
    }

    bool testAliasedString(alias func, Args...)(string s, Args args)
    {
        import std.algorithm.comparison : equal;
        auto a = func(TestAliasedString(s), args);
        auto b = func(s, args);
        static if (is(typeof(equal(a, b))))
        {
            // For ranges, compare contents instead of object identity.
            return equal(a, b);
        }
        else
        {
            return a == b;
        }
    }
}

void copyBackwards(T,U)(T[] src, U[] dest)
{
    assert(src.length == dest.length);
    for (size_t i=src.length; i-- > 0; )
        dest[i] = src[i];
}

void copyForward(T,U)(T[] src, U[] dest)
{
    assert(src.length == dest.length);
    for (size_t i=0; i<src.length; i++)
        dest[i] = src[i];
}

// TODO: update to reflect all major CPUs supporting unaligned reads
version (X86)
    enum hasUnalignedReads = true;
else version (X86_64)
    enum hasUnalignedReads = true;
else version (SystemZ)
    enum hasUnalignedReads = true;
else
    enum hasUnalignedReads = false; // better be safe then sorry

public enum dchar lineSep = '\u2028'; /// Constant $(CODEPOINT) (0x2028) - line separator.
public enum dchar paraSep = '\u2029'; /// Constant $(CODEPOINT) (0x2029) - paragraph separator.
public enum dchar nelSep  = '\u0085'; /// Constant $(CODEPOINT) (0x0085) - next line.

// test the intro example
@safe unittest
{
    import std.algorithm.searching : find;
    // initialize code point sets using script/block or property name
    // set contains code points from both scripts.
    auto set = unicode("Cyrillic") | unicode("Armenian");
    // or simpler and statically-checked look
    auto ascii = unicode.ASCII;
    auto currency = unicode.Currency_Symbol;

    // easy set ops
    auto a = set & ascii;
    assert(a.empty); // as it has no intersection with ascii
    a = set | ascii;
    auto b = currency - a; // subtract all ASCII, Cyrillic and Armenian

    // some properties of code point sets
    assert(b.length > 45); // 46 items in Unicode 6.1, even more in 6.2
    // testing presence of a code point in a set
    // is just fine, it is O(logN)
    assert(!b['$']);
    assert(!b['\u058F']); // Armenian dram sign
    assert(b['¥']);

    // building fast lookup tables, these guarantee O(1) complexity
    // 1-level Trie lookup table essentially a huge bit-set ~262Kb
    auto oneTrie = toTrie!1(b);
    // 2-level far more compact but typically slightly slower
    auto twoTrie = toTrie!2(b);
    // 3-level even smaller, and a bit slower yet
    auto threeTrie = toTrie!3(b);
    assert(oneTrie['£']);
    assert(twoTrie['£']);
    assert(threeTrie['£']);

    // build the trie with the most sensible trie level
    // and bind it as a functor
    auto cyrillicOrArmenian = toDelegate(set);
    auto balance = find!(cyrillicOrArmenian)("Hello ընկեր!");
    assert(balance == "ընկեր!");
    // compatible with bool delegate(dchar)
    bool delegate(dchar) bindIt = cyrillicOrArmenian;

    // Normalization
    string s = "Plain ascii (and not only), is always normalized!";
    assert(s is normalize(s));// is the same string

    string nonS = "A\u0308ffin"; // A ligature
    auto nS = normalize(nonS); // to NFC, the W3C endorsed standard
    assert(nS == "Äffin");
    assert(nS != nonS);
    string composed = "Äffin";

    assert(normalize!NFD(composed) == "A\u0308ffin");
    // to NFKD, compatibility decomposition useful for fuzzy matching/searching
    assert(normalize!NFKD("2¹⁰") == "210");
}

enum lastDchar = 0x10FFFF;

auto force(T, F)(F from)
if (isIntegral!T && !is(T == F))
{
    assert(from <= T.max && from >= T.min);
    return cast(T) from;
}

auto force(T, F)(F from)
if (isBitPacked!T && !is(T == F))
{
    assert(from <= 2^^bitSizeOf!T-1);
    return T(cast(TypeOfBitPacked!T) from);
}

auto force(T, F)(F from)
if (is(T == F))
{
    return from;
}

// repeat X times the bit-pattern in val assuming it's length is 'bits'
size_t replicateBits(size_t times, size_t bits)(size_t val) @safe pure nothrow @nogc
{
    static if (times == 1)
        return val;
    else static if (bits == 1)
    {
        static if (times == size_t.sizeof*8)
            return val ? size_t.max : 0;
        else
            return val ? (1 << times)-1 : 0;
    }
    else static if (times % 2)
        return (replicateBits!(times-1, bits)(val)<<bits) | val;
    else
        return replicateBits!(times/2, bits*2)((val << bits) | val);
}

@safe pure nothrow @nogc unittest // for replicate
{
    import std.algorithm.iteration : sum, map;
    import std.range : iota;
    size_t m = 0b111;
    size_t m2 = 0b01;
    foreach (i; AliasSeq!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
    {
        assert(replicateBits!(i, 3)(m)+1 == (1<<(3*i)));
        assert(replicateBits!(i, 2)(m2) == iota(0, i).map!"2^^(2*a)"().sum());
    }
}

// multiple arrays squashed into one memory block
struct MultiArray(Types...)
{
    import std.range.primitives : isOutputRange;
    this(size_t[] sizes...) @safe pure nothrow
    {
        assert(dim == sizes.length);
        size_t full_size;
        foreach (i, v; Types)
        {
            full_size += spaceFor!(bitSizeOf!v)(sizes[i]);
            sz[i] = sizes[i];
            static if (i >= 1)
                offsets[i] = offsets[i-1] +
                    spaceFor!(bitSizeOf!(Types[i-1]))(sizes[i-1]);
        }

        storage = new size_t[full_size];
    }

    this(const(size_t)[] raw_offsets,
        const(size_t)[] raw_sizes, const(size_t)[] data)const @safe pure nothrow @nogc
    {
        offsets[] = raw_offsets[];
        sz[] = raw_sizes[];
        storage = data;
    }

    @property auto slice(size_t n)()inout pure nothrow @nogc
    {
        auto ptr = raw_ptr!n;
        return packedArrayView!(Types[n])(ptr, sz[n]);
    }

    @property auto ptr(size_t n)()inout pure nothrow @nogc
    {
        auto ptr = raw_ptr!n;
        return inout(PackedPtr!(Types[n]))(ptr);
    }

    template length(size_t n)
    {
        @property size_t length()const @safe pure nothrow @nogc{ return sz[n]; }

        @property void length(size_t new_size)
        {
            if (new_size > sz[n])
            {// extend
                size_t delta = (new_size - sz[n]);
                sz[n] += delta;
                delta = spaceFor!(bitSizeOf!(Types[n]))(delta);
                storage.length +=  delta;// extend space at end
                // raw_slice!x must follow resize as it could be moved!
                // next stmts move all data past this array, last-one-goes-first
                static if (n != dim-1)
                {
                    auto start = raw_ptr!(n+1);
                    // len includes delta
                    size_t len = (storage.ptr+storage.length-start);

                    copyBackwards(start[0 .. len-delta], start[delta .. len]);

                    start[0 .. delta] = 0;
                    // offsets are used for raw_slice, ptr etc.
                    foreach (i; n+1 .. dim)
                        offsets[i] += delta;
                }
            }
            else if (new_size < sz[n])
            {// shrink
                size_t delta = (sz[n] - new_size);
                sz[n] -= delta;
                delta = spaceFor!(bitSizeOf!(Types[n]))(delta);
                // move all data past this array, forward direction
                static if (n != dim-1)
                {
                    auto start = raw_ptr!(n+1);
                    size_t len = (storage.ptr+storage.length-start);
                    copyForward(start[0 .. len-delta], start[delta .. len]);

                    // adjust offsets last, they affect raw_slice
                    foreach (i; n+1 .. dim)
                        offsets[i] -= delta;
                }
                storage.length -= delta;
            }
            // else - NOP
        }
    }

    @property size_t bytes(size_t n=size_t.max)() const @safe
    {
        static if (n == size_t.max)
            return storage.length*size_t.sizeof;
        else static if (n != Types.length-1)
            return (raw_ptr!(n+1)-raw_ptr!n)*size_t.sizeof;
        else
            return (storage.ptr+storage.length - raw_ptr!n)*size_t.sizeof;
    }

    void store(OutRange)(scope OutRange sink) const
        if (isOutputRange!(OutRange, char))
    {
        import std.format : formattedWrite;
        formattedWrite(sink, "[%( 0x%x, %)]", offsets[]);
        formattedWrite(sink, ", [%( 0x%x, %)]", sz[]);
        formattedWrite(sink, ", [%( 0x%x, %)]", storage);
    }

private:
    import std.meta : staticMap;
    @property auto raw_ptr(size_t n)()inout pure nothrow @nogc
    {
        static if (n == 0)
            return storage.ptr;
        else
        {
            return storage.ptr+offsets[n];
        }
    }
    enum dim = Types.length;
    size_t[dim] offsets;// offset for level x
    size_t[dim] sz;// size of level x
    alias bitWidth = staticMap!(bitSizeOf, Types);
    size_t[] storage;
}

@system unittest
{
    import std.conv : text;
    enum dg = (){
        // sizes are:
        // lvl0: 3, lvl1 : 2, lvl2: 1
        auto m = MultiArray!(int, ubyte, int)(3,2,1);

        static void check(size_t k, T)(ref T m, int n)
        {
            foreach (i; 0 .. n)
                assert(m.slice!(k)[i] == i+1, text("level:",i," : ",m.slice!(k)[0 .. n]));
        }

        static void checkB(size_t k, T)(ref T m, int n)
        {
            foreach (i; 0 .. n)
                assert(m.slice!(k)[i] == n-i, text("level:",i," : ",m.slice!(k)[0 .. n]));
        }

        static void fill(size_t k, T)(ref T m, int n)
        {
            foreach (i; 0 .. n)
                m.slice!(k)[i] = force!ubyte(i+1);
        }

        static void fillB(size_t k, T)(ref T m, int n)
        {
            foreach (i; 0 .. n)
                m.slice!(k)[i] = force!ubyte(n-i);
        }

        m.length!1 = 100;
        fill!1(m, 100);
        check!1(m, 100);

        m.length!0 = 220;
        fill!0(m, 220);
        check!1(m, 100);
        check!0(m, 220);

        m.length!2 = 17;
        fillB!2(m, 17);
        checkB!2(m, 17);
        check!0(m, 220);
        check!1(m, 100);

        m.length!2 = 33;
        checkB!2(m, 17);
        fillB!2(m, 33);
        checkB!2(m, 33);
        check!0(m, 220);
        check!1(m, 100);

        m.length!1 = 195;
        fillB!1(m, 195);
        checkB!1(m, 195);
        checkB!2(m, 33);
        check!0(m, 220);

        auto marr = MultiArray!(BitPacked!(uint, 4), BitPacked!(uint, 6))(20, 10);
        marr.length!0 = 15;
        marr.length!1 = 30;
        fill!1(marr, 30);
        fill!0(marr, 15);
        check!1(marr, 30);
        check!0(marr, 15);
        return 0;
    };
    enum ct = dg();
    auto rt = dg();
}

@system unittest
{// more bitpacking tests
    import std.conv : text;

    alias Bitty =
      MultiArray!(BitPacked!(size_t, 3)
                , BitPacked!(size_t, 4)
                , BitPacked!(size_t, 3)
                , BitPacked!(size_t, 6)
                , bool);
    alias fn1 = sliceBits!(13, 16);
    alias fn2 = sliceBits!( 9, 13);
    alias fn3 = sliceBits!( 6,  9);
    alias fn4 = sliceBits!( 0,  6);
    static void check(size_t lvl, MA)(ref MA arr){
        for (size_t i = 0; i< arr.length!lvl; i++)
            assert(arr.slice!(lvl)[i] == i, text("Mismatch on lvl ", lvl, " idx ", i, " value: ", arr.slice!(lvl)[i]));
    }

    static void fillIdx(size_t lvl, MA)(ref MA arr){
        for (size_t i = 0; i< arr.length!lvl; i++)
            arr.slice!(lvl)[i] = i;
    }
    Bitty m1;

    m1.length!4 = 10;
    m1.length!3 = 2^^6;
    m1.length!2 = 2^^3;
    m1.length!1 = 2^^4;
    m1.length!0 = 2^^3;

    m1.length!4 = 2^^16;

    for (size_t i = 0; i< m1.length!4; i++)
        m1.slice!(4)[i] = i % 2;

    fillIdx!1(m1);
    check!1(m1);
    fillIdx!2(m1);
    check!2(m1);
    fillIdx!3(m1);
    check!3(m1);
    fillIdx!0(m1);
    check!0(m1);
    check!3(m1);
    check!2(m1);
    check!1(m1);
    for (size_t i=0; i < 2^^16; i++)
    {
        m1.slice!(4)[i] = i % 2;
        m1.slice!(0)[fn1(i)] = fn1(i);
        m1.slice!(1)[fn2(i)] = fn2(i);
        m1.slice!(2)[fn3(i)] = fn3(i);
        m1.slice!(3)[fn4(i)] = fn4(i);
    }
    for (size_t i=0; i < 2^^16; i++)
    {
        assert(m1.slice!(4)[i] == i % 2);
        assert(m1.slice!(0)[fn1(i)] == fn1(i));
        assert(m1.slice!(1)[fn2(i)] == fn2(i));
        assert(m1.slice!(2)[fn3(i)] == fn3(i));
        assert(m1.slice!(3)[fn4(i)] == fn4(i));
    }
}

size_t spaceFor(size_t _bits)(size_t new_len) @safe pure nothrow @nogc
{
    import std.math : nextPow2;
    enum bits = _bits == 1 ? 1 : nextPow2(_bits - 1);// see PackedArrayView
    static if (bits > 8*size_t.sizeof)
    {
        static assert(bits % (size_t.sizeof*8) == 0);
        return new_len * bits/(8*size_t.sizeof);
    }
    else
    {
        enum factor = size_t.sizeof*8/bits;
        return (new_len+factor-1)/factor; // rounded up
    }
}

template isBitPackableType(T)
{
    enum isBitPackableType = isBitPacked!T
        || isIntegral!T || is(T == bool) || isSomeChar!T;
}

//============================================================================
template PackedArrayView(T)
if ((is(T dummy == BitPacked!(U, sz), U, size_t sz)
    && isBitPackableType!U) || isBitPackableType!T)
{
    import std.math : nextPow2;
    private enum bits = bitSizeOf!T;
    alias PackedArrayView = PackedArrayViewImpl!(T, bits > 1 ? nextPow2(bits - 1) : 1);
}

//unsafe and fast access to a chunk of RAM as if it contains packed values
template PackedPtr(T)
if ((is(T dummy == BitPacked!(U, sz), U, size_t sz)
    && isBitPackableType!U) || isBitPackableType!T)
{
    import std.math : nextPow2;
    private enum bits = bitSizeOf!T;
    alias PackedPtr = PackedPtrImpl!(T, bits > 1 ? nextPow2(bits - 1) : 1);
}

struct PackedPtrImpl(T, size_t bits)
{
pure nothrow:
    static assert(isPow2OrZero(bits));

    this(inout(size_t)* ptr)inout @safe @nogc
    {
        origin = ptr;
    }

    private T simpleIndex(size_t n) inout
    {
        immutable q = n / factor;
        immutable r = n % factor;
        return cast(T)((origin[q] >> bits*r) & mask);
    }

    private void simpleWrite(TypeOfBitPacked!T val, size_t n)
    in
    {
        static if (isIntegral!T)
            assert(val <= mask);
    }
    body
    {
        immutable q = n / factor;
        immutable r = n % factor;
        immutable tgt_shift = bits*r;
        immutable word = origin[q];
        origin[q] = (word & ~(mask << tgt_shift))
            | (cast(size_t) val << tgt_shift);
    }

    static if (factor == bytesPerWord// can safely pack by byte
         || factor == 1 // a whole word at a time
         || ((factor == bytesPerWord/2 || factor == bytesPerWord/4)
                && hasUnalignedReads)) // this needs unaligned reads
    {
        static if (factor == bytesPerWord)
            alias U = ubyte;
        else static if (factor == bytesPerWord/2)
            alias U = ushort;
        else static if (factor == bytesPerWord/4)
            alias U = uint;
        else static if (size_t.sizeof == 8 && factor == bytesPerWord/8)
            alias U = ulong;

        T opIndex(size_t idx) inout
        {
            T ret;
            version (LittleEndian)
                ret = __ctfe ? simpleIndex(idx) :
                    cast(inout(T))(cast(U*) origin)[idx];
            else
                ret = simpleIndex(idx);
            return ret;
        }

        static if (isBitPacked!T) // lack of user-defined implicit conversion
        {
            void opIndexAssign(T val, size_t idx)
            {
                return opIndexAssign(cast(TypeOfBitPacked!T) val, idx);
            }
        }

        void opIndexAssign(TypeOfBitPacked!T val, size_t idx)
        {
            version (LittleEndian)
            {
                if (__ctfe)
                    simpleWrite(val, idx);
                else
                    (cast(U*) origin)[idx] = cast(U) val;
            }
            else
                simpleWrite(val, idx);
        }
    }
    else
    {
        T opIndex(size_t n) inout
        {
            return simpleIndex(n);
        }

        static if (isBitPacked!T) // lack of user-defined implicit conversion
        {
            void opIndexAssign(T val, size_t idx)
            {
                return opIndexAssign(cast(TypeOfBitPacked!T) val, idx);
            }
        }

        void opIndexAssign(TypeOfBitPacked!T val, size_t n)
        {
            return simpleWrite(val, n);
        }
    }

private:
    // factor - number of elements in one machine word
    enum factor = size_t.sizeof*8/bits, mask = 2^^bits-1;
    enum bytesPerWord =  size_t.sizeof;
    size_t* origin;
}

// data is packed only by power of two sized packs per word,
// thus avoiding mul/div overhead at the cost of ultimate packing
// this construct doesn't own memory, only provides access, see MultiArray for usage
struct PackedArrayViewImpl(T, size_t bits)
{
pure nothrow:

    this(inout(size_t)* origin, size_t offset, size_t items) inout @safe
    {
        ptr = inout(PackedPtr!(T))(origin);
        ofs = offset;
        limit = items;
    }

    bool zeros(size_t s, size_t e)
    in
    {
        assert(s <= e);
    }
    body
    {
        s += ofs;
        e += ofs;
        immutable pad_s = roundUp(s);
        if ( s >= e)
        {
            foreach (i; s .. e)
                if (ptr[i])
                    return false;
            return true;
        }
        immutable pad_e = roundDown(e);
        size_t i;
        for (i=s; i<pad_s; i++)
            if (ptr[i])
                return false;
        // all in between is x*factor elements
        for (size_t j=i/factor; i<pad_e; i+=factor, j++)
            if (ptr.origin[j])
                return false;
        for (; i<e; i++)
            if (ptr[i])
                return false;
        return true;
    }

    T opIndex(size_t idx) inout
    in
    {
        assert(idx < limit);
    }
    body
    {
        return ptr[ofs + idx];
    }

    static if (isBitPacked!T) // lack of user-defined implicit conversion
    {
        void opIndexAssign(T val, size_t idx)
        {
            return opIndexAssign(cast(TypeOfBitPacked!T) val, idx);
        }
    }

    void opIndexAssign(TypeOfBitPacked!T val, size_t idx)
    in
    {
        assert(idx < limit);
    }
    body
    {
        ptr[ofs + idx] = val;
    }

    static if (isBitPacked!T) // lack of user-defined implicit conversions
    {
        void opSliceAssign(T val, size_t start, size_t end)
        {
            opSliceAssign(cast(TypeOfBitPacked!T) val, start, end);
        }
    }

    void opSliceAssign(TypeOfBitPacked!T val, size_t start, size_t end)
    in
    {
        assert(start <= end);
        assert(end <= limit);
    }
    body
    {
        // account for ofsetted view
        start += ofs;
        end += ofs;
        // rounded to factor granularity
        immutable pad_start = roundUp(start);// rounded up
        if (pad_start >= end) //rounded up >= then end of slice
        {
            //nothing to gain, use per element assignment
            foreach (i; start .. end)
                ptr[i] = val;
            return;
        }
        immutable pad_end = roundDown(end); // rounded down
        size_t i;
        for (i=start; i<pad_start; i++)
            ptr[i] = val;
        // all in between is x*factor elements
        if (pad_start != pad_end)
        {
            immutable repval = replicateBits!(factor, bits)(val);
            for (size_t j=i/factor; i<pad_end; i+=factor, j++)
                ptr.origin[j] = repval;// so speed it up by factor
        }
        for (; i<end; i++)
            ptr[i] = val;
    }

    auto opSlice(size_t from, size_t to)inout
    in
    {
        assert(from <= to);
        assert(ofs + to <= limit);
    }
    body
    {
        return typeof(this)(ptr.origin, ofs + from, to - from);
    }

    auto opSlice(){ return opSlice(0, length); }

    bool opEquals(T)(auto ref T arr) const
    {
        if (limit != arr.limit)
           return false;
        size_t s1 = ofs, s2 = arr.ofs;
        size_t e1 = s1 + limit, e2 = s2 + limit;
        if (s1 % factor == 0 && s2 % factor == 0 && length % factor == 0)
        {
            return ptr.origin[s1/factor .. e1/factor]
                == arr.ptr.origin[s2/factor .. e2/factor];
        }
        for (size_t i=0;i<limit; i++)
            if (this[i] != arr[i])
                return false;
        return true;
    }

    @property size_t length()const{ return limit; }

private:
    auto roundUp()(size_t val){ return (val+factor-1)/factor*factor; }
    auto roundDown()(size_t val){ return val/factor*factor; }
    // factor - number of elements in one machine word
    enum factor = size_t.sizeof*8/bits;
    PackedPtr!(T) ptr;
    size_t ofs, limit;
}


private struct SliceOverIndexed(T)
{
    enum assignableIndex = is(typeof((){ T.init[0] = Item.init; }));
    enum assignableSlice = is(typeof((){ T.init[0 .. 0] = Item.init; }));
    auto opIndex(size_t idx)const
    in
    {
        assert(idx < to - from);
    }
    body
    {
        return (*arr)[from+idx];
    }

    static if (assignableIndex)
    void opIndexAssign(Item val, size_t idx)
    in
    {
        assert(idx < to - from);
    }
    body
    {
       (*arr)[from+idx] = val;
    }

    auto opSlice(size_t a, size_t b)
    {
        return typeof(this)(from+a, from+b, arr);
    }

    // static if (assignableSlice)
    void opSliceAssign(T)(T val, size_t start, size_t end)
    {
        (*arr)[start+from .. end+from] = val;
    }

    auto opSlice()
    {
        return typeof(this)(from, to, arr);
    }

    @property size_t length()const { return to-from;}

    auto opDollar()const { return length; }

    @property bool empty()const { return from == to; }

    @property auto front()const { return (*arr)[from]; }

    static if (assignableIndex)
    @property void front(Item val) { (*arr)[from] = val; }

    @property auto back()const { return (*arr)[to-1]; }

    static if (assignableIndex)
    @property void back(Item val) { (*arr)[to-1] = val; }

    @property auto save() inout { return this; }

    void popFront() {   from++; }

    void popBack() {    to--; }

    bool opEquals(T)(auto ref T arr) const
    {
        if (arr.length != length)
            return false;
        for (size_t i=0; i <length; i++)
            if (this[i] != arr[i])
                return false;
        return true;
    }
private:
    alias Item = typeof(T.init[0]);
    size_t from, to;
    T* arr;
}

static assert(isRandomAccessRange!(SliceOverIndexed!(int[])));

SliceOverIndexed!(const(T)) sliceOverIndexed(T)(size_t a, size_t b, const(T)* x)
if (is(Unqual!T == T))
{
    return SliceOverIndexed!(const(T))(a, b, x);
}

// BUG? inout is out of reach
//...SliceOverIndexed.arr only parameters or stack based variables can be inout
SliceOverIndexed!T sliceOverIndexed(T)(size_t a, size_t b, T* x)
if (is(Unqual!T == T))
{
    return SliceOverIndexed!T(a, b, x);
}

@system unittest
{
    int[] idxArray = [2, 3, 5, 8, 13];
    auto sliced = sliceOverIndexed(0, idxArray.length, &idxArray);

    assert(!sliced.empty);
    assert(sliced.front == 2);
    sliced.front = 1;
    assert(sliced.front == 1);
    assert(sliced.back == 13);
    sliced.popFront();
    assert(sliced.front == 3);
    assert(sliced.back == 13);
    sliced.back = 11;
    assert(sliced.back == 11);
    sliced.popBack();

    assert(sliced.front == 3);
    assert(sliced[$-1] == 8);
    sliced = sliced[];
    assert(sliced[0] == 3);
    assert(sliced.back == 8);
    sliced = sliced[1..$];
    assert(sliced.front == 5);
    sliced = sliced[0..$-1];
    assert(sliced[$-1] == 5);

    int[] other = [2, 5];
    assert(sliced[] == sliceOverIndexed(1, 2, &other));
    sliceOverIndexed(0, 2, &idxArray)[0 .. 2] = -1;
    assert(idxArray[0 .. 2] == [-1, -1]);
    uint[] nullArr = null;
    auto nullSlice = sliceOverIndexed(0, 0, &idxArray);
    assert(nullSlice.empty);
}

private auto packedArrayView(T)(inout(size_t)* ptr, size_t items) @trusted pure nothrow
{
    return inout(PackedArrayView!T)(ptr, 0, items);
}


//============================================================================
// Partially unrolled binary search using Shar's method
//============================================================================

string genUnrolledSwitchSearch(size_t size) @safe pure nothrow
{
    import core.bitop : bsr;
    import std.array : replace;
    import std.conv : to;
    assert(isPow2OrZero(size));
    string code = `
    import core.bitop : bsr;
    auto power = bsr(m)+1;
    switch (power){`;
    size_t i = bsr(size);
    foreach_reverse (val; 0 .. bsr(size))
    {
        auto v = 2^^val;
        code ~= `
        case pow:
            if (pred(range[idx+m], needle))
                idx +=  m;
            goto case;
        `.replace("m", to!string(v))
        .replace("pow", to!string(i));
        i--;
    }
    code ~= `
        case 0:
            if (pred(range[idx], needle))
                idx += 1;
            goto default;
        `;
    code ~= `
        default:
    }`;
    return code;
}

bool isPow2OrZero(size_t sz) @safe pure nothrow @nogc
{
    // See also: std.math.isPowerOf2()
    return (sz & (sz-1)) == 0;
}

size_t uniformLowerBound(alias pred, Range, T)(Range range, T needle)
if (is(T : ElementType!Range))
{
    assert(isPow2OrZero(range.length));
    size_t idx = 0, m = range.length/2;
    while (m != 0)
    {
        if (pred(range[idx+m], needle))
            idx += m;
        m /= 2;
    }
    if (pred(range[idx], needle))
        idx += 1;
    return idx;
}

size_t switchUniformLowerBound(alias pred, Range, T)(Range range, T needle)
if (is(T : ElementType!Range))
{
    assert(isPow2OrZero(range.length));
    size_t idx = 0, m = range.length/2;
    enum max = 1 << 10;
    while (m >= max)
    {
        if (pred(range[idx+m], needle))
            idx += m;
        m /= 2;
    }
    mixin(genUnrolledSwitchSearch(max));
    return idx;
}

template sharMethod(alias uniLowerBound)
{
    size_t sharMethod(alias _pred="a<b", Range, T)(Range range, T needle)
        if (is(T : ElementType!Range))
    {
        import std.functional : binaryFun;
        import std.math : nextPow2, truncPow2;
        alias pred = binaryFun!_pred;
        if (range.length == 0)
            return 0;
        if (isPow2OrZero(range.length))
            return uniLowerBound!pred(range, needle);
        size_t n = truncPow2(range.length);
        if (pred(range[n-1], needle))
        {// search in another 2^^k area that fully covers the tail of range
            size_t k = nextPow2(range.length - n + 1);
            return range.length - k + uniLowerBound!pred(range[$-k..$], needle);
        }
        else
            return uniLowerBound!pred(range[0 .. n], needle);
    }
}

alias sharLowerBound = sharMethod!uniformLowerBound;
alias sharSwitchLowerBound = sharMethod!switchUniformLowerBound;

@safe unittest
{
    import std.array : array;
    import std.range : assumeSorted, iota;

    auto stdLowerBound(T)(T[] range, T needle)
    {
        return assumeSorted(range).lowerBound(needle).length;
    }
    immutable MAX = 5*1173;
    auto arr = array(iota(5, MAX, 5));
    assert(arr.length == MAX/5-1);
    foreach (i; 0 .. MAX+5)
    {
        auto st = stdLowerBound(arr, i);
        assert(st == sharLowerBound(arr, i));
        assert(st == sharSwitchLowerBound(arr, i));
    }
    arr = [];
    auto st = stdLowerBound(arr, 33);
    assert(st == sharLowerBound(arr, 33));
    assert(st == sharSwitchLowerBound(arr, 33));
}
//============================================================================

@safe
{
// hope to see simillar stuff in public interface... once Allocators are out
//@@@BUG moveFront and friends? dunno, for now it's POD-only

@trusted size_t genericReplace(Policy=void, T, Range)
    (ref T dest, size_t from, size_t to, Range stuff)
{
    import std.algorithm.mutation : copy;
    size_t delta = to - from;
    size_t stuff_end = from+stuff.length;
    if (stuff.length > delta)
    {// replace increases length
        delta = stuff.length - delta;// now, new is > old  by delta
        static if (is(Policy == void))
            dest.length = dest.length+delta;//@@@BUG lame @property
        else
            dest = Policy.realloc(dest, dest.length+delta);
        copyBackwards(dest[to .. dest.length-delta],
            dest[to+delta .. dest.length]);
        copyForward(stuff, dest[from .. stuff_end]);
    }
    else if (stuff.length == delta)
    {
        copy(stuff, dest[from .. to]);
    }
    else
    {// replace decreases length by delta
        delta = delta - stuff.length;
        copy(stuff, dest[from .. stuff_end]);
        copyForward(dest[to .. dest.length],
            dest[stuff_end .. dest.length-delta]);
        static if (is(Policy == void))
            dest.length = dest.length - delta;//@@@BUG lame @property
        else
            dest = Policy.realloc(dest, dest.length-delta);
    }
    return stuff_end;
}


// Simple storage manipulation policy
@trusted private struct GcPolicy
{
    import std.traits : isDynamicArray;

    static T[] dup(T)(const T[] arr)
    {
        return arr.dup;
    }

    static T[] alloc(T)(size_t size)
    {
        return new T[size];
    }

    static T[] realloc(T)(T[] arr, size_t sz)
    {
        arr.length = sz;
        return arr;
    }

    static void replaceImpl(T, Range)(ref T[] dest, size_t from, size_t to, Range stuff)
    {
        replaceInPlace(dest, from, to, stuff);
    }

    static void append(T, V)(ref T[] arr, V value)
        if (!isInputRange!V)
    {
        arr ~= force!T(value);
    }

    static void append(T, V)(ref T[] arr, V value)
        if (isInputRange!V)
    {
        insertInPlace(arr, arr.length, value);
    }

    static void destroy(T)(ref T arr)
        if (isDynamicArray!T && is(Unqual!T == T))
    {
        debug
        {
            arr[] = cast(typeof(T.init[0]))(0xdead_beef);
        }
        arr = null;
    }

    static void destroy(T)(ref T arr)
        if (isDynamicArray!T && !is(Unqual!T == T))
    {
        arr = null;
    }
}

// ditto
@trusted struct ReallocPolicy
{
    import std.range.primitives : hasLength;

    static T[] dup(T)(const T[] arr)
    {
        auto result = alloc!T(arr.length);
        result[] = arr[];
        return result;
    }

    static T[] alloc(T)(size_t size)
    {
        import core.stdc.stdlib : malloc;
        import std.exception : enforce;

        import core.checkedint : mulu;
        bool overflow;
        size_t nbytes = mulu(size, T.sizeof, overflow);
        if (overflow) assert(0);

        auto ptr = cast(T*) enforce(malloc(nbytes), "out of memory on C heap");
        return ptr[0 .. size];
    }

    static T[] realloc(T)(T[] arr, size_t size)
    {
        import core.stdc.stdlib : realloc;
        import std.exception : enforce;
        if (!size)
        {
            destroy(arr);
            return null;
        }

        import core.checkedint : mulu;
        bool overflow;
        size_t nbytes = mulu(size, T.sizeof, overflow);
        if (overflow) assert(0);

        auto ptr = cast(T*) enforce(realloc(arr.ptr, nbytes), "out of memory on C heap");
        return ptr[0 .. size];
    }

    static void replaceImpl(T, Range)(ref T[] dest, size_t from, size_t to, Range stuff)
    {
        genericReplace!(ReallocPolicy)(dest, from, to, stuff);
    }

    static void append(T, V)(ref T[] arr, V value)
        if (!isInputRange!V)
    {
        if (arr.length == size_t.max) assert(0);
        arr = realloc(arr, arr.length+1);
        arr[$-1] = force!T(value);
    }

    @safe unittest
    {
        int[] arr;
        ReallocPolicy.append(arr, 3);

        import std.algorithm.comparison : equal;
        assert(equal(arr, [3]));
    }

    static void append(T, V)(ref T[] arr, V value)
        if (isInputRange!V && hasLength!V)
    {
        import core.checkedint : addu;
        bool overflow;
        size_t nelems = addu(arr.length, value.length, overflow);
        if (overflow) assert(0);

        arr = realloc(arr, nelems);

        import std.algorithm.mutation : copy;
        copy(value, arr[$-value.length..$]);
    }

    @safe unittest
    {
        int[] arr;
        ReallocPolicy.append(arr, [1,2,3]);

        import std.algorithm.comparison : equal;
        assert(equal(arr, [1,2,3]));
    }

    static void destroy(T)(ref T[] arr)
    {
        import core.stdc.stdlib : free;
        if (arr.ptr)
            free(arr.ptr);
        arr = null;
    }
}

//build hack
alias _RealArray = CowArray!ReallocPolicy;

@safe unittest
{
    import std.algorithm.comparison : equal;

    with(ReallocPolicy)
    {
        bool test(T, U, V)(T orig, size_t from, size_t to, U toReplace, V result,
                   string file = __FILE__, size_t line = __LINE__)
        {
            {
                replaceImpl(orig, from, to, toReplace);
                scope(exit) destroy(orig);
                if (!equal(orig, result))
                    return false;
            }
            return true;
        }
        static T[] arr(T)(T[] args... )
        {
            return dup(args);
        }

        assert(test(arr([1, 2, 3, 4]), 0, 0, [5, 6, 7], [5, 6, 7, 1, 2, 3, 4]));
        assert(test(arr([1, 2, 3, 4]), 0, 2, cast(int[])[], [3, 4]));
        assert(test(arr([1, 2, 3, 4]), 0, 4, [5, 6, 7], [5, 6, 7]));
        assert(test(arr([1, 2, 3, 4]), 0, 2, [5, 6, 7], [5, 6, 7, 3, 4]));
        assert(test(arr([1, 2, 3, 4]), 2, 3, [5, 6, 7], [1, 2, 5, 6, 7, 4]));
    }
}

/**
    Tests if T is some kind a set of code points. Intended for template constraints.
*/
public template isCodepointSet(T)
{
    static if (is(T dummy == InversionList!(Args), Args...))
        enum isCodepointSet = true;
    else
        enum isCodepointSet = false;
}

/**
    Tests if $(D T) is a pair of integers that implicitly convert to $(D V).
    The following code must compile for any pair $(D T):
    ---
    (T x){ V a = x[0]; V b = x[1];}
    ---
    The following must not compile:
     ---
    (T x){ V c = x[2];}
    ---
*/
public template isIntegralPair(T, V=uint)
{
    enum isIntegralPair = is(typeof((T x){ V a = x[0]; V b = x[1];}))
        && !is(typeof((T x){ V c = x[2]; }));
}


/**
    The recommended default type for set of $(CODEPOINTS).
    For details, see the current implementation: $(LREF InversionList).
*/
public alias CodepointSet = InversionList!GcPolicy;


//@@@BUG: std.typecons tuples depend on std.format to produce fields mixin
// which relies on std.uni.isGraphical and this chain blows up with Forward reference error
// hence below doesn't seem to work
// public alias CodepointInterval = Tuple!(uint, "a", uint, "b");

/**
    The recommended type of $(REF Tuple, std,_typecons)
    to represent [a, b$(RPAREN) intervals of $(CODEPOINTS). As used in $(LREF InversionList).
    Any interval type should pass $(LREF isIntegralPair) trait.
*/
public struct CodepointInterval
{
pure:
    uint[2] _tuple;
    alias _tuple this;

@safe pure nothrow @nogc:

    this(uint low, uint high)
    {
        _tuple[0] = low;
        _tuple[1] = high;
    }
    bool opEquals(T)(T val) const
    {
        return this[0] == val[0] && this[1] == val[1];
    }
    @property ref inout(uint) a() inout { return _tuple[0]; }
    @property ref inout(uint) b() inout { return _tuple[1]; }
}

/**
    $(P
    $(D InversionList) is a set of $(CODEPOINTS)
    represented as an array of open-right [a, b$(RPAREN)
    intervals (see $(LREF CodepointInterval) above).
    The name comes from the way the representation reads left to right.
    For instance a set of all values [10, 50$(RPAREN), [80, 90$(RPAREN),
    plus a singular value 60 looks like this:
    )
    ---
    10, 50, 60, 61, 80, 90
    ---
    $(P
    The way to read this is: start with negative meaning that all numbers
    smaller then the next one are not present in this set (and positive
    - the contrary). Then switch positive/negative after each
    number passed from left to right.
    )
    $(P This way negative spans until 10, then positive until 50,
    then negative until 60, then positive until 61, and so on.
    As seen this provides a space-efficient storage of highly redundant data
    that comes in long runs. A description which Unicode $(CHARACTER)
    properties fit nicely. The technique itself could be seen as a variation
    on $(LINK2 https://en.wikipedia.org/wiki/Run-length_encoding, RLE encoding).
    )

    $(P Sets are value types (just like $(D int) is) thus they
        are never aliased.
    )
        Example:
        ---
        auto a = CodepointSet('a', 'z'+1);
        auto b = CodepointSet('A', 'Z'+1);
        auto c = a;
        a = a | b;
        assert(a == CodepointSet('A', 'Z'+1, 'a', 'z'+1));
        assert(a != c);
        ---
    $(P See also $(LREF unicode) for simpler construction of sets
        from predefined ones.
    )

    $(P Memory usage is 8 bytes per each contiguous interval in a set.
    The value semantics are achieved by using the
    $(HTTP en.wikipedia.org/wiki/Copy-on-write, COW) technique
    and thus it's $(RED not) safe to cast this type to $(D_KEYWORD shared).
    )

    Note:
    $(P It's not recommended to rely on the template parameters
    or the exact type of a current $(CODEPOINT) set in $(D std.uni).
    The type and parameters may change when the standard
    allocators design is finalized.
    Use $(LREF isCodepointSet) with templates or just stick with the default
    alias $(LREF CodepointSet) throughout the whole code base.
    )
*/
@trusted public struct InversionList(SP=GcPolicy)
{
    import std.range : assumeSorted;

    /**
        Construct from another code point set of any type.
    */
    this(Set)(Set set) pure
        if (isCodepointSet!Set)
    {
        uint[] arr;
        foreach (v; set.byInterval)
        {
            arr ~= v.a;
            arr ~= v.b;
        }
        data = CowArray!(SP).reuse(arr);
    }

    /**
        Construct a set from a forward range of code point intervals.
    */
    this(Range)(Range intervals) pure
        if (isForwardRange!Range && isIntegralPair!(ElementType!Range))
    {
        uint[] arr;
        foreach (v; intervals)
        {
            SP.append(arr, v.a);
            SP.append(arr, v.b);
        }
        data = CowArray!(SP).reuse(arr);
        sanitize(); //enforce invariant: sort intervals etc.
    }

    //helper function that avoids sanity check to be CTFE-friendly
    private static fromIntervals(Range)(Range intervals) pure
    {
        import std.algorithm.iteration : map;
        import std.range : roundRobin;
        auto flattened = roundRobin(intervals.save.map!"a[0]"(),
            intervals.save.map!"a[1]"());
        InversionList set;
        set.data = CowArray!(SP)(flattened);
        return set;
    }
    //ditto untill sort is CTFE-able
    private static fromIntervals()(uint[] intervals...) pure
    in
    {
        import std.conv : text;
        assert(intervals.length % 2 == 0, "Odd number of interval bounds [a, b)!");
        for (uint i = 0; i < intervals.length; i += 2)
        {
            auto a = intervals[i], b = intervals[i+1];
            assert(a < b, text("illegal interval [a, b): ", a, " > ", b));
        }
    }
    body
    {
        InversionList set;
        set.data = CowArray!(SP)(intervals);
        return set;
    }

    /**
        Construct a set from plain values of code point intervals.
    */
    this()(uint[] intervals...)
    in
    {
        import std.conv : text;
        assert(intervals.length % 2 == 0, "Odd number of interval bounds [a, b)!");
        for (uint i = 0; i < intervals.length; i += 2)
        {
            auto a = intervals[i], b = intervals[i+1];
            assert(a < b, text("illegal interval [a, b): ", a, " > ", b));
        }
    }
    body
    {
        data = CowArray!(SP)(intervals);
        sanitize(); //enforce invariant: sort intervals etc.
    }

    ///
    @safe unittest
    {
        import std.algorithm.comparison : equal;

        auto set = CodepointSet('a', 'z'+1, 'а', 'я'+1);
        foreach (v; 'a'..'z'+1)
            assert(set[v]);
        // Cyrillic lowercase interval
        foreach (v; 'а'..'я'+1)
            assert(set[v]);
        //specific order is not required, intervals may interesect
        auto set2 = CodepointSet('а', 'я'+1, 'a', 'd', 'b', 'z'+1);
        //the same end result
        assert(set2.byInterval.equal(set.byInterval));
    }

    /**
        Get range that spans all of the $(CODEPOINT) intervals in this $(LREF InversionList).

        Example:
        -----------
        import std.algorithm.comparison : equal;
        import std.typecons : tuple;

        auto set = CodepointSet('A', 'D'+1, 'a', 'd'+1);

        assert(set.byInterval.equal([tuple('A','E'), tuple('a','e')]));
        -----------
    */
    @property auto byInterval()
    {
        return Intervals!(typeof(data))(data);
    }

    /**
        Tests the presence of code point $(D val) in this set.
    */
    bool opIndex(uint val) const
    {
        // the <= ensures that searching in  interval of [a, b) for 'a' you get .length == 1
        // return assumeSorted!((a,b) => a <= b)(data[]).lowerBound(val).length & 1;
        return sharSwitchLowerBound!"a <= b"(data[], val) & 1;
    }

    ///
    @safe unittest
    {
        auto gothic = unicode.Gothic;
        // Gothic letter ahsa
        assert(gothic['\U00010330']);
        // no ascii in Gothic obviously
        assert(!gothic['$']);
    }


    // Linear scan for $(D ch). Useful only for small sets.
    // TODO:
    // used internally in std.regex
    // should be properly exposed in a public API ?
    package auto scanFor()(dchar ch) const
    {
        immutable len = data.length;
        for (size_t i = 0; i < len; i++)
            if (ch < data[i])
                return i & 1;
        return 0;
    }

    /// Number of $(CODEPOINTS) in this set
    @property size_t length()
    {
        size_t sum = 0;
        foreach (iv; byInterval)
        {
            sum += iv.b - iv.a;
        }
        return sum;
    }

// bootstrap full set operations from 4 primitives (suitable as a template mixin):
// addInterval, skipUpTo, dropUpTo & byInterval iteration
//============================================================================
public:
    /**
        $(P Sets support natural syntax for set algebra, namely: )
        $(BOOKTABLE ,
            $(TR $(TH Operator) $(TH Math notation) $(TH Description) )
            $(TR $(TD &) $(TD a ∩ b) $(TD intersection) )
            $(TR $(TD |) $(TD a ∪ b) $(TD union) )
            $(TR $(TD -) $(TD a ∖ b) $(TD subtraction) )
            $(TR $(TD ~) $(TD a ~ b) $(TD symmetric set difference i.e. (a ∪ b) \ (a ∩ b)) )
        )
    */
    This opBinary(string op, U)(U rhs)
        if (isCodepointSet!U || is(U:dchar))
    {
        static if (op == "&" || op == "|" || op == "~")
        {// symmetric ops thus can swap arguments to reuse r-value
            static if (is(U:dchar))
            {
                auto tmp = this;
                mixin("tmp "~op~"= rhs; ");
                return tmp;
            }
            else
            {
                static if (is(Unqual!U == U))
                {
                    // try hard to reuse r-value
                    mixin("rhs "~op~"= this;");
                    return rhs;
                }
                else
                {
                    auto tmp = this;
                    mixin("tmp "~op~"= rhs;");
                    return tmp;
                }
            }
        }
        else static if (op == "-") // anti-symmetric
        {
            auto tmp = this;
            tmp -= rhs;
            return tmp;
        }
        else
            static assert(0, "no operator "~op~" defined for Set");
    }

    ///
    @safe unittest
    {
        import std.algorithm.comparison : equal;
        import std.range : iota;

        auto lower = unicode.LowerCase;
        auto upper = unicode.UpperCase;
        auto ascii = unicode.ASCII;

        assert((lower & upper).empty); // no intersection
        auto lowerASCII = lower & ascii;
        assert(lowerASCII.byCodepoint.equal(iota('a', 'z'+1)));
        // throw away all of the lowercase ASCII
        assert((ascii - lower).length == 128 - 26);

        auto onlyOneOf = lower ~ ascii;
        assert(!onlyOneOf['Δ']); // not ASCII and not lowercase
        assert(onlyOneOf['$']); // ASCII and not lowercase
        assert(!onlyOneOf['a']); // ASCII and lowercase
        assert(onlyOneOf['я']); // not ASCII but lowercase

        // throw away all cased letters from ASCII
        auto noLetters = ascii - (lower | upper);
        assert(noLetters.length == 128 - 26*2);
    }

    /// The 'op=' versions of the above overloaded operators.
    ref This opOpAssign(string op, U)(U rhs)
        if (isCodepointSet!U || is(U:dchar))
    {
        static if (op == "|")    // union
        {
            static if (is(U:dchar))
            {
                this.addInterval(rhs, rhs+1);
                return this;
            }
            else
                return this.add(rhs);
        }
        else static if (op == "&")   // intersection
                return this.intersect(rhs);// overloaded
        else static if (op == "-")   // set difference
                return this.sub(rhs);// overloaded
        else static if (op == "~")   // symmetric set difference
        {
            auto copy = this & rhs;
            this |= rhs;
            this -= copy;
            return this;
        }
        else
            static assert(0, "no operator "~op~" defined for Set");
    }

    /**
        Tests the presence of codepoint $(D ch) in this set,
        the same as $(LREF opIndex).
    */
    bool opBinaryRight(string op: "in", U)(U ch) const
        if (is(U : dchar))
    {
        return this[ch];
    }

    ///
    @safe unittest
    {
        assert('я' in unicode.Cyrillic);
        assert(!('z' in unicode.Cyrillic));
    }



    /**
     * Obtains a set that is the inversion of this set.
     *
     * See_Also: $(LREF inverted)
     */
    auto opUnary(string op: "!")()
    {
        return this.inverted;
    }

    /**
        A range that spans each $(CODEPOINT) in this set.
    */
    @property auto byCodepoint()
    {
        @trusted static struct CodepointRange
        {
            this(This set)
            {
                r = set.byInterval;
                if (!r.empty)
                    cur = r.front.a;
            }

            @property dchar front() const
            {
                return cast(dchar) cur;
            }

            @property bool empty() const
            {
                return r.empty;
            }

            void popFront()
            {
                cur++;
                while (cur >= r.front.b)
                {
                    r.popFront();
                    if (r.empty)
                        break;
                    cur = r.front.a;
                }
            }
        private:
            uint cur;
            typeof(This.init.byInterval) r;
        }

        return CodepointRange(this);
    }

    ///
    @safe unittest
    {
        import std.algorithm.comparison : equal;
        import std.range : iota;

        auto set = unicode.ASCII;
        set.byCodepoint.equal(iota(0, 0x80));
    }

    /**
        $(P Obtain textual representation of this set in from of
        open-right intervals and feed it to $(D sink).
        )
        $(P Used by various standard formatting facilities such as
         $(REF formattedWrite, std,_format), $(REF write, std,_stdio),
         $(REF writef, std,_stdio), $(REF to, std,_conv) and others.
        )
        Example:
        ---
        import std.conv;
        assert(unicode.ASCII.to!string == "[0..128$(RPAREN)");
        ---
    */

    private import std.format : FormatSpec;

    /***************************************
     * Obtain a textual representation of this InversionList
     * in form of open-right intervals.
     *
     * The formatting flag is applied individually to each value, for example:
     * $(LI $(B %s) and $(B %d) format the intervals as a [low .. high$(RPAREN) range of integrals)
     * $(LI $(B %x) formats the intervals as a [low .. high$(RPAREN) range of lowercase hex characters)
     * $(LI $(B %X) formats the intervals as a [low .. high$(RPAREN) range of uppercase hex characters)
     */
    void toString(Writer)(scope Writer sink,
                  FormatSpec!char fmt) /* const */
    {
        import std.format : formatValue;
        auto range = byInterval;
        if (range.empty)
            return;

        while (1)
        {
            auto i = range.front;
            range.popFront();

            put(sink, "[");
            formatValue(sink, i.a, fmt);
            put(sink, "..");
            formatValue(sink, i.b, fmt);
            put(sink, ")");
            if (range.empty) return;
            put(sink, " ");
        }
    }

    ///
    @safe unittest
    {
        import std.conv : to;
        import std.format : format;
        import std.uni : unicode;

        assert(unicode.Cyrillic.to!string ==
            "[1024..1157) [1159..1320) [7467..7468) [7544..7545) [11744..11776) [42560..42648) [42655..42656)");

        // The specs '%s' and '%d' are equivalent to the to!string call above.
        assert(format("%d", unicode.Cyrillic) == unicode.Cyrillic.to!string);

        assert(format("%#x", unicode.Cyrillic) ==
            "[0x400..0x485) [0x487..0x528) [0x1d2b..0x1d2c) [0x1d78..0x1d79) [0x2de0..0x2e00) "
            ~"[0xa640..0xa698) [0xa69f..0xa6a0)");

        assert(format("%#X", unicode.Cyrillic) ==
            "[0X400..0X485) [0X487..0X528) [0X1D2B..0X1D2C) [0X1D78..0X1D79) [0X2DE0..0X2E00) "
            ~"[0XA640..0XA698) [0XA69F..0XA6A0)");
    }

    @safe unittest
    {
        import std.exception : assertThrown;
        import std.format : format, FormatException;
        assertThrown!FormatException(format("%a", unicode.ASCII));
    }


    /**
        Add an interval [a, b$(RPAREN) to this set.
    */
    ref add()(uint a, uint b)
    {
        addInterval(a, b);
        return this;
    }

    ///
    @safe unittest
    {
        CodepointSet someSet;
        someSet.add('0', '5').add('A','Z'+1);
        someSet.add('5', '9'+1);
        assert(someSet['0']);
        assert(someSet['5']);
        assert(someSet['9']);
        assert(someSet['Z']);
    }

private:

  package(std)  // used from: std.regex.internal.parser
    ref intersect(U)(U rhs)
        if (isCodepointSet!U)
    {
        Marker mark;
        foreach ( i; rhs.byInterval)
        {
            mark = this.dropUpTo(i.a, mark);
            mark = this.skipUpTo(i.b, mark);
        }
        this.dropUpTo(uint.max, mark);
        return this;
    }

    ref intersect()(dchar ch)
    {
        foreach (i; byInterval)
            if (i.a <= ch && ch < i.b)
                return this = This.init.add(ch, ch+1);
        this = This.init;
        return this;
    }

    @safe unittest
    {
        assert(unicode.Cyrillic.intersect('-').byInterval.empty);
    }

    ref sub()(dchar ch)
    {
        return subChar(ch);
    }

    // same as the above except that skip & drop parts are swapped
  package(std)  // used from: std.regex.internal.parser
    ref sub(U)(U rhs)
        if (isCodepointSet!U)
    {
        Marker mark;
        foreach (i; rhs.byInterval)
        {
            mark = this.skipUpTo(i.a, mark);
            mark = this.dropUpTo(i.b, mark);
        }
        return this;
    }

  package(std)  // used from: std.regex.internal.parse
    ref add(U)(U rhs)
        if (isCodepointSet!U)
    {
        Marker start;
        foreach (i; rhs.byInterval)
        {
            start = addInterval(i.a, i.b, start);
        }
        return this;
    }

// end of mixin-able part
//============================================================================
public:
    /**
        Obtains a set that is the inversion of this set.

        See the '!' $(LREF opUnary) for the same but using operators.
    */
    @property auto inverted()
    {
        InversionList inversion = this;
        if (inversion.data.length == 0)
        {
            inversion.addInterval(0, lastDchar+1);
            return inversion;
        }
        if (inversion.data[0] != 0)
            genericReplace(inversion.data, 0, 0, [0]);
        else
            genericReplace(inversion.data, 0, 1, cast(uint[]) null);
        if (data[data.length-1] != lastDchar+1)
            genericReplace(inversion.data,
                inversion.data.length, inversion.data.length, [lastDchar+1]);
        else
            genericReplace(inversion.data,
                inversion.data.length-1, inversion.data.length, cast(uint[]) null);

        return inversion;
    }

    ///
    @safe unittest
    {
        auto set = unicode.ASCII;
        // union with the inverse gets all of the code points in the Unicode
        assert((set | set.inverted).length == 0x110000);
        // no intersection with the inverse
        assert((set & set.inverted).empty);
    }

    /**
        Generates string with D source code of unary function with name of
        $(D funcName) taking a single $(D dchar) argument. If $(D funcName) is empty
        the code is adjusted to be a lambda function.

        The function generated tests if the $(CODEPOINT) passed
        belongs to this set or not. The result is to be used with string mixin.
        The intended usage area is aggressive optimization via meta programming
        in parser generators and the like.

        Note: Use with care for relatively small or regular sets. It
        could end up being slower then just using multi-staged tables.

        Example:
        ---
        import std.stdio;

        // construct set directly from [a, b$RPAREN intervals
        auto set = CodepointSet(10, 12, 45, 65, 100, 200);
        writeln(set);
        writeln(set.toSourceCode("func"));
        ---

        The above outputs something along the lines of:
        ---
        bool func(dchar ch)  @safe pure nothrow @nogc
        {
            if (ch < 45)
            {
                if (ch == 10 || ch == 11) return true;
                return false;
            }
            else if (ch < 65) return true;
            else
            {
                if (ch < 100) return false;
                if (ch < 200) return true;
                return false;
            }
        }
        ---
    */
    string toSourceCode(string funcName="")
    {
        import std.algorithm.searching : countUntil;
        import std.array : array;
        import std.format : format;
        enum maxBinary = 3;
        static string linearScope(R)(R ivals, string indent)
        {
            string result = indent~"{\n";
            string deeper = indent~"    ";
            foreach (ival; ivals)
            {
                immutable span = ival[1] - ival[0];
                assert(span != 0);
                if (span == 1)
                {
                    result ~= format("%sif (ch == %s) return true;\n", deeper, ival[0]);
                }
                else if (span == 2)
                {
                    result ~= format("%sif (ch == %s || ch == %s) return true;\n",
                        deeper, ival[0], ival[0]+1);
                }
                else
                {
                    if (ival[0] != 0) // dchar is unsigned and  < 0 is useless
                        result ~= format("%sif (ch < %s) return false;\n", deeper, ival[0]);
                    result ~= format("%sif (ch < %s) return true;\n", deeper, ival[1]);
                }
            }
            result ~= format("%sreturn false;\n%s}\n", deeper, indent); // including empty range of intervals
            return result;
        }

        static string binaryScope(R)(R ivals, string indent)
        {
            // time to do unrolled comparisons?
            if (ivals.length < maxBinary)
                return linearScope(ivals, indent);
            else
                return bisect(ivals, ivals.length/2, indent);
        }

        // not used yet if/elsebinary search is far better with DMD  as of 2.061
        // and GDC is doing fine job either way
        static string switchScope(R)(R ivals, string indent)
        {
            string result = indent~"switch (ch){\n";
            string deeper = indent~"    ";
            foreach (ival; ivals)
            {
                if (ival[0]+1 == ival[1])
                {
                    result ~= format("%scase %s: return true;\n",
                        deeper, ival[0]);
                }
                else
                {
                    result ~= format("%scase %s: .. case %s: return true;\n",
                         deeper, ival[0], ival[1]-1);
                }
            }
            result ~= deeper~"default: return false;\n"~indent~"}\n";
            return result;
        }

        static string bisect(R)(R range, size_t idx, string indent)
        {
            string deeper = indent ~ "    ";
            // bisect on one [a, b) interval at idx
            string result = indent~"{\n";
            // less branch, < a
            result ~= format("%sif (ch < %s)\n%s",
                deeper, range[idx][0], binaryScope(range[0 .. idx], deeper));
            // middle point,  >= a && < b
            result ~= format("%selse if (ch < %s) return true;\n",
                deeper, range[idx][1]);
            // greater or equal branch,  >= b
            result ~= format("%selse\n%s",
                deeper, binaryScope(range[idx+1..$], deeper));
            return result~indent~"}\n";
        }

        string code = format("bool %s(dchar ch) @safe pure nothrow @nogc\n",
            funcName.empty ? "function" : funcName);
        auto range = byInterval.array();
        // special case first bisection to be on ASCII vs beyond
        auto tillAscii = countUntil!"a[0] > 0x80"(range);
        if (tillAscii <= 0) // everything is ASCII or nothing is ascii (-1 & 0)
            code ~= binaryScope(range, "");
        else
            code ~= bisect(range, tillAscii, "");
        return code;
    }

    /**
        True if this set doesn't contain any $(CODEPOINTS).
    */
    @property bool empty() const
    {
        return data.length == 0;
    }

    ///
    @safe unittest
    {
        CodepointSet emptySet;
        assert(emptySet.length == 0);
        assert(emptySet.empty);
    }

private:
    alias This = typeof(this);
    alias Marker = size_t;

    // a random-access range of integral pairs
    static struct Intervals(Range)
    {
        this(Range sp)
        {
            slice = sp;
            start = 0;
            end = sp.length;
        }

        this(Range sp, size_t s, size_t e)
        {
            slice = sp;
            start = s;
            end = e;
        }

        @property auto front()const
        {
            immutable a = slice[start];
            immutable b = slice[start+1];
            return CodepointInterval(a, b);
        }

        //may break sorted property - but we need std.sort to access it
        //hence package protection attribute
        package @property void front(CodepointInterval val)
        {
            slice[start] = val.a;
            slice[start+1] = val.b;
        }

        @property auto back()const
        {
            immutable a = slice[end-2];
            immutable b = slice[end-1];
            return CodepointInterval(a, b);
        }

        //ditto about package
        package @property void back(CodepointInterval val)
        {
            slice[end-2] = val.a;
            slice[end-1] = val.b;
        }

        void popFront()
        {
            start += 2;
        }

        void popBack()
        {
            end -= 2;
        }

        auto opIndex(size_t idx) const
        {
            immutable a = slice[start+idx*2];
            immutable b = slice[start+idx*2+1];
            return CodepointInterval(a, b);
        }

        //ditto about package
        package void opIndexAssign(CodepointInterval val, size_t idx)
        {
            slice[start+idx*2] = val.a;
            slice[start+idx*2+1] = val.b;
        }

        auto opSlice(size_t s, size_t e)
        {
            return Intervals(slice, s*2+start, e*2+start);
        }

        @property size_t length()const {  return slice.length/2; }

        @property bool empty()const { return start == end; }

        @property auto save(){ return this; }
    private:
        size_t start, end;
        Range slice;
    }

    // called after construction from intervals
    // to make sure invariants hold
    void sanitize()
    {
        import std.algorithm.comparison : max;
        import std.algorithm.mutation : SwapStrategy;
        import std.algorithm.sorting : sort;
        if (data.length == 0)
            return;
        alias Ival = CodepointInterval;
        //intervals wrapper for a _range_ over packed array
        auto ivals = Intervals!(typeof(data[]))(data[]);
        //@@@BUG@@@ can't use "a.a < b.a" see issue 12265
        sort!((a,b) => a.a < b.a, SwapStrategy.stable)(ivals);
        // what follows is a variation on stable remove
        // differences:
        // - predicate is binary, and is tested against
        //   the last kept element (at 'i').
        // - predicate mutates lhs (merges rhs into lhs)
        size_t len = ivals.length;
        size_t i = 0;
        size_t j = 1;
        while (j < len)
        {
            if (ivals[i].b >= ivals[j].a)
            {
                ivals[i] = Ival(ivals[i].a, max(ivals[i].b, ivals[j].b));
                j++;
            }
            else //unmergable
            {
                // check if there is a hole after merges
                // (in the best case we do 0 writes to ivals)
                if (j != i+1)
                    ivals[i+1] = ivals[j]; //copy over
                i++;
                j++;
            }
        }
        len = i + 1;
        for (size_t k=0; k + 1 < len; k++)
        {
            assert(ivals[k].a < ivals[k].b);
            assert(ivals[k].b < ivals[k+1].a);
        }
        data.length = len * 2;
    }

    // special case for normal InversionList
    ref subChar(dchar ch)
    {
        auto mark = skipUpTo(ch);
        if (mark != data.length
            && data[mark] == ch && data[mark-1] == ch)
        {
            // it has split, meaning that ch happens to be in one of intervals
            data[mark] = data[mark]+1;
        }
        return this;
    }

    //
    Marker addInterval(int a, int b, Marker hint=Marker.init)
    in
    {
        assert(a <= b);
    }
    body
    {
        import std.range : assumeSorted, SearchPolicy;
        auto range = assumeSorted(data[]);
        size_t pos;
        size_t a_idx = hint + range[hint..$].lowerBound!(SearchPolicy.gallop)(a).length;
        if (a_idx == range.length)
        {
            //  [---+++----++++----++++++]
            //  [                         a  b]
            data.append(a, b);
            return data.length-1;
        }
        size_t b_idx = range[a_idx .. range.length].lowerBound!(SearchPolicy.gallop)(b).length+a_idx;
        uint[3] buf = void;
        uint to_insert;
        debug(std_uni)
        {
            writefln("a_idx=%d; b_idx=%d;", a_idx, b_idx);
        }
        if (b_idx == range.length)
        {
            //  [-------++++++++----++++++-]
            //  [      s     a                 b]
            if (a_idx & 1)// a in positive
            {
                buf[0] = b;
                to_insert = 1;
            }
            else// a in negative
            {
                buf[0] = a;
                buf[1] = b;
                to_insert = 2;
            }
            pos = genericReplace(data, a_idx, b_idx, buf[0 .. to_insert]);
            return pos - 1;
        }

        uint top = data[b_idx];

        debug(std_uni)
        {
            writefln("a_idx=%d; b_idx=%d;", a_idx, b_idx);
            writefln("a=%s; b=%s; top=%s;", a, b, top);
        }
        if (a_idx & 1)
        {// a in positive
            if (b_idx & 1)// b in positive
            {
                //  [-------++++++++----++++++-]
                //  [       s    a        b    ]
                buf[0] = top;
                to_insert = 1;
            }
            else // b in negative
            {
                //  [-------++++++++----++++++-]
                //  [       s    a   b         ]
                if (top == b)
                {
                    assert(b_idx+1 < data.length);
                    buf[0] = data[b_idx+1];
                    pos = genericReplace(data, a_idx, b_idx+2, buf[0 .. 1]);
                    return pos - 1;
                }
                buf[0] = b;
                buf[1] = top;
                to_insert = 2;
            }
        }
        else
        { // a in negative
            if (b_idx & 1) // b in positive
            {
                //  [----------+++++----++++++-]
                //  [     a     b              ]
                buf[0] = a;
                buf[1] = top;
                to_insert = 2;
            }
            else// b in negative
            {
                //  [----------+++++----++++++-]
                //  [  a       s      b        ]
                if (top == b)
                {
                    assert(b_idx+1 < data.length);
                    buf[0] = a;
                    buf[1] = data[b_idx+1];
                    pos = genericReplace(data, a_idx, b_idx+2, buf[0 .. 2]);
                    return pos - 1;
                }
                buf[0] = a;
                buf[1] = b;
                buf[2] = top;
                to_insert = 3;
            }
        }
        pos = genericReplace(data, a_idx, b_idx+1, buf[0 .. to_insert]);
        debug(std_uni)
        {
            writefln("marker idx: %d; length=%d", pos, data[pos], data.length);
            writeln("inserting ", buf[0 .. to_insert]);
        }
        return pos - 1;
    }

    //
    Marker dropUpTo(uint a, Marker pos=Marker.init)
    in
    {
        assert(pos % 2 == 0); // at start of interval
    }
    body
    {
        auto range = assumeSorted!"a <= b"(data[pos .. data.length]);
        if (range.empty)
            return pos;
        size_t idx = pos;
        idx += range.lowerBound(a).length;

        debug(std_uni)
        {
            writeln("dropUpTo full length=", data.length);
            writeln(pos,"~~~", idx);
        }
        if (idx == data.length)
            return genericReplace(data, pos, idx, cast(uint[])[]);
        if (idx & 1)
        {   // a in positive
            //[--+++----++++++----+++++++------...]
            //      |<---si       s  a  t
            genericReplace(data, pos, idx, [a]);
        }
        else
        {   // a in negative
            //[--+++----++++++----+++++++-------+++...]
            //      |<---si              s  a  t
            genericReplace(data, pos, idx, cast(uint[])[]);
        }
        return pos;
    }

    //
    Marker skipUpTo(uint a, Marker pos=Marker.init)
    out(result)
    {
        assert(result % 2 == 0);// always start of interval
        //(may be  0-width after-split)
    }
    body
    {
        assert(data.length % 2 == 0);
        auto range = assumeSorted!"a <= b"(data[pos .. data.length]);
        size_t idx = pos+range.lowerBound(a).length;

        if (idx >= data.length) // could have Marker point to recently removed stuff
            return data.length;

        if (idx & 1)// inside of interval, check for split
        {

            immutable top = data[idx];
            if (top == a)// no need to split, it's end
                return idx+1;
            immutable start = data[idx-1];
            if (a == start)
                return idx-1;
            // split it up
            genericReplace(data, idx, idx+1, [a, a, top]);
            return idx+1;        // avoid odd index
        }
        return idx;
    }

    CowArray!SP data;
}

@system unittest
{
    import std.conv : to;
    assert(unicode.ASCII.to!string() == "[0..128)");
}

// pedantic version for ctfe, and aligned-access only architectures
@system private uint safeRead24(scope const ubyte* ptr, size_t idx) pure nothrow @nogc
{
    idx *= 3;
    version (LittleEndian)
        return ptr[idx] + (cast(uint) ptr[idx+1]<<8)
             + (cast(uint) ptr[idx+2]<<16);
    else
        return (cast(uint) ptr[idx]<<16) + (cast(uint) ptr[idx+1]<<8)
             + ptr[idx+2];
}

// ditto
@system private void safeWrite24(scope ubyte* ptr, uint val, size_t idx) pure nothrow @nogc
{
    idx *= 3;
    version (LittleEndian)
    {
        ptr[idx] = val & 0xFF;
        ptr[idx+1] = (val >> 8) & 0xFF;
        ptr[idx+2] = (val >> 16) & 0xFF;
    }
    else
    {
        ptr[idx] = (val >> 16) & 0xFF;
        ptr[idx+1] = (val >> 8) & 0xFF;
        ptr[idx+2] = val & 0xFF;
    }
}

// unaligned x86-like read/write functions
@system private uint unalignedRead24(scope const ubyte* ptr, size_t idx) pure nothrow @nogc
{
    uint* src = cast(uint*)(ptr+3*idx);
    version (LittleEndian)
        return *src & 0xFF_FFFF;
    else
        return *src >> 8;
}

// ditto
@system private void unalignedWrite24(scope ubyte* ptr, uint val, size_t idx) pure nothrow @nogc
{
    uint* dest = cast(uint*)(cast(ubyte*) ptr + 3*idx);
    version (LittleEndian)
        *dest = val | (*dest & 0xFF00_0000);
    else
        *dest = (val << 8) | (*dest & 0xFF);
}

@system private uint read24(scope const ubyte* ptr, size_t idx) pure nothrow @nogc
{
    static if (hasUnalignedReads)
        return __ctfe ? safeRead24(ptr, idx) : unalignedRead24(ptr, idx);
    else
        return safeRead24(ptr, idx);
}

@system private void write24(scope ubyte* ptr, uint val, size_t idx) pure nothrow @nogc
{
    static if (hasUnalignedReads)
        return __ctfe ? safeWrite24(ptr, val, idx) : unalignedWrite24(ptr, val, idx);
    else
        return safeWrite24(ptr, val, idx);
}

struct CowArray(SP=GcPolicy)
{
    import std.range.primitives : hasLength;

  @safe:
    static auto reuse(uint[] arr)
    {
        CowArray cow;
        cow.data = arr;
        SP.append(cow.data, 1);
        assert(cow.refCount == 1);
        assert(cow.length == arr.length);
        return cow;
    }

    this(Range)(Range range)
        if (isInputRange!Range && hasLength!Range)
    {
        import std.algorithm.mutation : copy;
        length = range.length;
        copy(range, data[0..$-1]);
    }

    this(Range)(Range range)
        if (isForwardRange!Range && !hasLength!Range)
    {
        import std.algorithm.mutation : copy;
        import std.range.primitives : walkLength;
        immutable len = walkLength(range.save);
        length = len;
        copy(range, data[0..$-1]);
    }

    this(this)
    {
        if (!empty)
        {
            refCount = refCount + 1;
        }
    }

    ~this()
    {
        if (!empty)
        {
            immutable cnt = refCount;
            if (cnt == 1)
                SP.destroy(data);
            else
                refCount = cnt - 1;
        }
    }

    // no ref-count for empty U24 array
    @property bool empty() const { return data.length == 0; }

    // report one less then actual size
    @property size_t length() const
    {
        return data.length ? data.length - 1 : 0;
    }

    //+ an extra slot for ref-count
    @property void length(size_t len)
    {
        import std.algorithm.comparison : min;
        import std.algorithm.mutation : copy;
        if (len == 0)
        {
            if (!empty)
                freeThisReference();
            return;
        }
        immutable total = len + 1; // including ref-count
        if (empty)
        {
            data = SP.alloc!uint(total);
            refCount = 1;
            return;
        }
        immutable cur_cnt = refCount;
        if (cur_cnt != 1) // have more references to this memory
        {
            refCount = cur_cnt - 1;
            auto new_data = SP.alloc!uint(total);
            // take shrinking into account
            auto to_copy = min(total, data.length) - 1;
            copy(data[0 .. to_copy], new_data[0 .. to_copy]);
            data = new_data; // before setting refCount!
            refCount = 1;
        }
        else // 'this' is the only reference
        {
            // use the realloc (hopefully in-place operation)
            data = SP.realloc(data, total);
            refCount = 1; // setup a ref-count in the new end of the array
        }
    }

    alias opDollar = length;

    uint opIndex()(size_t idx)const
    {
        return data[idx];
    }

    void opIndexAssign(uint val, size_t idx)
    {
        auto cnt = refCount;
        if (cnt != 1)
            dupThisReference(cnt);
        data[idx] = val;
    }

    //
    auto opSlice(size_t from, size_t to)
    {
        if (!empty)
        {
            auto cnt = refCount;
            if (cnt != 1)
                dupThisReference(cnt);
        }
        return data[from .. to];

    }

    //
    auto opSlice(size_t from, size_t to) const
    {
        return data[from .. to];
    }

    // length slices before the ref count
    auto opSlice()
    {
        return opSlice(0, length);
    }

    // ditto
    auto opSlice() const
    {
        return opSlice(0, length);
    }

    void append(Range)(Range range)
        if (isInputRange!Range && hasLength!Range && is(ElementType!Range : uint))
    {
        size_t nl = length + range.length;
        length = nl;
        copy(range, this[nl-range.length .. nl]);
    }

    void append()(uint[] val...)
    {
        length = length + val.length;
        data[$-val.length-1 .. $-1] = val[];
    }

    bool opEquals()(auto const ref CowArray rhs)const
    {
        if (empty ^ rhs.empty)
            return false; // one is empty and the other isn't
        return empty || data[0..$-1] == rhs.data[0..$-1];
    }

private:
    // ref-count is right after the data
    @property uint refCount() const
    {
        return data[$-1];
    }

    @property void refCount(uint cnt)
    {
        data[$-1] = cnt;
    }

    void freeThisReference()
    {
        immutable count = refCount;
        if (count != 1) // have more references to this memory
        {
            // dec shared ref-count
            refCount = count - 1;
            data = [];
        }
        else
            SP.destroy(data);
        assert(!data.ptr);
    }

    void dupThisReference(uint count)
    in
    {
        assert(!empty && count != 1 && count == refCount);
    }
    body
    {
        import std.algorithm.mutation : copy;
        // dec shared ref-count
        refCount = count - 1;
        // copy to the new chunk of RAM
        auto new_data = SP.alloc!uint(data.length);
        // bit-blit old stuff except the counter
        copy(data[0..$-1], new_data[0..$-1]);
        data = new_data; // before setting refCount!
        refCount = 1; // so that this updates the right one
    }

    uint[] data;
}

@safe unittest// Uint24 tests
{
    import std.algorithm.comparison : equal;
    import std.algorithm.mutation : copy;
    import std.conv : text;
    import std.range : iota, chain;
    import std.range.primitives : isBidirectionalRange, isOutputRange;
    void funcRef(T)(ref T u24)
    {
        u24.length = 2;
        u24[1] = 1024;
        T u24_c = u24;
        assert(u24[1] == 1024);
        u24.length = 0;
        assert(u24.empty);
        u24.append([1, 2]);
        assert(equal(u24[], [1, 2]));
        u24.append(111);
        assert(equal(u24[], [1, 2, 111]));
        assert(!u24_c.empty && u24_c[1] == 1024);
        u24.length = 3;
        copy(iota(0, 3), u24[]);
        assert(equal(u24[], iota(0, 3)));
        assert(u24_c[1] == 1024);
    }

    void func2(T)(T u24)
    {
        T u24_2 = u24;
        T u24_3;
        u24_3 = u24_2;
        assert(u24_2 == u24_3);
        assert(equal(u24[], u24_2[]));
        assert(equal(u24_2[], u24_3[]));
        funcRef(u24_3);

        assert(equal(u24_3[], iota(0, 3)));
        assert(!equal(u24_2[], u24_3[]));
        assert(equal(u24_2[], u24[]));
        u24_2 = u24_3;
        assert(equal(u24_2[], iota(0, 3)));
        // to test that passed arg is intact outside
        // plus try out opEquals
        u24 = u24_3;
        u24 = T.init;
        u24_3 = T.init;
        assert(u24.empty);
        assert(u24 == u24_3);
        assert(u24 != u24_2);
    }

    foreach (Policy; AliasSeq!(GcPolicy, ReallocPolicy))
    {
        alias Range = typeof(CowArray!Policy.init[]);
        alias U24A = CowArray!Policy;
        static assert(isForwardRange!Range);
        static assert(isBidirectionalRange!Range);
        static assert(isOutputRange!(Range, uint));
        static assert(isRandomAccessRange!(Range));

        auto arr = U24A([42u, 36, 100]);
        assert(arr[0] == 42);
        assert(arr[1] == 36);
        arr[0] = 72;
        arr[1] = 0xFE_FEFE;
        assert(arr[0] == 72);
        assert(arr[1] == 0xFE_FEFE);
        assert(arr[2] == 100);
        U24A arr2 = arr;
        assert(arr2[0] == 72);
        arr2[0] = 11;
        // test COW-ness
        assert(arr[0] == 72);
        assert(arr2[0] == 11);
        // set this to about 100M to stress-test COW memory management
        foreach (v; 0 .. 10_000)
            func2(arr);
        assert(equal(arr[], [72, 0xFE_FEFE, 100]));

        auto r2 = U24A(iota(0, 100));
        assert(equal(r2[], iota(0, 100)), text(r2[]));
        copy(iota(10, 170, 2), r2[10 .. 90]);
        assert(equal(r2[], chain(iota(0, 10), iota(10, 170, 2), iota(90, 100)))
               , text(r2[]));
    }
}

version (unittest)
{
    private alias AllSets = AliasSeq!(InversionList!GcPolicy, InversionList!ReallocPolicy);
}

@safe unittest// core set primitives test
{
    import std.conv : text;
    foreach (CodeList; AllSets)
    {
        CodeList a;
        //"plug a hole" test
        a.add(10, 20).add(25, 30).add(15, 27);
        assert(a == CodeList(10, 30), text(a));

        auto x = CodeList.init;
        x.add(10, 20).add(30, 40).add(50, 60);

        a = x;
        a.add(20, 49);//[10, 49) [50, 60)
        assert(a == CodeList(10, 49, 50 ,60));

        a = x;
        a.add(20, 50);
        assert(a == CodeList(10, 60), text(a));

        // simple unions, mostly edge effects
        x = CodeList.init;
        x.add(10, 20).add(40, 60);

        a = x;
        a.add(10, 25); //[10, 25) [40, 60)
        assert(a == CodeList(10, 25, 40, 60));

        a = x;
        a.add(5, 15); //[5, 20) [40, 60)
        assert(a == CodeList(5, 20, 40, 60));

        a = x;
        a.add(0, 10); // [0, 20) [40, 60)
        assert(a == CodeList(0, 20, 40, 60));

        a = x;
        a.add(0, 5); // prepand
        assert(a == CodeList(0, 5, 10, 20, 40, 60), text(a));

        a = x;
        a.add(5, 20);
        assert(a == CodeList(5, 20, 40, 60));

        a = x;
        a.add(3, 37);
        assert(a == CodeList(3, 37, 40, 60));

        a = x;
        a.add(37, 65);
        assert(a == CodeList(10, 20, 37, 65));

        // some tests on helpers for set intersection
        x = CodeList.init.add(10, 20).add(40, 60).add(100, 120);
        a = x;

        auto m = a.skipUpTo(60);
        a.dropUpTo(110, m);
        assert(a == CodeList(10, 20, 40, 60, 110, 120), text(a.data[]));

        a = x;
        a.dropUpTo(100);
        assert(a == CodeList(100, 120), text(a.data[]));

        a = x;
        m = a.skipUpTo(50);
        a.dropUpTo(140, m);
        assert(a == CodeList(10, 20, 40, 50), text(a.data[]));
        a = x;
        a.dropUpTo(60);
        assert(a == CodeList(100, 120), text(a.data[]));
    }
}


//test constructor to work with any order of intervals
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.conv : text, to;
    import std.range : chain, iota;
    import std.typecons : tuple;
    //ensure constructor handles bad ordering and overlap
    auto c1 = CodepointSet('а', 'я'+1, 'А','Я'+1);
    foreach (ch; chain(iota('а', 'я'+1), iota('А','Я'+1)))
        assert(ch in c1, to!string(ch));

    //contiguos
    assert(CodepointSet(1000, 1006, 1006, 1009)
        .byInterval.equal([tuple(1000, 1009)]));
    //contains
    assert(CodepointSet(900, 1200, 1000, 1100)
        .byInterval.equal([tuple(900, 1200)]));
    //intersect left
    assert(CodepointSet(900, 1100, 1000, 1200)
        .byInterval.equal([tuple(900, 1200)]));
    //intersect right
    assert(CodepointSet(1000, 1200, 900, 1100)
        .byInterval.equal([tuple(900, 1200)]));

    //ditto with extra items at end
    assert(CodepointSet(1000, 1200, 900, 1100, 800, 850)
        .byInterval.equal([tuple(800, 850), tuple(900, 1200)]));
    assert(CodepointSet(900, 1100, 1000, 1200, 800, 850)
        .byInterval.equal([tuple(800, 850), tuple(900, 1200)]));

    //"plug a hole" test
    auto c2 = CodepointSet(20, 40,
        60, 80, 100, 140, 150, 200,
        40, 60, 80, 100, 140, 150
    );
    assert(c2.byInterval.equal([tuple(20, 200)]));

    auto c3 = CodepointSet(
        20, 40, 60, 80, 100, 140, 150, 200,
        0, 10, 15, 100, 10, 20, 200, 220);
    assert(c3.byInterval.equal([tuple(0, 140), tuple(150, 220)]));
}


@safe unittest
{   // full set operations
    import std.conv : text;
    foreach (CodeList; AllSets)
    {
        CodeList a, b, c, d;

        //"plug a hole"
        a.add(20, 40).add(60, 80).add(100, 140).add(150, 200);
        b.add(40, 60).add(80, 100).add(140, 150);
        c = a | b;
        d = b | a;
        assert(c == CodeList(20, 200), text(CodeList.stringof," ", c));
        assert(c == d, text(c," vs ", d));

        b = CodeList.init.add(25, 45).add(65, 85).add(95,110).add(150, 210);
        c = a | b; //[20,45) [60, 85) [95, 140) [150, 210)
        d = b | a;
        assert(c == CodeList(20, 45, 60, 85, 95, 140, 150, 210), text(c));
        assert(c == d, text(c," vs ", d));

        b = CodeList.init.add(10, 20).add(30,100).add(145,200);
        c = a | b;//[10, 140) [145, 200)
        d = b | a;
        assert(c == CodeList(10, 140, 145, 200));
        assert(c == d, text(c," vs ", d));

        b = CodeList.init.add(0, 10).add(15, 100).add(10, 20).add(200, 220);
        c = a | b;//[0, 140) [150, 220)
        d = b | a;
        assert(c == CodeList(0, 140, 150, 220));
        assert(c == d, text(c," vs ", d));


        a = CodeList.init.add(20, 40).add(60, 80);
        b = CodeList.init.add(25, 35).add(65, 75);
        c = a & b;
        d = b & a;
        assert(c == CodeList(25, 35, 65, 75), text(c));
        assert(c == d, text(c," vs ", d));

        a = CodeList.init.add(20, 40).add(60, 80).add(100, 140).add(150, 200);
        b = CodeList.init.add(25, 35).add(65, 75).add(110, 130).add(160, 180);
        c = a & b;
        d = b & a;
        assert(c == CodeList(25, 35, 65, 75, 110, 130, 160, 180), text(c));
        assert(c == d, text(c," vs ", d));

        a = CodeList.init.add(20, 40).add(60, 80).add(100, 140).add(150, 200);
        b = CodeList.init.add(10, 30).add(60, 120).add(135, 160);
        c = a & b;//[20, 30)[60, 80) [100, 120) [135, 140) [150, 160)
        d = b & a;

        assert(c == CodeList(20, 30, 60, 80, 100, 120, 135, 140, 150, 160),text(c));
        assert(c == d, text(c, " vs ",d));
        assert((c & a) == c);
        assert((d & b) == d);
        assert((c & d) == d);

        b = CodeList.init.add(40, 60).add(80, 100).add(140, 200);
        c = a & b;
        d = b & a;
        assert(c == CodeList(150, 200), text(c));
        assert(c == d, text(c, " vs ",d));
        assert((c & a) == c);
        assert((d & b) == d);
        assert((c & d) == d);

        assert((a & a) == a);
        assert((b & b) == b);

        a = CodeList.init.add(20, 40).add(60, 80).add(100, 140).add(150, 200);
        b = CodeList.init.add(30, 60).add(75, 120).add(190, 300);
        c = a - b;// [30, 40) [60, 75) [120, 140) [150, 190)
        d = b - a;// [40, 60) [80, 100) [200, 300)
        assert(c == CodeList(20, 30, 60, 75, 120, 140, 150, 190), text(c));
        assert(d == CodeList(40, 60, 80, 100, 200, 300), text(d));
        assert(c - d == c, text(c-d, " vs ", c));
        assert(d - c == d, text(d-c, " vs ", d));
        assert(c - c == CodeList.init);
        assert(d - d == CodeList.init);

        a = CodeList.init.add(20, 40).add( 60, 80).add(100, 140).add(150,            200);
        b = CodeList.init.add(10,  50).add(60,                           160).add(190, 300);
        c = a - b;// [160, 190)
        d = b - a;// [10, 20) [40, 50) [80, 100) [140, 150) [200, 300)
        assert(c == CodeList(160, 190), text(c));
        assert(d == CodeList(10, 20, 40, 50, 80, 100, 140, 150, 200, 300), text(d));
        assert(c - d == c, text(c-d, " vs ", c));
        assert(d - c == d, text(d-c, " vs ", d));
        assert(c - c == CodeList.init);
        assert(d - d == CodeList.init);

        a = CodeList.init.add(20,    40).add(60, 80).add(100,      140).add(150,  200);
        b = CodeList.init.add(10, 30).add(45,         100).add(130,             190);
        c = a ~ b; // [10, 20) [30, 40) [45, 60) [80, 130) [140, 150) [190, 200)
        d = b ~ a;
        assert(c == CodeList(10, 20, 30, 40, 45, 60, 80, 130, 140, 150, 190, 200),
               text(c));
        assert(c == d, text(c, " vs ", d));
    }
}

}

@safe unittest// vs single dchar
{
    import std.conv : text;
    CodepointSet a = CodepointSet(10, 100, 120, 200);
    assert(a - 'A' == CodepointSet(10, 65, 66, 100, 120, 200), text(a - 'A'));
    assert((a & 'B') == CodepointSet(66, 67));
}

@safe unittest// iteration & opIndex
{
    import std.algorithm.comparison : equal;
    import std.conv : text;
    import std.typecons : tuple, Tuple;

    foreach (CodeList; AliasSeq!(InversionList!(ReallocPolicy)))
    {
        auto arr = "ABCDEFGHIJKLMabcdefghijklm"d;
        auto a = CodeList('A','N','a', 'n');
        assert(equal(a.byInterval,
                [tuple(cast(uint)'A', cast(uint)'N'), tuple(cast(uint)'a', cast(uint)'n')]
            ), text(a.byInterval));

        // same @@@BUG as in issue 8949 ?
        version (bug8949)
        {
            import std.range : retro;
            assert(equal(retro(a.byInterval),
                [tuple(cast(uint)'a', cast(uint)'n'), tuple(cast(uint)'A', cast(uint)'N')]
            ), text(retro(a.byInterval)));
        }
        auto achr = a.byCodepoint;
        assert(equal(achr, arr), text(a.byCodepoint));
        foreach (ch; a.byCodepoint)
            assert(a[ch]);
        auto x = CodeList(100, 500, 600, 900, 1200, 1500);
        assert(equal(x.byInterval, [ tuple(100, 500), tuple(600, 900), tuple(1200, 1500)]), text(x.byInterval));
        foreach (ch; x.byCodepoint)
            assert(x[ch]);
        static if (is(CodeList == CodepointSet))
        {
            auto y = CodeList(x.byInterval);
            assert(equal(x.byInterval, y.byInterval));
        }
        assert(equal(CodepointSet.init.byInterval, cast(Tuple!(uint, uint)[])[]));
        assert(equal(CodepointSet.init.byCodepoint, cast(dchar[])[]));
    }
}

//============================================================================
// Generic Trie template and various ways to build it
//============================================================================

// debug helper to get a shortened array dump
auto arrayRepr(T)(T x)
{
    import std.conv : text;
    if (x.length > 32)
    {
        return text(x[0 .. 16],"~...~", x[x.length-16 .. x.length]);
    }
    else
        return text(x);
}

/**
    Maps $(D Key) to a suitable integer index within the range of $(D size_t).
    The mapping is constructed by applying predicates from $(D Prefix) left to right
    and concatenating the resulting bits.

    The first (leftmost) predicate defines the most significant bits of
    the resulting index.
 */
template mapTrieIndex(Prefix...)
{
    size_t mapTrieIndex(Key)(Key key)
        if (isValidPrefixForTrie!(Key, Prefix))
    {
        alias p = Prefix;
        size_t idx;
        foreach (i, v; p[0..$-1])
        {
            idx |= p[i](key);
            idx <<= p[i+1].bitSize;
        }
        idx |= p[$-1](key);
        return idx;
    }
}

/*
    $(D TrieBuilder) is a type used for incremental construction
    of $(LREF Trie)s.

    See $(LREF buildTrie) for generic helpers built on top of it.
*/
@trusted private struct TrieBuilder(Value, Key, Args...)
if (isBitPackableType!Value && isValidArgsForTrie!(Key, Args))
{
    import std.exception : enforce;

private:
    // last index is not stored in table, it is used as an offset to values in a block.
    static if (is(Value == bool))// always pack bool
        alias V = BitPacked!(Value, 1);
    else
        alias V = Value;
    static auto deduceMaxIndex(Preds...)()
    {
        size_t idx = 1;
        foreach (v; Preds)
            idx *= 2^^v.bitSize;
        return idx;
    }

    static if (is(typeof(Args[0]) : Key)) // Args start with upper bound on Key
    {
        alias Prefix = Args[1..$];
        enum lastPageSize = 2^^Prefix[$-1].bitSize;
        enum translatedMaxIndex = mapTrieIndex!(Prefix)(Args[0]);
        enum roughedMaxIndex =
            (translatedMaxIndex + lastPageSize-1)/lastPageSize*lastPageSize;
        // check warp around - if wrapped, use the default deduction rule
        enum maxIndex = roughedMaxIndex < translatedMaxIndex ?
            deduceMaxIndex!(Prefix)() : roughedMaxIndex;
    }
    else
    {
        alias Prefix = Args;
        enum maxIndex = deduceMaxIndex!(Prefix)();
    }

    alias getIndex = mapTrieIndex!(Prefix);

    enum lastLevel = Prefix.length-1;
    struct ConstructState
    {
        size_t idx_zeros, idx_ones;
    }
    // iteration over levels of Trie, each indexes its own level and thus a shortened domain
    size_t[Prefix.length] indices;
    // default filler value to use
    Value defValue;
    // this is a full-width index of next item
    size_t curIndex;
    // all-zeros page index, all-ones page index (+ indicator if there is such a page)
    ConstructState[Prefix.length] state;
    // the table being constructed
    MultiArray!(idxTypes!(Key, fullBitSize!(Prefix), Prefix[0..$]), V) table;

    @disable this();

    //shortcut for index variable at level 'level'
    @property ref idx(size_t level)(){ return indices[level]; }

    // this function assumes no holes in the input so
    // indices are going one by one
    void addValue(size_t level, T)(T val, size_t numVals)
    {
        alias j = idx!level;
        enum pageSize = 1 << Prefix[level].bitSize;
        if (numVals == 0)
            return;
        auto ptr = table.slice!(level);
        if (numVals == 1)
        {
            static if (level == Prefix.length-1)
                ptr[j] = val;
            else
            {// can incur narrowing conversion
                assert(j < ptr.length);
                ptr[j] = force!(typeof(ptr[j]))(val);
            }
            j++;
            if (j % pageSize == 0)
                spillToNextPage!level(ptr);
            return;
        }
        // longer row of values
        // get to the next page boundary
        immutable nextPB = (j + pageSize) & ~(pageSize-1);
        immutable n =  nextPB - j;// can fill right in this page
        if (numVals < n) //fits in current page
        {
            ptr[j .. j+numVals]  = val;
            j += numVals;
            return;
        }
        static if (level != 0)//on the first level it always fits
        {
            numVals -= n;
            //write till the end of current page
            ptr[j .. j+n]  = val;
            j += n;
            //spill to the next page
            spillToNextPage!level(ptr);
            // page at once loop
            if (state[level].idx_zeros != size_t.max && val == T.init)
            {
                alias NextIdx = typeof(table.slice!(level-1)[0]);
                addValue!(level-1)(force!NextIdx(state[level].idx_zeros),
                    numVals/pageSize);
                ptr = table.slice!level; //table structure might have changed
                numVals %= pageSize;
            }
            else
            {
                while (numVals >= pageSize)
                {
                    numVals -= pageSize;
                    ptr[j .. j+pageSize]  = val;
                    j += pageSize;
                    spillToNextPage!level(ptr);
                }
            }
            if (numVals)
            {
                // the leftovers, an incomplete page
                ptr[j .. j+numVals]  = val;
                j += numVals;
            }
        }
    }

    void spillToNextPage(size_t level, Slice)(ref Slice ptr)
    {
        // last level (i.e. topmost) has 1 "page"
        // thus it need not to add a new page on upper level
        static if (level != 0)
            spillToNextPageImpl!(level)(ptr);
    }

    // this can re-use the current page if duplicate or allocate a new one
    // it also makes sure that previous levels point to the correct page in this level
    void spillToNextPageImpl(size_t level, Slice)(ref Slice ptr)
    {
        alias NextIdx = typeof(table.slice!(level-1)[0]);
        NextIdx next_lvl_index;
        enum pageSize = 1 << Prefix[level].bitSize;
        assert(idx!level % pageSize == 0);
        immutable last = idx!level-pageSize;
        const slice = ptr[idx!level - pageSize .. idx!level];
        size_t j;
        for (j=0; j<last; j+=pageSize)
        {
            if (ptr[j .. j+pageSize] == slice)
            {
                // get index to it, reuse ptr space for the next block
                next_lvl_index = force!NextIdx(j/pageSize);
                version (none)
                {
                import std.stdio : writefln, writeln;
                writefln("LEVEL(%s) page mapped idx: %s: 0..%s  ---> [%s..%s]"
                        ,level
                        ,indices[level-1], pageSize, j, j+pageSize);
                writeln("LEVEL(", level
                        , ") mapped page is: ", slice, ": ", arrayRepr(ptr[j .. j+pageSize]));
                writeln("LEVEL(", level
                        , ") src page is :", ptr, ": ", arrayRepr(slice[0 .. pageSize]));
                }
                idx!level -= pageSize; // reuse this page, it is duplicate
                break;
            }
        }
        if (j == last)
        {
    L_allocate_page:
            next_lvl_index = force!NextIdx(idx!level/pageSize - 1);
            if (state[level].idx_zeros == size_t.max && ptr.zeros(j, j+pageSize))
            {
                state[level].idx_zeros = next_lvl_index;
            }
            // allocate next page
            version (none)
            {
            import std.stdio : writefln;
            writefln("LEVEL(%s) page allocated: %s"
                     , level, arrayRepr(slice[0 .. pageSize]));
            writefln("LEVEL(%s) index: %s ; page at this index %s"
                     , level
                     , next_lvl_index
                     , arrayRepr(
                         table.slice!(level)
                          [pageSize*next_lvl_index..(next_lvl_index+1)*pageSize]
                        ));
            }
            table.length!level = table.length!level + pageSize;
        }
    L_know_index:
        // for the previous level, values are indices to the pages in the current level
        addValue!(level-1)(next_lvl_index, 1);
        ptr = table.slice!level; //re-load the slice after moves
    }

    // idx - full-width index to fill with v (full-width index != key)
    // fills everything in the range of [curIndex, idx) with filler
    void putAt(size_t idx, Value v)
    {
        assert(idx >= curIndex);
        immutable numFillers = idx - curIndex;
        addValue!lastLevel(defValue, numFillers);
        addValue!lastLevel(v, 1);
        curIndex = idx + 1;
    }

    // ditto, but sets the range of [idxA, idxB) to v
    void putRangeAt(size_t idxA, size_t idxB, Value v)
    {
        assert(idxA >= curIndex);
        assert(idxB >= idxA);
        size_t numFillers = idxA - curIndex;
        addValue!lastLevel(defValue, numFillers);
        addValue!lastLevel(v, idxB - idxA);
        curIndex = idxB; // open-right
    }

    enum errMsg = "non-monotonic prefix function(s), an unsorted range or "~
        "duplicate key->value mapping";

public:
    /**
        Construct a builder, where $(D filler) is a value
        to indicate empty slots (or "not found" condition).
    */
    this(Value filler)
    {
        curIndex = 0;
        defValue = filler;
        // zeros-page index, ones-page index
        foreach (ref v; state)
            v = ConstructState(size_t.max, size_t.max);
        table = typeof(table)(indices);
        // one page per level is a bootstrap minimum
        foreach (i, Pred; Prefix)
            table.length!i = (1 << Pred.bitSize);
    }

    /**
        Put a value $(D v) into interval as
        mapped by keys from $(D a) to $(D b).
        All slots prior to $(D a) are filled with
        the default filler.
    */
    void putRange(Key a, Key b, Value v)
    {
        auto idxA = getIndex(a), idxB = getIndex(b);
        // indexes of key should always grow
        enforce(idxB >= idxA && idxA >= curIndex, errMsg);
        putRangeAt(idxA, idxB, v);
    }

    /**
        Put a value $(D v) into slot mapped by $(D key).
        All slots prior to $(D key) are filled with the
        default filler.
    */
    void putValue(Key key, Value v)
    {
        import std.conv : text;
        auto idx = getIndex(key);
        enforce(idx >= curIndex, text(errMsg, " ", idx));
        putAt(idx, v);
    }

    /// Finishes construction of Trie, yielding an immutable Trie instance.
    auto build()
    {
        static if (maxIndex != 0) // doesn't cover full range of size_t
        {
            assert(curIndex <= maxIndex);
            addValue!lastLevel(defValue, maxIndex - curIndex);
        }
        else
        {
            if (curIndex != 0 // couldn't wrap around
                || (Prefix.length != 1 && indices[lastLevel] == 0)) // can be just empty
            {
                addValue!lastLevel(defValue, size_t.max - curIndex);
                addValue!lastLevel(defValue, 1);
            }
            // else curIndex already completed the full range of size_t by wrapping around
        }
        return Trie!(V, Key, maxIndex, Prefix)(table);
    }
}

/**
    $(P A generic Trie data-structure for a fixed number of stages.
    The design goal is optimal speed with smallest footprint size.
    )
    $(P It's intentionally read-only and doesn't provide constructors.
     To construct one use a special builder,
     see $(LREF TrieBuilder) and $(LREF buildTrie).
    )

*/
@trusted private struct Trie(Value, Key, Args...)
if (isValidPrefixForTrie!(Key, Args)
    || (isValidPrefixForTrie!(Key, Args[1..$])
    && is(typeof(Args[0]) : size_t)))
{
    import std.range.primitives : isOutputRange;
    static if (is(typeof(Args[0]) : size_t))
    {
        private enum maxIndex = Args[0];
        private enum hasBoundsCheck = true;
        private alias Prefix = Args[1..$];
    }
    else
    {
        private enum hasBoundsCheck = false;
        private alias Prefix = Args;
    }

    private this()(typeof(_table) table)
    {
        _table = table;
    }

    // only for constant Tries constructed from precompiled tables
    private this()(const(size_t)[] offsets, const(size_t)[] sizes,
        const(size_t)[] data) const
    {
        _table = typeof(_table)(offsets, sizes, data);
    }

    /**
        $(P Lookup the $(D key) in this $(D Trie). )

        $(P The lookup always succeeds if key fits the domain
        provided during construction. The whole domain defined
        is covered so instead of not found condition
        the sentinel (filler) value could be used. )

        $(P See $(LREF buildTrie), $(LREF TrieBuilder) for how to
        define a domain of $(D Trie) keys and the sentinel value. )

        Note:
        Domain range-checking is only enabled in debug builds
        and results in assertion failure.
    */
    TypeOfBitPacked!Value opIndex()(Key key) const
    {
        static if (hasBoundsCheck)
            assert(mapTrieIndex!Prefix(key) < maxIndex);
        size_t idx;
        alias p = Prefix;
        idx = cast(size_t) p[0](key);
        foreach (i, v; p[0..$-1])
            idx = cast(size_t)((_table.ptr!i[idx]<<p[i+1].bitSize) + p[i+1](key));
        return _table.ptr!(p.length-1)[idx];
    }

    ///
    @property size_t bytes(size_t n=size_t.max)() const
    {
        return _table.bytes!n;
    }

    ///
    @property size_t pages(size_t n)() const
    {
        return (bytes!n+2^^(Prefix[n].bitSize-1))
                /2^^Prefix[n].bitSize;
    }

    ///
    void store(OutRange)(scope OutRange sink) const
        if (isOutputRange!(OutRange, char))
    {
        _table.store(sink);
    }

private:
    MultiArray!(idxTypes!(Key, fullBitSize!(Prefix), Prefix[0..$]), Value) _table;
}

// create a tuple of 'sliceBits' that slice the 'top' of bits into pieces of sizes 'sizes'
// left-to-right, the most significant bits first
template GetBitSlicing(size_t top, sizes...)
{
    static if (sizes.length > 0)
        alias GetBitSlicing =
            AliasSeq!(sliceBits!(top - sizes[0], top),
                      GetBitSlicing!(top - sizes[0], sizes[1..$]));
    else
        alias GetBitSlicing = AliasSeq!();
}

template callableWith(T)
{
    template callableWith(alias Pred)
    {
        static if (!is(typeof(Pred(T.init))))
            enum callableWith = false;
        else
        {
            alias Result = typeof(Pred(T.init));
            enum callableWith = isBitPackableType!(TypeOfBitPacked!(Result));
        }
    }
}

/*
    Check if $(D Prefix) is a valid set of predicates
    for $(D Trie) template having $(D Key) as the type of keys.
    This requires all predicates to be callable, take
    single argument of type $(D Key) and return unsigned value.
*/
template isValidPrefixForTrie(Key, Prefix...)
{
    import std.meta : allSatisfy;
    enum isValidPrefixForTrie = allSatisfy!(callableWith!Key, Prefix); // TODO: tighten the screws
}

/*
    Check if $(D Args) is a set of maximum key value followed by valid predicates
    for $(D Trie) template having $(D Key) as the type of keys.
*/
template isValidArgsForTrie(Key, Args...)
{
    static if (Args.length > 1)
    {
        enum isValidArgsForTrie = isValidPrefixForTrie!(Key, Args)
            || (isValidPrefixForTrie!(Key, Args[1..$]) && is(typeof(Args[0]) : Key));
    }
    else
        enum isValidArgsForTrie = isValidPrefixForTrie!Args;
}

@property size_t sumOfIntegerTuple(ints...)()
{
    size_t count=0;
    foreach (v; ints)
        count += v;
    return count;
}

/**
    A shorthand for creating a custom multi-level fixed Trie
    from a $(D CodepointSet). $(D sizes) are numbers of bits per level,
    with the most significant bits used first.

    Note: The sum of $(D sizes) must be equal 21.

    See_Also: $(LREF toTrie), which is even simpler.

    Example:
    ---
    {
        import std.stdio;
        auto set = unicode("Number");
        auto trie = codepointSetTrie!(8, 5, 8)(set);
        writeln("Input code points to test:");
        foreach (line; stdin.byLine)
        {
            int count=0;
            foreach (dchar ch; line)
                if (trie[ch])// is number
                    count++;
            writefln("Contains %d number code points.", count);
        }
    }
    ---
*/
public template codepointSetTrie(sizes...)
if (sumOfIntegerTuple!sizes == 21)
{
    auto codepointSetTrie(Set)(Set set)
        if (isCodepointSet!Set)
    {
        auto builder = TrieBuilder!(bool, dchar, lastDchar+1, GetBitSlicing!(21, sizes))(false);
        foreach (ival; set.byInterval)
            builder.putRange(ival[0], ival[1], true);
        return builder.build();
    }
}

/// Type of Trie generated by codepointSetTrie function.
public template CodepointSetTrie(sizes...)
if (sumOfIntegerTuple!sizes == 21)
{
    alias Prefix = GetBitSlicing!(21, sizes);
    alias CodepointSetTrie = typeof(TrieBuilder!(bool, dchar, lastDchar+1, Prefix)(false).build());
}

/**
    A slightly more general tool for building fixed $(D Trie)
    for the Unicode data.

    Specifically unlike $(D codepointSetTrie) it's allows creating mappings
    of $(D dchar) to an arbitrary type $(D T).

    Note: Overload taking $(D CodepointSet)s will naturally convert
    only to bool mapping $(D Trie)s.
*/
public template codepointTrie(T, sizes...)
if (sumOfIntegerTuple!sizes == 21)
{
    alias Prefix = GetBitSlicing!(21, sizes);

    static if (is(TypeOfBitPacked!T == bool))
    {
        auto codepointTrie(Set)(in Set set)
            if (isCodepointSet!Set)
        {
            return codepointSetTrie(set);
        }
    }

    auto codepointTrie()(T[dchar] map, T defValue=T.init)
    {
        return buildTrie!(T, dchar, Prefix)(map, defValue);
    }

    // unsorted range of pairs
    auto codepointTrie(R)(R range, T defValue=T.init)
        if (isInputRange!R
            && is(typeof(ElementType!R.init[0]) : T)
            && is(typeof(ElementType!R.init[1]) : dchar))
    {
        // build from unsorted array of pairs
        // TODO: expose index sorting functions for Trie
        return buildTrie!(T, dchar, Prefix)(range, defValue, true);
    }
}

@system pure unittest
{
    import std.algorithm.comparison : max;
    import std.algorithm.searching : count;

    // pick characters from the Greek script
    auto set = unicode.Greek;

    // a user-defined property (or an expensive function)
    // that we want to look up
    static uint luckFactor(dchar ch)
    {
        // here we consider a character lucky
        // if its code point has a lot of identical hex-digits
        // e.g. arabic letter DDAL (\u0688) has a "luck factor" of 2
        ubyte[6] nibbles; // 6 4-bit chunks of code point
        uint value = ch;
        foreach (i; 0 .. 6)
        {
            nibbles[i] = value & 0xF;
            value >>= 4;
        }
        uint luck;
        foreach (n; nibbles)
            luck = cast(uint) max(luck, count(nibbles[], n));
        return luck;
    }

    // only unsigned built-ins are supported at the moment
    alias LuckFactor = BitPacked!(uint, 3);

    // create a temporary associative array (AA)
    LuckFactor[dchar] map;
    foreach (ch; set.byCodepoint)
        map[ch] = LuckFactor(luckFactor(ch));

    // bits per stage are chosen randomly, fell free to optimize
    auto trie = codepointTrie!(LuckFactor, 8, 5, 8)(map);

    // from now on the AA is not needed
    foreach (ch; set.byCodepoint)
        assert(trie[ch] == luckFactor(ch)); // verify
    // CJK is not Greek, thus it has the default value
    assert(trie['\u4444'] == 0);
    // and here is a couple of quite lucky Greek characters:
    // Greek small letter epsilon with dasia
    assert(trie['\u1F11'] == 3);
    // Ancient Greek metretes sign
    assert(trie['\U00010181'] == 3);

}

/// Type of Trie as generated by codepointTrie function.
public template CodepointTrie(T, sizes...)
if (sumOfIntegerTuple!sizes == 21)
{
    alias Prefix = GetBitSlicing!(21, sizes);
    alias CodepointTrie = typeof(TrieBuilder!(T, dchar, lastDchar+1, Prefix)(T.init).build());
}

package template cmpK0(alias Pred)
{
    import std.typecons : Tuple;
    static bool cmpK0(Value, Key)
        (Tuple!(Value, Key) a, Tuple!(Value, Key) b)
    {
        return Pred(a[1]) < Pred(b[1]);
    }
}

/**
    The most general utility for construction of $(D Trie)s
    short of using $(D TrieBuilder) directly.

    Provides a number of convenience overloads.
    $(D Args) is tuple of maximum key value followed by
    predicates to construct index from key.

    Alternatively if the first argument is not a value convertible to $(D Key)
    then the whole tuple of $(D Args) is treated as predicates
    and the maximum Key is deduced from predicates.
*/
private template buildTrie(Value, Key, Args...)
if (isValidArgsForTrie!(Key, Args))
{
    static if (is(typeof(Args[0]) : Key)) // prefix starts with upper bound on Key
    {
        alias Prefix = Args[1..$];
    }
    else
        alias Prefix = Args;

    alias getIndex = mapTrieIndex!(Prefix);

    // for multi-sort
    template GetComparators(size_t n)
    {
        static if (n > 0)
            alias GetComparators =
                AliasSeq!(GetComparators!(n-1), cmpK0!(Prefix[n-1]));
        else
            alias GetComparators = AliasSeq!();
    }

    /*
        Build $(D Trie) from a range of a Key-Value pairs,
        assuming it is sorted by Key as defined by the following lambda:
        ------
        (a, b) => mapTrieIndex!(Prefix)(a) < mapTrieIndex!(Prefix)(b)
        ------
        Exception is thrown if it's detected that the above order doesn't hold.

        In other words $(LREF mapTrieIndex) should be a
        monotonically increasing function that maps $(D Key) to an integer.

        See_Also: $(REF sort, std,_algorithm),
        $(REF SortedRange, std,_range),
        $(REF setUnion, std,_algorithm).
    */
    auto buildTrie(Range)(Range range, Value filler=Value.init)
        if (isInputRange!Range && is(typeof(Range.init.front[0]) : Value)
            && is(typeof(Range.init.front[1]) : Key))
    {
        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);
        foreach (v; range)
            builder.putValue(v[1], v[0]);
        return builder.build();
    }

    /*
        If $(D Value) is bool (or BitPacked!(bool, x)) then it's possible
        to build $(D Trie) from a range of open-right intervals of $(D Key)s.
        The requirement  on the ordering of keys (and the behavior on the
        violation of it) is the same as for Key-Value range overload.

        Intervals denote ranges of !$(D filler) i.e. the opposite of filler.
        If no filler provided keys inside of the intervals map to true,
        and $(D filler) is false.
    */
    auto buildTrie(Range)(Range range, Value filler=Value.init)
        if (is(TypeOfBitPacked!Value ==  bool)
            && isInputRange!Range && is(typeof(Range.init.front[0]) : Key)
            && is(typeof(Range.init.front[1]) : Key))
    {
        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);
        foreach (ival; range)
            builder.putRange(ival[0], ival[1], !filler);
        return builder.build();
    }

    auto buildTrie(Range)(Range range, Value filler, bool unsorted)
        if (isInputRange!Range
            && is(typeof(Range.init.front[0]) : Value)
            && is(typeof(Range.init.front[1]) : Key))
    {
        import std.algorithm.sorting : multiSort;
        alias Comps = GetComparators!(Prefix.length);
        if (unsorted)
            multiSort!(Comps)(range);
        return buildTrie(range, filler);
    }

    /*
        If $(D Value) is bool (or BitPacked!(bool, x)) then it's possible
        to build $(D Trie) simply from an input range of $(D Key)s.
        The requirement  on the ordering of keys (and the behavior on the
        violation of it) is the same as for Key-Value range overload.

        Keys found in range denote !$(D filler) i.e. the opposite of filler.
        If no filler provided keys map to true, and $(D filler) is false.
    */
    auto buildTrie(Range)(Range range, Value filler=Value.init)
        if (is(TypeOfBitPacked!Value ==  bool)
            && isInputRange!Range && is(typeof(Range.init.front) : Key))
    {
        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);
        foreach (v; range)
            builder.putValue(v, !filler);
        return builder.build();
    }

    /*
        If $(D Key) is unsigned integer $(D Trie) could be constructed from array
        of values where array index serves as key.
    */
    auto buildTrie()(Value[] array, Value filler=Value.init)
        if (isUnsigned!Key)
    {
        auto builder = TrieBuilder!(Value, Key, Prefix)(filler);
        foreach (idx, v; array)
            builder.putValue(idx, v);
        return builder.build();
    }

    /*
        Builds $(D Trie) from associative array.
    */
    auto buildTrie(Key, Value)(Value[Key] map, Value filler=Value.init)
    {
        import std.array : array;
        import std.range : zip;
        auto range = array(zip(map.values, map.keys));
        return buildTrie(range, filler, true); // sort it
    }
}

// helper in place of assumeSize to
//reduce mangled name & help DMD inline Trie functors
struct clamp(size_t bits)
{
    static size_t opCall(T)(T arg){ return arg; }
    enum bitSize = bits;
}

struct clampIdx(size_t idx, size_t bits)
{
    static size_t opCall(T)(T arg){ return arg[idx]; }
    enum bitSize = bits;
}

/**
    Conceptual type that outlines the common properties of all UTF Matchers.

    Note: For illustration purposes only, every method
    call results in assertion failure.
    Use $(LREF utfMatcher) to obtain a concrete matcher
    for UTF-8 or UTF-16 encodings.
*/
public struct MatcherConcept
{
    /**
        $(P Perform a semantic equivalent 2 operations:
        decoding a $(CODEPOINT) at front of $(D inp) and testing if
        it belongs to the set of $(CODEPOINTS) of this matcher. )

        $(P The effect on $(D inp) depends on the kind of function called:)

        $(P Match. If the codepoint is found in the set then range $(D inp)
        is advanced by its size in $(S_LINK Code unit, code units),
        otherwise the range is not modifed.)

        $(P Skip. The range is always advanced by the size
        of the tested $(CODEPOINT) regardless of the result of test.)

        $(P Test. The range is left unaffected regardless
        of the result of test.)
    */
    public bool match(Range)(ref Range inp)
        if (isRandomAccessRange!Range && is(ElementType!Range : char))
    {
       assert(false);
    }

    ///ditto
    public bool skip(Range)(ref Range inp)
        if (isRandomAccessRange!Range && is(ElementType!Range : char))
    {
        assert(false);
    }

    ///ditto
    public bool test(Range)(ref Range inp)
        if (isRandomAccessRange!Range && is(ElementType!Range : char))
    {
        assert(false);
    }
    ///
    @safe unittest
    {
        string truth = "2² = 4";
        auto m = utfMatcher!char(unicode.Number);
        assert(m.match(truth)); // '2' is a number all right
        assert(truth == "² = 4"); // skips on match
        assert(m.match(truth)); // so is the superscript '2'
        assert(!m.match(truth)); // space is not a number
        assert(truth == " = 4"); // unaffected on no match
        assert(!m.skip(truth)); // same test ...
        assert(truth == "= 4"); // but skips a codepoint regardless
        assert(!m.test(truth)); // '=' is not a number
        assert(truth == "= 4"); // test never affects argument
    }

    /**
        Advanced feature - provide direct access to a subset of matcher based a
        set of known encoding lengths. Lengths are provided in
        $(S_LINK Code unit, code units). The sub-matcher then may do less
        operations per any $(D test)/$(D match).

        Use with care as the sub-matcher won't match
        any $(CODEPOINTS) that have encoded length that doesn't belong
        to the selected set of lengths. Also the sub-matcher object references
        the parent matcher and must not be used past the liftetime
        of the latter.

        Another caveat of using sub-matcher is that skip is not available
        preciesly because sub-matcher doesn't detect all lengths.
    */
    @property auto subMatcher(Lengths...)()
    {
        assert(0);
        return this;
    }

    @safe unittest
    {
        auto m = utfMatcher!char(unicode.Number);
        string square = "2²";
        // about sub-matchers
        assert(!m.subMatcher!(2,3,4).test(square)); // ASCII no covered
        assert(m.subMatcher!1.match(square)); // ASCII-only, works
        assert(!m.subMatcher!1.test(square)); // unicode '²'
        assert(m.subMatcher!(2,3,4).match(square));  //
        assert(square == "");
        wstring wsquare = "2²";
        auto m16 = utfMatcher!wchar(unicode.Number);
        // may keep ref, but the orignal (m16) must be kept alive
        auto bmp = m16.subMatcher!1;
        assert(bmp.match(wsquare)); // Okay, in basic multilingual plan
        assert(bmp.match(wsquare)); // And '²' too
    }
}

/**
    Test if $(D M) is an UTF Matcher for ranges of $(D Char).
*/
public enum isUtfMatcher(M, C) = __traits(compiles, (){
    C[] s;
    auto d = s.decoder;
    M m;
    assert(is(typeof(m.match(d)) == bool));
    assert(is(typeof(m.test(d)) == bool));
    static if (is(typeof(m.skip(d))))
    {
        assert(is(typeof(m.skip(d)) == bool));
        assert(is(typeof(m.skip(s)) == bool));
    }
    assert(is(typeof(m.match(s)) == bool));
    assert(is(typeof(m.test(s)) == bool));
});

@safe unittest
{
    alias CharMatcher = typeof(utfMatcher!char(CodepointSet.init));
    alias WcharMatcher = typeof(utfMatcher!wchar(CodepointSet.init));
    static assert(isUtfMatcher!(CharMatcher, char));
    static assert(isUtfMatcher!(CharMatcher, immutable(char)));
    static assert(isUtfMatcher!(WcharMatcher, wchar));
    static assert(isUtfMatcher!(WcharMatcher, immutable(wchar)));
}

enum Mode {
    alwaysSkip,
    neverSkip,
    skipOnMatch
}

mixin template ForwardStrings()
{
    private bool fwdStr(string fn, C)(ref C[] str) const pure
    {
        import std.utf : byCodeUnit;
        alias type = typeof(byCodeUnit(str));
        return mixin(fn~"(*cast(type*)&str)");
    }
}

template Utf8Matcher()
{
    enum validSize(int sz) = sz >= 1 && sz <= 4;

    void badEncoding() pure @safe
    {
        import std.utf : UTFException;
        throw new UTFException("Invalid UTF-8 sequence");
    }

    //for 1-stage ASCII
    alias AsciiSpec = AliasSeq!(bool, char, clamp!7);
    //for 2-stage lookup of 2 byte UTF-8 sequences
    alias Utf8Spec2 = AliasSeq!(bool, char[2],
        clampIdx!(0, 5), clampIdx!(1, 6));
    //ditto for 3 byte
    alias Utf8Spec3 = AliasSeq!(bool, char[3],
        clampIdx!(0, 4),
        clampIdx!(1, 6),
        clampIdx!(2, 6)
    );
    //ditto for 4 byte
    alias Utf8Spec4 = AliasSeq!(bool, char[4],
        clampIdx!(0, 3), clampIdx!(1, 6),
        clampIdx!(2, 6), clampIdx!(3, 6)
    );
    alias Tables = AliasSeq!(
        typeof(TrieBuilder!(AsciiSpec)(false).build()),
        typeof(TrieBuilder!(Utf8Spec2)(false).build()),
        typeof(TrieBuilder!(Utf8Spec3)(false).build()),
        typeof(TrieBuilder!(Utf8Spec4)(false).build())
    );
    alias Table(int size) = Tables[size-1];

    enum leadMask(size_t size) = (cast(size_t) 1<<(7 - size))-1;
    enum encMask(size_t size) = ((1 << size)-1)<<(8-size);

    char truncate()(char ch) pure @safe
    {
        ch -= 0x80;
        if (ch < 0x40)
        {
            return ch;
        }
        else
        {
            badEncoding();
            return cast(char) 0;
        }
    }

    static auto encode(size_t sz)(dchar ch)
        if (sz > 1)
    {
        import std.utf : encodeUTF = encode;
        char[4] buf;
        encodeUTF(buf, ch);
        char[sz] ret;
        buf[0] &= leadMask!sz;
        foreach (n; 1 .. sz)
            buf[n] = buf[n] & 0x3f; //keep 6 lower bits
        ret[] = buf[0 .. sz];
        return ret;
    }

    auto build(Set)(Set set)
    {
        import std.algorithm.iteration : map;
        auto ascii = set & unicode.ASCII;
        auto utf8_2 = set & CodepointSet(0x80, 0x800);
        auto utf8_3 = set & CodepointSet(0x800, 0x1_0000);
        auto utf8_4 = set & CodepointSet(0x1_0000, lastDchar+1);
        auto asciiT = ascii.byCodepoint.map!(x=>cast(char) x).buildTrie!(AsciiSpec);
        auto utf8_2T = utf8_2.byCodepoint.map!(x=>encode!2(x)).buildTrie!(Utf8Spec2);
        auto utf8_3T = utf8_3.byCodepoint.map!(x=>encode!3(x)).buildTrie!(Utf8Spec3);
        auto utf8_4T = utf8_4.byCodepoint.map!(x=>encode!4(x)).buildTrie!(Utf8Spec4);
        alias Ret = Impl!(1,2,3,4);
        return Ret(asciiT, utf8_2T, utf8_3T, utf8_4T);
    }

    // Bootstrap UTF-8 static matcher interface
    // from 3 primitives: tab!(size), lookup and Sizes
    mixin template DefMatcher()
    {
        import std.format : format;
        import std.meta : Erase, staticIndexOf;
        enum hasASCII = staticIndexOf!(1, Sizes) >= 0;
        alias UniSizes = Erase!(1, Sizes);

        //generate dispatch code sequence for unicode parts
        static auto genDispatch()
        {
            string code;
            foreach (size; UniSizes)
                code ~= format(q{
                    if ((ch & ~leadMask!%d) == encMask!(%d))
                        return lookup!(%d, mode)(inp);
                    else
                }, size, size, size);
            static if (Sizes.length == 4) //covers all code unit cases
                code ~= "{ badEncoding(); return false; }";
            else
                code ~= "return false;"; //may be just fine but not covered
            return code;
        }
        enum dispatch = genDispatch();

        public bool match(Range)(ref Range inp) const pure
            if (isRandomAccessRange!Range && is(ElementType!Range : char))
        {
            enum mode = Mode.skipOnMatch;
            assert(!inp.empty);
            immutable ch = inp[0];
            static if (hasASCII)
            {
                if (ch < 0x80)
                {
                    immutable r = tab!1[ch];
                    if (r)
                        inp.popFront();
                    return r;
                }
                else
                    mixin(dispatch);
            }
            else
                mixin(dispatch);
        }

        static if (Sizes.length == 4) // can skip iff can detect all encodings
        {
            public bool skip(Range)(ref Range inp) const pure @trusted
                if (isRandomAccessRange!Range && is(ElementType!Range : char))
            {
                enum mode = Mode.alwaysSkip;
                assert(!inp.empty);
                auto ch = inp[0];
                static if (hasASCII)
                {
                    if (ch < 0x80)
                    {
                        inp.popFront();
                        return tab!1[ch];
                    }
                    else
                        mixin(dispatch);
                }
                else
                    mixin(dispatch);
            }
        }

        public bool test(Range)(ref Range inp) const pure @trusted
            if (isRandomAccessRange!Range && is(ElementType!Range : char))
        {
            enum mode = Mode.neverSkip;
            assert(!inp.empty);
            auto ch = inp[0];
            static if (hasASCII)
            {
                if (ch < 0x80)
                    return tab!1[ch];
                else
                    mixin(dispatch);
            }
            else
                mixin(dispatch);
        }

        bool match(C)(ref C[] str) const pure @trusted
            if (isSomeChar!C)
        {
            return fwdStr!"match"(str);
        }

        bool skip(C)(ref C[] str) const pure @trusted
            if (isSomeChar!C)
        {
            return fwdStr!"skip"(str);
        }

        bool test(C)(ref C[] str) const pure @trusted
            if (isSomeChar!C)
        {
            return fwdStr!"test"(str);
        }

        mixin ForwardStrings;
    }

    struct Impl(Sizes...)
    {
        import std.meta : allSatisfy, staticMap;
        static assert(allSatisfy!(validSize, Sizes),
            "Only lengths of 1, 2, 3 and 4 code unit are possible for UTF-8");
    private:
        //pick tables for chosen sizes
        alias OurTabs = staticMap!(Table, Sizes);
        OurTabs tables;
        mixin DefMatcher;
        //static disptach helper UTF size ==> table
        alias tab(int i) = tables[i - 1];

        package @property auto subMatcher(SizesToPick...)() @trusted
        {
            return CherryPick!(Impl, SizesToPick)(&this);
        }

        bool lookup(int size, Mode mode, Range)(ref Range inp) const pure @trusted
        {
            import std.typecons : staticIota;
            if (inp.length < size)
            {
                badEncoding();
                return false;
            }
            char[size] needle = void;
            needle[0] = leadMask!size & inp[0];
            foreach (i; staticIota!(1, size))
            {
                needle[i] = truncate(inp[i]);
            }
            //overlong encoding checks
            static if (size == 2)
            {
                //0x80-0x7FF
                //got 6 bits in needle[1], must use at least 8 bits
                //must use at least 2 bits in needle[1]
                if (needle[0] < 2) badEncoding();
            }
            else static if (size == 3)
            {
                //0x800-0xFFFF
                //got 6 bits in needle[2], must use at least 12bits
                //must use 6 bits in needle[1] or anything in needle[0]
                if (needle[0] == 0 && needle[1] < 0x20) badEncoding();
            }
            else static if (size == 4)
            {
                //0x800-0xFFFF
                //got 2x6=12 bits in needle[2 .. 3] must use at least 17bits
                //must use 5 bits (or above) in needle[1] or anything in needle[0]
                if (needle[0] == 0 && needle[1] < 0x10) badEncoding();
            }
            static if (mode == Mode.alwaysSkip)
            {
                inp.popFrontN(size);
                return tab!size[needle];
            }
            else static if (mode == Mode.neverSkip)
            {
                return tab!size[needle];
            }
            else
            {
                static assert(mode == Mode.skipOnMatch);
                if (tab!size[needle])
                {
                    inp.popFrontN(size);
                    return true;
                }
                else
                    return false;
            }
        }
    }

    struct CherryPick(I, Sizes...)
    {
        import std.meta : allSatisfy;
        static assert(allSatisfy!(validSize, Sizes),
            "Only lengths of 1, 2, 3 and 4 code unit are possible for UTF-8");
    private:
        I* m;
        @property ref tab(int i)() const pure { return m.tables[i - 1]; }
        bool lookup(int size, Mode mode, Range)(ref Range inp) const pure
        {
            return m.lookup!(size, mode)(inp);
        }
        mixin DefMatcher;
    }
}

template Utf16Matcher()
{
    enum validSize(int sz) = sz >= 1 && sz <= 2;

    void badEncoding() pure
    {
        import std.utf : UTFException;
        throw new UTFException("Invalid UTF-16 sequence");
    }

    // 1-stage ASCII
    alias AsciiSpec = AliasSeq!(bool, wchar, clamp!7);
    //2-stage BMP
    alias BmpSpec = AliasSeq!(bool, wchar, sliceBits!(7, 16), sliceBits!(0, 7));
    //4-stage - full Unicode
    //assume that 0xD800 & 0xDC00 bits are cleared
    //thus leaving 10 bit per wchar to worry about
    alias UniSpec = AliasSeq!(bool, wchar[2],
        assumeSize!(x=>x[0]>>4, 6), assumeSize!(x=>x[0]&0xf, 4),
        assumeSize!(x=>x[1]>>6, 4), assumeSize!(x=>x[1]&0x3f, 6),
    );
    alias Ascii = typeof(TrieBuilder!(AsciiSpec)(false).build());
    alias Bmp = typeof(TrieBuilder!(BmpSpec)(false).build());
    alias Uni = typeof(TrieBuilder!(UniSpec)(false).build());

    auto encode2(dchar ch)
    {
        ch -= 0x1_0000;
        assert(ch <= 0xF_FFFF);
        wchar[2] ret;
        //do not put surrogate bits, they are sliced off
        ret[0] = cast(wchar)(ch >> 10);
        ret[1] = (ch & 0xFFF);
        return ret;
    }

    auto build(Set)(Set set)
    {
        import std.algorithm.iteration : map;
        auto ascii = set & unicode.ASCII;
        auto bmp = (set & CodepointSet.fromIntervals(0x80, 0xFFFF+1))
            - CodepointSet.fromIntervals(0xD800, 0xDFFF+1);
        auto other = set - (bmp | ascii);
        auto asciiT = ascii.byCodepoint.map!(x=>cast(char) x).buildTrie!(AsciiSpec);
        auto bmpT = bmp.byCodepoint.map!(x=>cast(wchar) x).buildTrie!(BmpSpec);
        auto otherT = other.byCodepoint.map!(x=>encode2(x)).buildTrie!(UniSpec);
        alias Ret = Impl!(1,2);
        return Ret(asciiT, bmpT, otherT);
    }

    //bootstrap full UTF-16 matcher interace from
    //sizeFlags, lookupUni and ascii
    mixin template DefMatcher()
    {
        public bool match(Range)(ref Range inp) const pure @trusted
            if (isRandomAccessRange!Range && is(ElementType!Range : wchar))
        {
            enum mode = Mode.skipOnMatch;
            assert(!inp.empty);
            immutable ch = inp[0];
            static if (sizeFlags & 1)
            {
                if (ch < 0x80)
                {
                  if (ascii[ch])
                  {
                      inp.popFront();
                      return true;
                  }
                  else
                      return false;
                }
                return lookupUni!mode(inp);
            }
            else
                return lookupUni!mode(inp);
        }

        static if (Sizes.length == 2)
        {
            public bool skip(Range)(ref Range inp) const pure @trusted
                if (isRandomAccessRange!Range && is(ElementType!Range : wchar))
            {
                enum mode = Mode.alwaysSkip;
                assert(!inp.empty);
                immutable ch = inp[0];
                static if (sizeFlags & 1)
                {
                    if (ch < 0x80)
                    {
                        inp.popFront();
                        return ascii[ch];
                    }
                    else
                        return lookupUni!mode(inp);
                }
                else
                    return lookupUni!mode(inp);
            }
        }

        public bool test(Range)(ref Range inp) const pure @trusted
            if (isRandomAccessRange!Range && is(ElementType!Range : wchar))
        {
            enum mode = Mode.neverSkip;
            assert(!inp.empty);
            auto ch = inp[0];
            static if (sizeFlags & 1)
                return ch < 0x80 ? ascii[ch] : lookupUni!mode(inp);
            else
                return lookupUni!mode(inp);
        }

        bool match(C)(ref C[] str) const pure @trusted
            if (isSomeChar!C)
        {
            return fwdStr!"match"(str);
        }

        bool skip(C)(ref C[] str) const pure @trusted
            if (isSomeChar!C)
        {
            return fwdStr!"skip"(str);
        }

        bool test(C)(ref C[] str) const pure @trusted
            if (isSomeChar!C)
        {
            return fwdStr!"test"(str);
        }

        mixin ForwardStrings; //dispatch strings to range versions
    }

    struct Impl(Sizes...)
        if (Sizes.length >= 1 && Sizes.length <= 2)
    {
    private:
        import std.meta : allSatisfy;
        static assert(allSatisfy!(validSize, Sizes),
            "Only lengths of 1 and 2 code units are possible in UTF-16");
        static if (Sizes.length > 1)
            enum sizeFlags = Sizes[0] | Sizes[1];
        else
            enum sizeFlags = Sizes[0];

        static if (sizeFlags & 1)
        {
            Ascii ascii;
            Bmp bmp;
        }
        static if (sizeFlags & 2)
        {
            Uni uni;
        }
        mixin DefMatcher;

        package @property auto subMatcher(SizesToPick...)() @trusted
        {
            return CherryPick!(Impl, SizesToPick)(&this);
        }

        bool lookupUni(Mode mode, Range)(ref Range inp) const pure
        {
            wchar x = cast(wchar)(inp[0] - 0xD800);
            //not a high surrogate
            if (x > 0x3FF)
            {
                //low surrogate
                if (x <= 0x7FF) badEncoding();
                static if (sizeFlags & 1)
                {
                    auto ch = inp[0];
                    static if (mode == Mode.alwaysSkip)
                        inp.popFront();
                    static if (mode == Mode.skipOnMatch)
                    {
                        if (bmp[ch])
                        {
                            inp.popFront();
                            return true;
                        }
                        else
                            return false;
                    }
                    else
                        return bmp[ch];
                }
                else //skip is not available for sub-matchers, so just false
                    return false;
            }
            else
            {
                static if (sizeFlags & 2)
                {
                    if (inp.length < 2)
                        badEncoding();
                    wchar y = cast(wchar)(inp[1] - 0xDC00);
                    //not a low surrogate
                    if (y > 0x3FF)
                        badEncoding();
                    wchar[2] needle = [inp[0] & 0x3ff, inp[1] & 0x3ff];
                    static if (mode == Mode.alwaysSkip)
                        inp.popFrontN(2);
                    static if (mode == Mode.skipOnMatch)
                    {
                        if (uni[needle])
                        {
                            inp.popFrontN(2);
                            return true;
                        }
                        else
                            return false;
                    }
                    else
                        return uni[needle];
                }
                else //ditto
                    return false;
            }
        }
    }

    struct CherryPick(I, Sizes...)
        if (Sizes.length >= 1 && Sizes.length <= 2)
    {
    private:
        import std.meta : allSatisfy;
        I* m;
        enum sizeFlags = I.sizeFlags;

        static if (sizeFlags & 1)
        {
            @property ref ascii()() const pure{ return m.ascii; }
        }

        bool lookupUni(Mode mode, Range)(ref Range inp) const pure
        {
            return m.lookupUni!mode(inp);
        }
        mixin DefMatcher;
        static assert(allSatisfy!(validSize, Sizes),
            "Only lengths of 1 and 2 code units are possible in UTF-16");
    }
}

private auto utf8Matcher(Set)(Set set) @trusted
{
    return Utf8Matcher!().build(set);
}

private auto utf16Matcher(Set)(Set set) @trusted
{
    return Utf16Matcher!().build(set);
}

/**
    Constructs a matcher object
    to classify $(CODEPOINTS) from the $(D set) for encoding
    that has $(D Char) as code unit.

    See $(LREF MatcherConcept) for API outline.
*/
public auto utfMatcher(Char, Set)(Set set) @trusted
if (isCodepointSet!Set)
{
    static if (is(Char : char))
        return utf8Matcher(set);
    else static if (is(Char : wchar))
        return utf16Matcher(set);
    else static if (is(Char : dchar))
        static assert(false, "UTF-32 needs no decoding,
            and thus not supported by utfMatcher");
    else
        static assert(false, "Only character types 'char' and 'wchar' are allowed");
}


//a range of code units, packed with index to speed up forward iteration
package auto decoder(C)(C[] s, size_t offset=0) @safe pure nothrow @nogc
if (is(C : wchar) || is(C : char))
{
    static struct Decoder
    {
    pure nothrow:
        C[] str;
        size_t idx;
        @property C front(){ return str[idx]; }
        @property C back(){ return str[$-1]; }
        void popFront(){ idx++; }
        void popBack(){ str = str[0..$-1]; }
        void popFrontN(size_t n){ idx += n; }
        @property bool empty(){ return idx == str.length; }
        @property auto save(){ return this; }
        auto opIndex(size_t i){ return str[idx+i]; }
        @property size_t length(){ return str.length - idx; }
        alias opDollar = length;
        auto opSlice(size_t a, size_t b){ return Decoder(str[0 .. idx+b], idx+a); }
    }
    static assert(isRandomAccessRange!Decoder);
    static assert(is(ElementType!Decoder : C));
    return Decoder(s, offset);
}

@safe unittest
{
    string rs = "hi! ﾈемног砀 текста";
    auto codec = rs.decoder;
    auto utf8 =  utf8Matcher(unicode.Letter);
    auto asc = utf8.subMatcher!(1);
    auto uni = utf8.subMatcher!(2,3,4);
    assert(asc.test(codec));
    assert(!uni.match(codec));
    assert(utf8.skip(codec));
    assert(codec.idx == 1);

    assert(!uni.match(codec));
    assert(asc.test(codec));
    assert(utf8.skip(codec));
    assert(codec.idx == 2);
    assert(!asc.match(codec));

    assert(!utf8.test(codec));
    assert(!utf8.skip(codec));

    assert(!asc.test(codec));
    assert(!utf8.test(codec));
    assert(!utf8.skip(codec));
    assert(utf8.test(codec));
    foreach (i; 0 .. 7)
    {
        assert(!asc.test(codec));
        assert(uni.test(codec));
        assert(utf8.skip(codec));
    }
    assert(!utf8.test(codec));
    assert(!utf8.skip(codec));
    //the same with match where applicable
    codec = rs.decoder;
    assert(utf8.match(codec));
    assert(codec.idx == 1);
    assert(utf8.match(codec));
    assert(codec.idx == 2);
    assert(!utf8.match(codec));
    assert(codec.idx == 2);
    assert(!utf8.skip(codec));
    assert(!utf8.skip(codec));

    foreach (i; 0 .. 7)
    {
        assert(!asc.test(codec));
        assert(utf8.test(codec));
        assert(utf8.match(codec));
    }
    auto i = codec.idx;
    assert(!utf8.match(codec));
    assert(codec.idx == i);
}

@safe unittest
{
    import std.range : stride;
    static bool testAll(Matcher, Range)(ref Matcher m, ref Range r)
    {
        bool t = m.test(r);
        auto save = r.idx;
        assert(t == m.match(r));
        assert(r.idx == save || t); //ether no change or was match
        r.idx = save;
        static if (is(typeof(m.skip(r))))
        {
            assert(t == m.skip(r));
            assert(r.idx != save); //always changed
            r.idx = save;
        }
        return t;
    }
    auto utf16 = utfMatcher!wchar(unicode.L);
    auto bmp = utf16.subMatcher!1;
    auto nonBmp = utf16.subMatcher!1;
    auto utf8 = utfMatcher!char(unicode.L);
    auto ascii = utf8.subMatcher!1;
    auto uni2 = utf8.subMatcher!2;
    auto uni3 = utf8.subMatcher!3;
    auto uni24 = utf8.subMatcher!(2,4);
    foreach (ch; unicode.L.byCodepoint.stride(3))
    {
        import std.utf : encode;
        char[4] buf;
        wchar[2] buf16;
        auto len = encode(buf, ch);
        auto len16 = encode(buf16, ch);
        auto c8 = buf[0 .. len].decoder;
        auto c16 = buf16[0 .. len16].decoder;
        assert(testAll(utf16, c16));
        assert(testAll(bmp, c16) || len16 != 1);
        assert(testAll(nonBmp, c16) || len16 != 2);

        assert(testAll(utf8, c8));

        //submatchers return false on out of their domain
        assert(testAll(ascii, c8) || len != 1);
        assert(testAll(uni2, c8) || len != 2);
        assert(testAll(uni3, c8) || len != 3);
        assert(testAll(uni24, c8) || (len != 2 && len != 4));
    }
}

// cover decode fail cases of Matcher
@system unittest
{
    import std.algorithm.iteration : map;
    import std.exception : collectException;
    import std.format : format;
    auto utf16 = utfMatcher!wchar(unicode.L);
    auto utf8 = utfMatcher!char(unicode.L);
    //decode failure cases UTF-8
    alias fails8 = AliasSeq!("\xC1", "\x80\x00","\xC0\x00", "\xCF\x79",
        "\xFF\x00\0x00\0x00\x00", "\xC0\0x80\0x80\x80", "\x80\0x00\0x00\x00",
        "\xCF\x00\0x00\0x00\x00");
    foreach (msg; fails8)
    {
        assert(collectException((){
            auto s = msg;
            size_t idx = 0;
            utf8.test(s);
        }()), format("%( %2x %)", cast(ubyte[]) msg));
    }
    //decode failure cases UTF-16
    alias fails16 = AliasSeq!([0xD811], [0xDC02]);
    foreach (msg; fails16)
    {
        assert(collectException((){
            auto s = msg.map!(x => cast(wchar) x);
            utf16.test(s);
        }()));
    }
}

/++
    Convenience function to construct optimal configurations for
    packed Trie from any $(D set) of $(CODEPOINTS).

    The parameter $(D level) indicates the number of trie levels to use,
    allowed values are: 1, 2, 3 or 4. Levels represent different trade-offs
    speed-size wise.

    $(P Level 1 is fastest and the most memory hungry (a bit array). )
    $(P Level 4 is the slowest and has the smallest footprint. )

    See the $(S_LINK Synopsis, Synopsis) section for example.

    Note:
    Level 4 stays very practical (being faster and more predictable)
    compared to using direct lookup on the $(D set) itself.


+/
public auto toTrie(size_t level, Set)(Set set)
if (isCodepointSet!Set)
{
    static if (level == 1)
        return codepointSetTrie!(21)(set);
    else static if (level == 2)
        return codepointSetTrie!(10, 11)(set);
    else static if (level == 3)
        return codepointSetTrie!(8, 5, 8)(set);
    else static if (level == 4)
         return codepointSetTrie!(6, 4, 4, 7)(set);
    else
        static assert(false,
            "Sorry, toTrie doesn't support levels > 4, use codepointSetTrie directly");
}

/**
    $(P Builds a $(D Trie) with typically optimal speed-size trade-off
    and wraps it into a delegate of the following type:
    $(D bool delegate(dchar ch)). )

    $(P Effectively this creates a 'tester' lambda suitable
    for algorithms like std.algorithm.find that take unary predicates. )

    See the $(S_LINK Synopsis, Synopsis) section for example.
*/
public auto toDelegate(Set)(Set set)
if (isCodepointSet!Set)
{
    // 3 is very small and is almost as fast as 2-level (due to CPU caches?)
    auto t = toTrie!3(set);
    return (dchar ch) => t[ch];
}

/**
    $(P Opaque wrapper around unsigned built-in integers and
    code unit (char/wchar/dchar) types.
    Parameter $(D sz) indicates that the value is confined
    to the range of [0, 2^^sz$(RPAREN). With this knowledge it can be
    packed more tightly when stored in certain
    data-structures like trie. )

    Note:
    $(P The $(D BitPacked!(T, sz)) is implicitly convertible to $(D T)
    but not vise-versa. Users have to ensure the value fits in
    the range required and use the $(D cast)
    operator to perform the conversion.)
*/
struct BitPacked(T, size_t sz)
if (isIntegral!T || is(T:dchar))
{
    enum bitSize = sz;
    T _value;
    alias _value this;
}

/*
    Depending on the form of the passed argument $(D bitSizeOf) returns
    the amount of bits required to represent a given type
    or a return type of a given functor.
*/
template bitSizeOf(Args...)
if (Args.length == 1)
{
    import std.traits : ReturnType;
    alias T = Args[0];
    static if (__traits(compiles, { size_t val = T.bitSize; })) //(is(typeof(T.bitSize) : size_t))
    {
        enum bitSizeOf = T.bitSize;
    }
    else static if (is(ReturnType!T dummy == BitPacked!(U, bits), U, size_t bits))
    {
        enum bitSizeOf = bitSizeOf!(ReturnType!T);
    }
    else
    {
        enum bitSizeOf = T.sizeof*8;
    }
}

/**
    Tests if $(D T) is some instantiation of $(LREF BitPacked)!(U, x)
    and thus suitable for packing.
*/
template isBitPacked(T)
{
    static if (is(T dummy == BitPacked!(U, bits), U, size_t bits))
        enum isBitPacked = true;
    else
        enum isBitPacked = false;
}

/**
    Gives the type $(D U) from $(LREF BitPacked)!(U, x)
    or $(D T) itself for every other type.
*/
template TypeOfBitPacked(T)
{
    static if (is(T dummy == BitPacked!(U, bits), U, size_t bits))
        alias TypeOfBitPacked = U;
    else
        alias TypeOfBitPacked = T;
}

/*
    Wrapper, used in definition of custom data structures from $(D Trie) template.
    Applying it to a unary lambda function indicates that the returned value always
    fits within $(D bits) of bits.
*/
struct assumeSize(alias Fn, size_t bits)
{
    enum bitSize = bits;
    static auto ref opCall(T)(auto ref T arg)
    {
        return Fn(arg);
    }
}

/*
    A helper for defining lambda function that yields a slice
    of certain bits from an unsigned integral value.
    The resulting lambda is wrapped in assumeSize and can be used directly
    with $(D Trie) template.
*/
struct sliceBits(size_t from, size_t to)
{
    //for now bypass assumeSize, DMD has trouble inlining it
    enum bitSize = to-from;
    static auto opCall(T)(T x)
    out(result)
    {
        assert(result < (1 << to-from));
    }
    body
    {
        static assert(from < to);
        static if (from == 0)
            return x & ((1 << to)-1);
        else
        return (x >> from) & ((1<<(to-from))-1);
    }
}

@safe pure nothrow @nogc uint low_8(uint x) { return x&0xFF; }
@safe pure nothrow @nogc uint midlow_8(uint x){ return (x&0xFF00)>>8; }
alias lo8 = assumeSize!(low_8, 8);
alias mlo8 = assumeSize!(midlow_8, 8);

static assert(bitSizeOf!lo8 == 8);
static assert(bitSizeOf!(sliceBits!(4, 7)) == 3);
static assert(bitSizeOf!(BitPacked!(uint, 2)) == 2);

template Sequence(size_t start, size_t end)
{
    static if (start < end)
        alias Sequence = AliasSeq!(start, Sequence!(start+1, end));
    else
        alias Sequence = AliasSeq!();
}

//---- TRIE TESTS ----
@system unittest
{
    import std.algorithm.iteration : map;
    import std.algorithm.sorting : sort;
    import std.array : array;
    import std.conv : text, to;
    import std.range : iota;
    static trieStats(TRIE)(TRIE t)
    {
        version (std_uni_stats)
        {
            import std.stdio : writefln, writeln;
            writeln("---TRIE FOOTPRINT STATS---");
            foreach (i; staticIota!(0, t.table.dim) )
            {
                writefln("lvl%s = %s bytes;  %s pages"
                         , i, t.bytes!i, t.pages!i);
            }
            writefln("TOTAL: %s bytes", t.bytes);
            version (none)
            {
                writeln("INDEX (excluding value level):");
                foreach (i; staticIota!(0, t.table.dim-1) )
                    writeln(t.table.slice!(i)[0 .. t.table.length!i]);
            }
            writeln("---------------------------");
        }
    }
    //@@@BUG link failure, lambdas not found by linker somehow (in case of trie2)
    // alias lo8   = assumeSize!(8, function (uint x) { return x&0xFF; });
    // alias next8 = assumeSize!(7, function (uint x) { return (x&0x7F00)>>8; });
    alias Set = CodepointSet;
    auto set = Set('A','Z','a','z');
    auto trie = buildTrie!(bool, uint, 256, lo8)(set.byInterval);// simple bool array
    for (int a='a'; a<'z';a++)
        assert(trie[a]);
    for (int a='A'; a<'Z';a++)
        assert(trie[a]);
    for (int a=0; a<'A'; a++)
        assert(!trie[a]);
    for (int a ='Z'; a<'a'; a++)
        assert(!trie[a]);
    trieStats(trie);

    auto redundant2 = Set(
        1, 18, 256+2, 256+111, 512+1, 512+18, 768+2, 768+111);
    auto trie2 = buildTrie!(bool, uint, 1024, mlo8, lo8)(redundant2.byInterval);
    trieStats(trie2);
    foreach (e; redundant2.byCodepoint)
        assert(trie2[e], text(cast(uint) e, " - ", trie2[e]));
    foreach (i; 0 .. 1024)
    {
        assert(trie2[i] == (i in redundant2));
    }


    auto redundant3 = Set(
          2,    4,    6,    8,    16,
       2+16, 4+16, 16+6, 16+8, 16+16,
       2+32, 4+32, 32+6, 32+8,
      );

    enum max3 = 256;
    // sliceBits
    auto trie3 = buildTrie!(bool, uint, max3,
            sliceBits!(6,8), sliceBits!(4,6), sliceBits!(0,4)
        )(redundant3.byInterval);
    trieStats(trie3);
    foreach (i; 0 .. max3)
        assert(trie3[i] == (i in redundant3), text(cast(uint) i));

    auto redundant4 = Set(
            10, 64, 64+10, 128, 128+10, 256, 256+10, 512,
            1000, 2000, 3000, 4000, 5000, 6000
        );
    enum max4 = 2^^16;
    auto trie4 = buildTrie!(bool, size_t, max4,
            sliceBits!(13, 16), sliceBits!(9, 13), sliceBits!(6, 9) , sliceBits!(0, 6)
        )(redundant4.byInterval);
    foreach (i; 0 .. max4)
    {
        if (i in redundant4)
            assert(trie4[i], text(cast(uint) i));
    }
    trieStats(trie4);

        alias mapToS = mapTrieIndex!(useItemAt!(0, char));
        string[] redundantS = ["tea", "start", "orange"];
        redundantS.sort!((a,b) => mapToS(a) < mapToS(b))();
        auto strie = buildTrie!(bool, string, useItemAt!(0, char))(redundantS);
        // using first char only
        assert(redundantS == ["orange", "start", "tea"]);
        assert(strie["test"], text(strie["test"]));
        assert(!strie["aea"]);
        assert(strie["s"]);

    // a bit size test
    auto a = array(map!(x => to!ubyte(x))(iota(0, 256)));
    auto bt = buildTrie!(bool, ubyte, sliceBits!(7, 8), sliceBits!(5, 7), sliceBits!(0, 5))(a);
    trieStats(bt);
    foreach (i; 0 .. 256)
        assert(bt[cast(ubyte) i]);
}

template useItemAt(size_t idx, T)
if (isIntegral!T || is(T: dchar))
{
    size_t impl(in T[] arr){ return arr[idx]; }
    alias useItemAt = assumeSize!(impl, 8*T.sizeof);
}

template useLastItem(T)
{
    size_t impl(in T[] arr){ return arr[$-1]; }
    alias useLastItem = assumeSize!(impl, 8*T.sizeof);
}

template fullBitSize(Prefix...)
{
    static if (Prefix.length > 0)
        enum fullBitSize = bitSizeOf!(Prefix[0])+fullBitSize!(Prefix[1..$]);
    else
        enum fullBitSize = 0;
}

template idxTypes(Key, size_t fullBits, Prefix...)
{
    static if (Prefix.length == 1)
    {// the last level is value level, so no index once reduced to 1-level
        alias idxTypes = AliasSeq!();
    }
    else
    {
        // Important note on bit packing
        // Each level has to hold enough of bits to address the next one
        // The bottom level is known to hold full bit width
        // thus it's size in pages is full_bit_width - size_of_last_prefix
        // Recourse on this notion
        alias idxTypes =
            AliasSeq!(
                idxTypes!(Key, fullBits - bitSizeOf!(Prefix[$-1]), Prefix[0..$-1]),
                BitPacked!(typeof(Prefix[$-2](Key.init)), fullBits - bitSizeOf!(Prefix[$-1]))
            );
    }
}

//============================================================================

@safe pure int comparePropertyName(Char1, Char2)(const(Char1)[] a, const(Char2)[] b)
if (is(Char1 : dchar) && is(Char2 : dchar))
{
    import std.algorithm.comparison : cmp;
    import std.algorithm.iteration : map, filter;
    import std.ascii : toLower;
    static bool pred(dchar c) {return !c.isWhite && c != '-' && c != '_';}
    return cmp(
        a.map!toLower.filter!pred,
        b.map!toLower.filter!pred);
}

@safe pure unittest
{
    assert(!comparePropertyName("foo-bar", "fooBar"));
}

bool propertyNameLess(Char1, Char2)(const(Char1)[] a, const(Char2)[] b) @safe pure
if (is(Char1 : dchar) && is(Char2 : dchar))
{
    return comparePropertyName(a, b) < 0;
}

//============================================================================
// Utilities for compression of Unicode code point sets
//============================================================================

@safe void compressTo(uint val, ref ubyte[] arr) pure nothrow
{
    // not optimized as usually done 1 time (and not public interface)
    if (val < 128)
        arr ~= cast(ubyte) val;
    else if (val < (1 << 13))
    {
        arr ~= (0b1_00 << 5) | cast(ubyte)(val >> 8);
        arr ~= val & 0xFF;
    }
    else
    {
        assert(val < (1 << 21));
        arr ~= (0b1_01 << 5) | cast(ubyte)(val >> 16);
        arr ~= (val >> 8) & 0xFF;
        arr ~= val  & 0xFF;
    }
}

@safe uint decompressFrom(const(ubyte)[] arr, ref size_t idx) pure
{
    import std.exception : enforce;
    immutable first = arr[idx++];
    if (!(first & 0x80)) // no top bit -> [0 .. 127]
        return first;
    immutable extra = ((first >> 5) & 1) + 1; // [1, 2]
    uint val = (first & 0x1F);
    enforce(idx + extra <= arr.length, "bad code point interval encoding");
    foreach (j; 0 .. extra)
        val = (val << 8) | arr[idx+j];
    idx += extra;
    return val;
}


package ubyte[] compressIntervals(Range)(Range intervals)
if (isInputRange!Range && isIntegralPair!(ElementType!Range))
{
    ubyte[] storage;
    uint base = 0;
    // RLE encode
    foreach (val; intervals)
    {
        compressTo(val[0]-base, storage);
        base = val[0];
        if (val[1] != lastDchar+1) // till the end of the domain so don't store it
        {
            compressTo(val[1]-base, storage);
            base = val[1];
        }
    }
    return storage;
}

@safe pure unittest
{
    import std.algorithm.comparison : equal;
    import std.typecons : tuple;

    auto run = [tuple(80, 127), tuple(128, (1 << 10)+128)];
    ubyte[] enc = [cast(ubyte) 80, 47, 1, (0b1_00 << 5) | (1 << 2), 0];
    assert(compressIntervals(run) == enc);
    auto run2 = [tuple(0, (1 << 20)+512+1), tuple((1 << 20)+512+4, lastDchar+1)];
    ubyte[] enc2 = [cast(ubyte) 0, (0b1_01 << 5) | (1 << 4), 2, 1, 3]; // odd length-ed
    assert(compressIntervals(run2) == enc2);
    size_t  idx = 0;
    assert(decompressFrom(enc, idx) == 80);
    assert(decompressFrom(enc, idx) == 47);
    assert(decompressFrom(enc, idx) == 1);
    assert(decompressFrom(enc, idx) == (1 << 10));
    idx = 0;
    assert(decompressFrom(enc2, idx) == 0);
    assert(decompressFrom(enc2, idx) == (1 << 20)+512+1);
    assert(equal(decompressIntervals(compressIntervals(run)), run));
    assert(equal(decompressIntervals(compressIntervals(run2)), run2));
}

// Creates a range of $(D CodepointInterval) that lazily decodes compressed data.
@safe package auto decompressIntervals(const(ubyte)[] data) pure
{
    return DecompressedIntervals(data);
}

@safe struct DecompressedIntervals
{
pure:
    const(ubyte)[] _stream;
    size_t _idx;
    CodepointInterval _front;

    this(const(ubyte)[] stream)
    {
        _stream = stream;
        popFront();
    }

    @property CodepointInterval front()
    {
        assert(!empty);
        return _front;
    }

    void popFront()
    {
        if (_idx == _stream.length)
        {
            _idx = size_t.max;
            return;
        }
        uint base = _front[1];
        _front[0] = base + decompressFrom(_stream, _idx);
        if (_idx == _stream.length)// odd length ---> till the end
            _front[1] = lastDchar+1;
        else
        {
            base = _front[0];
            _front[1] = base + decompressFrom(_stream, _idx);
        }
    }

    @property bool empty() const
    {
        return _idx == size_t.max;
    }

    @property DecompressedIntervals save() { return this; }
}

static assert(isInputRange!DecompressedIntervals);
static assert(isForwardRange!DecompressedIntervals);
//============================================================================

version (std_uni_bootstrap){}
else
{

// helper for looking up code point sets
@trusted ptrdiff_t findUnicodeSet(alias table, C)(in C[] name) pure
{
    import std.algorithm.iteration : map;
    import std.range : assumeSorted;
    auto range = assumeSorted!((a,b) => propertyNameLess(a,b))
        (table.map!"a.name"());
    size_t idx = range.lowerBound(name).length;
    if (idx < range.length && comparePropertyName(range[idx], name) == 0)
        return idx;
    return -1;
}

// another one that loads it
@trusted bool loadUnicodeSet(alias table, Set, C)(in C[] name, ref Set dest) pure
{
    auto idx = findUnicodeSet!table(name);
    if (idx >= 0)
    {
        dest = Set(asSet(table[idx].compressed));
        return true;
    }
    return false;
}

@trusted bool loadProperty(Set=CodepointSet, C)
    (in C[] name, ref Set target) pure
{
    import std.internal.unicode_tables : uniProps; // generated file
    alias ucmp = comparePropertyName;
    // conjure cumulative properties by hand
    if (ucmp(name, "L") == 0 || ucmp(name, "Letter") == 0)
    {
        target = asSet(uniProps.Lu);
        target |= asSet(uniProps.Ll);
        target |= asSet(uniProps.Lt);
        target |= asSet(uniProps.Lo);
        target |= asSet(uniProps.Lm);
    }
    else if (ucmp(name,"LC") == 0 || ucmp(name,"Cased Letter")==0)
    {
        target = asSet(uniProps.Ll);
        target |= asSet(uniProps.Lu);
        target |= asSet(uniProps.Lt);// Title case
    }
    else if (ucmp(name, "M") == 0 || ucmp(name, "Mark") == 0)
    {
        target = asSet(uniProps.Mn);
        target |= asSet(uniProps.Mc);
        target |= asSet(uniProps.Me);
    }
    else if (ucmp(name, "N") == 0 || ucmp(name, "Number") == 0)
    {
        target = asSet(uniProps.Nd);
        target |= asSet(uniProps.Nl);
        target |= asSet(uniProps.No);
    }
    else if (ucmp(name, "P") == 0 || ucmp(name, "Punctuation") == 0)
    {
        target = asSet(uniProps.Pc);
        target |= asSet(uniProps.Pd);
        target |= asSet(uniProps.Ps);
        target |= asSet(uniProps.Pe);
        target |= asSet(uniProps.Pi);
        target |= asSet(uniProps.Pf);
        target |= asSet(uniProps.Po);
    }
    else if (ucmp(name, "S") == 0 || ucmp(name, "Symbol") == 0)
    {
        target = asSet(uniProps.Sm);
        target |= asSet(uniProps.Sc);
        target |= asSet(uniProps.Sk);
        target |= asSet(uniProps.So);
    }
    else if (ucmp(name, "Z") == 0 || ucmp(name, "Separator") == 0)
    {
        target = asSet(uniProps.Zs);
        target |= asSet(uniProps.Zl);
        target |= asSet(uniProps.Zp);
    }
    else if (ucmp(name, "C") == 0 || ucmp(name, "Other") == 0)
    {
        target = asSet(uniProps.Co);
        target |= asSet(uniProps.Lo);
        target |= asSet(uniProps.No);
        target |= asSet(uniProps.So);
        target |= asSet(uniProps.Po);
    }
    else if (ucmp(name, "graphical") == 0)
    {
        target = asSet(uniProps.Alphabetic);

        target |= asSet(uniProps.Mn);
        target |= asSet(uniProps.Mc);
        target |= asSet(uniProps.Me);

        target |= asSet(uniProps.Nd);
        target |= asSet(uniProps.Nl);
        target |= asSet(uniProps.No);

        target |= asSet(uniProps.Pc);
        target |= asSet(uniProps.Pd);
        target |= asSet(uniProps.Ps);
        target |= asSet(uniProps.Pe);
        target |= asSet(uniProps.Pi);
        target |= asSet(uniProps.Pf);
        target |= asSet(uniProps.Po);

        target |= asSet(uniProps.Zs);

        target |= asSet(uniProps.Sm);
        target |= asSet(uniProps.Sc);
        target |= asSet(uniProps.Sk);
        target |= asSet(uniProps.So);
    }
    else if (ucmp(name, "any") == 0)
        target = Set.fromIntervals(0, 0x110000);
    else if (ucmp(name, "ascii") == 0)
        target = Set.fromIntervals(0, 0x80);
    else
        return loadUnicodeSet!(uniProps.tab)(name, target);
    return true;
}

// CTFE-only helper for checking property names at compile-time
@safe bool isPrettyPropertyName(C)(in C[] name)
{
    import std.algorithm.searching : find;
    auto names = [
        "L", "Letter",
        "LC", "Cased Letter",
        "M", "Mark",
        "N", "Number",
        "P", "Punctuation",
        "S", "Symbol",
        "Z", "Separator",
        "Graphical",
        "any",
        "ascii"
    ];
    auto x = find!(x => comparePropertyName(x, name) == 0)(names);
    return !x.empty;
}

// ditto, CTFE-only, not optimized
@safe private static bool findSetName(alias table, C)(in C[] name)
{
    return findUnicodeSet!table(name) >= 0;
}

template SetSearcher(alias table, string kind)
{
    /// Run-time checked search.
    static auto opCall(C)(in C[] name)
        if (is(C : dchar))
    {
        import std.conv : to;
        CodepointSet set;
        if (loadUnicodeSet!table(name, set))
            return set;
        throw new Exception("No unicode set for "~kind~" by name "
            ~name.to!string()~" was found.");
    }
    /// Compile-time checked search.
    static @property auto opDispatch(string name)()
    {
        static if (findSetName!table(name))
        {
            CodepointSet set;
            loadUnicodeSet!table(name, set);
            return set;
        }
        else
            static assert(false, "No unicode set for "~kind~" by name "
                ~name~" was found.");
    }
}

/**
    A single entry point to lookup Unicode $(CODEPOINT) sets by name or alias of
    a block, script or general category.

    It uses well defined standard rules of property name lookup.
    This includes fuzzy matching of names, so that
    'White_Space', 'white-SpAce' and 'whitespace' are all considered equal
    and yield the same set of white space $(CHARACTERS).
*/
@safe public struct unicode
{
    /**
        Performs the lookup of set of $(CODEPOINTS)
        with compile-time correctness checking.
        This short-cut version combines 3 searches:
        across blocks, scripts, and common binary properties.

        Note that since scripts and blocks overlap the
        usual trick to disambiguate is used - to get a block use
        $(D unicode.InBlockName), to search a script
        use $(D unicode.ScriptName).

        See_Also: $(LREF block), $(LREF script)
        and (not included in this search) $(LREF hangulSyllableType).
    */

    static @property auto opDispatch(string name)() pure
    {
        static if (findAny(name))
            return loadAny(name);
        else
            static assert(false, "No unicode set by name "~name~" was found.");
    }

    ///
    @safe unittest
    {
        import std.exception : collectException;
        auto ascii = unicode.ASCII;
        assert(ascii['A']);
        assert(ascii['~']);
        assert(!ascii['\u00e0']);
        // matching is case-insensitive
        assert(ascii == unicode.ascII);
        assert(!ascii['à']);
        // underscores, '-' and whitespace in names are ignored too
        auto latin = unicode.in_latin1_Supplement;
        assert(latin['à']);
        assert(!latin['$']);
        // BTW Latin 1 Supplement is a block, hence "In" prefix
        assert(latin == unicode("In Latin 1 Supplement"));
        // run-time look up throws if no such set is found
        assert(collectException(unicode("InCyrilliac")));
    }

    /**
        The same lookup across blocks, scripts, or binary properties,
        but performed at run-time.
        This version is provided for cases where $(D name)
        is not known beforehand; otherwise compile-time
        checked $(LREF opDispatch) is typically a better choice.

        See the $(S_LINK Unicode properties, table of properties) for available
        sets.
    */
    static auto opCall(C)(in C[] name)
        if (is(C : dchar))
    {
        return loadAny(name);
    }

    /**
        Narrows down the search for sets of $(CODEPOINTS) to all Unicode blocks.

        Note:
        Here block names are unambiguous as no scripts are searched
        and thus to search use simply $(D unicode.block.BlockName) notation.

        See $(S_LINK Unicode properties, table of properties) for available sets.
        See_Also: $(S_LINK Unicode properties, table of properties).
    */
    struct block
    {
        import std.internal.unicode_tables : blocks; // generated file
        mixin SetSearcher!(blocks.tab, "block");
    }

    ///
    @safe unittest
    {
        // use .block for explicitness
        assert(unicode.block.Greek_and_Coptic == unicode.InGreek_and_Coptic);
    }

    /**
        Narrows down the search for sets of $(CODEPOINTS) to all Unicode scripts.

        See the $(S_LINK Unicode properties, table of properties) for available
        sets.
    */
    struct script
    {
        import std.internal.unicode_tables : scripts; // generated file
        mixin SetSearcher!(scripts.tab, "script");
    }

    ///
    @safe unittest
    {
        auto arabicScript = unicode.script.arabic;
        auto arabicBlock = unicode.block.arabic;
        // there is an intersection between script and block
        assert(arabicBlock['؁']);
        assert(arabicScript['؁']);
        // but they are different
        assert(arabicBlock != arabicScript);
        assert(arabicBlock == unicode.inArabic);
        assert(arabicScript == unicode.arabic);
    }

    /**
        Fetch a set of $(CODEPOINTS) that have the given hangul syllable type.

        Other non-binary properties (once supported) follow the same
        notation - $(D unicode.propertyName.propertyValue) for compile-time
        checked access and $(D unicode.propertyName(propertyValue))
        for run-time checked one.

        See the $(S_LINK Unicode properties, table of properties) for available
        sets.
    */
    struct hangulSyllableType
    {
        import std.internal.unicode_tables : hangul; // generated file
        mixin SetSearcher!(hangul.tab, "hangul syllable type");
    }

    ///
    @safe unittest
    {
        // L here is syllable type not Letter as in unicode.L short-cut
        auto leadingVowel = unicode.hangulSyllableType("L");
        // check that some leading vowels are present
        foreach (vowel; '\u1110'..'\u115F')
            assert(leadingVowel[vowel]);
        assert(leadingVowel == unicode.hangulSyllableType.L);
    }

private:
    alias ucmp = comparePropertyName;

    static bool findAny(string name)
    {
        import std.internal.unicode_tables : blocks, scripts, uniProps; // generated file
        return isPrettyPropertyName(name)
            || findSetName!(uniProps.tab)(name) || findSetName!(scripts.tab)(name)
            || (ucmp(name[0 .. 2],"In") == 0 && findSetName!(blocks.tab)(name[2..$]));
    }

    static auto loadAny(Set=CodepointSet, C)(in C[] name) pure
    {
        import std.conv : to;
        import std.internal.unicode_tables : blocks, scripts; // generated file
        Set set;
        immutable loaded = loadProperty(name, set) || loadUnicodeSet!(scripts.tab)(name, set)
            || (name.length > 2 && ucmp(name[0 .. 2],"In") == 0
                && loadUnicodeSet!(blocks.tab)(name[2..$], set));
        if (loaded)
            return set;
        throw new Exception("No unicode set by name "~name.to!string()~" was found.");
    }

    // FIXME: re-disable once the compiler is fixed
    // Disabled to prevent the mistake of creating instances of this pseudo-struct.
    //@disable ~this();
}

@safe unittest
{
    import std.internal.unicode_tables : blocks, uniProps; // generated file
    assert(unicode("InHebrew") == asSet(blocks.Hebrew));
    assert(unicode("separator") == (asSet(uniProps.Zs) | asSet(uniProps.Zl) | asSet(uniProps.Zp)));
    assert(unicode("In-Kharoshthi") == asSet(blocks.Kharoshthi));
}

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

private static bool isRegionalIndicator(dchar ch) @safe pure @nogc nothrow
{
    return ch >= '\U0001F1E6' && ch <= '\U0001F1FF';
}

template genericDecodeGrapheme(bool getValue)
{
    alias graphemeExtend = graphemeExtendTrie;
    alias spacingMark = mcTrie;
    static if (getValue)
        alias Value = Grapheme;
    else
        alias Value = void;

    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);
        while (!range.empty)
        {
            ch = range.front;
            final switch (state) with(GraphemeState)
            {
            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);
                else
                    goto L_End_Extend;
            break;
            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;
            }
        }
    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

/++
    Computes the length of grapheme cluster starting at $(D index).
    Both the resulting length and the $(D index) are measured
    in $(S_LINK Code unit, code units).

    Params:
        C = type that is implicitly convertible to $(D dchars)
        input = array of grapheme clusters
        index = starting index into $(D input[])

    Returns:
        length of grapheme cluster
+/
size_t graphemeStride(C)(in C[] input, size_t index)
if (is(C : dchar))
{
    auto src = input[index..$];
    auto n = src.length;
    genericDecodeGrapheme!(false)(src);
    return n - src.length;
}

///
@safe unittest
{
    assert(graphemeStride("  ", 1) == 1);
    // A + combing ring above
    string city = "A\u030Arhus";
    size_t first = graphemeStride(city, 0);
    assert(first == 3); //\u030A has 2 UTF-8 code units
    assert(city[0 .. first] == "A\u030A");
    assert(city[first..$] == "rhus");
}

/++
    Reads one full grapheme cluster from an input range of dchar $(D inp).

    For examples see the $(LREF Grapheme) below.

    Note:
    This function modifies $(D inp) and thus $(D inp)
    must be an L-value.
+/
Grapheme decodeGrapheme(Input)(ref Input inp)
if (isInputRange!Input && is(Unqual!(ElementType!Input) == dchar))
{
    return genericDecodeGrapheme!true(inp);
}

@system unittest
{
    import std.algorithm.comparison : equal;

    Grapheme gr;
    string s = " \u0020\u0308 ";
    gr = decodeGrapheme(s);
    assert(gr.length == 1 && gr[0] == ' ');
    gr = decodeGrapheme(s);
    assert(gr.length == 2 && equal(gr[0 .. 2], " \u0308"));
    s = "\u0300\u0308\u1100";
    assert(equal(decodeGrapheme(s)[], "\u0300\u0308"));
    assert(equal(decodeGrapheme(s)[], "\u1100"));
    s = "\u11A8\u0308\uAC01";
    assert(equal(decodeGrapheme(s)[], "\u11A8\u0308"));
    assert(equal(decodeGrapheme(s)[], "\uAC01"));
}

/++
    $(P Iterate a string by grapheme.)

    $(P Useful for doing string manipulation that needs to be aware
    of graphemes.)

    See_Also:
        $(LREF byCodePoint)
+/
auto byGrapheme(Range)(Range range)
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar))
{
    // TODO: Bidirectional access
    static struct Result(R)
    {
        private R _range;
        private Grapheme _front;

        bool empty() @property
        {
            return _front.length == 0;
        }

        Grapheme front() @property
        {
            return _front;
        }

        void popFront()
        {
            _front = _range.empty ? Grapheme.init : _range.decodeGrapheme();
        }

        static if (isForwardRange!R)
        {
            Result save() @property
            {
                return Result(_range.save, _front);
            }
        }
    }

    auto result = Result!(Range)(range);
    result.popFront();
    return result;
}

///
@safe unittest
{
    import std.algorithm.comparison : equal;
    import std.range.primitives : walkLength;
    import std.range : take, drop;
    auto text = "noe\u0308l"; // noël using e + combining diaeresis
    assert(text.walkLength == 5); // 5 code points

    auto gText = text.byGrapheme;
    assert(gText.walkLength == 4); // 4 graphemes

    assert(gText.take(3).equal("noe\u0308".byGrapheme));
    assert(gText.drop(3).equal("l".byGrapheme));
}

// For testing non-forward-range input ranges
version (unittest)
private static struct InputRangeString
{
    private string s;

    bool empty() @property { return s.empty; }
    dchar front() @property { return s.front; }
    void popFront() { s.popFront(); }
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.array : array;
    import std.range : retro;
    import std.range.primitives : walkLength;
    assert("".byGrapheme.walkLength == 0);

    auto reverse = "le\u0308on";
    assert(reverse.walkLength == 5);

    auto gReverse = reverse.byGrapheme;
    assert(gReverse.walkLength == 4);

    foreach (text; AliasSeq!("noe\u0308l"c, "noe\u0308l"w, "noe\u0308l"d))
    {
        assert(text.walkLength == 5);
        static assert(isForwardRange!(typeof(text)));

        auto gText = text.byGrapheme;
        static assert(isForwardRange!(typeof(gText)));
        assert(gText.walkLength == 4);
        assert(gText.array.retro.equal(gReverse));
    }

    auto nonForwardRange = InputRangeString("noe\u0308l").byGrapheme;
    static assert(!isForwardRange!(typeof(nonForwardRange)));
    assert(nonForwardRange.walkLength == 4);
}

/++
    $(P Lazily transform a range of $(LREF Grapheme)s to a range of code points.)

    $(P Useful for converting the result to a string after doing operations
    on graphemes.)

    $(P Acts as the identity function when given a range of code points.)
+/
auto byCodePoint(Range)(Range range)
if (isInputRange!Range && is(Unqual!(ElementType!Range) == Grapheme))
{
    // TODO: Propagate bidirectional access
    static struct Result
    {
        private Range _range;
        private size_t i = 0;

        bool empty() @property
        {
            return _range.empty;
        }

        dchar front() @property
        {
            return _range.front[i];
        }

        void popFront()
        {
            ++i;

            if (i >= _range.front.length)
            {
                _range.popFront();
                i = 0;
            }
        }

        static if (isForwardRange!Range)
        {
            Result save() @property
            {
                return Result(_range.save, i);
            }
        }
    }

    return Result(range);
}

/// Ditto
Range byCodePoint(Range)(Range range)
if (isInputRange!Range && is(Unqual!(ElementType!Range) == dchar))
{
    return range;
}

///
@safe unittest
{
    import std.array : array;
    import std.conv : text;
    import std.range : retro;

    string s = "noe\u0308l"; // noël

    // reverse it and convert the result to a string
    string reverse = s.byGrapheme
        .array
        .retro
        .byCodePoint
        .text;

    assert(reverse == "le\u0308on"); // lëon
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.range.primitives : walkLength;
    assert("".byGrapheme.byCodePoint.equal(""));

    string text = "noe\u0308l";
    static assert(is(typeof(text.byCodePoint) == string));

    auto gText = InputRangeString(text).byGrapheme;
    static assert(!isForwardRange!(typeof(gText)));

    auto cpText = gText.byCodePoint;
    static assert(!isForwardRange!(typeof(cpText)));

    assert(cpText.walkLength == text.walkLength);
}

@trusted:

/++
    $(P A structure designed to effectively pack $(CHARACTERS)
    of a $(CLUSTER).
    )

    $(P $(D Grapheme) has value semantics so 2 copies of a $(D Grapheme)
    always refer to distinct objects. In most actual scenarios a $(D Grapheme)
    fits on the stack and avoids memory allocation overhead for all but quite
    long clusters.
    )

    See_Also: $(LREF decodeGrapheme), $(LREF graphemeStride)
+/
@trusted struct Grapheme
{
    import std.traits : isDynamicArray;

public:
    /// Ctor
    this(C)(in C[] chars...)
        if (is(C : dchar))
    {
        this ~= chars;
    }

    ///ditto
    this(Input)(Input seq)
        if (!isDynamicArray!Input
            && isInputRange!Input && is(ElementType!Input : dchar))
    {
        this ~= seq;
    }

    /// Gets a $(CODEPOINT) at the given index in this cluster.
    dchar opIndex(size_t index) const pure nothrow @nogc
    {
        assert(index < length);
        return read24(isBig ? ptr_ : small_.ptr, index);
    }

    /++
        Writes a $(CODEPOINT) $(D ch) at given index in this cluster.

        Warning:
        Use of this facility may invalidate grapheme cluster,
        see also $(LREF Grapheme.valid).
    +/
    void opIndexAssign(dchar ch, size_t index) pure nothrow @nogc
    {
        assert(index < length);
        write24(isBig ? ptr_ : small_.ptr, ch, index);
    }

    ///
    @safe unittest
    {
        auto g = Grapheme("A\u0302");
        assert(g[0] == 'A');
        assert(g.valid);
        g[1] = '~'; // ASCII tilda is not a combining mark
        assert(g[1] == '~');
        assert(!g.valid);
    }

    /++
        Random-access range over Grapheme's $(CHARACTERS).

        Warning: Invalidates when this Grapheme leaves the scope,
        attempts to use it then would lead to memory corruption.
    +/
    @system SliceOverIndexed!Grapheme opSlice(size_t a, size_t b) pure nothrow @nogc
    {
        return sliceOverIndexed(a, b, &this);
    }

    /// ditto
    @system SliceOverIndexed!Grapheme opSlice() pure nothrow @nogc
    {
        return sliceOverIndexed(0, length, &this);
    }

    /// Grapheme cluster length in $(CODEPOINTS).
    @property size_t length() const pure nothrow @nogc
    {
        return isBig ? len_ : slen_ & 0x7F;
    }

    /++
        Append $(CHARACTER) $(D ch) to this grapheme.
        Warning:
        Use of this facility may invalidate grapheme cluster,
        see also $(D valid).

        See_Also: $(LREF Grapheme.valid)
    +/
    ref opOpAssign(string op)(dchar ch)
    {
        static if (op == "~")
        {
            if (!isBig)
            {
                if (slen_ == small_cap)
                    convertToBig();// & fallthrough to "big" branch
                else
                {
                    write24(small_.ptr, ch, smallLength);
                    slen_++;
                    return this;
                }
            }

            assert(isBig);
            if (len_ == cap_)
            {
                import core.checkedint : addu, mulu;
                bool overflow;
                cap_ = addu(cap_, grow, overflow);
                auto nelems = mulu(3, addu(cap_, 1, overflow), overflow);
                if (overflow) assert(0);
                ptr_ = cast(ubyte*) pureRealloc(ptr_, nelems);
                if (ptr_ is null) onOutOfMemoryError();
            }
            write24(ptr_, ch, len_++);
            return this;
        }
        else
            static assert(false, "No operation "~op~" defined for Grapheme");
    }

    ///
    @system unittest
    {
        import std.algorithm.comparison : equal;
        auto g = Grapheme("A");
        assert(g.valid);
        g ~= '\u0301';
        assert(g[].equal("A\u0301"));
        assert(g.valid);
        g ~= "B";
        // not a valid grapheme cluster anymore
        assert(!g.valid);
        // still could be useful though
        assert(g[].equal("A\u0301B"));
    }

    /// Append all $(CHARACTERS) from the input range $(D inp) to this Grapheme.
    ref opOpAssign(string op, Input)(Input inp)
        if (isInputRange!Input && is(ElementType!Input : dchar))
    {
        static if (op == "~")
        {
            foreach (dchar ch; inp)
                this ~= ch;
            return this;
        }
        else
            static assert(false, "No operation "~op~" defined for Grapheme");
    }

    /++
        True if this object contains valid extended grapheme cluster.
        Decoding primitives of this module always return a valid $(D Grapheme).

        Appending to and direct manipulation of grapheme's $(CHARACTERS) may
        render it no longer valid. Certain applications may chose to use
        Grapheme as a "small string" of any $(CODEPOINTS) and ignore this property
        entirely.
    +/
    @property bool valid()() /*const*/
    {
        auto r = this[];
        genericDecodeGrapheme!false(r);
        return r.length == 0;
    }

    this(this) pure @nogc nothrow
    {
        if (isBig)
        {// dup it
            import core.checkedint : addu, mulu;
            bool overflow;
            auto raw_cap = mulu(3, addu(cap_, 1, overflow), overflow);
            if (overflow) assert(0);

            auto p = cast(ubyte*) pureMalloc(raw_cap);
            if (p is null) onOutOfMemoryError();
            p[0 .. raw_cap] = ptr_[0 .. raw_cap];
            ptr_ = p;
        }
    }

    ~this() pure @nogc nothrow
    {
        if (isBig)
        {
            pureFree(ptr_);
        }
    }


private:
    enum small_bytes = ((ubyte*).sizeof+3*size_t.sizeof-1);
    // "out of the blue" grow rate, needs testing
    // (though graphemes are typically small < 9)
    enum grow = 20;
    enum small_cap = small_bytes/3;
    enum small_flag = 0x80, small_mask = 0x7F;
    // 16 bytes in 32bits, should be enough for the majority of cases
    union
    {
        struct
        {
            ubyte* ptr_;
            size_t cap_;
            size_t len_;
            size_t padding_;
        }
        struct
        {
            ubyte[small_bytes] small_;
            ubyte slen_;
        }
    }

    void convertToBig() pure @nogc nothrow
    {
        static assert(grow.max / 3 - 1 >= grow);
        enum nbytes = 3 * (grow + 1);
        size_t k = smallLength;
        ubyte* p = cast(ubyte*) pureMalloc(nbytes);
        if (p is null) onOutOfMemoryError();
        for (int i=0; i<k; i++)
            write24(p, read24(small_.ptr, i), i);
        // now we can overwrite small array data
        ptr_ = p;
        len_ = slen_;
        assert(grow > len_);
        cap_ = grow;
        setBig();
    }

    void setBig() pure nothrow @nogc { slen_ |= small_flag; }

    @property size_t smallLength() const pure nothrow @nogc
    {
        return slen_ & small_mask;
    }
    @property ubyte isBig() const pure nothrow @nogc
    {
        return slen_ & small_flag;
    }
}

static assert(Grapheme.sizeof == size_t.sizeof*4);


@system pure /*nothrow @nogc*/ unittest // TODO: string .front is GC and throw
{
    import std.algorithm.comparison : equal;
    Grapheme[3] data = [Grapheme("Ю"), Grapheme("У"), Grapheme("З")];
    assert(byGrapheme("ЮУЗ").equal(data[]));
}

///
@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : filter;
    import std.range : isRandomAccessRange;

    string bold = "ku\u0308hn";

    // note that decodeGrapheme takes parameter by ref
    auto first = decodeGrapheme(bold);

    assert(first.length == 1);
    assert(first[0] == 'k');

    // the next grapheme is 2 characters long
    auto wideOne = decodeGrapheme(bold);
    // slicing a grapheme yields a random-access range of dchar
    assert(wideOne[].equal("u\u0308"));
    assert(wideOne.length == 2);
    static assert(isRandomAccessRange!(typeof(wideOne[])));

    // all of the usual range manipulation is possible
    assert(wideOne[].filter!isMark().equal("\u0308"));

    auto g = Grapheme("A");
    assert(g.valid);
    g ~= '\u0301';
    assert(g[].equal("A\u0301"));
    assert(g.valid);
    g ~= "B";
    // not a valid grapheme cluster anymore
    assert(!g.valid);
    // still could be useful though
    assert(g[].equal("A\u0301B"));
}

@safe unittest
{
    auto g = Grapheme("A\u0302");
    assert(g[0] == 'A');
    assert(g.valid);
    g[1] = '~'; // ASCII tilda is not a combining mark
    assert(g[1] == '~');
    assert(!g.valid);
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.iteration : map;
    import std.conv : text;
    import std.range : iota;

    // not valid clusters (but it just a test)
    auto g  = Grapheme('a', 'b', 'c', 'd', 'e');
    assert(g[0] == 'a');
    assert(g[1] == 'b');
    assert(g[2] == 'c');
    assert(g[3] == 'd');
    assert(g[4] == 'e');
    g[3] = 'Й';
    assert(g[2] == 'c');
    assert(g[3] == 'Й', text(g[3], " vs ", 'Й'));
    assert(g[4] == 'e');
    assert(!g.valid);

    g ~= 'ц';
    g ~= '~';
    assert(g[0] == 'a');
    assert(g[1] == 'b');
    assert(g[2] == 'c');
    assert(g[3] == 'Й');
    assert(g[4] == 'e');
    assert(g[5] == 'ц');
    assert(g[6] == '~');
    assert(!g.valid);

    Grapheme copy = g;
    copy[0] = 'X';
    copy[1] = '-';
    assert(g[0] == 'a' && copy[0] == 'X');
    assert(g[1] == 'b' && copy[1] == '-');
    assert(equal(g[2 .. g.length], copy[2 .. copy.length]));
    copy = Grapheme("АБВГДЕЁЖЗИКЛМ");
    assert(equal(copy[0 .. 8], "АБВГДЕЁЖ"), text(copy[0 .. 8]));
    copy ~= "xyz";
    assert(equal(copy[13 .. 15], "xy"), text(copy[13 .. 15]));
    assert(!copy.valid);

    Grapheme h;
    foreach (dchar v; iota(cast(int)'A', cast(int)'Z'+1).map!"cast(dchar)a"())
        h ~= v;
    assert(equal(h[], iota(cast(int)'A', cast(int)'Z'+1)));
}

/++
    $(P Does basic case-insensitive comparison of $(D r1) and $(D r2).
    This function uses simpler comparison rule thus achieving better performance
    than $(LREF icmp). However keep in mind the warning below.)

    Params:
        r1 = an input range of characters
        r2 = an input range of characters

    Returns:
        An $(D int) that is 0 if the strings match,
        &lt;0 if $(D r1) is lexicographically "less" than $(D r2),
        &gt;0 if $(D r1) is lexicographically "greater" than $(D r2)

    Warning:
    This function only handles 1:1 $(CODEPOINT) mapping
    and thus is not sufficient for certain alphabets
    like German, Greek and few others.

    See_Also:
        $(LREF icmp)
        $(REF cmp, std,algorithm,comparison)
+/
int sicmp(S1, S2)(S1 r1, S2 r2)
if (isInputRange!S1 && isSomeChar!(ElementEncodingType!S1)
    && isInputRange!S2 && isSomeChar!(ElementEncodingType!S2))
{
    import std.internal.unicode_tables : sTable = simpleCaseTable; // generated file
    import std.utf : byDchar;

    auto str1 = r1.byDchar;
    auto str2 = r2.byDchar;

    foreach (immutable lhs; str1)
    {
        if (str2.empty)
            return 1;
        immutable rhs = str2.front;
        str2.popFront();
        int diff = lhs - rhs;
        if (!diff)
            continue;
        size_t idx = simpleCaseTrie[lhs];
        size_t idx2 = simpleCaseTrie[rhs];
        // simpleCaseTrie is packed index table
        if (idx != EMPTY_CASE_TRIE)
        {
            if (idx2 != EMPTY_CASE_TRIE)
            {// both cased chars
                // adjust idx --> start of bucket
                idx = idx - sTable[idx].n;
                idx2 = idx2 - sTable[idx2].n;
                if (idx == idx2)// one bucket, equivalent chars
                    continue;
                else//  not the same bucket
                    diff = sTable[idx].ch - sTable[idx2].ch;
            }
            else
                diff = sTable[idx - sTable[idx].n].ch - rhs;
        }
        else if (idx2 != EMPTY_CASE_TRIE)
        {
            diff = lhs - sTable[idx2 - sTable[idx2].n].ch;
        }
        // one of chars is not cased at all
        return diff;
    }
    return str2.empty ? 0 : -1;
}

///
@safe @nogc pure nothrow unittest
{
    assert(sicmp("Август", "авгусТ") == 0);
    // Greek also works as long as there is no 1:M mapping in sight
    assert(sicmp("ΌΎ", "όύ") == 0);
    // things like the following won't get matched as equal
    // Greek small letter iota with dialytika and tonos
    assert(sicmp("ΐ", "\u03B9\u0308\u0301") != 0);

    // while icmp has no problem with that
    assert(icmp("ΐ", "\u03B9\u0308\u0301") == 0);
    assert(icmp("ΌΎ", "όύ") == 0);
}

// overloads for the most common cases to reduce compile time
@safe @nogc pure nothrow
{
    int sicmp(const(char)[] str1, const(char)[] str2)
    { return sicmp!(const(char)[], const(char)[])(str1, str2); }
    int sicmp(const(wchar)[] str1, const(wchar)[] str2)
    { return sicmp!(const(wchar)[], const(wchar)[])(str1, str2); }
    int sicmp(const(dchar)[] str1, const(dchar)[] str2)
    { return sicmp!(const(dchar)[], const(dchar)[])(str1, str2); }
}

private int fullCasedCmp(Range)(dchar lhs, dchar rhs, ref Range rtail)
{
    import std.algorithm.searching : skipOver;
    import std.internal.unicode_tables : fullCaseTable; // generated file
    alias fTable = fullCaseTable;
    size_t idx = fullCaseTrie[lhs];
    // fullCaseTrie is packed index table
    if (idx == EMPTY_CASE_TRIE)
        return lhs;
    immutable start = idx - fTable[idx].n;
    immutable end = fTable[idx].size + start;
    assert(fTable[start].entry_len == 1);
    for (idx=start; idx<end; idx++)
    {
        auto entryLen = fTable[idx].entry_len;
        if (entryLen == 1)
        {
            if (fTable[idx].seq[0] == rhs)
            {
                return 0;
            }
        }
        else
        {// OK it's a long chunk, like 'ss' for German
            dstring seq = fTable[idx].seq[0 .. entryLen];
            if (rhs == seq[0]
                && rtail.skipOver(seq[1..$]))
            {
                // note that this path modifies rtail
                // iff we managed to get there
                return 0;
            }
        }
    }
    return fTable[start].seq[0]; // new remapped character for accurate diffs
}

/++
    Does case insensitive comparison of `r1` and `r2`.
    Follows the rules of full case-folding mapping.
    This includes matching as equal german ß with "ss" and
    other 1:M $(CODEPOINT) mappings unlike $(LREF sicmp).
    The cost of `icmp` being pedantically correct is
    slightly worse performance.

    Params:
        r1 = a forward range of characters
        r2 = a forward range of characters

    Returns:
        An $(D int) that is 0 if the strings match,
        &lt;0 if $(D str1) is lexicographically "less" than $(D str2),
        &gt;0 if $(D str1) is lexicographically "greater" than $(D str2)

    See_Also:
        $(LREF sicmp)
        $(REF cmp, std,algorithm,comparison)
+/
int icmp(S1, S2)(S1 r1, S2 r2)
if (isForwardRange!S1 && isSomeChar!(ElementEncodingType!S1)
    && isForwardRange!S2 && isSomeChar!(ElementEncodingType!S2))
{
    import std.utf : byDchar;

    auto str1 = r1.byDchar;
    auto str2 = r2.byDchar;

    for (;;)
    {
        if (str1.empty)
            return str2.empty ? 0 : -1;
        immutable lhs = str1.front;
        if (str2.empty)
            return 1;
        immutable rhs = str2.front;
        str1.popFront();
        str2.popFront();
        if (!(lhs - rhs))
            continue;
        // first try to match lhs to <rhs,right-tail> sequence
        immutable cmpLR = fullCasedCmp(lhs, rhs, str2);
        if (!cmpLR)
            continue;
        // then rhs to <lhs,left-tail> sequence
        immutable cmpRL = fullCasedCmp(rhs, lhs, str1);
        if (!cmpRL)
            continue;
        // cmpXX contain remapped codepoints
        // to obtain stable ordering of icmp
        return cmpLR - cmpRL;
    }
}

///
@safe @nogc pure nothrow unittest
{
    assert(icmp("Rußland", "Russland") == 0);
    assert(icmp("ᾩ -> \u1F70\u03B9", "\u1F61\u03B9 -> ᾲ") == 0);
}

/**
 * By using $(REF byUTF, std,utf) and its aliases, GC allocations via auto-decoding
 * and thrown exceptions can be avoided, making `icmp` `@safe @nogc nothrow pure`.
 */
@safe @nogc nothrow pure unittest
{
    import std.utf : byDchar;

    assert(icmp("Rußland".byDchar, "Russland".byDchar) == 0);
    assert(icmp("ᾩ -> \u1F70\u03B9".byDchar, "\u1F61\u03B9 -> ᾲ".byDchar) == 0);
}

// test different character types
@safe unittest
{
    assert(icmp("Rußland", "Russland") == 0);
    assert(icmp("Rußland"w, "Russland") == 0);
    assert(icmp("Rußland", "Russland"w) == 0);
    assert(icmp("Rußland"w, "Russland"w) == 0);
    assert(icmp("Rußland"d, "Russland"w) == 0);
    assert(icmp("Rußland"w, "Russland"d) == 0);
}

// overloads for the most common cases to reduce compile time
@safe @nogc pure nothrow
{
    int icmp(const(char)[] str1, const(char)[] str2)
    { return icmp!(const(char)[], const(char)[])(str1, str2); }
    int icmp(const(wchar)[] str1, const(wchar)[] str2)
    { return icmp!(const(wchar)[], const(wchar)[])(str1, str2); }
    int icmp(const(dchar)[] str1, const(dchar)[] str2)
    { return icmp!(const(dchar)[], const(dchar)[])(str1, str2); }
}

@safe unittest
{
    import std.algorithm.sorting : sort;
    import std.conv : to;
    import std.exception : assertCTFEable;
    assertCTFEable!(
    {
    foreach (cfunc; AliasSeq!(icmp, sicmp))
    {
        foreach (S1; AliasSeq!(string, wstring, dstring))
        foreach (S2; AliasSeq!(string, wstring, dstring))
        (){ // avoid slow optimizations for large functions @@@BUG@@@ 2396
            assert(cfunc("".to!S1(), "".to!S2()) == 0);
            assert(cfunc("A".to!S1(), "".to!S2()) > 0);
            assert(cfunc("".to!S1(), "0".to!S2()) < 0);
            assert(cfunc("abc".to!S1(), "abc".to!S2()) == 0);
            assert(cfunc("abcd".to!S1(), "abc".to!S2()) > 0);
            assert(cfunc("abc".to!S1(), "abcd".to!S2()) < 0);
            assert(cfunc("Abc".to!S1(), "aBc".to!S2()) == 0);
            assert(cfunc("авГуст".to!S1(), "АВгУСТ".to!S2()) == 0);
            // Check example:
            assert(cfunc("Август".to!S1(), "авгусТ".to!S2()) == 0);
            assert(cfunc("ΌΎ".to!S1(), "όύ".to!S2()) == 0);
        }();
        // check that the order is properly agnostic to the case
        auto strs = [ "Apple", "ORANGE",  "orAcle", "amp", "banana"];
        sort!((a,b) => cfunc(a,b) < 0)(strs);
        assert(strs == ["amp", "Apple",  "banana", "orAcle", "ORANGE"]);
    }
    assert(icmp("ßb", "ssa") > 0);
    // Check example:
    assert(icmp("Russland", "Rußland") == 0);
    assert(icmp("ᾩ -> \u1F70\u03B9", "\u1F61\u03B9 -> ᾲ") == 0);
    assert(icmp("ΐ"w, "\u03B9\u0308\u0301") == 0);
    assert(sicmp("ΐ", "\u03B9\u0308\u0301") != 0);
    //bugzilla 11057
    assert( icmp("K", "L") < 0 );
    });
}

// issue 17372
@safe pure unittest
{
    import std.algorithm.iteration : joiner, map;
    import std.algorithm.sorting : sort;
    import std.array : array;
    auto a = [["foo", "bar"], ["baz"]].map!(line => line.joiner(" ")).array.sort!((a, b) => icmp(a, b) < 0);
}

// This is package for the moment to be used as a support tool for std.regex
// It needs a better API
/*
    Return a range of all $(CODEPOINTS) that casefold to
    and from this $(D ch).
*/
package auto simpleCaseFoldings(dchar ch) @safe
{
    import std.internal.unicode_tables : simpleCaseTable; // generated file
    alias sTable = simpleCaseTable;
    static struct Range
    {
    @safe pure nothrow:
        uint idx; //if == uint.max, then read c.
        union
        {
            dchar c; // == 0 - empty range
            uint len;
        }
        @property bool isSmall() const { return idx == uint.max; }

        this(dchar ch)
        {
            idx = uint.max;
            c = ch;
        }

        this(uint start, uint size)
        {
            idx = start;
            len = size;
        }

        @property dchar front() const
        {
            assert(!empty);
            if (isSmall)
            {
                return c;
            }
            auto ch = sTable[idx].ch;
            return ch;
        }

        @property bool empty() const
        {
            if (isSmall)
            {
                return c == 0;
            }
            return len == 0;
        }

        @property size_t length() const
        {
            if (isSmall)
            {
                return c == 0 ? 0 : 1;
            }
            return len;
        }

        void popFront()
        {
            if (isSmall)
                c = 0;
            else
            {
                idx++;
                len--;
            }
        }
    }
    immutable idx = simpleCaseTrie[ch];
    if (idx == EMPTY_CASE_TRIE)
        return Range(ch);
    auto entry = sTable[idx];
    immutable start = idx - entry.n;
    return Range(start, entry.size);
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.searching : canFind;
    import std.array : array;
    import std.exception : assertCTFEable;
    assertCTFEable!((){
        auto r = simpleCaseFoldings('Э').array;
        assert(r.length == 2);
        assert(r.canFind('э') && r.canFind('Э'));
        auto sr = simpleCaseFoldings('~');
        assert(sr.equal("~"));
        //A with ring above - casefolds to the same bucket as Angstrom sign
        sr = simpleCaseFoldings('Å');
        assert(sr.length == 3);
        assert(sr.canFind('å') && sr.canFind('Å') && sr.canFind('\u212B'));
    });
}

/++
    $(P Returns the $(S_LINK Combining class, combining class) of $(D ch).)
+/
ubyte combiningClass(dchar ch) @safe pure nothrow @nogc
{
    return combiningClassTrie[ch];
}

///
@safe unittest
{
    // shorten the code
    alias CC = combiningClass;

    // combining tilda
    assert(CC('\u0303') == 230);
    // combining ring below
    assert(CC('\u0325') == 220);
    // the simple consequence is that  "tilda" should be
    // placed after a "ring below" in a sequence
}

@safe pure nothrow @nogc unittest
{
    foreach (ch; 0 .. 0x80)
        assert(combiningClass(ch) == 0);
    assert(combiningClass('\u05BD') == 22);
    assert(combiningClass('\u0300') == 230);
    assert(combiningClass('\u0317') == 220);
    assert(combiningClass('\u1939') == 222);
}

/// Unicode character decomposition type.
enum UnicodeDecomposition {
    /// Canonical decomposition. The result is canonically equivalent sequence.
    Canonical,
    /**
         Compatibility decomposition. The result is compatibility equivalent sequence.
         Note: Compatibility decomposition is a $(B lossy) conversion,
         typically suitable only for fuzzy matching and internal processing.
    */
    Compatibility
}

/**
    Shorthand aliases for character decomposition type, passed as a
    template parameter to $(LREF decompose).
*/
enum {
    Canonical = UnicodeDecomposition.Canonical,
    Compatibility = UnicodeDecomposition.Compatibility
}

/++
    Try to canonically compose 2 $(CHARACTERS).
    Returns the composed $(CHARACTER) if they do compose and dchar.init otherwise.

    The assumption is that $(D first) comes before $(D second) in the original text,
    usually meaning that the first is a starter.

    Note: Hangul syllables are not covered by this function.
    See $(D composeJamo) below.
+/
public dchar compose(dchar first, dchar second) pure nothrow @safe
{
    import std.algorithm.iteration : map;
    import std.internal.unicode_comp : compositionTable, composeCntShift, composeIdxMask;
    import std.range : assumeSorted;
    immutable packed = compositionJumpTrie[first];
    if (packed == ushort.max)
        return dchar.init;
    // unpack offset and length
    immutable idx = packed & composeIdxMask, cnt = packed >> composeCntShift;
    // TODO: optimize this micro binary search (no more then 4-5 steps)
    auto r = compositionTable[idx .. idx+cnt].map!"a.rhs"().assumeSorted();
    immutable target = r.lowerBound(second).length;
    if (target == cnt)
        return dchar.init;
    immutable entry = compositionTable[idx+target];
    if (entry.rhs != second)
        return dchar.init;
    return entry.composed;
}

///
@safe unittest
{
    assert(compose('A','\u0308') == '\u00C4');
    assert(compose('A', 'B') == dchar.init);
    assert(compose('C', '\u0301') == '\u0106');
    // note that the starter is the first one
    // thus the following doesn't compose
    assert(compose('\u0308', 'A') == dchar.init);
}

/++
    Returns a full $(S_LINK Canonical decomposition, Canonical)
    (by default) or $(S_LINK Compatibility decomposition, Compatibility)
    decomposition of $(CHARACTER) $(D ch).
    If no decomposition is available returns a $(LREF Grapheme)
    with the $(D ch) itself.

    Note:
    This function also decomposes hangul syllables
    as prescribed by the standard.

    See_Also: $(LREF decomposeHangul) for a restricted version
    that takes into account only hangul syllables  but
    no other decompositions.
+/
public Grapheme decompose(UnicodeDecomposition decompType=Canonical)(dchar ch) @safe
{
    import std.algorithm.searching : until;
    import std.internal.unicode_decomp : decompCompatTable, decompCanonTable;
    static if (decompType == Canonical)
    {
        alias table = decompCanonTable;
        alias mapping = canonMappingTrie;
    }
    else static if (decompType == Compatibility)
    {
        alias table = decompCompatTable;
        alias mapping = compatMappingTrie;
    }
    immutable idx = mapping[ch];
    if (!idx) // not found, check hangul arithmetic decomposition
        return decomposeHangul(ch);
    auto decomp = table[idx..$].until(0);
    return Grapheme(decomp);
}

///
@system unittest
{
    import std.algorithm.comparison : equal;

    assert(compose('A','\u0308') == '\u00C4');
    assert(compose('A', 'B') == dchar.init);
    assert(compose('C', '\u0301') == '\u0106');
    // note that the starter is the first one
    // thus the following doesn't compose
    assert(compose('\u0308', 'A') == dchar.init);

    assert(decompose('Ĉ')[].equal("C\u0302"));
    assert(decompose('D')[].equal("D"));
    assert(decompose('\uD4DC')[].equal("\u1111\u1171\u11B7"));
    assert(decompose!Compatibility('¹')[].equal("1"));
}

//----------------------------------------------------------------------------
// Hangul specific composition/decomposition
enum jamoSBase = 0xAC00;
enum jamoLBase = 0x1100;
enum jamoVBase = 0x1161;
enum jamoTBase = 0x11A7;
enum jamoLCount = 19, jamoVCount = 21, jamoTCount = 28;
enum jamoNCount = jamoVCount * jamoTCount;
enum jamoSCount = jamoLCount * jamoNCount;

// Tests if $(D ch) is a Hangul leading consonant jamo.
bool isJamoL(dchar ch) pure nothrow @nogc @safe
{
    // first cmp rejects ~ 1M code points above leading jamo range
    return ch < jamoLBase+jamoLCount && ch >= jamoLBase;
}

// Tests if $(D ch) is a Hangul vowel jamo.
bool isJamoT(dchar ch) pure nothrow @nogc @safe
{
    // first cmp rejects ~ 1M code points above trailing jamo range
    // Note: ch == jamoTBase doesn't indicate trailing jamo (TIndex must be > 0)
    return ch < jamoTBase+jamoTCount && ch > jamoTBase;
}

// Tests if $(D ch) is a Hangul trailnig consonant jamo.
bool isJamoV(dchar ch) pure nothrow @nogc @safe
{
    // first cmp rejects ~ 1M code points above vowel range
    return  ch < jamoVBase+jamoVCount && ch >= jamoVBase;
}

int hangulSyllableIndex(dchar ch) pure nothrow @nogc @safe
{
    int idxS = cast(int) ch - jamoSBase;
    return idxS >= 0 && idxS < jamoSCount ? idxS : -1;
}

// internal helper: compose hangul syllables leaving dchar.init in holes
void hangulRecompose(dchar[] seq) pure nothrow @nogc @safe
{
    for (size_t idx = 0; idx + 1 < seq.length; )
    {
        if (isJamoL(seq[idx]) && isJamoV(seq[idx+1]))
        {
            immutable int indexL = seq[idx] - jamoLBase;
            immutable int indexV = seq[idx+1] - jamoVBase;
            immutable int indexLV = indexL * jamoNCount + indexV * jamoTCount;
            if (idx + 2 < seq.length && isJamoT(seq[idx+2]))
            {
                seq[idx] = jamoSBase + indexLV + seq[idx+2] - jamoTBase;
                seq[idx+1] = dchar.init;
                seq[idx+2] = dchar.init;
                idx += 3;
            }
            else
            {
                seq[idx] = jamoSBase + indexLV;
                seq[idx+1] = dchar.init;
                idx += 2;
            }
        }
        else
            idx++;
    }
}

//----------------------------------------------------------------------------
public:

/**
    Decomposes a Hangul syllable. If $(D ch) is not a composed syllable
    then this function returns $(LREF Grapheme) containing only $(D ch) as is.
*/
Grapheme decomposeHangul(dchar ch) @safe
{
    immutable idxS = cast(int) ch - jamoSBase;
    if (idxS < 0 || idxS >= jamoSCount) return Grapheme(ch);
    immutable idxL = idxS / jamoNCount;
    immutable idxV = (idxS % jamoNCount) / jamoTCount;
    immutable idxT = idxS % jamoTCount;

    immutable partL = jamoLBase + idxL;
    immutable partV = jamoVBase + idxV;
    if (idxT > 0) // there is a trailling consonant (T); <L,V,T> decomposition
        return Grapheme(partL, partV, jamoTBase + idxT);
    else // <L, V> decomposition
        return Grapheme(partL, partV);
}

///
@system unittest
{
    import std.algorithm.comparison : equal;
    assert(decomposeHangul('\uD4DB')[].equal("\u1111\u1171\u11B6"));
}

/++
    Try to compose hangul syllable out of a leading consonant ($(D lead)),
    a $(D vowel) and optional $(D trailing) consonant jamos.

    On success returns the composed LV or LVT hangul syllable.

    If any of $(D lead) and $(D vowel) are not a valid hangul jamo
    of the respective $(CHARACTER) class returns dchar.init.
+/
dchar composeJamo(dchar lead, dchar vowel, dchar trailing=dchar.init) pure nothrow @nogc @safe
{
    if (!isJamoL(lead))
        return dchar.init;
    immutable indexL = lead - jamoLBase;
    if (!isJamoV(vowel))
        return dchar.init;
    immutable indexV = vowel - jamoVBase;
    immutable indexLV = indexL * jamoNCount + indexV * jamoTCount;
    immutable dchar syllable = jamoSBase + indexLV;
    return isJamoT(trailing) ? syllable + (trailing - jamoTBase) : syllable;
}

///
@safe unittest
{
    assert(composeJamo('\u1111', '\u1171', '\u11B6') == '\uD4DB');
    // leaving out T-vowel, or passing any codepoint
    // that is not trailing consonant composes an LV-syllable
    assert(composeJamo('\u1111', '\u1171') == '\uD4CC');
    assert(composeJamo('\u1111', '\u1171', ' ') == '\uD4CC');
    assert(composeJamo('\u1111', 'A') == dchar.init);
    assert(composeJamo('A', '\u1171') == dchar.init);
}

@system unittest
{
    import std.algorithm.comparison : equal;
    import std.conv : text;

    static void testDecomp(UnicodeDecomposition T)(dchar ch, string r)
    {
        Grapheme g = decompose!T(ch);
        assert(equal(g[], r), text(g[], " vs ", r));
    }
    testDecomp!Canonical('\u1FF4', "\u03C9\u0301\u0345");
    testDecomp!Canonical('\uF907', "\u9F9C");
    testDecomp!Compatibility('\u33FF', "\u0067\u0061\u006C");
    testDecomp!Compatibility('\uA7F9', "\u0153");

    // check examples
    assert(decomposeHangul('\uD4DB')[].equal("\u1111\u1171\u11B6"));
    assert(composeJamo('\u1111', '\u1171', '\u11B6') == '\uD4DB');
    assert(composeJamo('\u1111', '\u1171') == '\uD4CC'); // leave out T-vowel
    assert(composeJamo('\u1111', '\u1171', ' ') == '\uD4CC');
    assert(composeJamo('\u1111', 'A') == dchar.init);
    assert(composeJamo('A', '\u1171') == dchar.init);
}

/**
    Enumeration type for normalization forms,
    passed as template parameter for functions like $(LREF normalize).
*/
enum NormalizationForm {
    NFC,
    NFD,
    NFKC,
    NFKD
}


enum {
    /**
        Shorthand aliases from values indicating normalization forms.
    */
    NFC = NormalizationForm.NFC,
    ///ditto
    NFD = NormalizationForm.NFD,
    ///ditto
    NFKC = NormalizationForm.NFKC,
    ///ditto
    NFKD = NormalizationForm.NFKD
}

/++
    Returns $(D input) string normalized to the chosen form.
    Form C is used by default.

    For more information on normalization forms see
    the $(S_LINK Normalization, normalization section).

    Note:
    In cases where the string in question is already normalized,
    it is returned unmodified and no memory allocation happens.
+/
inout(C)[] normalize(NormalizationForm norm=NFC, C)(inout(C)[] input)
{
    import std.algorithm.mutation : SwapStrategy;
    import std.algorithm.sorting : sort;
    import std.array : appender;
    import std.range : zip;

    auto anchors = splitNormalized!norm(input);
    if (anchors[0] == input.length && anchors[1] == input.length)
        return input;
    dchar[] decomposed;
    decomposed.reserve(31);
    ubyte[] ccc;
    ccc.reserve(31);
    auto app = appender!(C[])();
    do
    {
        app.put(input[0 .. anchors[0]]);
        foreach (dchar ch; input[anchors[0]..anchors[1]])
            static if (norm == NFD || norm == NFC)
            {
                foreach (dchar c; decompose!Canonical(ch)[])
                    decomposed ~= c;
            }
            else // NFKD & NFKC
            {
                foreach (dchar c; decompose!Compatibility(ch)[])
                    decomposed ~= c;
            }
        ccc.length = decomposed.length;
        size_t firstNonStable = 0;
        ubyte lastClazz = 0;

        foreach (idx, dchar ch; decomposed)
        {
            immutable clazz = combiningClass(ch);
            ccc[idx] = clazz;
            if (clazz == 0 && lastClazz != 0)
            {
                // found a stable code point after unstable ones
                sort!("a[0] < b[0]", SwapStrategy.stable)
                    (zip(ccc[firstNonStable .. idx], decomposed[firstNonStable .. idx]));
                firstNonStable = decomposed.length;
            }
            else if (clazz != 0 && lastClazz == 0)
            {
                // found first unstable code point after stable ones
                firstNonStable = idx;
            }
            lastClazz = clazz;
        }
        sort!("a[0] < b[0]", SwapStrategy.stable)
            (zip(ccc[firstNonStable..$], decomposed[firstNonStable..$]));
        static if (norm == NFC || norm == NFKC)
        {
            import std.algorithm.searching : countUntil;
            auto first = countUntil(ccc, 0);
            if (first >= 0) // no starters?? no recomposition
            {
                for (;;)
                {
                    immutable second = recompose(first, decomposed, ccc);
                    if (second == decomposed.length)
                        break;
                    first = second;
                }
                // 2nd pass for hangul syllables
                hangulRecompose(decomposed);
            }
        }
        static if (norm == NFD || norm == NFKD)
            app.put(decomposed);
        else
        {
            import std.algorithm.mutation : remove;
            auto clean = remove!("a == dchar.init", SwapStrategy.stable)(decomposed);
            app.put(decomposed[0 .. clean.length]);
        }
        // reset variables
        decomposed.length = 0;
        decomposed.assumeSafeAppend();
        ccc.length = 0;
        ccc.assumeSafeAppend();
        input = input[anchors[1]..$];
        // and move on
        anchors = splitNormalized!norm(input);
    }while (anchors[0] != input.length);
    app.put(input[0 .. anchors[0]]);
    return cast(inout(C)[])app.data;
}

///
@safe unittest
{
    // any encoding works
    wstring greet = "Hello world";
    assert(normalize(greet) is greet); // the same exact slice

    // An example of a character with all 4 forms being different:
    // Greek upsilon with acute and hook symbol (code point 0x03D3)
    assert(normalize!NFC("ϓ") == "\u03D3");
    assert(normalize!NFD("ϓ") == "\u03D2\u0301");
    assert(normalize!NFKC("ϓ") == "\u038E");
    assert(normalize!NFKD("ϓ") == "\u03A5\u0301");
}

@safe unittest
{
    import std.conv : text;

    assert(normalize!NFD("abc\uF904def") == "abc\u6ED1def", text(normalize!NFD("abc\uF904def")));
    assert(normalize!NFKD("2¹⁰") == "210", normalize!NFKD("2¹⁰"));
    assert(normalize!NFD("Äffin") == "A\u0308ffin");

    // check example

    // any encoding works
    wstring greet = "Hello world";
    assert(normalize(greet) is greet); // the same exact slice

    // An example of a character with all 4 forms being different:
    // Greek upsilon with acute and hook symbol (code point 0x03D3)
    assert(normalize!NFC("ϓ") == "\u03D3");
    assert(normalize!NFD("ϓ") == "\u03D2\u0301");
    assert(normalize!NFKC("ϓ") == "\u038E");
    assert(normalize!NFKD("ϓ") == "\u03A5\u0301");
}

// canonically recompose given slice of code points, works in-place and mutates data
private size_t recompose(size_t start, dchar[] input, ubyte[] ccc) pure nothrow @safe
{
    assert(input.length == ccc.length);
    int accumCC = -1;// so that it's out of 0 .. 255 range
    // writefln("recomposing %( %04x %)", input);
    // first one is always a starter thus we start at i == 1
    size_t i = start+1;
    for (; ; )
    {
        if (i == input.length)
            break;
        immutable curCC = ccc[i];
        // In any character sequence beginning with a starter S
        // a character C is blocked from S if and only if there
        // is some character B between S and C, and either B
        // is a starter or it has the same or higher combining class as C.
        //------------------------
        // Applying to our case:
        // S is input[0]
        // accumCC is the maximum CCC of characters between C and S,
        //     as ccc are sorted
        // C is input[i]

        if (curCC > accumCC)
        {
            immutable comp = compose(input[start], input[i]);
            if (comp != dchar.init)
            {
                input[start] = comp;
                input[i] = dchar.init;// put a sentinel
                // current was merged so its CCC shouldn't affect
                // composing with the next one
            }
            else
            {
                // if it was a starter then accumCC is now 0, end of loop
                accumCC = curCC;
                if (accumCC == 0)
                    break;
            }
        }
        else
        {
            // ditto here
            accumCC = curCC;
            if (accumCC == 0)
                break;
        }
        i++;
    }
    return i;
}

// returns tuple of 2 indexes that delimit:
// normalized text, piece that needs normalization and
// the rest of input starting with stable code point
private auto splitNormalized(NormalizationForm norm, C)(const(C)[] input)
{
    import std.typecons : tuple;
    ubyte lastCC = 0;

    foreach (idx, dchar ch; input)
    {
        static if (norm == NFC)
            if (ch < 0x0300)
            {
                lastCC = 0;
                continue;
            }
        immutable ubyte CC = combiningClass(ch);
        if (lastCC > CC && CC != 0)
        {
            return seekStable!norm(idx, input);
        }

        if (notAllowedIn!norm(ch))
        {
           return seekStable!norm(idx, input);
        }
        lastCC = CC;
    }
    return tuple(input.length, input.length);
}

private auto seekStable(NormalizationForm norm, C)(size_t idx, in C[] input)
{
    import std.typecons : tuple;
    import std.utf : codeLength;

    auto br = input[0 .. idx];
    size_t region_start = 0;// default
    for (;;)
    {
        if (br.empty)// start is 0
            break;
        dchar ch = br.back;
        if (combiningClass(ch) == 0 && allowedIn!norm(ch))
        {
            region_start = br.length - codeLength!C(ch);
            break;
        }
        br.popFront();
    }
    ///@@@BUG@@@ can't use find: " find is a nested function and can't be used..."
    size_t region_end=input.length;// end is $ by default
    foreach (i, dchar ch; input[idx..$])
    {
        if (combiningClass(ch) == 0 && allowedIn!norm(ch))
        {
            region_end = i+idx;
            break;
        }
    }
    // writeln("Region to normalize: ", input[region_start .. region_end]);
    return tuple(region_start, region_end);
}

/**
    Tests if dchar $(D ch) is always allowed (Quick_Check=YES) in normalization
    form $(D norm).
*/
public bool allowedIn(NormalizationForm norm)(dchar ch)
{
    return !notAllowedIn!norm(ch);
}

///
@safe unittest
{
    // e.g. Cyrillic is always allowed, so is ASCII
    assert(allowedIn!NFC('я'));
    assert(allowedIn!NFD('я'));
    assert(allowedIn!NFKC('я'));
    assert(allowedIn!NFKD('я'));
    assert(allowedIn!NFC('Z'));
}

// not user friendly name but more direct
private bool notAllowedIn(NormalizationForm norm)(dchar ch)
{
    static if (norm == NFC)
        alias qcTrie = nfcQCTrie;
    else static if (norm == NFD)
        alias qcTrie = nfdQCTrie;
    else static if (norm == NFKC)
        alias qcTrie = nfkcQCTrie;
    else static if (norm == NFKD)
        alias qcTrie = nfkdQCTrie;
    else
        static assert("Unknown normalization form "~norm);
    return qcTrie[ch];
}

@safe unittest
{
    assert(allowedIn!NFC('я'));
    assert(allowedIn!NFD('я'));
    assert(allowedIn!NFKC('я'));
    assert(allowedIn!NFKD('я'));
    assert(allowedIn!NFC('Z'));
}

}

version (std_uni_bootstrap)
{
    // old version used for bootstrapping of gen_uni.d that generates
    // up to date optimal versions of all of isXXX functions
    @safe pure nothrow @nogc public bool isWhite(dchar c)
    {
        import std.ascii : isWhite;
        return isWhite(c) ||
               c == lineSep || c == paraSep ||
               c == '\u0085' || c == '\u00A0' || c == '\u1680' || c == '\u180E' ||
               (c >= '\u2000' && c <= '\u200A') ||
               c == '\u202F' || c == '\u205F' || c == '\u3000';
    }
}
else
{

// trusted -> avoid bounds check
@trusted pure nothrow @nogc private
{
    import std.internal.unicode_tables; // : toLowerTable, toTitleTable, toUpperTable; // generated file

    // hide template instances behind functions (Bugzilla 13232)
    ushort toLowerIndex(dchar c) { return toLowerIndexTrie[c]; }
    ushort toLowerSimpleIndex(dchar c) { return toLowerSimpleIndexTrie[c]; }
    dchar toLowerTab(size_t idx) { return toLowerTable[idx]; }

    ushort toTitleIndex(dchar c) { return toTitleIndexTrie[c]; }
    ushort toTitleSimpleIndex(dchar c) { return toTitleSimpleIndexTrie[c]; }
    dchar toTitleTab(size_t idx) { return toTitleTable[idx]; }

    ushort toUpperIndex(dchar c) { return toUpperIndexTrie[c]; }
    ushort toUpperSimpleIndex(dchar c) { return toUpperSimpleIndexTrie[c]; }
    dchar toUpperTab(size_t idx) { return toUpperTable[idx]; }
}

public:

/++
    Whether or not $(D c) is a Unicode whitespace $(CHARACTER).
    (general Unicode category: Part of C0(tab, vertical tab, form feed,
    carriage return, and linefeed characters), Zs, Zl, Zp, and NEL(U+0085))
+/
@safe pure nothrow @nogc
public bool isWhite(dchar c)
{
    import std.internal.unicode_tables : isWhiteGen; // generated file
    return isWhiteGen(c); // call pregenerated binary search
}

/++
    Return whether $(D c) is a Unicode lowercase $(CHARACTER).
+/
@safe pure nothrow @nogc
bool isLower(dchar c)
{
    import std.ascii : isLower, isASCII;
    if (isASCII(c))
        return isLower(c);
    return lowerCaseTrie[c];
}

@safe unittest
{
    import std.ascii : isLower;
    foreach (v; 0 .. 0x80)
        assert(isLower(v) == .isLower(v));
    assert(.isLower('я'));
    assert(.isLower('й'));
    assert(!.isLower('Ж'));
    // Greek HETA
    assert(!.isLower('\u0370'));
    assert(.isLower('\u0371'));
    assert(!.isLower('\u039C')); // capital MU
    assert(.isLower('\u03B2')); // beta
    // from extended Greek
    assert(!.isLower('\u1F18'));
    assert(.isLower('\u1F00'));
    foreach (v; unicode.lowerCase.byCodepoint)
        assert(.isLower(v) && !isUpper(v));
}


/++
    Return whether $(D c) is a Unicode uppercase $(CHARACTER).
+/
@safe pure nothrow @nogc
bool isUpper(dchar c)
{
    import std.ascii : isUpper, isASCII;
    if (isASCII(c))
        return isUpper(c);
    return upperCaseTrie[c];
}

@safe unittest
{
    import std.ascii : isLower;
    foreach (v; 0 .. 0x80)
        assert(isLower(v) == .isLower(v));
    assert(!isUpper('й'));
    assert(isUpper('Ж'));
    // Greek HETA
    assert(isUpper('\u0370'));
    assert(!isUpper('\u0371'));
    assert(isUpper('\u039C')); // capital MU
    assert(!isUpper('\u03B2')); // beta
    // from extended Greek
    assert(!isUpper('\u1F00'));
    assert(isUpper('\u1F18'));
    foreach (v; unicode.upperCase.byCodepoint)
        assert(isUpper(v) && !.isLower(v));
}


//TODO: Hidden for now, needs better API.
//Other transforms could use better API as well, but this one is a new primitive.
@safe pure nothrow @nogc
private dchar toTitlecase(dchar c)
{
    // optimize ASCII case
    if (c < 0xAA)
    {
        if (c < 'a')
            return c;
        if (c <= 'z')
            return c - 32;
        return c;
    }
    size_t idx = toTitleSimpleIndex(c);
    if (idx != ushort.max)
    {
        return toTitleTab(idx);
    }
    return c;
}

private alias UpperTriple = AliasSeq!(toUpperIndex, MAX_SIMPLE_UPPER, toUpperTab);
private alias LowerTriple = AliasSeq!(toLowerIndex, MAX_SIMPLE_LOWER, toLowerTab);

// generic toUpper/toLower on whole string, creates new or returns as is
private S toCase(alias indexFn, uint maxIdx, alias tableFn, alias asciiConvert, S)(S s) @trusted pure
if (isSomeString!S)
{
    import std.array : appender;
    import std.ascii : isASCII;

    foreach (i, dchar cOuter; s)
    {
        ushort idx = indexFn(cOuter);
        if (idx == ushort.max)
            continue;
        auto result = appender!S(s[0 .. i]);
        result.reserve(s.length);
        foreach (dchar c; s[i .. $])
        {
            if (c.isASCII)
            {
                result.put(asciiConvert(c));
            }
            else
            {
                idx = indexFn(c);
                if (idx == ushort.max)
                    result.put(c);
                else if (idx < maxIdx)
                {
                    c = tableFn(idx);
                    result.put(c);
                }
                else
                {
                    auto val = tableFn(idx);
                    // unpack length + codepoint
                    immutable uint len = val >> 24;
                    result.put(cast(dchar)(val & 0xFF_FFFF));
                    foreach (j; idx+1 .. idx+len)
                        result.put(tableFn(j));
                }
            }
        }
        return result.data;
    }
    return s;
}

@safe unittest //12428
{
    import std.array : replicate;
    auto s = "abcdefghij".replicate(300);
    s = s[0 .. 10];

    toUpper(s);

    assert(s == "abcdefghij");
}


// generic toUpper/toLower on whole range, returns range
private auto toCaser(alias indexFn, uint maxIdx, alias tableFn, alias asciiConvert, Range)(Range str)
    // Accept range of dchar's
if (isInputRange!Range &&
    isSomeChar!(ElementEncodingType!Range) &&
    ElementEncodingType!Range.sizeof == dchar.sizeof)
{
    static struct ToCaserImpl
    {
        @property bool empty()
        {
            return !nLeft && r.empty;
        }

        @property auto front()
        {
            import std.ascii : isASCII;

            if (!nLeft)
            {
                dchar c = r.front;
                if (c.isASCII)
                {
                    buf[0] = asciiConvert(c);
                    nLeft = 1;
                }
                else
                {
                    const idx = indexFn(c);
                    if (idx == ushort.max)
                    {
                        buf[0] = c;
                        nLeft = 1;
                    }
                    else if (idx < maxIdx)
                    {
                        buf[0] = tableFn(idx);
                        nLeft = 1;
                    }
                    else
                    {
                        immutable val = tableFn(idx);
                        // unpack length + codepoint
                        nLeft = val >> 24;
                        if (nLeft == 0)
                            nLeft = 1;
                        assert(nLeft <= buf.length);
                        buf[nLeft - 1] = cast(dchar)(val & 0xFF_FFFF);
                        foreach (j; 1 .. nLeft)
                            buf[nLeft - j - 1] = tableFn(idx + j);
                    }
                }
            }
            return buf[nLeft - 1];
        }

        void popFront()
        {
            if (!nLeft)
                front;
            assert(nLeft);
            --nLeft;
            if (!nLeft)
                r.popFront();
        }

        static if (isForwardRange!Range)
        {
            @property auto save()
            {
                auto ret = this;
                ret.r = r.save;
                return ret;
            }
        }

      private:
        Range r;
        uint nLeft;
        dchar[3] buf = void;
    }

    return ToCaserImpl(str);
}

/*********************
 * Convert input range or string to upper or lower case.
 *
 * Does not allocate memory.
 * Characters in UTF-8 or UTF-16 format that cannot be decoded
 * are treated as $(REF replacementDchar, std,utf).
 *
 * Params:
 *      str = string or range of characters
 *
 * Returns:
 *      an InputRange of dchars
 *
 * See_Also:
 *      $(LREF toUpper), $(LREF toLower)
 */

auto asLowerCase(Range)(Range str)
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&
    !isConvertibleToString!Range)
{
    static if (ElementEncodingType!Range.sizeof < dchar.sizeof)
    {
        import std.utf : byDchar;

        // Decode first
        return asLowerCase(str.byDchar);
    }
    else
    {
        static import std.ascii;
        return toCaser!(LowerTriple, std.ascii.toLower)(str);
    }
}

/// ditto
auto asUpperCase(Range)(Range str)
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&
    !isConvertibleToString!Range)
{
    static if (ElementEncodingType!Range.sizeof < dchar.sizeof)
    {
        import std.utf : byDchar;

        // Decode first
        return asUpperCase(str.byDchar);
    }
    else
    {
        static import std.ascii;
        return toCaser!(UpperTriple, std.ascii.toUpper)(str);
    }
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert("hEllo".asUpperCase.equal("HELLO"));
}

// explicitly undocumented
auto asLowerCase(Range)(auto ref Range str)
if (isConvertibleToString!Range)
{
    import std.traits : StringTypeOf;
    return asLowerCase!(StringTypeOf!Range)(str);
}

// explicitly undocumented
auto asUpperCase(Range)(auto ref Range str)
if (isConvertibleToString!Range)
{
    import std.traits : StringTypeOf;
    return asUpperCase!(StringTypeOf!Range)(str);
}

@safe unittest
{
    assert(testAliasedString!asLowerCase("hEllo"));
    assert(testAliasedString!asUpperCase("hEllo"));
}

@safe unittest
{
    import std.array : array;

    auto a = "HELLo".asLowerCase;
    auto savea = a.save;
    auto s = a.array;
    assert(s == "hello");
    s = savea.array;
    assert(s == "hello");

    string[] lower = ["123", "abcфеж", "\u0131\u023f\u03c9", "i\u0307\u1Fe2"];
    string[] upper = ["123", "ABCФЕЖ", "I\u2c7e\u2126", "\u0130\u03A5\u0308\u0300"];

    foreach (i, slwr; lower)
    {
        import std.utf : byChar;

        auto sx = slwr.asUpperCase.byChar.array;
        assert(sx == toUpper(slwr));
        auto sy = upper[i].asLowerCase.byChar.array;
        assert(sy == toLower(upper[i]));
    }

    // Not necessary to call r.front
    for (auto r = lower[3].asUpperCase; !r.empty; r.popFront())
    {
    }

    import std.algorithm.comparison : equal;

    "HELLo"w.asLowerCase.equal("hello"d);
    "HELLo"w.asUpperCase.equal("HELLO"d);
    "HELLo"d.asLowerCase.equal("hello"d);
    "HELLo"d.asUpperCase.equal("HELLO"d);

    import std.utf : byChar;
    assert(toLower("\u1Fe2") == asLowerCase("\u1Fe2").byChar.array);
}

// generic capitalizer on whole range, returns range
private auto toCapitalizer(alias indexFnUpper, uint maxIdxUpper, alias tableFnUpper,
                           Range)(Range str)
    // Accept range of dchar's
if (isInputRange!Range &&
    isSomeChar!(ElementEncodingType!Range) &&
    ElementEncodingType!Range.sizeof == dchar.sizeof)
{
    static struct ToCapitalizerImpl
    {
        @property bool empty()
        {
            return lower ? lwr.empty : !nLeft && r.empty;
        }

        @property auto front()
        {
            if (lower)
                return lwr.front;

            if (!nLeft)
            {
                immutable dchar c = r.front;
                const idx = indexFnUpper(c);
                if (idx == ushort.max)
                {
                    buf[0] = c;
                    nLeft = 1;
                }
                else if (idx < maxIdxUpper)
                {
                    buf[0] = tableFnUpper(idx);
                    nLeft = 1;
                }
                else
                {
                    immutable val = tableFnUpper(idx);
                    // unpack length + codepoint
                    nLeft = val >> 24;
                    if (nLeft == 0)
                        nLeft = 1;
                    assert(nLeft <= buf.length);
                    buf[nLeft - 1] = cast(dchar)(val & 0xFF_FFFF);
                    foreach (j; 1 .. nLeft)
                        buf[nLeft - j - 1] = tableFnUpper(idx + j);
                }
            }
            return buf[nLeft - 1];
        }

        void popFront()
        {
            if (lower)
                lwr.popFront();
            else
            {
                if (!nLeft)
                    front;
                assert(nLeft);
                --nLeft;
                if (!nLeft)
                {
                    r.popFront();
                    lwr = r.asLowerCase();
                    lower = true;
                }
            }
        }

        static if (isForwardRange!Range)
        {
            @property auto save()
            {
                auto ret = this;
                ret.r = r.save;
                ret.lwr = lwr.save;
                return ret;
            }
        }

      private:
        Range r;
        typeof(r.asLowerCase) lwr; // range representing the lower case rest of string
        bool lower = false;     // false for first character, true for rest of string
        dchar[3] buf = void;
        uint nLeft = 0;
    }

    return ToCapitalizerImpl(str);
}

/*********************
 * Capitalize input range or string, meaning convert the first
 * character to upper case and subsequent characters to lower case.
 *
 * Does not allocate memory.
 * Characters in UTF-8 or UTF-16 format that cannot be decoded
 * are treated as $(REF replacementDchar, std,utf).
 *
 * Params:
 *      str = string or range of characters
 *
 * Returns:
 *      an InputRange of dchars
 *
 * See_Also:
 *      $(LREF toUpper), $(LREF toLower)
 *      $(LREF asUpperCase), $(LREF asLowerCase)
 */

auto asCapitalized(Range)(Range str)
if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) &&
    !isConvertibleToString!Range)
{
    static if (ElementEncodingType!Range.sizeof < dchar.sizeof)
    {
        import std.utf : byDchar;

        // Decode first
        return toCapitalizer!UpperTriple(str.byDchar);
    }
    else
    {
        return toCapitalizer!UpperTriple(str);
    }
}

///
@safe pure unittest
{
    import std.algorithm.comparison : equal;

    assert("hEllo".asCapitalized.equal("Hello"));
}

auto asCapitalized(Range)(auto ref Range str)
if (isConvertibleToString!Range)
{
    import std.traits : StringTypeOf;
    return asCapitalized!(StringTypeOf!Range)(str);
}

@safe unittest
{
    assert(testAliasedString!asCapitalized("hEllo"));
}

@safe pure nothrow @nogc unittest
{
    auto r = "hEllo".asCapitalized();
    assert(r.front == 'H');
}

@safe unittest
{
    import std.array : array;

    auto a = "hELLo".asCapitalized;
    auto savea = a.save;
    auto s = a.array;
    assert(s == "Hello");
    s = savea.array;
    assert(s == "Hello");

    string[2][] cases =
    [
        ["", ""],
        ["h", "H"],
        ["H", "H"],
        ["3", "3"],
        ["123", "123"],
        ["h123A", "H123a"],
        ["феж", "Феж"],
        ["\u1Fe2", "\u03a5\u0308\u0300"],
    ];

    foreach (i; 0 .. cases.length)
    {
        import std.utf : byChar;

        auto r = cases[i][0].asCapitalized.byChar.array;
        auto result = cases[i][1];
        assert(r == result);
    }

    // Don't call r.front
    for (auto r = "\u1Fe2".asCapitalized; !r.empty; r.popFront())
    {
    }

    import std.algorithm.comparison : equal;

    "HELLo"w.asCapitalized.equal("Hello"d);
    "hElLO"w.asCapitalized.equal("Hello"d);
    "hello"d.asCapitalized.equal("Hello"d);
    "HELLO"d.asCapitalized.equal("Hello"d);

    import std.utf : byChar;
    assert(asCapitalized("\u0130").byChar.array == asUpperCase("\u0130").byChar.array);
}

// TODO: helper, I wish std.utf was more flexible (and stright)
private size_t encodeTo(scope char[] buf, size_t idx, dchar c) @trusted pure nothrow @nogc
{
    if (c <= 0x7F)
    {
        buf[idx] = cast(char) c;
        idx++;
    }
    else if (c <= 0x7FF)
    {
        buf[idx] = cast(char)(0xC0 | (c >> 6));
        buf[idx+1] = cast(char)(0x80 | (c & 0x3F));
        idx += 2;
    }
    else if (c <= 0xFFFF)
    {
        buf[idx] = cast(char)(0xE0 | (c >> 12));
        buf[idx+1] = cast(char)(0x80 | ((c >> 6) & 0x3F));
        buf[idx+2] = cast(char)(0x80 | (c & 0x3F));
        idx += 3;
    }
    else if (c <= 0x10FFFF)
    {
        buf[idx] = cast(char)(0xF0 | (c >> 18));
        buf[idx+1] = cast(char)(0x80 | ((c >> 12) & 0x3F));
        buf[idx+2] = cast(char)(0x80 | ((c >> 6) & 0x3F));
        buf[idx+3] = cast(char)(0x80 | (c & 0x3F));
        idx += 4;
    }
    else
        assert(0);
    return idx;
}

@safe unittest
{
    char[] s = "abcd".dup;
    size_t i = 0;
    i = encodeTo(s, i, 'X');
    assert(s == "Xbcd");

    i = encodeTo(s, i, cast(dchar)'\u00A9');
    assert(s == "X\xC2\xA9d");
}

// TODO: helper, I wish std.utf was more flexible (and stright)
private size_t encodeTo(scope wchar[] buf, size_t idx, dchar c) @trusted pure
{
    import std.utf : UTFException;
    if (c <= 0xFFFF)
    {
        if (0xD800 <= c && c <= 0xDFFF)
            throw (new UTFException("Encoding an isolated surrogate code point in UTF-16")).setSequence(c);
        buf[idx] = cast(wchar) c;
        idx++;
    }
    else if (c <= 0x10FFFF)
    {
        buf[idx] = cast(wchar)((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
        buf[idx+1] = cast(wchar)(((c - 0x10000) & 0x3FF) + 0xDC00);
        idx += 2;
    }
    else
        assert(0);
    return idx;
}

private size_t encodeTo(scope dchar[] buf, size_t idx, dchar c) @trusted pure nothrow @nogc
{
    buf[idx] = c;
    idx++;
    return idx;
}

private void toCaseInPlace(alias indexFn, uint maxIdx, alias tableFn, C)(ref C[] s) @trusted pure
if (is(C == char) || is(C == wchar)  || is(C == dchar))
{
    import std.utf : decode, codeLength;
    size_t curIdx = 0;
    size_t destIdx = 0;
    alias slowToCase = toCaseInPlaceAlloc!(indexFn, maxIdx, tableFn);
    size_t lastUnchanged = 0;
    // in-buffer move of bytes to a new start index
    // the trick is that it may not need to copy at all
    static size_t moveTo(C[] str, size_t dest, size_t from, size_t to)
    {
        // Interestingly we may just bump pointer for a while
        // then have to copy if a re-cased char was smaller the original
        // later we may regain pace with char that got bigger
        // In the end it sometimes flip-flops between the 2 cases below
        if (dest == from)
            return to;
        // got to copy
        foreach (C c; str[from .. to])
            str[dest++] = c;
        return dest;
    }
    while (curIdx != s.length)
    {
        size_t startIdx = curIdx;
        immutable ch = decode(s, curIdx);
        // TODO: special case for ASCII
        immutable caseIndex = indexFn(ch);
        if (caseIndex == ushort.max) // unchanged, skip over
        {
            continue;
        }
        else if (caseIndex < maxIdx)  // 1:1 codepoint mapping
        {
            // previous cased chars had the same length as uncased ones
            // thus can just adjust pointer
            destIdx = moveTo(s, destIdx, lastUnchanged, startIdx);
            lastUnchanged = curIdx;
            immutable cased = tableFn(caseIndex);
            immutable casedLen = codeLength!C(cased);
            if (casedLen + destIdx > curIdx) // no place to fit cased char
            {
                // switch to slow codepath, where we allocate
                return slowToCase(s, startIdx, destIdx);
            }
            else
            {
                destIdx = encodeTo(s, destIdx, cased);
            }
        }
        else  // 1:m codepoint mapping, slow codepath
        {
            destIdx = moveTo(s, destIdx, lastUnchanged, startIdx);
            lastUnchanged = curIdx;
            return slowToCase(s, startIdx, destIdx);
        }
        assert(destIdx <= curIdx);
    }
    if (lastUnchanged != s.length)
    {
        destIdx = moveTo(s, destIdx, lastUnchanged, s.length);
    }
    s = s[0 .. destIdx];
}

// helper to precalculate size of case-converted string
private template toCaseLength(alias indexFn, uint maxIdx, alias tableFn)
{
    size_t toCaseLength(C)(in C[] str)
    {
        import std.utf : decode, codeLength;
        size_t codeLen = 0;
        size_t lastNonTrivial = 0;
        size_t curIdx = 0;
        while (curIdx != str.length)
        {
            immutable startIdx = curIdx;
            immutable ch = decode(str, curIdx);
            immutable ushort caseIndex = indexFn(ch);
            if (caseIndex == ushort.max)
                continue;
            else if (caseIndex < maxIdx)
            {
                codeLen += startIdx - lastNonTrivial;
                lastNonTrivial = curIdx;
                immutable cased = tableFn(caseIndex);
                codeLen += codeLength!C(cased);
            }
            else
            {
                codeLen += startIdx - lastNonTrivial;
                lastNonTrivial = curIdx;
                immutable val = tableFn(caseIndex);
                immutable len = val >> 24;
                immutable dchar cased = val & 0xFF_FFFF;
                codeLen += codeLength!C(cased);
                foreach (j; caseIndex+1 .. caseIndex+len)
                    codeLen += codeLength!C(tableFn(j));
            }
        }
        if (lastNonTrivial != str.length)
            codeLen += str.length - lastNonTrivial;
        return codeLen;
    }
}

@safe unittest
{
    alias toLowerLength = toCaseLength!(LowerTriple);
    assert(toLowerLength("abcd") == 4);
    assert(toLowerLength("аБВгд456") == 10+3);
}

// slower code path that preallocates and then copies
// case-converted stuf to the new string
private template toCaseInPlaceAlloc(alias indexFn, uint maxIdx, alias tableFn)
{
    void toCaseInPlaceAlloc(C)(ref C[] s, size_t curIdx,
        size_t destIdx) @trusted pure
        if (is(C == char) || is(C == wchar) || is(C == dchar))
    {
        import std.utf : decode;
        alias caseLength = toCaseLength!(indexFn, maxIdx, tableFn);
        auto trueLength = destIdx + caseLength(s[curIdx..$]);
        C[] ns = new C[trueLength];
        ns[0 .. destIdx] = s[0 .. destIdx];
        size_t lastUnchanged = curIdx;
        while (curIdx != s.length)
        {
            immutable startIdx = curIdx; // start of current codepoint
            immutable ch = decode(s, curIdx);
            immutable caseIndex = indexFn(ch);
            if (caseIndex == ushort.max) // skip over
            {
                continue;
            }
            else if (caseIndex < maxIdx)  // 1:1 codepoint mapping
            {
                immutable cased = tableFn(caseIndex);
                auto toCopy = startIdx - lastUnchanged;
                ns[destIdx .. destIdx+toCopy] = s[lastUnchanged .. startIdx];
                lastUnchanged = curIdx;
                destIdx += toCopy;
                destIdx = encodeTo(ns, destIdx, cased);
            }
            else  // 1:m codepoint mapping, slow codepath
            {
                auto toCopy = startIdx - lastUnchanged;
                ns[destIdx .. destIdx+toCopy] = s[lastUnchanged .. startIdx];
                lastUnchanged = curIdx;
                destIdx += toCopy;
                auto val = tableFn(caseIndex);
                // unpack length + codepoint
                immutable uint len = val >> 24;
                destIdx = encodeTo(ns, destIdx, cast(dchar)(val & 0xFF_FFFF));
                foreach (j; caseIndex+1 .. caseIndex+len)
                    destIdx = encodeTo(ns, destIdx, tableFn(j));
            }
        }
        if (lastUnchanged != s.length)
        {
            auto toCopy = s.length - lastUnchanged;
            ns[destIdx .. destIdx+toCopy] = s[lastUnchanged..$];
            destIdx += toCopy;
        }
        assert(ns.length == destIdx);
        s = ns;
    }
}

/++
    Converts $(D s) to lowercase (by performing Unicode lowercase mapping) in place.
    For a few characters string length may increase after the transformation,
    in such a case the function reallocates exactly once.
    If $(D s) does not have any uppercase characters, then $(D s) is unaltered.
+/
void toLowerInPlace(C)(ref C[] s) @trusted pure
if (is(C == char) || is(C == wchar) || is(C == dchar))
{
    toCaseInPlace!(LowerTriple)(s);
}
// overloads for the most common cases to reduce compile time
@safe pure /*TODO nothrow*/
{
    void toLowerInPlace(ref char[] s)
    { toLowerInPlace!char(s); }
    void toLowerInPlace(ref wchar[] s)
    { toLowerInPlace!wchar(s); }
    void toLowerInPlace(ref dchar[] s)
    { toLowerInPlace!dchar(s); }
}

/++
    Converts $(D s) to uppercase  (by performing Unicode uppercase mapping) in place.
    For a few characters string length may increase after the transformation,
    in such a case the function reallocates exactly once.
    If $(D s) does not have any lowercase characters, then $(D s) is unaltered.
+/
void toUpperInPlace(C)(ref C[] s) @trusted pure
if (is(C == char) || is(C == wchar) || is(C == dchar))
{
    toCaseInPlace!(UpperTriple)(s);
}
// overloads for the most common cases to reduce compile time/code size
@safe pure /*TODO nothrow*/
{
    void toUpperInPlace(ref char[] s)
    { toUpperInPlace!char(s); }
    void toUpperInPlace(ref wchar[] s)
    { toUpperInPlace!wchar(s); }
    void toUpperInPlace(ref dchar[] s)
    { toUpperInPlace!dchar(s); }
}

/++
    If $(D c) is a Unicode uppercase $(CHARACTER), then its lowercase equivalent
    is returned. Otherwise $(D c) is returned.

    Warning: certain alphabets like German and Greek have no 1:1
    upper-lower mapping. Use overload of toLower which takes full string instead.
+/
@safe pure nothrow @nogc
dchar toLower(dchar c)
{
     // optimize ASCII case
    if (c < 0xAA)
    {
        if (c < 'A')
            return c;
        if (c <= 'Z')
            return c + 32;
        return c;
    }
    size_t idx = toLowerSimpleIndex(c);
    if (idx != ushort.max)
    {
        return toLowerTab(idx);
    }
    return c;
}

/++
    Returns a string which is identical to $(D s) except that all of its
    characters are converted to lowercase (by preforming Unicode lowercase mapping).
    If none of $(D s) characters were affected, then $(D s) itself is returned.
+/
S toLower(S)(S s) @trusted pure
if (isSomeString!S)
{
    static import std.ascii;
    return toCase!(LowerTriple, std.ascii.toLower)(s);
}
// overloads for the most common cases to reduce compile time
@safe pure /*TODO nothrow*/
{
    string toLower(string s)
    { return toLower!string(s); }
    wstring toLower(wstring s)
    { return toLower!wstring(s); }
    dstring toLower(dstring s)
    { return toLower!dstring(s); }

    @safe unittest
    {
        // https://issues.dlang.org/show_bug.cgi?id=16663

        static struct String
        {
            string data;
            alias data this;
        }

        void foo()
        {
            auto u = toLower(String(""));
        }
    }
}


@system unittest //@@@BUG std.format is not @safe
{
    static import std.ascii;
    import std.format : format;
    foreach (ch; 0 .. 0x80)
        assert(std.ascii.toLower(ch) == toLower(ch));
    assert(toLower('Я') == 'я');
    assert(toLower('Δ') == 'δ');
    foreach (ch; unicode.upperCase.byCodepoint)
    {
        dchar low = ch.toLower();
        assert(low == ch || isLower(low), format("%s -> %s", ch, low));
    }
    assert(toLower("АЯ") == "ая");

    assert("\u1E9E".toLower == "\u00df");
    assert("\u00df".toUpper == "SS");
}

//bugzilla 9629
@safe unittest
{
    wchar[] test = "hello þ world"w.dup;
    auto piece = test[6 .. 7];
    toUpperInPlace(piece);
    assert(test == "hello Þ world");
}


@safe unittest
{
    import std.algorithm.comparison : cmp;
    string s1 = "FoL";
    string s2 = toLower(s1);
    assert(cmp(s2, "fol") == 0, s2);
    assert(s2 != s1);

    char[] s3 = s1.dup;
    toLowerInPlace(s3);
    assert(s3 == s2);

    s1 = "A\u0100B\u0101d";
    s2 = toLower(s1);
    s3 = s1.dup;
    assert(cmp(s2, "a\u0101b\u0101d") == 0);
    assert(s2 !is s1);
    toLowerInPlace(s3);
    assert(s3 == s2);

    s1 = "A\u0460B\u0461d";
    s2 = toLower(s1);
    s3 = s1.dup;
    assert(cmp(s2, "a\u0461b\u0461d") == 0);
    assert(s2 !is s1);
    toLowerInPlace(s3);
    assert(s3 == s2);

    s1 = "\u0130";
    s2 = toLower(s1);
    s3 = s1.dup;
    assert(s2 == "i\u0307");
    assert(s2 !is s1);
    toLowerInPlace(s3);
    assert(s3 == s2);

    // Test on wchar and dchar strings.
    assert(toLower("Some String"w) == "some string"w);
    assert(toLower("Some String"d) == "some string"d);

    // bugzilla 12455
    dchar c = 'İ'; // '\U0130' LATIN CAPITAL LETTER I WITH DOT ABOVE
    assert(isUpper(c));
    assert(toLower(c) == 'i');
    // extend on 12455 reprot - check simple-case toUpper too
    c = '\u1f87';
    assert(isLower(c));
    assert(toUpper(c) == '\u1F8F');
}


/++
    If $(D c) is a Unicode lowercase $(CHARACTER), then its uppercase equivalent
    is returned. Otherwise $(D c) is returned.

    Warning:
    Certain alphabets like German and Greek have no 1:1
    upper-lower mapping. Use overload of toUpper which takes full string instead.

    toUpper can be used as an argument to $(REF map, std,algorithm,iteration)
    to produce an algorithm that can convert a range of characters to upper case
    without allocating memory.
    A string can then be produced by using $(REF copy, std,algorithm,mutation)
    to send it to an $(REF appender, std,array).
+/
@safe pure nothrow @nogc
dchar toUpper(dchar c)
{
    // optimize ASCII case
    if (c < 0xAA)
    {
        if (c < 'a')
            return c;
        if (c <= 'z')
            return c - 32;
        return c;
    }
    size_t idx = toUpperSimpleIndex(c);
    if (idx != ushort.max)
    {
        return toUpperTab(idx);
    }
    return c;
}

///
@system unittest
{
    import std.algorithm.iteration : map;
    import std.algorithm.mutation : copy;
    import std.array : appender;

    auto abuf = appender!(char[])();
    "hello".map!toUpper.copy(&abuf);
    assert(abuf.data == "HELLO");
}

@safe unittest
{
    static import std.ascii;
    import std.format : format;
    foreach (ch; 0 .. 0x80)
        assert(std.ascii.toUpper(ch) == toUpper(ch));
    assert(toUpper('я') == 'Я');
    assert(toUpper('δ') == 'Δ');
    auto title = unicode.Titlecase_Letter;
    foreach (ch; unicode.lowerCase.byCodepoint)
    {
        dchar up = ch.toUpper();
        assert(up == ch || isUpper(up) || title[up],
            format("%x -> %x", ch, up));
    }
}

/++
    Returns a string which is identical to $(D s) except that all of its
    characters are converted to uppercase (by preforming Unicode uppercase mapping).
    If none of $(D s) characters were affected, then $(D s) itself is returned.
+/
S toUpper(S)(S s) @trusted pure
if (isSomeString!S)
{
    static import std.ascii;
    return toCase!(UpperTriple, std.ascii.toUpper)(s);
}
// overloads for the most common cases to reduce compile time
@safe pure /*TODO nothrow*/
{
    string toUpper(string s)
    { return toUpper!string(s); }
    wstring toUpper(wstring s)
    { return toUpper!wstring(s); }
    dstring toUpper(dstring s)
    { return toUpper!dstring(s); }

    @safe unittest
    {
        // https://issues.dlang.org/show_bug.cgi?id=16663

        static struct String
        {
            string data;
            alias data this;
        }

        void foo()
        {
            auto u = toUpper(String(""));
        }
    }
}

@safe unittest
{
    import std.algorithm.comparison : cmp;

    string s1 = "FoL";
    string s2;
    char[] s3;

    s2 = toUpper(s1);
    s3 = s1.dup; toUpperInPlace(s3);
    assert(s3 == s2, s3);
    assert(cmp(s2, "FOL") == 0);
    assert(s2 !is s1);

    s1 = "a\u0100B\u0101d";
    s2 = toUpper(s1);
    s3 = s1.dup; toUpperInPlace(s3);
    assert(s3 == s2);
    assert(cmp(s2, "A\u0100B\u0100D") == 0);
    assert(s2 !is s1);

    s1 = "a\u0460B\u0461d";
    s2 = toUpper(s1);
    s3 = s1.dup; toUpperInPlace(s3);
    assert(s3 == s2);
    assert(cmp(s2, "A\u0460B\u0460D") == 0);
    assert(s2 !is s1);
}

@system unittest
{
    static void doTest(C)(const(C)[] s, const(C)[] trueUp, const(C)[] trueLow)
    {
        import std.format : format;
        string diff = "src: %( %x %)\nres: %( %x %)\ntru: %( %x %)";
        auto low = s.toLower() , up = s.toUpper();
        auto lowInp = s.dup, upInp = s.dup;
        lowInp.toLowerInPlace();
        upInp.toUpperInPlace();
        assert(low == trueLow, format(diff, low, trueLow));
        assert(up == trueUp,  format(diff, up, trueUp));
        assert(lowInp == trueLow,
            format(diff, cast(ubyte[]) s, cast(ubyte[]) lowInp, cast(ubyte[]) trueLow));
        assert(upInp == trueUp,
            format(diff, cast(ubyte[]) s, cast(ubyte[]) upInp, cast(ubyte[]) trueUp));
    }
    foreach (S; AliasSeq!(dstring, wstring, string))
    {

        S easy = "123";
        S good = "abCФеж";
        S awful = "\u0131\u023f\u2126";
        S wicked = "\u0130\u1FE2";
        auto options = [easy, good, awful, wicked];
        S[] lower = ["123", "abcфеж", "\u0131\u023f\u03c9", "i\u0307\u1Fe2"];
        S[] upper = ["123", "ABCФЕЖ", "I\u2c7e\u2126", "\u0130\u03A5\u0308\u0300"];

        foreach (val; AliasSeq!(easy, good))
        {
            auto e = val.dup;
            auto g = e;
            e.toUpperInPlace();
            assert(e is g);
            e.toLowerInPlace();
            assert(e is g);
        }
        foreach (i, v; options)
        {
            doTest(v, upper[i], lower[i]);
        }

        // a few combinatorial runs
        foreach (i; 0 .. options.length)
        foreach (j; i .. options.length)
        foreach (k; j .. options.length)
        {
            auto sample = options[i] ~ options[j] ~ options[k];
            auto sample2 = options[k] ~ options[j] ~ options[i];
            doTest(sample, upper[i] ~ upper[j] ~ upper[k],
                lower[i] ~ lower[j] ~ lower[k]);
            doTest(sample2, upper[k] ~ upper[j] ~ upper[i],
                lower[k] ~ lower[j] ~ lower[i]);
        }
    }
}


/++
    Returns whether $(D c) is a Unicode alphabetic $(CHARACTER)
    (general Unicode category: Alphabetic).
+/
@safe pure nothrow @nogc
bool isAlpha(dchar c)
{
    // optimization
    if (c < 0xAA)
    {
        size_t x = c - 'A';
        if (x <= 'Z' - 'A')
            return true;
        else
        {
            x = c - 'a';
            if (x <= 'z'-'a')
                return true;
        }
        return false;
    }

    return alphaTrie[c];
}

@safe unittest
{
    auto alpha = unicode("Alphabetic");
    foreach (ch; alpha.byCodepoint)
        assert(isAlpha(ch));
    foreach (ch; 0 .. 0x4000)
        assert((ch in alpha) == isAlpha(ch));
}


/++
    Returns whether $(D c) is a Unicode mark
    (general Unicode category: Mn, Me, Mc).
+/
@safe pure nothrow @nogc
bool isMark(dchar c)
{
    return markTrie[c];
}

@safe unittest
{
    auto mark = unicode("Mark");
    foreach (ch; mark.byCodepoint)
        assert(isMark(ch));
    foreach (ch; 0 .. 0x4000)
        assert((ch in mark) == isMark(ch));
}

/++
    Returns whether $(D c) is a Unicode numerical $(CHARACTER)
    (general Unicode category: Nd, Nl, No).
+/
@safe pure nothrow @nogc
bool isNumber(dchar c)
{
    // optimization for ascii case
    if (c <= 0x7F)
    {
        return c >= '0' && c <= '9';
    }
    else
    {
        return numberTrie[c];
    }
}

@safe unittest
{
    auto n = unicode("N");
    foreach (ch; n.byCodepoint)
        assert(isNumber(ch));
    foreach (ch; 0 .. 0x4000)
        assert((ch in n) == isNumber(ch));
}

/++
    Returns whether $(D c) is a Unicode alphabetic $(CHARACTER) or number.
    (general Unicode category: Alphabetic, Nd, Nl, No).

    Params:
        c = any Unicode character
    Returns:
        `true` if the character is in the Alphabetic, Nd, Nl, or No Unicode
        categories
+/
@safe pure nothrow @nogc
bool isAlphaNum(dchar c)
{
    static import std.ascii;

    // optimization for ascii case
    if (std.ascii.isASCII(c))
    {
        return std.ascii.isAlphaNum(c);
    }
    else
    {
        return isAlpha(c) || isNumber(c);
    }
}

@safe unittest
{
    auto n = unicode("N");
    auto alpha = unicode("Alphabetic");

    foreach (ch; n.byCodepoint)
        assert(isAlphaNum(ch));

    foreach (ch; alpha.byCodepoint)
        assert(isAlphaNum(ch));

    foreach (ch; 0 .. 0x4000)
    {
        assert(((ch in n) || (ch in alpha)) == isAlphaNum(ch));
    }
}

/++
    Returns whether $(D c) is a Unicode punctuation $(CHARACTER)
    (general Unicode category: Pd, Ps, Pe, Pc, Po, Pi, Pf).
+/
@safe pure nothrow @nogc
bool isPunctuation(dchar c)
{
    static import std.ascii;

    // optimization for ascii case
    if (c <= 0x7F)
    {
        return std.ascii.isPunctuation(c);
    }
    else
    {
        return punctuationTrie[c];
    }
}

@safe unittest
{
    assert(isPunctuation('\u0021'));
    assert(isPunctuation('\u0028'));
    assert(isPunctuation('\u0029'));
    assert(isPunctuation('\u002D'));
    assert(isPunctuation('\u005F'));
    assert(isPunctuation('\u00AB'));
    assert(isPunctuation('\u00BB'));
    foreach (ch; unicode("P").byCodepoint)
        assert(isPunctuation(ch));
}

/++
    Returns whether $(D c) is a Unicode symbol $(CHARACTER)
    (general Unicode category: Sm, Sc, Sk, So).
+/
@safe pure nothrow @nogc
bool isSymbol(dchar c)
{
   return symbolTrie[c];
}

@safe unittest
{
    import std.format : format;
    assert(isSymbol('\u0024'));
    assert(isSymbol('\u002B'));
    assert(isSymbol('\u005E'));
    assert(isSymbol('\u00A6'));
    foreach (ch; unicode("S").byCodepoint)
        assert(isSymbol(ch), format("%04x", ch));
}

/++
    Returns whether $(D c) is a Unicode space $(CHARACTER)
    (general Unicode category: Zs)
    Note: This doesn't include '\n', '\r', \t' and other non-space $(CHARACTER).
    For commonly used less strict semantics see $(LREF isWhite).
+/
@safe pure nothrow @nogc
bool isSpace(dchar c)
{
    import std.internal.unicode_tables : isSpaceGen; // generated file
    return isSpaceGen(c);
}

@safe unittest
{
    assert(isSpace('\u0020'));
    auto space = unicode.Zs;
    foreach (ch; space.byCodepoint)
        assert(isSpace(ch));
    foreach (ch; 0 .. 0x1000)
        assert(isSpace(ch) == space[ch]);
}


/++
    Returns whether $(D c) is a Unicode graphical $(CHARACTER)
    (general Unicode category: L, M, N, P, S, Zs).

+/
@safe pure nothrow @nogc
bool isGraphical(dchar c)
{
    return graphicalTrie[c];
}


@safe unittest
{
    auto set = unicode("Graphical");
    import std.format : format;
    foreach (ch; set.byCodepoint)
        assert(isGraphical(ch), format("%4x", ch));
    foreach (ch; 0 .. 0x4000)
        assert((ch in set) == isGraphical(ch));
}


/++
    Returns whether $(D c) is a Unicode control $(CHARACTER)
    (general Unicode category: Cc).
+/
@safe pure nothrow @nogc
bool isControl(dchar c)
{
    import std.internal.unicode_tables : isControlGen; // generated file
    return isControlGen(c);
}

@safe unittest
{
    assert(isControl('\u0000'));
    assert(isControl('\u0081'));
    assert(!isControl('\u0100'));
    auto cc = unicode.Cc;
    foreach (ch; cc.byCodepoint)
        assert(isControl(ch));
    foreach (ch; 0 .. 0x1000)
        assert(isControl(ch) == cc[ch]);
}


/++
    Returns whether $(D c) is a Unicode formatting $(CHARACTER)
    (general Unicode category: Cf).
+/
@safe pure nothrow @nogc
bool isFormat(dchar c)
{
    import std.internal.unicode_tables : isFormatGen; // generated file
    return isFormatGen(c);
}


@safe unittest
{
    assert(isFormat('\u00AD'));
    foreach (ch; unicode("Format").byCodepoint)
        assert(isFormat(ch));
}

// code points for private use, surrogates are not likely to change in near feature
// if need be they can be generated from unicode data as well

/++
    Returns whether $(D c) is a Unicode Private Use $(CODEPOINT)
    (general Unicode category: Co).
+/
@safe pure nothrow @nogc
bool isPrivateUse(dchar c)
{
    return (0x00_E000 <= c && c <= 0x00_F8FF)
        || (0x0F_0000 <= c && c <= 0x0F_FFFD)
        || (0x10_0000 <= c && c <= 0x10_FFFD);
}

/++
    Returns whether $(D c) is a Unicode surrogate $(CODEPOINT)
    (general Unicode category: Cs).
+/
@safe pure nothrow @nogc
bool isSurrogate(dchar c)
{
    return (0xD800 <= c && c <= 0xDFFF);
}

/++
    Returns whether $(D c) is a Unicode high surrogate (lead surrogate).
+/
@safe pure nothrow @nogc
bool isSurrogateHi(dchar c)
{
    return (0xD800 <= c && c <= 0xDBFF);
}

/++
    Returns whether $(D c) is a Unicode low surrogate (trail surrogate).
+/
@safe pure nothrow @nogc
bool isSurrogateLo(dchar c)
{
    return (0xDC00 <= c && c <= 0xDFFF);
}

/++
    Returns whether $(D c) is a Unicode non-character i.e.
    a $(CODEPOINT) with no assigned abstract character.
    (general Unicode category: Cn)
+/
@safe pure nothrow @nogc
bool isNonCharacter(dchar c)
{
    return nonCharacterTrie[c];
}

@safe unittest
{
    auto set = unicode("Cn");
    foreach (ch; set.byCodepoint)
        assert(isNonCharacter(ch));
}

private:
// load static data from pre-generated tables into usable datastructures


@safe auto asSet(const (ubyte)[] compressed) pure
{
    return CodepointSet.fromIntervals(decompressIntervals(compressed));
}

@safe pure nothrow auto asTrie(T...)(in TrieEntry!T e)
{
    return const(CodepointTrie!T)(e.offsets, e.sizes, e.data);
}

@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
    // increase the object size of the caller.
    auto lowerCaseTrie() { static immutable res = asTrie(lowerCaseTrieEntries); return res; }
    auto upperCaseTrie() { static immutable res = asTrie(upperCaseTrieEntries); return res; }
    auto simpleCaseTrie() { static immutable res = asTrie(simpleCaseTrieEntries); return res; }
    auto fullCaseTrie() { static immutable res = asTrie(fullCaseTrieEntries); return res; }
    auto alphaTrie() { static immutable res = asTrie(alphaTrieEntries); return res; }
    auto markTrie() { static immutable res = asTrie(markTrieEntries); return res; }
    auto numberTrie() { static immutable res = asTrie(numberTrieEntries); return res; }
    auto punctuationTrie() { static immutable res = asTrie(punctuationTrieEntries); return res; }
    auto symbolTrie() { static immutable res = asTrie(symbolTrieEntries); return res; }
    auto graphicalTrie() { static immutable res = asTrie(graphicalTrieEntries); return res; }
    auto nonCharacterTrie() { static immutable res = asTrie(nonCharacterTrieEntries); return res; }

    //normalization quick-check tables
    auto nfcQCTrie()
    {
        import std.internal.unicode_norm : nfcQCTrieEntries;
        static immutable res = asTrie(nfcQCTrieEntries);
        return res;
    }

    auto nfdQCTrie()
    {
        import std.internal.unicode_norm : nfdQCTrieEntries;
        static immutable res = asTrie(nfdQCTrieEntries);
        return res;
    }

    auto nfkcQCTrie()
    {
        import std.internal.unicode_norm : nfkcQCTrieEntries;
        static immutable res = asTrie(nfkcQCTrieEntries);
        return res;
    }

    auto nfkdQCTrie()
    {
        import std.internal.unicode_norm : nfkdQCTrieEntries;
        static immutable res = asTrie(nfkdQCTrieEntries);
        return res;
    }

    //grapheme breaking algorithm tables
    auto mcTrie()
    {
        import std.internal.unicode_grapheme : mcTrieEntries;
        static immutable res = asTrie(mcTrieEntries);
        return res;
    }

    auto graphemeExtendTrie()
    {
        import std.internal.unicode_grapheme : graphemeExtendTrieEntries;
        static immutable res = asTrie(graphemeExtendTrieEntries);
        return res;
    }

    auto hangLV()
    {
        import std.internal.unicode_grapheme : hangulLVTrieEntries;
        static immutable res = asTrie(hangulLVTrieEntries);
        return res;
    }

    auto hangLVT()
    {
        import std.internal.unicode_grapheme : hangulLVTTrieEntries;
        static immutable res = asTrie(hangulLVTTrieEntries);
        return res;
    }

    // tables below are used for composition/decomposition
    auto combiningClassTrie()
    {
        import std.internal.unicode_comp : combiningClassTrieEntries;
        static immutable res = asTrie(combiningClassTrieEntries);
        return res;
    }

    auto compatMappingTrie()
    {
        import std.internal.unicode_decomp : compatMappingTrieEntries;
        static immutable res = asTrie(compatMappingTrieEntries);
        return res;
    }

    auto canonMappingTrie()
    {
        import std.internal.unicode_decomp : canonMappingTrieEntries;
        static immutable res = asTrie(canonMappingTrieEntries);
        return res;
    }

    auto compositionJumpTrie()
    {
        import std.internal.unicode_comp : compositionJumpTrieEntries;
        static immutable res = asTrie(compositionJumpTrieEntries);
        return res;
    }

    //case conversion tables
    auto toUpperIndexTrie() { static immutable res = asTrie(toUpperIndexTrieEntries); return res; }
    auto toLowerIndexTrie() { static immutable res = asTrie(toLowerIndexTrieEntries); return res; }
    auto toTitleIndexTrie() { static immutable res = asTrie(toTitleIndexTrieEntries); return res; }
    //simple case conversion tables
    auto toUpperSimpleIndexTrie() { static immutable res = asTrie(toUpperSimpleIndexTrieEntries); return res; }
    auto toLowerSimpleIndexTrie() { static immutable res = asTrie(toLowerSimpleIndexTrieEntries); return res; }
    auto toTitleSimpleIndexTrie() { static immutable res = asTrie(toTitleSimpleIndexTrieEntries); return res; }

}

}// version (!std_uni_bootstrap)
