Medical Imaging Interaction Toolkit  2018.4.99-36d69b77
Medical Imaging Interaction Toolkit
usAny.h
Go to the documentation of this file.
1 /*=============================================================================
2 
3  Library: CppMicroServices
4 
5 
6 Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
7 Extracted from Boost 1.46.1 and adapted for CppMicroServices.
8 
9 Permission is hereby granted, free of charge, to any person or organization
10 obtaining a copy of the software and accompanying documentation covered by
11 this license (the "Software") to use, reproduce, display, distribute,
12 execute, and transmit the Software, and to prepare derivative works of the
13 Software, and to permit third-parties to whom the Software is furnished to
14 do so, all subject to the following:
15 
16 The copyright notices in the Software and this entire statement, including
17 the above license grant, this restriction and the following disclaimer,
18 must be included in all copies of the Software, in whole or in part, and
19 all derivative works of the Software, unless such copies or derivative
20 works are solely in the form of machine-executable object code generated by
21 a source language processor.
22 
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
26 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
27 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
28 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 DEALINGS IN THE SOFTWARE.
30 
31 =========================================================================*/
32 
33 #ifndef US_ANY_H
34 #define US_ANY_H
35 
36 #include <algorithm>
37 #include <typeinfo>
38 #include <sstream>
39 #include <vector>
40 #include <list>
41 #include <set>
42 #include <map>
43 
44 #include <usCoreConfig.h>
45 
47 
48 class Any;
49 
50 US_Core_EXPORT std::string any_value_to_string(const Any& any);
51 
52 US_Core_EXPORT std::string any_value_to_json(const Any& val);
53 US_Core_EXPORT std::string any_value_to_json(const std::string& val);
54 US_Core_EXPORT std::string any_value_to_json(bool val);
55 
56 template<class T>
57 std::string any_value_to_string(const T& val)
58 {
59  std::stringstream ss;
60  ss << val;
61  return ss.str();
62 }
63 
64 template<class T>
65 std::string any_value_to_json(const T& val)
66 {
67  return any_value_to_string(val);
68 }
69 
73 template<typename Iterator>
74 std::string container_to_string(Iterator i1, Iterator i2)
75 {
76  std::stringstream ss;
77  ss << "[";
78  const Iterator begin = i1;
79  for ( ; i1 != i2; ++i1)
80  {
81  if (i1 == begin) ss << any_value_to_string(*i1);
82  else ss << "," << any_value_to_string(*i1);
83  }
84  ss << "]";
85  return ss.str();
86 }
87 
91 template<typename Iterator>
92 std::string container_to_json(Iterator i1, Iterator i2)
93 {
94  std::stringstream ss;
95  ss << "[";
96  const Iterator begin = i1;
97  for ( ; i1 != i2; ++i1)
98  {
99  if (i1 == begin) ss << any_value_to_json(*i1);
100  else ss << "," << any_value_to_json(*i1);
101  }
102  ss << "]";
103  return ss.str();
104 }
105 
106 template<class E>
107 std::string any_value_to_string(const std::vector<E>& vec)
108 {
109  return container_to_string(vec.begin(), vec.end());
110 }
111 
112 template<class E>
113 std::string any_value_to_json(const std::vector<E>& vec)
114 {
115  return container_to_json(vec.begin(), vec.end());
116 }
117 
118 template<class E>
119 std::string any_value_to_string(const std::list<E>& l)
120 {
121  return container_to_string(l.begin(), l.end());
122 }
123 
124 template<class E>
125 std::string any_value_to_json(const std::list<E>& l)
126 {
127  return container_to_json(l.begin(), l.end());
128 }
129 
130 template<class E>
131 std::string any_value_to_string(const std::set<E>& s)
132 {
133  return container_to_string(s.begin(), s.end());
134 }
135 
136 template<class E>
137 std::string any_value_to_json(const std::set<E>& s)
138 {
139  return container_to_json(s.begin(), s.end());
140 }
141 
142 template<class M>
143 std::string any_value_to_string(const std::map<M, Any>& m);
144 
145 template<class K, class V>
146 std::string any_value_to_string(const std::map<K, V>& m);
147 
148 template<class M>
149 std::string any_value_to_json(const std::map<M, Any>& m);
150 
151 template<class K, class V>
152 std::string any_value_to_json(const std::map<K, V>& m);
153 
154 
163 class Any
164 {
165 public:
166 
170  Any(): _content(nullptr)
171  { }
172 
184  template <typename ValueType>
185  Any(const ValueType& value)
186  : _content(new Holder<ValueType>(value))
187  { }
188 
194  Any(const Any& other)
195  : _content(other._content ? other._content->Clone() : nullptr)
196  { }
197 
199  {
200  delete _content;
201  }
202 
208  Any& Swap(Any& rhs)
209  {
210  std::swap(_content, rhs._content);
211  return *this;
212  }
213 
225  template <typename ValueType>
226  Any& operator = (const ValueType& rhs)
227  {
228  Any(rhs).Swap(*this);
229  return *this;
230  }
231 
237  Any& operator = (const Any& rhs)
238  {
239  Any(rhs).Swap(*this);
240  return *this;
241  }
242 
246  bool Empty() const
247  {
248  return !_content;
249  }
250 
257  std::string ToString() const
258  {
259  return _content->ToString();
260  }
261 
267  std::string ToJSON() const
268  {
269  return Empty() ? "null" : _content->ToJSON();
270  }
271 
278  const std::type_info& Type() const
279  {
280  return _content ? _content->Type() : typeid(void);
281  }
282 
283 private:
284 
285  class Placeholder
286  {
287  public:
288  virtual ~Placeholder()
289  { }
290 
291  virtual std::string ToString() const = 0;
292  virtual std::string ToJSON() const = 0;
293 
294  virtual const std::type_info& Type() const = 0;
295  virtual Placeholder* Clone() const = 0;
296  };
297 
298  template <typename ValueType>
299  class Holder: public Placeholder
300  {
301  public:
302  Holder(const ValueType& value)
303  : _held(value)
304  { }
305 
306  std::string ToString() const override
307  {
308  return any_value_to_string(_held);
309  }
310 
311  std::string ToJSON() const override
312  {
313  return any_value_to_json(_held);
314  }
315 
316  const std::type_info& Type() const override
317  {
318  return typeid(ValueType);
319  }
320 
321  Placeholder* Clone() const override
322  {
323  return new Holder(_held);
324  }
325 
326  ValueType _held;
327 
328  private: // intentionally left unimplemented
329  Holder& operator=(const Holder &);
330  };
331 
332 private:
333  template <typename ValueType>
334  friend ValueType* any_cast(Any*);
335 
336  template <typename ValueType>
337  friend ValueType* unsafe_any_cast(Any*);
338 
339  Placeholder* _content;
340 };
341 
342 class BadAnyCastException : public std::bad_cast
343 {
344 public:
345 
346  BadAnyCastException(const std::string& msg = "")
347  : std::bad_cast(), _msg(msg)
348  {}
349 
350  ~BadAnyCastException() throw() override {}
351 
352  const char * what() const throw() override
353  {
354  if (_msg.empty())
355  return "US_PREPEND_NAMESPACE(BadAnyCastException): "
356  "failed conversion using US_PREPEND_NAMESPACE(any_cast)";
357  else
358  return _msg.c_str();
359  }
360 
361 private:
362 
363  std::string _msg;
364 };
365 
376 template <typename ValueType>
378 {
379  return operand && operand->Type() == typeid(ValueType)
380  ? &static_cast<Any::Holder<ValueType>*>(operand->_content)->_held
381  : nullptr;
382 }
383 
394 template <typename ValueType>
395 const ValueType* any_cast(const Any* operand)
396 {
397  return any_cast<ValueType>(const_cast<Any*>(operand));
398 }
399 
412 template <typename ValueType>
413 ValueType any_cast(const Any& operand)
414 {
415  ValueType* result = any_cast<ValueType>(const_cast<Any*>(&operand));
416  if (!result) throw BadAnyCastException("Failed to convert between const Any types");
417  return *result;
418 }
419 
432 template <typename ValueType>
434 {
435  ValueType* result = any_cast<ValueType>(&operand);
436  if (!result) throw BadAnyCastException("Failed to convert between Any types");
437  return *result;
438 }
439 
448 template <typename ValueType>
449 const ValueType& ref_any_cast(const Any & operand)
450 {
451  ValueType* result = any_cast<ValueType>(const_cast<Any*>(&operand));
452  if (!result) throw BadAnyCastException("RefAnyCast: Failed to convert between const Any types");
453  return *result;
454 }
455 
464 template <typename ValueType>
466 {
467  ValueType* result = any_cast<ValueType>(&operand);
468  if (!result) throw BadAnyCastException("RefAnyCast: Failed to convert between Any types");
469  return *result;
470 }
471 
481 template <typename ValueType>
483 {
484  return &static_cast<Any::Holder<ValueType>*>(operand->_content)->_held;
485 }
486 
496 template <typename ValueType>
497 const ValueType* unsafe_any_cast(const Any* operand)
498 {
499  return any_cast<ValueType>(const_cast<Any*>(operand));
500 }
501 
502 
503 template<class K>
504 std::string any_value_to_string(const std::map<K, Any>& m)
505 {
506  std::stringstream ss;
507  ss << "{";
508  typedef typename std::map<K, Any>::const_iterator Iterator;
509  Iterator i1 = m.begin();
510  const Iterator begin = i1;
511  const Iterator end = m.end();
512  for ( ; i1 != end; ++i1)
513  {
514  if (i1 == begin) ss << i1->first << " : " << i1->second.ToString();
515  else ss << ", " << i1->first << " : " << i1->second.ToString();
516  }
517  ss << "}";
518  return ss.str();
519 }
520 
521 template<class K, class V>
522 std::string any_value_to_string(const std::map<K, V>& m)
523 {
524  std::stringstream ss;
525  ss << "{";
526  typedef typename std::map<K, V>::const_iterator Iterator;
527  Iterator i1 = m.begin();
528  const Iterator begin = i1;
529  const Iterator end = m.end();
530  for ( ; i1 != end; ++i1)
531  {
532  if (i1 == begin) ss << i1->first << " : " << i1->second;
533  else ss << ", " << i1->first << " : " << i1->second;
534  }
535  ss << "}";
536  return ss.str();
537 }
538 
539 template<class K>
540 std::string any_value_to_json(const std::map<K, Any>& m)
541 {
542  std::stringstream ss;
543  ss << "{";
544  typedef typename std::map<K, Any>::const_iterator Iterator;
545  Iterator i1 = m.begin();
546  const Iterator begin = i1;
547  const Iterator end = m.end();
548  for ( ; i1 != end; ++i1)
549  {
550  if (i1 == begin) ss << "\"" << i1->first << "\" : " << i1->second.ToJSON();
551  else ss << ", " << "\"" << i1->first << "\" : " << i1->second.ToJSON();
552  }
553  ss << "}";
554  return ss.str();
555 }
556 
557 template<class K, class V>
558 std::string any_value_to_json(const std::map<K, V>& m)
559 {
560  std::stringstream ss;
561  ss << "{";
562  typedef typename std::map<K, V>::const_iterator Iterator;
563  Iterator i1 = m.begin();
564  const Iterator begin = i1;
565  const Iterator end = m.end();
566  for ( ; i1 != end; ++i1)
567  {
568  if (i1 == begin) ss << "\"" << i1->first << "\" : " << i1->second;
569  else ss << ", " << "\"" << i1->first << "\" : " << i1->second;
570  }
571  ss << "}";
572  return ss.str();
573 }
574 
576 
577 #endif // US_ANY_H
Any & Swap(Any &rhs)
Definition: usAny.h:208
STL namespace.
Any(const Any &other)
Definition: usAny.h:194
bool Empty() const
Definition: usAny.h:246
std::string ToString() const
Definition: usAny.h:257
std::string container_to_json(Iterator i1, Iterator i2)
Definition: usAny.h:92
Any(const ValueType &value)
Definition: usAny.h:185
const char * what() const override
Definition: usAny.h:352
ValueType
Type of the value held by a Value object.
Definition: jsoncpp.h:345
#define US_Core_EXPORT
Definition: usCoreExport.h:21
const std::type_info & Type() const
Definition: usAny.h:278
std::string ToJSON() const
Definition: usAny.h:267
Any()
Definition: usAny.h:170
Definition: usAny.h:163
~BadAnyCastException() override
Definition: usAny.h:350
std::string any_value_to_json(const std::map< K, Any > &m)
Definition: usAny.h:540
std::string container_to_string(Iterator i1, Iterator i2)
Definition: usAny.h:74
ValueType & ref_any_cast(Any &operand)
Definition: usAny.h:465
const ValueType * unsafe_any_cast(const Any *operand)
Definition: usAny.h:497
static void swap(T &x, T &y)
Definition: svm.cpp:58
#define US_END_NAMESPACE
std::string any_value_to_string(const std::map< K, Any > &m)
Definition: usAny.h:504
#define US_BEGIN_NAMESPACE
ValueType any_cast(Any &operand)
Definition: usAny.h:433
BadAnyCastException(const std::string &msg="")
Definition: usAny.h:346
~Any()
Definition: usAny.h:198