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