KrisLibrary  1.0.0
AnyCollection.h
1 #ifndef ANY_COLLECTION_H
2 #define ANY_COLLECTION_H
3 
4 #include <KrisLibrary/Logger.h>
5 #include "AnyValue.h"
6 #include <KrisLibrary/errors.h>
7 #include <vector>
8 #include <map>
9 #include <memory>
10 #include "stl_tr1.h"
11 
16 struct AnyKeyable
17 {
18  AnyKeyable();
19  AnyKeyable(const AnyKeyable& rhs);
20  AnyKeyable(bool value);
21  AnyKeyable(char value);
22  AnyKeyable(unsigned char value);
23  AnyKeyable(int value);
24  AnyKeyable(unsigned int value);
25  AnyKeyable(float value);
26  AnyKeyable(double value);
27  AnyKeyable(const std::string& value);
28  AnyKeyable(const char* value);
29  size_t hash() const;
30  bool operator == (const AnyKeyable& rhs) const;
31 
32  AnyValue value;
33 };
34 
35 BEGIN_TR1_NAMESPACE
36 
37 template <>
38 struct hash<AnyKeyable> : public unary_function<AnyKeyable,size_t>
39 {
40  size_t operator()(const AnyKeyable& key) const { return key.hash(); }
41 };
42 
43 END_TR1_NAMESPACE
44 
45 
46 
74 {
75  public:
76  typedef std::shared_ptr<AnyCollection> AnyCollectionPtr;
77 
78  AnyCollection();
79  AnyCollection(AnyValue value);
80  template <class T>
81  AnyCollection(const std::vector<T>& array);
82  template <class T,class T2>
83  AnyCollection(const std::map<T,T2>& map);
84  template <class T,class T2>
85  AnyCollection(const UNORDERED_MAP_TEMPLATE<T,T2>& map);
86 
89  size_t size() const;
91  bool null() const;
93  bool collection() const;
95  bool isvalue() const;
97  bool isarray() const;
99  bool ismap() const;
101  size_t depth() const;
103  operator const AnyValue& () const;
104  operator AnyValue& ();
105  //coerce cast to plain data type
106  template<class T>
107  operator T() const;
108  //coerce cast to plain data type
109  template<class T>
110  bool as(T& value) const;
111  //coerce cast a flat array type to a vector
112  template<class T>
113  bool asvector(std::vector<T>& values) const;
114  //retrieve elements of a flat array type
115  bool asvector(std::vector<AnyValue>& values) const;
116  //test equality with value
117  template <class T>
118  bool operator == (const T& value) const;
119  //test inequality with value
120  template <class T>
121  bool operator != (const T& value) const { return !operator == (value); }
122  //make into an array
123  void resize(size_t n);
124  //clears to an empty type
125  void clear();
126  //accessors
127  AnyCollectionPtr find(int i) const;
128  AnyCollectionPtr find(const char* str) const;
129  AnyCollectionPtr find(AnyKeyable key) const;
130  AnyCollectionPtr insert(int i);
131  AnyCollectionPtr insert(const char* str);
132  AnyCollectionPtr insert(AnyKeyable key);
133  AnyCollection& operator[](int i);
134  const AnyCollection& operator[](int i) const;
135  AnyCollection& operator[](const char* str);
136  const AnyCollection& operator[](const char* str) const;
137  AnyCollection& operator[](AnyKeyable key);
138  const AnyCollection& operator[](AnyKeyable key) const;
139 
141  void shallow_copy(const AnyCollection& rhs);
143  void deep_copy(const AnyCollection& rhs);
144 
146  AnyCollection& operator = (const AnyCollection& rhs);
148  AnyCollection& operator = (AnyValue value);
150  AnyCollection& operator = (bool v) { return operator = (AnyValue(v)); }
151  AnyCollection& operator = (char v) { return operator = (AnyValue(v)); }
152  AnyCollection& operator = (unsigned char v) { return operator = (AnyValue(v)); }
153  AnyCollection& operator = (int v) { return operator = (AnyValue(v)); }
154  AnyCollection& operator = (unsigned int v) { return operator = (AnyValue(v)); }
155  AnyCollection& operator = (float v) { return operator = (AnyValue(v)); }
156  AnyCollection& operator = (double v) { return operator = (AnyValue(v)); }
157  AnyCollection& operator = (const std::string& str) { return operator = (AnyValue(str)); }
159  AnyCollection& operator = (const char* str) { return operator = (std::string(str)); }
161  template <class T>
162  AnyCollection& operator = (const std::vector<T>& array);
164  template <class T,class T2>
165  AnyCollection& operator = (const std::map<T,T2>& map);
167  template <class T,class T2>
168  AnyCollection& operator = (const UNORDERED_MAP_TEMPLATE<T,T2>& map);
169 
175  AnyCollectionPtr lookup(const std::string& reference,bool insert=false,char delim='.',char lbracket='[',char rbracket=']');
176  AnyCollectionPtr lookup(const std::vector<std::string>& path,bool insert=false);
177  AnyCollectionPtr lookup(const std::vector<AnyKeyable>& path,bool insert=false);
179  static bool parse_reference(const std::string& reference,std::vector<std::string>& path,char delim='.',char lbracket='[',char rbracket=']');
183  bool match_path(const std::vector<std::string>& path,std::vector<AnyKeyable>& key_path) const;
184 
189  AnyCollectionPtr slice(const std::string& reference,const char* delims=".[]:,");
190 
199  bool subcollection(const std::vector<std::string>& paths,AnyCollection& subset,const char* delims=".[]:,");
200 
202  void enumerate(std::vector<AnyCollectionPtr >& collections) const;
204  void enumerate_keys(std::vector<AnyKeyable>& elements) const;
206  void enumerate_values(std::vector<AnyValue>& elements) const;
208  void enumerate_keys_dfs(std::vector<std::vector<AnyKeyable> >& paths) const;
210  void enumerate_values_dfs(std::vector<AnyValue>& elements) const;
211 
215  void merge(const AnyCollection& other);
218  void deepmerge(const AnyCollection& other);
224  bool fill(AnyCollection& universe,bool checkSuperset=false);
225 
227  bool read(std::istream& in);
228  bool read(const char* data);
230  void write(std::ostream& out,int indent=0) const;
232  void write_inline(std::ostream& out) const;
233 
234  private:
235  enum Type { None, Value, Array, Map };
236  typedef AnyValue ValueType;
237  typedef std::vector<AnyCollectionPtr > ArrayType;
238  typedef UNORDERED_MAP_TEMPLATE<AnyKeyable,AnyCollectionPtr > MapType;
239 
240  Type type;
241  ValueType value;
242  ArrayType array;
243  MapType map;
244 };
245 
246 inline std::istream& operator >> (std::istream& in,AnyCollection& c)
247 {
248  bool res=c.read(in);
249  if(!res) in.setstate(std::ios::failbit);
250  return in;
251 }
252 
253 
254 inline std::ostream& operator << (std::ostream& out,const AnyCollection& c)
255 {
256  c.write(out);
257  return out;
258 }
259 
260 template <class T>
261 AnyCollection::AnyCollection(const std::vector<T>& array)
262  :type(None)
263 {
264  operator = (array);
265 }
266 
267 template <class T,class T2>
268 AnyCollection::AnyCollection(const std::map<T,T2>& map)
269  :type(None)
270 {
271  operator = (map);
272 }
273 
274 template <class T,class T2>
275 AnyCollection::AnyCollection(const UNORDERED_MAP_TEMPLATE<T,T2>& map)
276  :type(None)
277 {
278  operator = (map);
279 }
280 
281 
282 template<class T>
283 AnyCollection::operator T() const
284 {
285  T res;
286  if(!as(res)) {
287  if(type == Value)
288  FatalError("AnyCollection: coercion from %s to %s failed\n",value.type().name(),typeid(T).name());
289  else if(type == None)
290  FatalError("AnyCollection: coersion to %s failed, item does not exist\n",typeid(T).name());
291  else
292  FatalError("AnyCollection: coersion to %s failed, not of value type\n",typeid(T).name());
293  }
294  return res;
295 }
296 
297 template<class T>
298 bool AnyCollection::as(T& result) const
299 {
300  if(type == Value) {
301  bool res=CoerceCast<T>(value,result);
302  return res;
303  }
304  else {
305  return false;
306  }
307 }
308 
309 template <class T>
310 bool AnyCollection::operator == (const T& v) const
311 {
312  if(type != Value) return false;
313  return value == v;
314 }
315 
316 template<class T>
317 bool AnyCollection::asvector(std::vector<T>& values) const
318 {
319  std::vector<AnyValue> anyvalues;
320  if(!asvector(anyvalues)) return false;
321  values.resize(anyvalues.size());
322  for(size_t i=0;i<values.size();i++) {
323  bool res = CoerceCast<T>(anyvalues[i],values[i]);
324  if(!res) {
325  LOG4CXX_INFO(KrisLibrary::logger(),"Coerce cast "<<anyvalues[i].type().name()<<" to "<<typeid(T).name()<<" failed for element "<<(int)i);
326  return false;
327  }
328  }
329  return true;
330 }
331 
332 
333 template <class T>
334 AnyCollection& AnyCollection::operator = (const std::vector<T>& _array)
335 {
336  type = Array;
337  array.resize(_array.size());
338  for(size_t i=0;i<array.size();i++)
339  array[i] = std::make_shared<AnyCollection>(_array[i]);
340  return *this;
341 }
342 
343 template <class T,class T2>
344 AnyCollection& AnyCollection::operator = (const std::map<T,T2>& _map)
345 {
346  type = Map;
347  for(typename std::map<T,T2>::const_iterator i=_map.begin();i!=_map.end();i++)
348  map[i->first] = std::make_shared<AnyCollection>(i->second);
349  return *this;
350 }
351 
352 template <class T,class T2>
353 AnyCollection& AnyCollection::operator = (const UNORDERED_MAP_TEMPLATE<T,T2>& _map)
354 {
355  type = Map;
356  for(typename UNORDERED_MAP_TEMPLATE<T,T2>::const_iterator i=_map.begin();i!=_map.end();i++)
357  map[i->first] = std::make_shared<AnyCollection>(i->second);
358  return *this;
359 }
360 
361 #endif
A flexible hierarchical collection of AnyValues, which can be easily initialized to contain primitive...
Definition: AnyCollection.h:73
A polymorphic container class that can contain data of any type.
Definition: AnyValue.h:25
void write(std::ostream &out, int indent=0) const
Writes in JSON format.
Definition: AnyCollection.cpp:1502
Any primitive value (bool, char, unsigned char, int, unsigned int, float, double, string) that we kno...
Definition: AnyCollection.h:16
The logging system used in KrisLibrary.
AnyCollection & operator=(const AnyCollection &rhs)
shallow copy
Definition: AnyCollection.cpp:1103
bool read(std::istream &in)
Reads in JSON format.
Definition: AnyCollection.cpp:1377