1 module s2.util.container.btree_map; 2 3 import s2.util.container.btree; 4 5 import std.algorithm : map; 6 import std.functional : binaryFun; 7 import std.meta : allSatisfy; 8 import std.range : ElementType, isInputRange; 9 import std.traits : isDynamicArray, isImplicitlyConvertible; 10 11 /** 12 * An associative-array or map implementation based upon a B-Tree. 13 */ 14 final class BTreeMap(KeyT, ValueT, size_t NodeSizeV = 256, alias KeyLessF = "a < b") { 15 public: 16 static struct Pair { 17 KeyT key; 18 ValueT value; 19 } 20 21 alias _isKeyLess = binaryFun!KeyLessF; 22 23 alias BTreeT = BTree!(Pair, NodeSizeV, (pair1, pair2) => _isKeyLess(pair1.key, pair2.key)); 24 25 BTreeT bTree; 26 27 // Forward compatible methods like: empty(), length(), opSlice(), etc. 28 alias bTree this; 29 30 this() { 31 bTree = new BTreeT(); 32 } 33 34 /// Insertion 35 void insert(K, V)(K key, V value) 36 if (isImplicitlyConvertible!(K, KeyT) && isImplicitlyConvertible!(V, ValueT)) { 37 return bTree.insert(Pair(key, value)); 38 } 39 40 ValueT opIndexAssign(ValueT value, KeyT key) { 41 bTree.insert(Pair(key, value)); 42 return value; 43 } 44 45 /// Membership 46 bool opBinaryRight(string op)(KeyT key) 47 if (op == "in") { 48 return Pair(key) in bTree; 49 } 50 51 /// Removal 52 void remove(KeyT key) { 53 bTree.remove(Pair(key)); 54 } 55 56 /// Ranges 57 BTreeT.Range upperRange(KeyT key) { 58 return bTree.upperRange(Pair(key)); 59 } 60 61 BTreeT.Range lowerRange(KeyT key) { 62 return bTree.lowerRange(Pair(key)); 63 } 64 65 BTreeT.Range equalRange(KeyT key) { 66 return bTree.equalRange(Pair(key)); 67 } 68 }