Supporting inout haystack in array-overload of findSplitBefore without template-bloat
Per Nordlöw
per.nordlow at gmail.com
Sun Oct 27 14:57:29 UTC 2019
On Sunday, 27 October 2019 at 14:29:01 UTC, Per Nordlöw wrote:
> which results in the following interesting compiler error:
>
>
> array_algorithm.d(506,12): Error: modify `inout` to `immutable`
> is not allowed inside `inout` function
> assert(r.pre == "a*");
> ^
> array_algorithm.d(507,12): Error: modify `inout` to `immutable`
> is not allowed inside `inout` function
> assert(r.post == "b");
> ^
> array_algorithm.d(514,5): Error: static assert:
> `is(typeof(r.pre()) == const(char)[])` is false
> static assert(is(typeof(r.pre()) == const(char)[]));
A non-templated and less bloated but still suboptimal solution is
to defined inlined overloads for the member functions, this case
`pre()`:
auto findSplitAfter_inout(T)(scope inout(T)[] haystack,
scope const T needle) @trusted
{
static struct Result
{
private T[] _haystack;
private size_t _offset;
auto pre() @trusted
{
pragma(inline, true);
if (_isMiss) { return _haystack[$ .. $]; }
return _haystack.ptr[0 .. _offset + 1];
}
auto pre() const @trusted
{
pragma(inline, true);
if (_isMiss) { return _haystack[$ .. $]; }
return _haystack.ptr[0 .. _offset + 1];
}
auto pre() immutable @trusted
{
pragma(inline, true);
if (_isMiss) { return _haystack[$ .. $]; }
return _haystack.ptr[0 .. _offset + 1];
}
auto post() const @trusted
{
if (_isMiss) { return _haystack[0 .. $]; }
return _haystack.ptr[_offset + 1 .. _haystack.length];
}
bool opCast(T : bool)() const
{
return !_isMiss;
}
private bool _isMiss() const
{
return _haystack.length == _offset;
}
}
foreach (const offset, const ref e; haystack)
{
if (e == needle)
{
return inout(Result)(haystack, offset);
}
}
return inout(Result)(haystack, haystack.length);
}
///
@safe pure nothrow @nogc unittest
{
auto r = "a*b".findSplitAfter_inout('*');
static assert(is(typeof(r.pre()) == string));
assert(r);
assert(r.pre == "a*");
assert(r.post == "b");
}
More information about the Digitalmars-d-learn
mailing list