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