Atlas 0.7.0
Networking protocol for the Worldforge system.
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
17namespace Atlas { namespace Message {
18
21{
22 public:
23 WrongTypeException() noexcept : Atlas::Exception("Wrong Message::Element type") { }
24};
25
26class Element;
27
28typedef std::int64_t IntType;
29typedef double FloatType;
30typedef void * PtrType;
31typedef std::string StringType;
32typedef std::map<std::string, Element> MapType;
33typedef std::vector<Element> ListType;
34
39{
40public:
41 enum Type {
42 TYPE_NONE,
43 TYPE_INT,
44 TYPE_FLOAT,
45 TYPE_PTR,
46 TYPE_STRING,
47 TYPE_MAP,
48 TYPE_LIST
49 };
50
51private:
52
54 void clear(Type new_type = TYPE_NONE);
55
56public:
59 : t(TYPE_NONE)
60 {
61 }
62
64 ~Element()
65 {
66 clear();
67 }
68
70 Element(const Element& obj);
71
74 Element(Element&& obj) noexcept;
75
77 Element(int v)
78 : t(TYPE_INT), i(v)
79 {
80 }
81
82 Element(long v)
83 : t(TYPE_INT), i(v)
84 {
85 }
86
87 Element(long long v)
88 : t(TYPE_INT), i(v)
89 {
90 }
91
93 Element(bool v)
94 : t(TYPE_INT), i(v)
95 {
96 }
97
99 Element(FloatType v)
100 : t(TYPE_FLOAT), f(v)
101 {
102 }
103
105 Element(PtrType v)
106 : t(TYPE_PTR), p(v)
107 {
108 }
109
111 Element(const char* v)
112 : t(TYPE_STRING)
113 {
114 if(v) {
115 s = new DataType<StringType>(v);
116 }
117 else
118 s = new DataType<StringType>();
119 }
120
122 Element(const StringType& v)
123 : t(TYPE_STRING)
124 {
125 s = new DataType<StringType>(v);
126 }
128 Element(StringType&& v)
129 : t(TYPE_STRING)
130 {
131 s = new DataType<StringType>(std::move(v));
132 }
133
135 Element(const MapType& v)
136 : t(TYPE_MAP)
137 {
138 m = new DataType<MapType>(v);
139 }
141 Element(MapType&& v)
142 : t(TYPE_MAP)
143 {
144 m = new DataType<MapType>(std::move(v));
145 }
146
148 Element(const ListType& v)
149 : t(TYPE_LIST)
150 {
151 l = new DataType<ListType>(v);
152 }
154 Element(ListType&& v)
155 : t(TYPE_LIST)
156 {
157 l = new DataType<ListType>(std::move(v));
158 }
159
161 Element& operator=(const Element& obj);
162
168 Element& operator=(Element&& obj) noexcept;
169
170 Element& operator=(int v)
171 {
172 if (TYPE_INT != t)
173 {
174 clear(TYPE_INT);
175 }
176 i = v;
177 return *this;
178 }
179
180 Element& operator=(long v)
181 {
182 if (TYPE_INT != t)
183 {
184 clear(TYPE_INT);
185 }
186 i = v;
187 return *this;
188 }
189
190 Element& operator=(long long v)
191 {
192 if (TYPE_INT != t)
193 {
194 clear(TYPE_INT);
195 }
196 i = v;
197 return *this;
198 }
199
200 Element& operator=(bool v)
201 {
202 if (TYPE_INT != t)
203 {
204 clear(TYPE_INT);
205 }
206 i = v;
207 return *this;
208 }
209
210 Element& operator=(FloatType v)
211 {
212 if (TYPE_FLOAT != t)
213 {
214 clear(TYPE_FLOAT);
215 }
216 f = v;
217 return *this;
218 }
219
220 Element& operator=(PtrType v)
221 {
222 if (TYPE_PTR != t)
223 {
224 clear(TYPE_PTR);
225 }
226 p = v;
227 return *this;
228 }
229
230 Element& operator=(const char * v)
231 {
232 if (TYPE_STRING != t || !s->unique())
233 {
234 clear(TYPE_STRING);
235 s = new DataType<StringType>(std::string(v));
236 } else {
237 *s = StringType(v);
238 }
239 return *this;
240 }
241
242 Element& operator=(const StringType & v)
243 {
244 if (TYPE_STRING != t || !s->unique())
245 {
246 clear(TYPE_STRING);
247 s = new DataType<StringType>(v);
248 } else {
249 *s = v;
250 }
251 return *this;
252 }
253
254 Element& operator=(StringType && v)
255 {
256 if (TYPE_STRING != t || !s->unique())
257 {
258 clear(TYPE_STRING);
259 s = new DataType<StringType>(v);
260 } else {
261 *s = v;
262 }
263 return *this;
264 }
265
266 Element& operator=(const MapType & v)
267 {
268 if (TYPE_MAP != t || !m->unique())
269 {
270 clear(TYPE_MAP);
271 m = new DataType<MapType>(v);
272 } else {
273 *m = v;
274 }
275 return *this;
276 }
277
278 Element& operator=(MapType && v)
279 {
280 if (TYPE_MAP != t || !m->unique())
281 {
282 clear(TYPE_MAP);
283 m = new DataType<MapType>(std::move(v));
284 } else {
285 *m = v;
286 }
287 return *this;
288 }
289
290 Element& operator=(const ListType & v)
291 {
292 if (TYPE_LIST != t || !l->unique())
293 {
294 clear(TYPE_LIST);
295 l = new DataType<ListType>(v);
296 } else {
297 *l = v;
298 }
299 return *this;
300 }
301
302 Element& operator=(ListType && v)
303 {
304 if (TYPE_LIST != t || !l->unique())
305 {
306 clear(TYPE_LIST);
307 l = new DataType<ListType>(std::move(v));
308 } else {
309 *l = v;
310 }
311 return *this;
312 }
313
315 bool operator==(const Element& o) const;
316
318 template<class C>
319 bool operator!=(C c) const
320 {
321 return !(*this == c);
322 }
323
325 bool operator==(int v) const
326 {
327 return (t == TYPE_INT && i == v);
328 }
329
331 bool operator==(long v) const
332 {
333 return (t == TYPE_INT && i == v);
334 }
335
336 bool operator==(long long v) const
337 {
338 return (t == TYPE_INT && i == v);
339 }
341 bool operator==(FloatType v) const
342 {
343 return t == TYPE_FLOAT && Equal(f, v);
344 }
345
347 bool operator==(PtrType v) const
348 {
349 return t == TYPE_PTR && p == v;
350 }
351
353 bool operator==(const char * v) const
354 {
355 if(t == TYPE_STRING)
356 return (*s == v);
357 return false;
358 }
359
361 bool operator==(const StringType& v) const
362 {
363 if(t == TYPE_STRING)
364 return (*s == v);
365 return false;
366 }
367
369 bool operator==(const MapType& v) const
370 {
371 if(t == TYPE_MAP)
372 return (*m == v);
373 return false;
374 }
375
377 bool operator==(const ListType& v) const
378 {
379 if (t == TYPE_LIST)
380 return (*l == v);
381 return false;
382 }
383
385 Type getType() const { return t; }
387 bool isNone() const { return (t == TYPE_NONE); }
389 bool isInt() const { return (t == TYPE_INT); }
391 bool isFloat() const { return (t == TYPE_FLOAT); }
393 bool isPtr() const { return (t == TYPE_PTR); }
395 bool isNum() const { return ((t == TYPE_FLOAT) || (t == TYPE_INT)); }
397 bool isString() const { return (t == TYPE_STRING); }
399 bool isMap() const { return (t == TYPE_MAP); }
401 bool isList() const { return (t == TYPE_LIST); }
402
404 IntType asInt() const
405 {
406 if (t == TYPE_INT) return i;
407 throw WrongTypeException();
408 }
409 IntType Int() const
410 {
411 return i;
412 }
414 FloatType asFloat() const
415 {
416 if (t == TYPE_FLOAT) return f;
417 throw WrongTypeException();
418 }
419 FloatType Float() const
420 {
421 return f;
422 }
424 PtrType asPtr() const
425 {
426 if (t == TYPE_PTR) return p;
427 throw WrongTypeException();
428 }
429 PtrType Ptr() const
430 {
431 return p;
432 }
434 FloatType asNum() const
435 {
436 if (t == TYPE_FLOAT) return f;
437 if (t == TYPE_INT) return FloatType(i);
438 throw WrongTypeException();
439 }
441 const std::string& asString() const
442 {
443 if (t == TYPE_STRING) return *s;
444 throw WrongTypeException();
445 }
447 std::string& asString()
448 {
449 if (t == TYPE_STRING) return *(s = s->makeUnique());
450 throw WrongTypeException();
451 }
452 const StringType& String() const
453 {
454 return *s;
455 }
456 StringType& String()
457 {
458 return *(s = s->makeUnique());
459 }
460
467 StringType&& moveString() {
468 if (t != TYPE_STRING) throw WrongTypeException();
469 s = s->makeUnique();
470 return s->move();
471 }
472
474 const MapType& asMap() const
475 {
476 if (t == TYPE_MAP) return *m;
477 throw WrongTypeException();
478 }
480 MapType& asMap()
481 {
482 if (t == TYPE_MAP) return *(m = m->makeUnique());
483 throw WrongTypeException();
484 }
485 const MapType& Map() const
486 {
487 return *m;
488 }
489 MapType& Map()
490 {
491 return *(m = m->makeUnique());
492 }
493
500 MapType&& moveMap() {
501 if (t != TYPE_MAP) throw WrongTypeException();
502 m = m->makeUnique();
503 return m->move();
504 }
505
507 const ListType& asList() const
508 {
509 if (t == TYPE_LIST) return *l;
510 throw WrongTypeException();
511 }
513 ListType& asList()
514 {
515 if (t == TYPE_LIST) return *(l = l->makeUnique());
516 throw WrongTypeException();
517 }
518 const ListType& List() const
519 {
520 return *l;
521 }
522 ListType& List()
523 {
524 return *(l = l->makeUnique());
525 }
526
533 ListType&& moveList() {
534 if (t != TYPE_LIST) throw WrongTypeException();
535 l = l->makeUnique();
536 return l->move();
537 }
538
539 static const char * typeName(Type);
540
541protected:
542
543 template<class C>
545 {
546 public:
547 DataType() : _refcount(1), _data(nullptr) {}
548
549 explicit DataType(const C& c) : _refcount(1), _data(c) {}
550 explicit DataType(C&& c) : _refcount(1), _data(std::move(c)) {}
551 DataType(const DataType&) = delete;
552
553 DataType& operator=(const C& c) {_data = c; return *this;}
554 DataType& operator=(const C&& c) {_data = std::move(c); return *this;}
555 DataType& operator=(const DataType&) = delete;
556
557 bool operator==(const C& c) const {return _data == c;}
558
559 void ref() {++_refcount;}
560 void unref() {if(--_refcount == 0) delete this;}
561
562 bool unique() const {return _refcount == 1;}
563 DataType* makeUnique()
564 {
565 if(unique())
566 return this;
567 unref(); // _refcount > 1, so this is fine
568 return new DataType(_data);
569 }
570
571 operator C&() {return _data;}
578 C&& move() {
579 return std::move(_data);
580 }
581// operator const C&() const {return _data;}
582
583 private:
584
585 unsigned long _refcount;
586 C _data;
587 };
588
589 Type t;
590 union {
591 IntType i;
592 FloatType f;
593 void* p;
594 DataType<StringType>* s;
595 DataType<MapType>* m;
596 DataType<ListType>* l;
597 };
598};
599
600} } // namespace Atlas::Message
601
602
603#endif // ATLAS_MESSAGE_ELEMENT_H
ListType & asList()
Retrieve the current value as a non-const ListType reference.
Definition: Element.h:513
bool operator==(FloatType v) const
Check for equality with a double.
Definition: Element.h:341
Element(const StringType &v)
Set type to std::string, and value to v.
Definition: Element.h:122
bool operator==(const StringType &v) const
Check for equality with a std::string.
Definition: Element.h:361
Element(FloatType v)
Set type to double, and value to v.
Definition: Element.h:99
bool isString() const
Check whether the current type is std::string.
Definition: Element.h:397
Element(bool v)
Set type to int, and value to v.
Definition: Element.h:93
bool operator==(const Element &o) const
Check for equality with another Element.
Definition: Element.cpp:176
bool isNum() const
Check whether the current type is numeric.
Definition: Element.h:395
StringType && moveString()
Definition: Element.h:467
Element(ListType &&v)
Set type to ListType, and move v.
Definition: Element.h:154
PtrType asPtr() const
Retrieve the current value as a pointer.
Definition: Element.h:424
MapType && moveMap()
Definition: Element.h:500
FloatType asFloat() const
Retrieve the current value as a double.
Definition: Element.h:414
FloatType asNum() const
Retrieve the current value as a number.
Definition: Element.h:434
Element(const char *v)
Set type to std::string, and value to v.
Definition: Element.h:111
bool isFloat() const
Check whether the current type is double.
Definition: Element.h:391
std::string & asString()
Retrieve the current value as a non-const std::string reference.
Definition: Element.h:447
Element(int v)
Set type to int, and value to v.
Definition: Element.h:77
bool isPtr() const
Check whether the current type is pointer.
Definition: Element.h:393
bool operator==(int v) const
Check for equality with a int.
Definition: Element.h:325
Element(StringType &&v)
Set type to std::string, and move v.
Definition: Element.h:128
Type getType() const
Get the current type.
Definition: Element.h:385
const ListType & asList() const
Retrieve the current value as a const ListType reference.
Definition: Element.h:507
Element(PtrType v)
Set type to PtrType, and value to v.
Definition: Element.h:105
const MapType & asMap() const
Retrieve the current value as a const MapType reference.
Definition: Element.h:474
bool operator==(const MapType &v) const
Check for equality with a MapType.
Definition: Element.h:369
bool operator==(const ListType &v) const
Check for equality with a ListType.
Definition: Element.h:377
bool operator==(PtrType v) const
Check for equality with a pointer.
Definition: Element.h:347
MapType & asMap()
Retrieve the current value as a non-const MapType reference.
Definition: Element.h:480
Element & operator=(const Element &obj)
overload assignment operator !
Definition: Element.cpp:96
Element()
Construct an empty object.
Definition: Element.h:58
ListType && moveList()
Definition: Element.h:533
bool isMap() const
Check whether the current type is MapType.
Definition: Element.h:399
bool operator!=(C c) const
Check for inequality with anything we can check equality with.
Definition: Element.h:319
Element(const ListType &v)
Set type to ListType, and value to v.
Definition: Element.h:148
const std::string & asString() const
Retrieve the current value as a const std::string reference.
Definition: Element.h:441
bool isList() const
Check whether the current type is ListType.
Definition: Element.h:401
bool operator==(const char *v) const
Check for equality with a const char *.
Definition: Element.h:353
Element(MapType &&v)
Set type to MapType, and move v.
Definition: Element.h:141
IntType asInt() const
Retrieve the current value as a int.
Definition: Element.h:404
Element(const MapType &v)
Set type to MapType, and value to v.
Definition: Element.h:135
bool operator==(long v) const
Check for equality with a int.
Definition: Element.h:331
bool isNone() const
Check whether the current type is nothing.
Definition: Element.h:387
bool isInt() const
Check whether the current type is int.
Definition: Element.h:389
An exception class issued when the wrong type is requested in as().
Definition: Element.h:21
Definition: Bridge.h:20