All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Dictionary.h
Go to the documentation of this file.
1 /*
2  * Dictionary.h
3  *
4  * This file is part of the HausmiSEP project
5  *
6  * Copyright (C) 2012, 2013 Marco Alvarado (malvcr@gmail.com)
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef DICTIONARY_H_
23 #define DICTIONARY_H_
24 
25 #include <HSEP/HSEPObject.h>
26 #include <HSEP/Exceptions.h>
27 
28 #include <map>
29 #include <string>
30 #include <functional>
31 
32 using namespace std;
33 
34 namespace HSEP {
35 
43  template<class T>
44  class Dictionary : public HSEPObject {
45  map<string,T*> aCatalog;
46  public:
47 
48  typedef function<void (string& pKeyRef, T*& pValuePtrRef)> ForEachWorker;
49 
50  Dictionary() : HSEPObject("Dictionary") {
51  } // constructor
52 
53  virtual ~Dictionary() {
54  clear();
55  } // destructor
56 
62  void operator()(Dictionary& pReference) {
63 
64  pReference.forEach([&](string& pKeyRef, T* pValuePtr){
65  put(pKeyRef,*pValuePtr); // value by reference, to force T's copy constructor
66  });
67 
68  } // operator()
69 
81  T& ref(string& pKeyRef) {
82 
83  T* vResultPtr = nullptr;
84 
85  if (aCatalog.count(pKeyRef)>0) {
86  vResultPtr = aCatalog[pKeyRef];
87  }
88  else {
89  // This is a logic error, so it must be managed as what it really is, before trying
90  // to create phantom elements inside the internal container.
91  //
92  throw NullReferenceException();
93  }
94  return *vResultPtr;
95 
96  } // ref
97 
109  T& ref(const char* pKeyPtr) {
110  string vKey = string(pKeyPtr);
111  return ref(vKey);
112  } // ref
113 
120  T* ptr(string& pKeyRef) {
121 
122  T* vResultPtr = nullptr;
123 
124  if (aCatalog.count(pKeyRef)>0) {
125  vResultPtr = aCatalog[pKeyRef];
126  }
127  return vResultPtr;
128 
129  } // ptr
130 
137  T* ptr(const char* pKeyPtr) {
138  string vKey = string(pKeyPtr);
139  return ref(vKey);
140  } // ptr
141 
148  bool has(string& pKeyRef) {
149  return (aCatalog.count(pKeyRef)>0);
150  }
151 
158  bool has(const char* pKeyPtr) {
159  string vKey(pKeyPtr);
160  return has(vKey);
161  }
162 
172  void put(string& pKeyRef, T& pValueRef) {
173 
174  T* vValuePtr = new T(pValueRef);
175 
176  if (aCatalog.count(pKeyRef)>0) {
177  // Don't try to execute the "delete" on the internal element; the erase
178  // method will do it correctly.
179  aCatalog.erase(pKeyRef);
180  }
181  aCatalog[pKeyRef] = vValuePtr;
182 
183  } // put
184 
194  void put(const char* pKeyPtr, T& pValueRef) {
195  string vKey(pKeyPtr);
196  put (vKey,pValueRef);
197  } // put
198 
208  void put(string& pKeyRef, T* pValuePtr) {
209 
210  if (aCatalog.count(pKeyRef)>0) {
211  aCatalog.erase(pKeyRef);
212  }
213  aCatalog[pKeyRef] = pValuePtr;
214 
215  } // put
216 
226  void put(const char* pKeyPtr, T* pValuePtr) {
227 
228  string vKey(pKeyPtr);
229  put (vKey,pValuePtr);
230 
231  } // put
232 
237  void erase(const char* pKeyPtr) {
238  string vKey(pKeyPtr);
239  aCatalog.erase(vKey);
240  } // erase
241 
246  void erase(string& pKeyRef) {
247  aCatalog.erase(pKeyRef);
248  } // erase
249 
254  void clear() {
255 
256  forEach([](string& xKeyRef, T*& xValuePtrRef) {
257  T* vValuePtrCopy = xValuePtrRef;
258  delete vValuePtrCopy;
259  xValuePtrRef = nullptr;
260  });
261  aCatalog.clear();
262 
263  } // clear
264 
274  bool forEach(ForEachWorker pWorker) {
275 
276  // Normally, we define the result as true only when everything was processed. However,
277  // we work the "forEach" as an exception, because the result "false" is intended only
278  // to declare that the "pWorker" function performed an illegal operation and that the
279  // forEach was aborted because of that.
280  //
281  bool vResult = true;
282 
283  for (pair<string,T*> vPair : aCatalog) {
284  try {
285  pWorker(vPair.first, vPair.second);
286  }
287  catch(exception& vExc) {
288  setLastError(vExc.what());
289  vResult = false;
290  break; // unmanaged error ... let's stop the cycle
291  }
292  }
293  return vResult;
294 
295  } // forEach
296 
301  size_t size() {
302  return aCatalog.size();
303  }
304 
305  }; // Dictionary class
306 
325 #define SETSTRDICT(dict,name,value) \
326  string v##name = value; \
327  dict.put(#name,v##name)
328 
329 } // HSEP namespace
330 
331 #endif /* DICTIONARY_H_ */