Supporting inout haystack in array-overload of findSplitBefore without template-bloat

Per Nordlöw per.nordlow at gmail.com
Sun Oct 27 15:21:10 UTC 2019


On Sunday, 27 October 2019 at 14:57:29 UTC, Per Nordlöw wrote:
> @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");
> }

Made it work! :)


/** Array-overload for `findSplitAfter` with default predicate.
  *
  * See_Also: 
https://forum.dlang.org/post/dhxwgtaubzbmjaqjmnmq@forum.dlang.org
  */
auto findSplitAfter(T)(scope inout(T)[] haystack, // TODO support 
inout? See_Also: 
https://forum.dlang.org/post/jtpchtddgenhjuwhqdsq@forum.dlang.org
                        scope const T needle) @trusted
{
     static struct Result
     {
         private T[] _haystack;
         private size_t _offset;

     pragma(inline, true):

         inout(T)[] pre() @trusted inout
         {
             if (_isMiss) { return _haystack[$ .. $]; }
             return _haystack.ptr[0 .. _offset + 1];
         }

         inout(T)[] post() @trusted inout
         {
             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
{
     char[] haystack;
     auto r = haystack.findSplitAfter('*');
     static assert(is(typeof(r.pre()) == char[]));
     static assert(is(typeof(r.post()) == char[]));
}

///
@safe pure nothrow @nogc unittest
{
     const(char)[] haystack;
     auto r = haystack.findSplitAfter('*');
     static assert(is(typeof(r.pre()) == const(char)[]));
     static assert(is(typeof(r.post()) == const(char)[]));
}

///
@safe pure nothrow @nogc unittest
{
     auto r = "a*b".findSplitAfter('*');
     static assert(is(typeof(r.pre()) == string));
     static assert(is(typeof(r.post()) == string));
     assert(r);
     assert(r.pre == "a*");
     assert(r.post == "b");
}



More information about the Digitalmars-d-learn mailing list