1 /// module for a sorted map class
2 module ydlib.sortedMap;
3 
4 import std.format;
5 import ydlib.list;
6 
7 /// exception used for sorted map errors
8 class SortedMapException : Exception {
9 	this(string msg, string file = __FILE__, size_t line = __LINE__) {
10 		super(msg, file, line);
11 	}
12 }
13 
14 struct MapEntry(T1, T2) {
15 	T1 key;
16 	T2 value;
17 }
18 
19 /// sorted map class
20 class SortedMap(T1, T2) {
21 	/// linked list of entries
22 	List!(MapEntry!(T1, T2)) entries;
23 
24 	this() {
25 		entries = new List!(MapEntry!(T1, T2));
26 	}
27 
28 	/// overrides in keyword
29 	T2* opBinaryRight(string op: "in")(T1 key) {
30 		foreach (e ; entries) {
31 			if (e.value.key == key) {
32 				return &e.value.value;
33 			}
34 		}
35 
36 		return null;
37 	}
38 
39 	/// overrides index
40 	T2 opIndex(T1 key) {
41 		auto ret = key in this;
42 
43 		if (ret is null) {
44 			throw new SortedMapException("Key not found in sorted map");
45 		}
46 
47 		return *ret;
48 	}
49 
50 	/// overrides assigning to index
51 	void opIndexAssign(T2 value, T1 key) {
52 		foreach (e ; entries) {
53 			if (e.value.key == key) {
54 				e.value.value = value;
55 				return;
56 			}
57 		}
58 	
59 		auto entry = MapEntry!(T1, T2)(key, value);
60 
61 		if (entries.head is null) {
62 			entries.head = new ListNode!(MapEntry!(T1, T2))(entry);
63 			return;
64 		}
65 
66 		foreach (e ; entries) {
67 			if (e.value.key > key) {
68 				e.InsertBefore(entries, entry);
69 				return;
70 			}
71 		}
72 
73 		entries ~= entry;
74 	}
75 
76 	/// overrides foreach loops
77 	int opApply(scope int delegate(T1 key, ref T2 value) dg) {
78 		foreach (e ; entries) {
79 			int result = dg(e.value.key, e.value.value);
80 
81 			if (result) {
82 				return result;
83 			}
84 		}
85 
86 		return 0;
87 	}
88 }