1 module skia.Dictionary;
2 
3 import std..string;
4 import std.typecons;
5 
6 import skia.Common;
7 import skia.Exceptions;
8 
9 //
10 // Type parameters:
11 //   TKey:
12 //     The type of the keys in the dictionary.
13 //
14 //   TValue:
15 //     The type of the values in the dictionary.
16 class Dictionary(TKey, TValue) : IDictionary!(TKey, TValue)
17 {
18 	private TValue[TKey] m_dict;
19 	private CaseSensitive cs;
20 
21 	this(CaseSensitive cs = CaseSensitive.yes)
22 	{
23 		this.cs = cs;
24 	}
25 
26 
27 	size_t Count() @property
28 	{
29 		return m_dict.length;
30 	}
31 
32 
33 	void Add(TKey key, TValue value)
34 	{
35 		static if(is(TKey == string)) {
36 			if (cs == CaseSensitive.no)
37 				key = key.toUpper;
38 		}
39 		m_dict[key] = value;
40 	}
41 
42 
43 	// Summary:
44 	//     Gets or sets the value associated with the specified key.
45 	//
46 	// Parameters:
47 	//   key:
48 	//     The key of the value to get or set.
49 	//
50 	// Returns:
51 	//     The value associated with the specified key. If the specified key is not
52 	//     found, a get operation throws a System.Collections.Generic.KeyNotFoundException,
53 	//     and a set operation creates a new element with the specified key.
54 	//
55 	// Exceptions:
56 	//   System.ArgumentNullException:
57 	//     key is null.
58 	//
59 	//   System.Collections.Generic.KeyNotFoundException:
60 	//     The property is retrieved and key does not exist in the collection.
61 	TValue opIndex(TKey key)
62 	{
63 		static if(is(TKey == string)) {
64 			if (cs == CaseSensitive.no)
65 				key = key.toUpper;
66 		}
67 
68 		TValue *value_ptr = (key in m_dict);
69 		if (value_ptr !is null)
70 			return *value_ptr;
71 
72 		throw new Exception(std..string.format("The key doesn't exist: %s", key));
73 	}
74 
75 
76 	TValue opIndexAssign(TValue value, TKey key)
77 	{
78 		static if(is(TKey == string)) {
79 			if (cs == CaseSensitive.no)
80 				key = key.toUpper;
81 		}
82 
83 		m_dict[key] = value;
84 		return value;
85 	}
86 
87 	int opApply(scope int delegate(ref TKey key, TValue value) dg)
88     {
89 		if (dg is null)
90             throw new NullPointerException("");
91 
92         int result = 0;
93 		foreach(TKey key, TValue value; m_dict) {
94 			result = dg(key, value);
95 			if (result) break;
96 		}
97 
98 		return result;
99     }
100 
101 	//
102 	// Summary:
103 	//     Gets the value associated with the specified key.
104 	//
105 	// Parameters:
106 	//   key:
107 	//     The key of the value to get.
108 	//
109 	//   value:
110 	//     When this method returns, contains the value associated with the specified
111 	//     key, if the key is found; otherwise, the default value for the type of the
112 	//     value parameter. This parameter is passed uninitialized.
113 	//
114 	// Returns:
115 	//     true if the System.Collections.Generic.Dictionary<TKey,TValue> contains an
116 	//     element with the specified key; otherwise, false.
117 	//
118 	// Exceptions:
119 	//   System.ArgumentNullException:
120 	//     key is null.
121 	bool TryGetValue(TKey key, out TValue value)
122 	{
123 		static if(is(TKey == string)) {
124 			if (cs == CaseSensitive.no)
125 				key = key.toUpper;
126 		}
127 
128 		TValue *value_ptr = (key in m_dict);
129 		if (value_ptr !is null)
130 		{
131 			value = *value_ptr;
132 			return true;
133 		}
134 
135 		return false;
136 	}
137 
138 	//
139 	// Summary:
140 	//     Removes the value with the specified key from the System.Collections.Generic.Dictionary<TKey,TValue>.
141 	//
142 	// Parameters:
143 	//   key:
144 	//     The key of the element to remove.
145 	//
146 	// Returns:
147 	//     true if the element is successfully found and removed; otherwise, false.
148 	//     This method returns false if key is not found in the System.Collections.Generic.Dictionary<TKey,TValue>.
149 	//
150 	// Exceptions:
151 	//   System.ArgumentNullException:
152 	//     key is null.
153 	bool Remove(TKey key)
154 	{
155 		static if(is(TKey == string)) {
156 			if (cs == CaseSensitive.no)
157 				key = key.toUpper;
158 		}
159 
160 		TValue *value_ptr = (key in m_dict);
161 		if(value_ptr !is null)
162 		{
163 			m_dict.remove(key);
164 			return true;
165 		}
166 
167 		return false;
168 	}
169 
170 
171 	//
172 	// Summary:
173 	//     Removes all keys and values from the System.Collections.Generic.Dictionary<TKey,TValue>.
174 	void Clear()
175 	{
176 		// foreach(TKey key; m_dict.keys)
177 		// {
178 		// 	m_dict.remove(key);
179 		// }
180         m_dict.clear();
181 	}
182 
183 	//
184 	// Summary:
185 	//     Determines whether the System.Collections.Generic.Dictionary<TKey,TValue>
186 	//     contains the specified key.
187 	//
188 	// Parameters:
189 	//   key:
190 	//     The key to locate in the System.Collections.Generic.Dictionary<TKey,TValue>.
191 	//
192 	// Returns:
193 	//     true if the System.Collections.Generic.Dictionary<TKey,TValue> contains an
194 	//     element with the specified key; otherwise, false.
195 	//
196 	// Exceptions:
197 	//   System.ArgumentNullException:
198 	//     key is null.
199 	bool ContainsKey(TKey key)
200 	{
201 		static if(is(TKey == string)) {
202 			if (cs == CaseSensitive.no)
203 				key = key.toUpper;
204 		}
205 
206 		TValue *value_ptr = (key in m_dict);
207 		return value_ptr !is null;
208 	}
209 
210 
211 	//
212 	// Summary:
213 	//     Determines whether the System.Collections.Generic.Dictionary<TKey,TValue>
214 	//     contains a specific value.
215 	//
216 	// Parameters:
217 	//   value:
218 	//     The value to locate in the System.Collections.Generic.Dictionary<TKey,TValue>.
219 	//     The value can be null for reference types.
220 	//
221 	// Returns:
222 	//     true if the System.Collections.Generic.Dictionary<TKey,TValue> contains an
223 	//     element with the specified value; otherwise, false.
224 	bool ContainsValue(TValue value)
225 	{
226 		foreach(TValue v; m_dict.values)
227 		{
228 			if (value == v)
229 				return true;
230 		}
231 		return false;
232 	}
233 
234 	TKey[] Keys()
235 	{
236 		return m_dict.keys;
237 	}
238 
239 	TValue[] Values() 
240 	{
241 		return m_dict.values;
242 	}
243 }