Supporting inout haystack in array-overload of findSplitBefore without template-bloat
Per Nordlöw
per.nordlow at gmail.com
Sun Oct 27 14:29:01 UTC 2019
Is it possible to make this array-overload of findSplitBefore
support `inout`-qualified `haystack` parameter and return type
without using a templated `Result`?
auto findSplitBefore(T)(scope const T[] haystack, // TODO support
inout?
scope const T needle)
{
struct Result
{
private alias Haystack = typeof(haystack);
private Haystack _haystack;
private size_t _offset;
inout(Haystack) pre() inout @trusted
{
return _haystack.ptr[0 .. _offset];
}
inout(Haystack) post() inout @trusted
{
if (_isMiss) { return _haystack[$ .. $]; }
return _haystack.ptr[_offset .. _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 Result(haystack, offset);
}
}
return Result(haystack, haystack.length);
}
///
@safe pure nothrow @nogc unittest
{
const r = "a*b".findSplitBefore('*');
assert(r);
assert(r.pre == "a");
assert(r.post == "*b");
}
This is my attempt so far
auto findSplitAfter(T)(scope inout(T)[] haystack, // TODO support
inout?
scope const T needle) @trusted
{
struct Result
{
private T[] _haystack;
private size_t _offset;
inout(T)[] pre() inout @trusted
{
if (_isMiss) { return _haystack[$ .. $]; }
return _haystack.ptr[0 .. _offset + 1];
}
inout(T)[] post() inout @trusted
{
if (_isMiss) { return _haystack[0 .. $]; }
return _haystack.ptr[_offset + 1 .. _haystack.length];
}
bool opCast(T : bool)() const @trusted
{
return !_isMiss;
}
private bool _isMiss() const @trusted
{
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
{
const r = "a*b".findSplitAfter('*');
assert(r);
assert(r.pre == "a*");
assert(r.post == "b");
}
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)[]));
More information about the Digitalmars-d-learn
mailing list