1 /** 2 * Tree Map 3 * Copyright: © 2014 Economic Modeling Specialists, Intl. 4 * Authors: Brian Schott 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 6 */ 7 8 module containers.treemap; 9 10 /** 11 * A key→value mapping where the keys are guaranteed to be sorted. 12 * Params: 13 * K = the key type 14 * V = the value type 15 * less = the key comparison function to use 16 * supportGC = true to support storing GC-allocated objects, false otherwise 17 * cacheLineSize = the size of the internal nodes in bytes 18 */ 19 struct TreeMap(K, V, alias less = "a < b", bool supportGC = true, 20 size_t cacheLineSize = 64) 21 { 22 23 this(this) @disable; 24 25 /// Supports $(B treeMap[key] = value;) syntax. 26 void opIndexAssign(V value, K key) 27 { 28 auto tme = TreeMapElement(key, value); 29 tree.insert(tme); 30 } 31 32 /// Supports $(B treeMap[key]) syntax. 33 auto opIndex(this This)(K key) const 34 { 35 alias CET = ContainerElementType!(This, V); 36 auto tme = TreeMapElement(key); 37 return cast(CET) tree.equalRange(tme).front.value; 38 } 39 40 /** 41 * Removes the key→value mapping for the given key. 42 * Params: key = the key to remove 43 * Returns: true if the key existed in the map 44 */ 45 bool remove(K key) 46 { 47 auto tme = TreeMapElement(key); 48 return tree.remove(tme); 49 } 50 51 /// Returns: true if the mapping contains the given key 52 bool containsKey(K key) 53 { 54 auto tme = TreeMapElement(key); 55 return tree.contains(tme); 56 } 57 58 /// Returns: true if the mapping is empty 59 bool empty() const pure nothrow @property @safe @nogc 60 { 61 return tree.empty; 62 } 63 64 /// Returns: the number of key→value pairs in the map 65 size_t length() const pure nothrow @property @safe @nogc 66 { 67 return tree.length; 68 } 69 70 /// Supports $(B foreach(k, v; treeMap)) syntax. 71 int opApply(this This)(int delegate(ref K, ref V) loopBody) 72 { 73 int result; 74 foreach (ref tme; tree[]) 75 { 76 result = loopBody(tme.key, tme.value); 77 if (result) 78 break; 79 } 80 return result; 81 } 82 83 private: 84 85 import containers.ttree : TTree; 86 import containers.internal.storage_type : ContainerStorageType; 87 import containers.internal.element_type : ContainerElementType; 88 89 static struct TreeMapElement 90 { 91 ContainerStorageType!K key; 92 ContainerStorageType!V value; 93 int opCmp(ref const TreeMapElement other) const 94 { 95 import std.functional : binaryFun; 96 return binaryFun!less(key, other.key); 97 } 98 } 99 TTree!(TreeMapElement, false, "a.opCmp(b) > 0", supportGC, cacheLineSize) tree; 100 } 101 102 unittest 103 { 104 TreeMap!(string, string) tm; 105 tm["test1"] = "hello"; 106 tm["test2"] = "world"; 107 tm.remove("test1"); 108 tm.remove("test2"); 109 }