1 /** Hybrid array containers. 2 */ 3 module nxt.hybrid_array; 4 5 import std.traits : isIntegral; 6 import nxt.filters : isDynamicDenseSetFilterable; 7 import nxt.my_mallocator : Mallocator; 8 9 /** Hybrid container combining `DynamicDenseSetFilter` growable into `DynamicArray`. 10 * 11 * Has O(1) unordered element access via slicing. 12 * 13 * For use in graph algorithms with limited index ranges. 14 * 15 * TODO: better name? 16 */ 17 struct DynamicDenseSetFilterGrowableArray(E, Allocator = Mallocator) 18 if (isDynamicDenseSetFilterable!E) 19 { 20 import nxt.filters : DynamicDenseSetFilter, Growable, Copyable; 21 import nxt.container.dynamic_array : DynamicArray; 22 23 alias ElementType = E; 24 25 @disable this(this); 26 27 pragma(inline, true): 28 29 /** Insert element `e`. 30 Returns: precense status of element before insertion. 31 */ 32 bool insert()(E e) /* template-lazy */ 33 { 34 // TODO: this doesn’t seem right: 35 const hit = _set.insert(e); 36 if (!hit) 37 _array.insertBack(e); 38 return hit; 39 } 40 alias put = insert; // OutputRange compatibility 41 42 /// Check if element `e` is stored/contained. 43 bool contains()(E e) const => _set.contains(e); /* template-lazy */ 44 /// ditto 45 bool opBinaryRight(string op)(E e) const if (op == "in") => contains(e); 46 47 /// Check if empty. 48 bool empty() const @property => _array.empty; 49 50 /// Get length. 51 @property size_t length() const => _array.length; 52 53 /// Non-mutable slicing. 54 auto opSlice() const => _array.opSlice; /* template-lazy */ 55 56 /// Clear contents. 57 void clear()() /* template-lazy */ 58 { 59 _set.clear(); 60 _array.clear(); 61 } 62 63 private: 64 // TODO: merge into store with only one length and capcity 65 DynamicDenseSetFilter!(E, Growable.yes, Copyable.no) _set; 66 DynamicArray!(E, Allocator) _array; 67 } 68 69 @safe pure nothrow @nogc: 70 71 unittest 72 { 73 DynamicDenseSetFilterGrowableArray!uint x; 74 75 assert(!x.insert(42)); 76 assert(x.contains(42)); 77 assert(x[] == [42].s); 78 79 assert(x.insert(42)); 80 assert(x.contains(42)); 81 assert(x[] == [42].s); 82 83 assert(!x.insert(43)); 84 assert(x.contains(43)); 85 assert(x[] == [42, 43].s); 86 87 x.clear(); 88 assert(x.empty()); 89 90 assert(!x.insert(44)); 91 assert(x.contains(44)); 92 assert(x[] == [44].s); 93 } 94 95 version(unittest) 96 { 97 import nxt.array_help : s; 98 }