Atlas-C++
Element.h
1 // This file may be redistributed and modified only under the terms of
2 // the GNU Lesser General Public License (See COPYING for details).
3 // Copyright (C) 2000-2001 Stefanus Du Toit, Karsten-O. Laux and Al Riddoch
4 
5 // $Id$
6 
7 #ifndef ATLAS_MESSAGE_ELEMENT_H
8 #define ATLAS_MESSAGE_ELEMENT_H
9 
10 #include <Atlas/Exception.h>
11 #include <Atlas/float.h>
12 
13 #include <string>
14 #include <map>
15 #include <vector>
16 
17 namespace Atlas { namespace Message {
18 
21 {
22  public:
23  WrongTypeException() noexcept : Atlas::Exception("Wrong Message::Element type") { }
24 };
25 
26 class Element;
27 
28 typedef long IntType;
29 typedef double FloatType;
30 typedef void * PtrType;
31 typedef std::string StringType;
32 typedef std::map<std::string, Element> MapType;
33 typedef std::vector<Element> ListType;
34 
60 class Element
61 {
62 public:
63  enum Type {
64  TYPE_NONE,
65  TYPE_INT,
66  TYPE_FLOAT,
67  TYPE_PTR,
68  TYPE_STRING,
69  TYPE_MAP,
70  TYPE_LIST
71  };
72 
73 private:
74 
76  void clear(Type new_type = TYPE_NONE);
77 
78 public:
81  : t(TYPE_NONE)
82  {
83  }
84 
86  ~Element()
87  {
88  clear();
89  }
90 
92  Element(const Element& obj);
93 
96  Element(Element&& obj) noexcept;
97 
99  Element(int v)
100  : t(TYPE_INT), i(v)
101  {
102  }
103 
105  Element(bool v)
106  : t(TYPE_INT), i(v)
107  {
108  }
109 
111  Element(IntType v)
112  : t(TYPE_INT), i(v)
113  {
114  }
115 
117  Element(float v)
118  : t(TYPE_FLOAT), f(v)
119  {
120  }
121 
123  Element(FloatType v)
124  : t(TYPE_FLOAT), f(v)
125  {
126  }
127 
129  Element(PtrType v)
130  : t(TYPE_PTR), p(v)
131  {
132  }
133 
135  Element(const char* v)
136  : t(TYPE_STRING)
137  {
138  if(v)
139  s = new DataType<StringType>(v);
140  else
141  s = new DataType<StringType>();
142  }
143 
145  Element(const StringType& v)
146  : t(TYPE_STRING)
147  {
148  s = new DataType<StringType>(v);
149  }
151  Element(StringType&& v)
152  : t(TYPE_STRING)
153  {
154  s = new DataType<StringType>(std::move(v));
155  }
156 
158  Element(const MapType& v)
159  : t(TYPE_MAP)
160  {
161  m = new DataType<MapType>(v);
162  }
164  Element(MapType&& v)
165  : t(TYPE_MAP)
166  {
167  m = new DataType<MapType>(std::move(v));
168  }
169 
171  Element(const ListType& v)
172  : t(TYPE_LIST)
173  {
174  l = new DataType<ListType>(v);
175  }
177  Element(ListType&& v)
178  : t(TYPE_LIST)
179  {
180  l = new DataType<ListType>(std::move(v));
181  }
182 
184  Element& operator=(const Element& obj);
185 
191  Element& operator=(Element&& obj) noexcept;
192 
193  Element& operator=(int v)
194  {
195  if (TYPE_INT != t)
196  {
197  clear(TYPE_INT);
198  }
199  i = v;
200  return *this;
201  }
202 
203  Element& operator=(bool v)
204  {
205  if (TYPE_INT != t)
206  {
207  clear(TYPE_INT);
208  }
209  i = v;
210  return *this;
211  }
212 
213  Element& operator=(IntType v)
214  {
215  if (TYPE_INT != t)
216  {
217  clear(TYPE_INT);
218  }
219  i = v;
220  return *this;
221  }
222 
223  Element& operator=(float v)
224  {
225  if (TYPE_FLOAT != t)
226  {
227  clear(TYPE_FLOAT);
228  }
229  f = v;
230  return *this;
231  }
232 
233  Element& operator=(FloatType v)
234  {
235  if (TYPE_FLOAT != t)
236  {
237  clear(TYPE_FLOAT);
238  }
239  f = v;
240  return *this;
241  }
242 
243  Element& operator=(PtrType v)
244  {
245  if (TYPE_PTR != t)
246  {
247  clear(TYPE_PTR);
248  }
249  p = v;
250  return *this;
251  }
252 
253  Element& operator=(const char * v)
254  {
255  if (TYPE_STRING != t || !s->unique())
256  {
257  clear(TYPE_STRING);
258  s = new DataType<StringType>(v);
259  } else {
260  *s = StringType(v);
261  }
262  return *this;
263  }
264 
265  Element& operator=(const StringType & v)
266  {
267  if (TYPE_STRING != t || !s->unique())
268  {
269  clear(TYPE_STRING);
270  s = new DataType<StringType>(v);
271  } else {
272  *s = v;
273  }
274  return *this;
275  }
276 
277  Element& operator=(StringType && v)
278  {
279  if (TYPE_STRING != t || !s->unique())
280  {
281  clear(TYPE_STRING);
282  s = new DataType<StringType>(std::move(v));
283  } else {
284  *s = v;
285  }
286  return *this;
287  }
288 
289  Element& operator=(const MapType & v)
290  {
291  if (TYPE_MAP != t || !m->unique())
292  {
293  clear(TYPE_MAP);
294  m = new DataType<MapType>(v);
295  } else {
296  *m = v;
297  }
298  return *this;
299  }
300 
301  Element& operator=(MapType && v)
302  {
303  if (TYPE_MAP != t || !m->unique())
304  {
305  clear(TYPE_MAP);
306  m = new DataType<MapType>(std::move(v));
307  } else {
308  *m = v;
309  }
310  return *this;
311  }
312 
313  Element& operator=(const ListType & v)
314  {
315  if (TYPE_LIST != t || !l->unique())
316  {
317  clear(TYPE_LIST);
318  l = new DataType<ListType>(v);
319  } else {
320  *l = v;
321  }
322  return *this;
323  }
324 
325  Element& operator=(ListType && v)
326  {
327  if (TYPE_LIST != t || !l->unique())
328  {
329  clear(TYPE_LIST);
330  l = new DataType<ListType>(std::move(v));
331  } else {
332  *l = v;
333  }
334  return *this;
335  }
336 
338  bool operator==(const Element& o) const;
339 
340 #if defined(__GNUC__) && __GNUC__ < 3
341  bool operator!=(const Element& o) const
342  {
343  return !(*this == o);
344  }
345 #endif // defined(__GNUC__) && __GNUC__ < 3
346 
348  template<class C>
349  bool operator!=(C c) const
350  {
351  return !(*this == c);
352  }
353 
355  bool operator==(IntType v) const
356  {
357  return (t == TYPE_INT && i == v);
358  }
359 
361  bool operator==(FloatType v) const
362  {
363  return t == TYPE_FLOAT && Equal(f, v);
364  }
365 
367  bool operator==(PtrType v) const
368  {
369  return t == TYPE_PTR && p == v;
370  }
371 
373  bool operator==(const char * v) const
374  {
375  if(t == TYPE_STRING)
376  return (*s == v);
377  return false;
378  }
379 
381  bool operator==(const StringType& v) const
382  {
383  if(t == TYPE_STRING)
384  return (*s == v);
385  return false;
386  }
387 
389  bool operator==(const MapType& v) const
390  {
391  if(t == TYPE_MAP)
392  return (*m == v);
393  return false;
394  }
395 
397  bool operator==(const ListType& v) const
398  {
399  if (t == TYPE_LIST)
400  return (*l == v);
401  return false;
402  }
403 
405  Type getType() const { return t; }
407  bool isNone() const { return (t == TYPE_NONE); }
409  bool isInt() const { return (t == TYPE_INT); }
411  bool isFloat() const { return (t == TYPE_FLOAT); }
413  bool isPtr() const { return (t == TYPE_PTR); }
415  bool isNum() const { return ((t == TYPE_FLOAT) || (t == TYPE_INT)); }
417  bool isString() const { return (t == TYPE_STRING); }
419  bool isMap() const { return (t == TYPE_MAP); }
421  bool isList() const { return (t == TYPE_LIST); }
422 
424  IntType asInt() const
425  {
426  if (t == TYPE_INT) return i;
427  throw WrongTypeException();
428  }
429  IntType Int() const
430  {
431  return i;
432  }
434  FloatType asFloat() const
435  {
436  if (t == TYPE_FLOAT) return f;
437  throw WrongTypeException();
438  }
439  FloatType Float() const
440  {
441  return f;
442  }
444  PtrType asPtr() const
445  {
446  if (t == TYPE_PTR) return p;
447  throw WrongTypeException();
448  }
449  PtrType Ptr() const
450  {
451  return p;
452  }
454  FloatType asNum() const
455  {
456  if (t == TYPE_FLOAT) return f;
457  if (t == TYPE_INT) return FloatType(i);
458  throw WrongTypeException();
459  }
461  const std::string& asString() const
462  {
463  if (t == TYPE_STRING) return *s;
464  throw WrongTypeException();
465  }
467  std::string& asString()
468  {
469  if (t == TYPE_STRING) return *(s = s->makeUnique());
470  throw WrongTypeException();
471  }
472  const StringType& String() const
473  {
474  return *s;
475  }
476  StringType& String()
477  {
478  return *(s = s->makeUnique());
479  }
480 
487  StringType moveString() {
488  if (t != TYPE_STRING) throw WrongTypeException();
489  s = s->makeUnique();
490  return std::move(s->move());
491  }
492 
494  const MapType& asMap() const
495  {
496  if (t == TYPE_MAP) return *m;
497  throw WrongTypeException();
498  }
500  MapType& asMap()
501  {
502  if (t == TYPE_MAP) return *(m = m->makeUnique());
503  throw WrongTypeException();
504  }
505  const MapType& Map() const
506  {
507  return *m;
508  }
509  MapType& Map()
510  {
511  return *(m = m->makeUnique());
512  }
513 
520  MapType moveMap() {
521  if (t != TYPE_MAP) throw WrongTypeException();
522  m = m->makeUnique();
523  return std::move(m->move());
524  }
525 
527  const ListType& asList() const
528  {
529  if (t == TYPE_LIST) return *l;
530  throw WrongTypeException();
531  }
533  ListType& asList()
534  {
535  if (t == TYPE_LIST) return *(l = l->makeUnique());
536  throw WrongTypeException();
537  }
538  const ListType& List() const
539  {
540  return *l;
541  }
542  ListType& List()
543  {
544  return *(l = l->makeUnique());
545  }
546 
553  ListType moveList() {
554  if (t != TYPE_LIST) throw WrongTypeException();
555  l = l->makeUnique();
556  return std::move(l->move());
557  }
558 
559  static const char * typeName(Type);
560 
561 protected:
562 
563  template<class C>
564  class DataType
565  {
566  public:
567  DataType() : _refcount(1), _data(0) {}
568 
569  explicit DataType(const C& c) : _refcount(1), _data(c) {}
570  explicit DataType(C&& c) : _refcount(1), _data(std::move(c)) {}
571  DataType(const DataType&) = delete;
572 
573  DataType& operator=(const C& c) {_data = c; return *this;}
574  DataType& operator=(const C&& c) {_data = std::move(c); return *this;}
575  DataType& operator=(const DataType&) = delete;
576 
577  bool operator==(const C& c) const {return _data == c;}
578 
579  void ref() {++_refcount;}
580  void unref() {if(--_refcount == 0) delete this;}
581 
582  bool unique() const {return _refcount == 1;}
583  DataType* makeUnique()
584  {
585  if(unique())
586  return this;
587  unref(); // _refcount > 1, so this is fine
588  return new DataType(_data);
589  }
590 
591  operator C&() {return _data;}
598  C move() {
599  return std::move(_data);
600  }
601 // operator const C&() const {return _data;}
602 
603  private:
604 
605  unsigned long _refcount;
606  C _data;
607  };
608 
609  Type t;
610  union {
611  IntType i;
612  FloatType f;
613  void* p;
617  };
618 };
619 
620 } } // namespace Atlas::Message
621 
622 
623 #endif // ATLAS_MESSAGE_ELEMENT_H
ListType moveList()
Moves the list out of the Element.
Definition: Element.h:553
MapType & asMap()
Retrieve the current value as a non-const MapType reference.
Definition: Element.h:500
Element(const ListType &v)
Set type to ListType, and value to v.
Definition: Element.h:171
FloatType asFloat() const
Retrieve the current value as a double.
Definition: Element.h:434
const MapType & asMap() const
Retrieve the current value as a const MapType reference.
Definition: Element.h:494
bool operator==(FloatType v) const
Check for equality with a double.
Definition: Element.h:361
bool operator!=(C c) const
Check for inequality with anything we can check equality with.
Definition: Element.h:349
bool operator==(PtrType v) const
Check for equality with a pointer.
Definition: Element.h:367
bool operator==(IntType v) const
Check for equality with a int.
Definition: Element.h:355
bool operator==(const char *v) const
Check for equality with a const char *.
Definition: Element.h:373
bool isNum() const
Check whether the current type is numeric.
Definition: Element.h:415
Element(const MapType &v)
Set type to MapType, and value to v.
Definition: Element.h:158
Element(IntType v)
Set type to int, and value to v.
Definition: Element.h:111
Element(MapType &&v)
Set type to MapType, and move v.
Definition: Element.h:164
const std::string & asString() const
Retrieve the current value as a const std::string reference.
Definition: Element.h:461
C move()
Moves the data out of the container.
Definition: Element.h:598
Element(const StringType &v)
Set type to std::string, and value to v.
Definition: Element.h:145
Multi-type container.
Definition: Element.h:60
Element()
Construct an empty object.
Definition: Element.h:80
MapType moveMap()
Moves the map out of the Element.
Definition: Element.h:520
bool isFloat() const
Check whether the current type is double.
Definition: Element.h:411
IntType asInt() const
Retrieve the current value as a int.
Definition: Element.h:424
bool operator==(const StringType &v) const
Check for equality with a std::string.
Definition: Element.h:381
The Atlas namespace.
Definition: Bridge.h:20
StringType moveString()
Moves the string out of the Element.
Definition: Element.h:487
bool isPtr() const
Check whether the current type is pointer.
Definition: Element.h:413
bool isNone() const
Check whether the current type is nothing.
Definition: Element.h:407
Element(bool v)
Set type to int, and value to v.
Definition: Element.h:105
const ListType & asList() const
Retrieve the current value as a const ListType reference.
Definition: Element.h:527
FloatType asNum() const
Retrieve the current value as a number.
Definition: Element.h:454
Element(FloatType v)
Set type to double, and value to v.
Definition: Element.h:123
bool operator==(const ListType &v) const
Check for equality with a ListType.
Definition: Element.h:397
Element(StringType &&v)
Set type to std::string, and move v.
Definition: Element.h:151
An exception class issued when the wrong type is requested in as().
Definition: Element.h:20
bool isList() const
Check whether the current type is ListType.
Definition: Element.h:421
bool isMap() const
Check whether the current type is MapType.
Definition: Element.h:419
ListType & asList()
Retrieve the current value as a non-const ListType reference.
Definition: Element.h:533
bool operator==(const MapType &v) const
Check for equality with a MapType.
Definition: Element.h:389
Element(PtrType v)
Set type to PtrType, and value to v.
Definition: Element.h:129
Element(float v)
Set type to double, and value to v.
Definition: Element.h:117
bool isInt() const
Check whether the current type is int.
Definition: Element.h:409
Type getType() const
Get the current type.
Definition: Element.h:405
Element(ListType &&v)
Set type to ListType, and move v.
Definition: Element.h:177
Element(int v)
Set type to int, and value to v.
Definition: Element.h:99
Base class for all exceptions thrown by Atlas-C++.
Definition: Exception.h:17
bool isString() const
Check whether the current type is std::string.
Definition: Element.h:417
Element(const char *v)
Set type to std::string, and value to v.
Definition: Element.h:135
PtrType asPtr() const
Retrieve the current value as a pointer.
Definition: Element.h:444
std::string & asString()
Retrieve the current value as a non-const std::string reference.
Definition: Element.h:467

Copyright 2000-2004 the respective authors.

This document can be licensed under the terms of the GNU Free Documentation License or the GNU General Public License and may be freely distributed under the terms given by one of these licenses.