On Thursday, 12 May 2022 at 14:06:13 UTC, Arjan wrote:
On Thursday, 12 May 2022 at 11:05:08 UTC, Basile B. wrote:
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:

- Operator overloading in certain cases was confusing, I remember that for one particular form once I had to use your book instead of the official specs (when opSlice and opIndex are combined)


I still have the thing :

```d
/**
 * CharMap is an helper struct that allows to test
 * if a char is within a set of characters.
 */
struct CharMap
{
    private bool[] _map;
    private dchar _min, _max;

    private void setMinMax(dchar value) pure nothrow @safe
    {
        if (value <= _min) _min = value;
        else if (value >= _max) _max = value;
        _map.length = _max + 1 - _min;
    }

    /**
     * Used in the construction process.
     *
     * Params:
     *      lo = The dchar that defines the range lower bound.
* hi = The dchar that defines the range upper bound (inclusive).
     *
     * Examples:
     * ---
     * CharMap cm = CharMap['0'..'9'];
     * ---
     */
static CharRange opSlice(int index)(dchar lo, dchar hi) pure nothrow @safe @nogc
    {
        return CharRange(lo, hi);
    }

    /**
     * Used in the construction process.
     *
     * Params:
* a = A list made of character slices, of single characters or
     *
* any other values whose type is implicitly convertible to dchar.
     *
     * Examples:
     * ---
     * CharMap cm = CharMap['0'..'9', '.', 'f', 'd', 38, 39];
     * ---
     */
    static CharMap opIndex(A...)(A a) pure nothrow @safe
    {
        CharMap result;

        // bounds
        foreach(elem; a)
        {
            alias T = typeof(elem);
static if (isSomeChar!T || isImplicitlyConvertible!(T, dchar))
            {
                result.setMinMax(elem);
            }
            else static if (is(T == CharRange))
            {
                result.setMinMax(elem._min);
                result.setMinMax(elem._max);
            }
else static assert(0, "unsupported opIndex argument type: " ~ T.stringof);
        }

        result._map[] = false;
        foreach(elem; a)
        {
            alias T = typeof(elem);
static if (isSomeChar!T || isImplicitlyConvertible!(T, dchar))
                result._map[elem - result._min] = true;
            else static if (is(T == CharRange))
            {
foreach(size_t i; elem._min - result._min .. elem._max - result._min + 1)
                    result._map[i] = true;
            }
        }
        return result;
    }

    /**
     * Returns true if a character is within the map.
     *
     * Params:
     *      c = A character or any value convertible to a dchar.
     */
bool opBinaryRight(string op = "in", C)(C c) const pure nothrow @safe @nogc
    if (op == "in")
    {
static if (isSomeChar!C || isImplicitlyConvertible!(C, dchar))
        {
            if (_min > c || c > _max) return false;
            else return _map[c - _min];
        }
else static assert(0, `invalid argument type for CharMap.opBinaryRight!"in"(): ` ~ C.stringof);
    }
}
///
pure @safe unittest
{
    CharMap cm = CharMap['a'..'f', '0'..'9' , 'A'..'F', '_', 9];
    assert('a' in cm);
    assert('b' in cm);
    assert('c' in cm);
    assert('d' in cm);
    assert('e' in cm);
    assert('f' in cm);
    assert('g' !in cm);
    assert('A' in cm);
    assert('B' in cm);
    assert('C' in cm);
    assert('D' in cm);
    assert('E' in cm);
    assert('F' in cm);
    assert('G' !in cm);
    assert('0' in cm);
    assert('4' in cm);
    assert('9' in cm);
    assert('_' in cm);
    assert('%' !in cm);
    assert('\t' in cm);
}
```



Reply via email to