Thread overview
More Generic Variants of findSplit.*() in Demangling/Parsing
Aug 14, 2014
Nordlöw
Aug 14, 2014
Nordlöw
Aug 14, 2014
Nordlöw
Aug 14, 2014
Nordlöw
Aug 14, 2014
Nordlöw
August 14, 2014
I'm currently working on implementing demangling of ELF C++ symbols according to

https://en.wikipedia.org/wiki/Name_mangling

A reoccurring pattern high-level pattern is to use the std.algorithm: findSplit.* functions to make algorithm single-pass when possible.

I'm however lacking a variant of this that takes a condition template argument instead of an input range element as function parameter.

Something like

auto findSplitBefore(alias condition, R)(R range) if (isInputRange!R)
{
    import std.algorithm: until;
    auto hit = range.until!condition;
    auto rest = "";
    return tuple(hit, rest);
}

unittest
{
    import std.algorithm: equal;
    import std.ascii: isDigit;
    auto x = "11ab".findSplitBefore!(a => !a.isDigit);
    assert(equal(x[0], "11"));
    /* assert(equal(x[1], "ab")); */
}

But how do I get the second part in a single pass?

Is copying (duplicating) the existing Phobos implementations the only alternative here?

If so I believe we should generalize these Phobos algorithms into the variants described above and implement the old ones by calling the generalized ones typically as

auto findSplit(R)(R range, E element) if (isInputRange!R)
{
    return range.findSplit!(a => a == element);
}

BTW: Does anybody have any good refs on ELF C++ demangling. The wikipedia article is a bit sparse.

Destroy!
August 14, 2014
On Thursday, 14 August 2014 at 20:25:20 UTC, Nordlöw wrote:
> Destroy!

Correction: These algorithms require ForwardRanges.
August 14, 2014
On Thursday, 14 August 2014 at 20:28:38 UTC, Nordlöw wrote:
> On Thursday, 14 August 2014 at 20:25:20 UTC, Nordlöw wrote:
>> Destroy!
>
> Correction: These algorithms require ForwardRanges.

Ooops, I just realized that we can't express current Phobos implementations using my variant. Current algorithms take ranges not range values as a needle. My mistake. Are my overloads still wanted?
August 14, 2014
On Thursday, 14 August 2014 at 20:48:42 UTC, Nordlöw wrote:
> Ooops, I just realized that we can't express current Phobos implementations using my variant. Current algorithms take ranges not range values as a needle. My mistake. Are my overloads still wanted?

Ok. I finally understood that a simplification was the way to go:

/** Simpler Variant of Phobos' findSplitBefore. */
auto findSplitBefore(alias pred, R1)(R1 haystack) if (isForwardRange!R1)
{
    static if (isSomeString!R1 ||
               sRandomAccessRange!R1)
    {
        auto balance = haystack.find!pred;
        immutable pos = haystack.length - balance.length;
        return tuple(haystack[0 .. pos],
                     haystack[pos .. haystack.length]);
    }
    else
    {
        auto original = haystack.save;
        auto h = haystack.save;
        size_t pos;
        while (!h.empty)
        {
            if (unaryFun!pred(h.front))
            {
                h.popFront();
            }
            else
            {
                haystack.popFront();
                h = haystack.save;
                ++pos;
            }
        }
        return tuple(takeExactly(original, pos),
                     haystack);
    }
}

unittest
{
    import std.algorithm: equal;
    import std.ascii: isDigit;
    auto x = "11ab".findSplitBefore!(a => !a.isDigit);
    assert(equal(x[0], "11"));
    assert(equal(x[1], "ab"));
}

Should this go into Phobos?
August 14, 2014
On Thursday, 14 August 2014 at 21:04:06 UTC, Nordlöw wrote:
> Should this go into Phobos?

My variants can be found at the bottom of

https://github.com/nordlow/justd/blob/master/algorithm_ex.d