1 module nxt.container_algorithm;
2 
3 import std.traits : hasMember;
4 
5 /** Try to pop first occurrence of `needle` in `haystack` (if any).
6     Returns: `true` iff pop was made, `false` otherwise.
7  */
8 bool popFirstMaybe(alias pred = "a == b", C, E)(ref C haystack,
9                                                 in E needle)
10 if (hasMember!(C, "length") &&
11         hasMember!(C, "popAt"))
12     // TODO activate this restriction
13     // if (hasSlicing!C &&
14     //     is(ElementType!C == E.init))
15 {
16     import std.functional : binaryFun;
17     // doesn't work for uncopyable element types: import std.algorithm.searching : countUntil;
18     size_t offset = 0;
19     foreach (const ref e; haystack[])
20     {
21         if (binaryFun!pred(e, needle)) { break; }
22         offset += 1;
23     }
24     if (offset != haystack.length)
25     {
26         haystack.popAt(offset);
27         return true;
28     }
29     return false;
30 }
31 
32 /** Remove element at index `index` in `r`.
33  *
34  * TODO reuse in array*.d
35  * TODO better name removeAt
36  */
37 void shiftToFrontAt(T)(T[] r, size_t index) @trusted
38 {
39     assert(index + 1 <= r.length);
40 
41     // TODO use this instead:
42     // immutable si = index + 1;   // source index
43     // immutable ti = index;       // target index
44     // immutable restLength = this.length - (index + 1);
45     // moveEmplaceAll(_store.ptr[si .. si + restLength],
46     //                _store.ptr[ti .. ti + restLength]);
47 
48     // for each element index that needs to be moved
49     foreach (immutable i; 0 .. r.length - (index + 1))
50     {
51         immutable si = index + i + 1; // source index
52         immutable ti = index + i;     // target index
53         import core.lifetime : moveEmplace;
54         moveEmplace(r.ptr[si], // TODO remove `move` when compiler does it for us
55                     r.ptr[ti]);
56     }
57 }
58 
59 @safe pure nothrow @nogc unittest
60 {
61     int[4] x = [11, 12, 13, 14];
62     x[].shiftToFrontAt(1);
63     assert(x == [11, 13, 14, 14]);
64 }