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)
38     @trusted
39 {
40     assert(index + 1 <= r.length);
41 
42     // TODO use this instead:
43     // immutable si = index + 1;   // source index
44     // immutable ti = index;       // target index
45     // immutable restLength = this.length - (index + 1);
46     // moveEmplaceAll(_store.ptr[si .. si + restLength],
47     //                _store.ptr[ti .. ti + restLength]);
48 
49     // for each element index that needs to be moved
50     foreach (immutable i; 0 .. r.length - (index + 1))
51     {
52         immutable si = index + i + 1; // source index
53         immutable ti = index + i;     // target index
54         import core.lifetime : moveEmplace;
55         moveEmplace(r.ptr[si], // TODO remove `move` when compiler does it for us
56                     r.ptr[ti]);
57     }
58 }
59 
60 @safe pure nothrow @nogc unittest
61 {
62     int[4] x = [11, 12, 13, 14];
63     x[].shiftToFrontAt(1);
64     assert(x == [11, 13, 14, 14]);
65 }
66 
67 version(unittest)
68 {
69     // import nxt.array_help : s;
70     // import nxt.dbgio;
71 }