Library of Assembled Shared Sources
dictionary.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_DICTIONARY_INL
46#define LASS_GUARDIAN_OF_INCLUSION_UTIL_DICTIONARY_INL
47
48#include "util_common.h"
49#include "dictionary.h"
50
51namespace lass
52{
53namespace util
54{
55
56// --- public --------------------------------------------------------------------------------------
57
58template <typename K, typename V, typename KL, typename VL>
59Dictionary<K, V, KL, VL>::Dictionary():
60 map_(),
61 hasDefault_(false),
62 enableSuggestions_(false)
63{
64}
65
66
67
68template <typename K, typename V, typename KL, typename VL>
69Dictionary<K, V, KL, VL>::Dictionary(TKeyLess iKeyLess):
70 map_(),
71 keyLess_(iKeyLess),
72 hasDefault_(false),
73 enableSuggestions_(false)
74{
75}
76
77
78
79template <typename K, typename V, typename KL, typename VL>
80Dictionary<K, V, KL, VL>::Dictionary(TKeyLess iKeyLess, TValueLess iValueLess):
81 map_(),
82 keyLess_(iKeyLess),
83 valueLess_(iValueLess),
84 hasDefault_(false),
85 enableSuggestions_(false)
86{
87}
88
89
90
91/** add a key and value to dictionary as new entry.
92 */
93template <typename K, typename V, typename KL, typename VL>
94void Dictionary<K, V, KL, VL>::add(const TKey& iKey, const TValue& iValue)
95{
96 std::pair<typename TMap::iterator, typename TMap::iterator> range = map_.equal_range(iKey);
97 for (typename TMap::iterator i = range.first; i != range.second; ++i)
98 {
99 if (equalValues(i->second, iValue))
100 {
101 return;
102 }
103 }
104 map_.insert(typename TMap::value_type(iKey, iValue));
105}
106
107
108
109/** remove a key and value from the dictionary.
110 */
111template <typename K, typename V, typename KL, typename VL>
112void Dictionary<K, V, KL, VL>::remove(const TKey& iKey, const TValue& iValue)
113{
114 std::pair<typename TMap::iterator, typename TMap::iterator> range = map_.equal_range(iKey);
115 for (typename TMap::iterator i = range.first; i != range.second; ++i)
116 {
117 if (equalValues(i->second, iValue))
118 {
119 map_.erase(i);
120 return;
121 }
122 }
123}
124
125
126
127/** set key and value to be used as default ones.
128 * Once @e default key and value are set, these will be returned on occasions you try to look up a
129 * key or value but it can't be found.
130 */
131template <typename K, typename V, typename KL, typename VL>
132void Dictionary<K, V, KL, VL>::setDefault(const TKey& iKey, const TValue& iValue)
133{
134 defaultKey_ = iKey;
135 defaultValue_ = iValue;
136 hasDefault_ = true;
137}
138
139
140
141/** clear default key and value.
142 * If no @e default key and value are set, and exception will be thrown on occasions you try to look
143 * up a key or value but it can't be found.
144 */
145template <typename K, typename V, typename KL, typename VL>
147{
148 hasDefault_ = false;
149}
150
151
152
153/** return true if dictionary has value
154 */
155template <typename K, typename V, typename KL, typename VL>
157{
158 return hasDefault_;
159}
160
161
162
163/** if enabled, suggestions of valid keys or values will be included in the exception that
164 * is thrown in case a key or value is not found and there's no default.
165 */
166template <typename K, typename V, typename KL, typename VL>
169 enableSuggestions_ = enable;
172
174/** look up a value by key
175 * @return
176 * - the value that belongs to the key.
177 * - if such a value can not be found and an @e default value is set, then this @e default
178 * will be returned.
179 * @note
180 * if multiple entries with the same key are found, only one is returned. It is not
181 * specified which one this will be. If you want all entries with this key, use @c values(iKey).
182 * @throw
183 * if no value can be found that belongs to the key and no @e default value is set, then
184 * an exception will be thrown.
185 */
186template <typename K, typename V, typename KL, typename VL>
187const typename Dictionary<K, V, KL, VL>::TValue&
189{
190 typename TMap::const_iterator i = map_.find(iKey);
191 if (i == map_.end())
192 {
193 if (!hasDefault_)
194 {
195 if (enableSuggestions_)
196 {
197 LASS_THROW("Key '" << iKey << "' is not found in dictionary, please try one "
198 << "of these: " << keys());
199 }
200 else
201 {
202 LASS_THROW("Key '" << iKey << "' is not found in dictionary.");
203 }
204 }
205 return defaultValue_;
206 }
207 return i->second;
208}
209
210
211
212/** look up a key by value
213 * @return
214 * - the key to which the value belongs
215 * - if such a key can not be found and an @e default key is set, then this @e default will
216 * be returned.
217 * @note
218 * if multiple entries with the same value are found, only one is returned. It is not
219 * specified which one this will be. If you want all entries with this value, use @c keys(iValue).
220 * @throw if no key can be found to wich the value belongs and no @e default key is set, then an
221 * exception will be thrown.
222 */
223template <typename K, typename V, typename KL, typename VL>
224const typename Dictionary<K, V, KL, VL>::TKey&
225Dictionary<K, V, KL, VL>::key(TValueParam iValue) const
226{
227 for (typename TMap::const_iterator i = map_.begin(); i != map_.end(); ++i)
228 {
229 if (equalValues(i->second, iValue))
230 {
231 return i->first;
232 }
233 }
234 if (!hasDefault_)
235 {
236 if (enableSuggestions_)
237 {
238 LASS_THROW("Value '" << iValue << "' is not found in dictionary, please try one "
239 << "of these: " << values());
240 }
241 else
242 {
243 LASS_THROW("Value '" << iValue << "' is not found in dictionary.");
244 }
245 }
246 return defaultKey_;
247}
248
249
250
251/** return all keys in the dictionary
252 */
253template <typename K, typename V, typename KL, typename VL>
254typename Dictionary<K, V, KL, VL>::TKeys
256{
257 TKeys result;
258 for (typename TMap::const_iterator i = map_.begin(); i != map_.end(); ++i)
259 {
260 result.insert(i->first);
261 }
262 return result;
263}
264
265
266
267/** return all values in the dictionary
268 */
269template <typename K, typename V, typename KL, typename VL>
270typename Dictionary<K, V, KL, VL>::TValues
272{
273 TValues result;
274 for (typename TMap::const_iterator i = map_.begin(); i != map_.end(); ++i)
275 {
276 result.insert(i->second);
277 }
278 return result;
279}
280
281
282
283/** return all keys that have value @a iValue.
284 */
285template <typename K, typename V, typename KL, typename VL>
286typename Dictionary<K, V, KL, VL>::TKeys
287Dictionary<K, V, KL, VL>::keys(TValueParam iValue) const
288{
289 TKeys result;
290 for (typename TMap::const_iterator i = map_.begin(); i != map_.end(); ++i)
291 {
292 if (equalValues(i->second, iValue))
293 {
294 result.insert(i->first);
295 }
296 }
297 return result;
298}
299
300
301
302/** return all values in the dictionary
303 */
304template <typename K, typename V, typename KL, typename VL>
305typename Dictionary<K, V, KL, VL>::TValues
307{
308 TValues result;
309 std::pair<typename TMap::const_iterator, typename TMap::const_iterator> range = map_.equal_range(iKey);
310 for (typename TMap::const_iterator i = range.first; i != range.second; ++i)
311 {
312 result.insert(i->second);
313 }
314 return result;
315}
316
317
318
319/** return true if @a iKey is a key of dictionary
320 */
321template <typename K, typename V, typename KL, typename VL>
322bool Dictionary<K, V, KL, VL>::isKey(TKeyParam iKey) const
323{
324 return map_.find(iKey) != map_.end();
325}
326
327
328
329/** return true if @a iValue is a value of dictionary
330 */
331template <typename K, typename V, typename KL, typename VL>
332bool Dictionary<K, V, KL, VL>::isValue(TValueParam iValue) const
333{
334 for (typename TMap::const_iterator i = map_.begin(); i != map_.end(); ++i)
335 {
336 if (equalValues(i->second, iValue))
337 {
338 return true;
339 }
340 }
341 return false;
342}
343
344
345
346// --- protected -----------------------------------------------------------------------------------
347
348
349
350// --- private -------------------------------------------------------------------------------------
351
352template <typename K, typename V, typename KL, typename VL>
353bool Dictionary<K, V, KL, VL>::equalValues(TValueParam iA, TValueParam iB) const
354{
355 return !valueLess_(iA, iB) && !valueLess_(iB, iA);
356}
357
358
359
360// --- free ----------------------------------------------------------------------------------------
361
362
363
364}
365
366}
367
368#endif
369
370// EOF
void remove(const TKey &iKey, const TValue &iValue)
remove a key and value from the dictionary.
bool hasDefault() const
return true if dictionary has value
void setDefault(const TKey &iKey, const TValue &iValue)
set key and value to be used as default ones.
bool isValue(TValueParam iValue) const
return true if iValue is a value of dictionary
void clearDefault()
clear default key and value.
const TKey & key(TValueParam iValue) const
look up a key by value
void add(const TKey &iKey, const TValue &iValue)
add a key and value to dictionary as new entry.
TValues values() const
return all values in the dictionary
const TValue & operator[](TKeyParam iKey) const
look up a value by key
void enableSuggestions(bool enable=true)
if enabled, suggestions of valid keys or values will be included in the exception that is thrown in c...
bool isKey(TKeyParam iKey) const
return true if iKey is a key of dictionary
TKeys keys() const
return all keys in the dictionary
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Definition config.h:53