Medical Imaging Interaction Toolkit  2026.06.00
Medical Imaging Interaction Toolkit
usAny.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef US_ANY_H
14 #define US_ANY_H
15 
16 #include <algorithm>
17 #include <typeinfo>
18 #include <sstream>
19 #include <vector>
20 #include <list>
21 #include <set>
22 #include <map>
23 
24 #include <usGlobalConfig.h>
26 
27 namespace us {
28 
29 class Any;
30 
32 
34 MITKCPPMICROSERVICES_EXPORT std::string any_value_to_json(const std::string& val);
36 
37 template<class T>
38 std::string any_value_to_string(const T& val)
39 {
40  std::stringstream ss;
41  ss << val;
42  return ss.str();
43 }
44 
45 template<class T>
46 std::string any_value_to_json(const T& val)
47 {
48  return any_value_to_string(val);
49 }
50 
54 template<typename Iterator>
55 std::string container_to_string(Iterator i1, Iterator i2)
56 {
57  std::stringstream ss;
58  ss << "[";
59  const Iterator begin = i1;
60  for ( ; i1 != i2; ++i1)
61  {
62  if (i1 == begin) ss << any_value_to_string(*i1);
63  else ss << "," << any_value_to_string(*i1);
64  }
65  ss << "]";
66  return ss.str();
67 }
68 
72 template<typename Iterator>
73 std::string container_to_json(Iterator i1, Iterator i2)
74 {
75  std::stringstream ss;
76  ss << "[";
77  const Iterator begin = i1;
78  for ( ; i1 != i2; ++i1)
79  {
80  if (i1 == begin) ss << any_value_to_json(*i1);
81  else ss << "," << any_value_to_json(*i1);
82  }
83  ss << "]";
84  return ss.str();
85 }
86 
87 template<class E>
88 std::string any_value_to_string(const std::vector<E>& vec)
89 {
90  return container_to_string(vec.begin(), vec.end());
91 }
92 
93 template<class E>
94 std::string any_value_to_json(const std::vector<E>& vec)
95 {
96  return container_to_json(vec.begin(), vec.end());
97 }
98 
99 template<class E>
100 std::string any_value_to_string(const std::list<E>& l)
101 {
102  return container_to_string(l.begin(), l.end());
103 }
104 
105 template<class E>
106 std::string any_value_to_json(const std::list<E>& l)
107 {
108  return container_to_json(l.begin(), l.end());
109 }
110 
111 template<class E>
112 std::string any_value_to_string(const std::set<E>& s)
113 {
114  return container_to_string(s.begin(), s.end());
115 }
116 
117 template<class E>
118 std::string any_value_to_json(const std::set<E>& s)
119 {
120  return container_to_json(s.begin(), s.end());
121 }
122 
123 template<class M>
124 std::string any_value_to_string(const std::map<M, Any>& m);
125 
126 template<class K, class V>
127 std::string any_value_to_string(const std::map<K, V>& m);
128 
129 template<class M>
130 std::string any_value_to_json(const std::map<M, Any>& m);
131 
132 template<class K, class V>
133 std::string any_value_to_json(const std::map<K, V>& m);
134 
135 
144 class Any
145 {
146 public:
147 
151  Any(): _content(nullptr)
152  { }
153 
165  template <typename ValueType>
166  Any(const ValueType& value)
167  : _content(new Holder<ValueType>(value))
168  { }
169 
175  Any(const Any& other)
176  : _content(other._content ? other._content->Clone() : nullptr)
177  { }
178 
180  {
181  delete _content;
182  }
183 
189  Any& Swap(Any& rhs)
190  {
191  std::swap(_content, rhs._content);
192  return *this;
193  }
194 
206  template <typename ValueType>
207  Any& operator = (const ValueType& rhs)
208  {
209  Any(rhs).Swap(*this);
210  return *this;
211  }
212 
218  Any& operator = (const Any& rhs)
219  {
220  Any(rhs).Swap(*this);
221  return *this;
222  }
223 
227  bool Empty() const
228  {
229  return !_content;
230  }
231 
239  std::string ToString() const
240  {
241  return Empty() ? std::string() : _content->ToString();
242  }
243 
249  std::string ToJSON() const
250  {
251  return Empty() ? "null" : _content->ToJSON();
252  }
253 
260  const std::type_info& Type() const
261  {
262  return _content ? _content->Type() : typeid(void);
263  }
264 
265 private:
266 
267  class Placeholder
268  {
269  public:
270  virtual ~Placeholder()
271  { }
272 
273  virtual std::string ToString() const = 0;
274  virtual std::string ToJSON() const = 0;
275 
276  virtual const std::type_info& Type() const = 0;
277  virtual Placeholder* Clone() const = 0;
278  };
279 
280  template <typename ValueType>
281  class Holder: public Placeholder
282  {
283  public:
284  Holder(const ValueType& value)
285  : _held(value)
286  { }
287 
288  std::string ToString() const override
289  {
290  return any_value_to_string(_held);
291  }
292 
293  std::string ToJSON() const override
294  {
295  return any_value_to_json(_held);
296  }
297 
298  const std::type_info& Type() const override
299  {
300  return typeid(ValueType);
301  }
302 
303  Placeholder* Clone() const override
304  {
305  return new Holder(_held);
306  }
307 
308  ValueType _held;
309 
310  private: // intentionally left unimplemented
311  Holder& operator=(const Holder &);
312  };
313 
314 private:
315  template <typename ValueType>
316  friend ValueType* any_cast(Any*);
317 
318  template <typename ValueType>
319  friend ValueType* unsafe_any_cast(Any*);
320 
321  Placeholder* _content;
322 };
323 
332 class BadAnyCastException : public std::bad_cast
333 {
334 public:
335 
336  BadAnyCastException(const std::string& msg = "")
337  : std::bad_cast(), _msg(msg)
338  {}
339 
340  ~BadAnyCastException() throw() override {}
341 
342  const char * what() const throw() override
343  {
344  if (_msg.empty())
345  return "us::BadAnyCastException: "
346  "failed conversion using us::any_cast";
347  else
348  return _msg.c_str();
349  }
350 
351 private:
352 
353  std::string _msg;
354 };
355 
366 template <typename ValueType>
367 ValueType* any_cast(Any* operand)
368 {
369  return operand && operand->Type() == typeid(ValueType)
370  ? &static_cast<Any::Holder<ValueType>*>(operand->_content)->_held
371  : nullptr;
372 }
373 
384 template <typename ValueType>
385 const ValueType* any_cast(const Any* operand)
386 {
387  return any_cast<ValueType>(const_cast<Any*>(operand));
388 }
389 
402 template <typename ValueType>
403 ValueType any_cast(const Any& operand)
404 {
405  ValueType* result = any_cast<ValueType>(const_cast<Any*>(&operand));
406  if (!result) throw BadAnyCastException("Failed to convert between const Any types");
407  return *result;
408 }
409 
422 template <typename ValueType>
423 ValueType any_cast(Any& operand)
424 {
425  ValueType* result = any_cast<ValueType>(&operand);
426  if (!result) throw BadAnyCastException("Failed to convert between Any types");
427  return *result;
428 }
429 
438 template <typename ValueType>
439 const ValueType& ref_any_cast(const Any & operand)
440 {
441  ValueType* result = any_cast<ValueType>(const_cast<Any*>(&operand));
442  if (!result) throw BadAnyCastException("RefAnyCast: Failed to convert between const Any types");
443  return *result;
444 }
445 
454 template <typename ValueType>
455 ValueType& ref_any_cast(Any& operand)
456 {
457  ValueType* result = any_cast<ValueType>(&operand);
458  if (!result) throw BadAnyCastException("RefAnyCast: Failed to convert between Any types");
459  return *result;
460 }
461 
471 template <typename ValueType>
472 ValueType* unsafe_any_cast(Any* operand)
473 {
474  return &static_cast<Any::Holder<ValueType>*>(operand->_content)->_held;
475 }
476 
486 template <typename ValueType>
487 const ValueType* unsafe_any_cast(const Any* operand)
488 {
489  return any_cast<ValueType>(const_cast<Any*>(operand));
490 }
491 
492 
493 template<class K>
494 std::string any_value_to_string(const std::map<K, Any>& m)
495 {
496  std::stringstream ss;
497  ss << "{";
498  typedef typename std::map<K, Any>::const_iterator Iterator;
499  Iterator i1 = m.begin();
500  const Iterator begin = i1;
501  const Iterator end = m.end();
502  for ( ; i1 != end; ++i1)
503  {
504  if (i1 == begin) ss << i1->first << " : " << i1->second.ToString();
505  else ss << ", " << i1->first << " : " << i1->second.ToString();
506  }
507  ss << "}";
508  return ss.str();
509 }
510 
511 template<class K, class V>
512 std::string any_value_to_string(const std::map<K, V>& m)
513 {
514  std::stringstream ss;
515  ss << "{";
516  typedef typename std::map<K, V>::const_iterator Iterator;
517  Iterator i1 = m.begin();
518  const Iterator begin = i1;
519  const Iterator end = m.end();
520  for ( ; i1 != end; ++i1)
521  {
522  if (i1 == begin) ss << i1->first << " : " << i1->second;
523  else ss << ", " << i1->first << " : " << i1->second;
524  }
525  ss << "}";
526  return ss.str();
527 }
528 
529 template<class K>
530 std::string any_value_to_json(const std::map<K, Any>& m)
531 {
532  std::stringstream ss;
533  ss << "{";
534  typedef typename std::map<K, Any>::const_iterator Iterator;
535  Iterator i1 = m.begin();
536  const Iterator begin = i1;
537  const Iterator end = m.end();
538  for ( ; i1 != end; ++i1)
539  {
540  if (i1 == begin) ss << "\"" << i1->first << "\" : " << i1->second.ToJSON();
541  else ss << ", " << "\"" << i1->first << "\" : " << i1->second.ToJSON();
542  }
543  ss << "}";
544  return ss.str();
545 }
546 
547 template<class K, class V>
548 std::string any_value_to_json(const std::map<K, V>& m)
549 {
550  std::stringstream ss;
551  ss << "{";
552  typedef typename std::map<K, V>::const_iterator Iterator;
553  Iterator i1 = m.begin();
554  const Iterator begin = i1;
555  const Iterator end = m.end();
556  for ( ; i1 != end; ++i1)
557  {
558  if (i1 == begin) ss << "\"" << i1->first << "\" : " << i1->second;
559  else ss << ", " << "\"" << i1->first << "\" : " << i1->second;
560  }
561  ss << "}";
562  return ss.str();
563 }
564 
565 }
566 
567 #endif // US_ANY_H
#define MITKCPPMICROSERVICES_EXPORT
An Any class represents a general type and is capable of storing any type, supporting type-safe extra...
Definition: usAny.h:145
Any & Swap(Any &rhs)
Swaps the content of the two Anys.
Definition: usAny.h:189
Any & operator=(const ValueType &rhs)
Assignment operator for all types != Any.
Definition: usAny.h:207
friend ValueType * unsafe_any_cast(Any *)
Definition: usAny.h:472
bool Empty() const
Returns true if the Any is empty.
Definition: usAny.h:227
Any(const Any &other)
Copy constructor, works with empty Anys and initialized Any values.
Definition: usAny.h:175
Any(const ValueType &value)
Creates an Any which stores the init parameter inside.
Definition: usAny.h:166
std::string ToJSON() const
Returns a JSON representation for the content.
Definition: usAny.h:249
const std::type_info & Type() const
Returns the type information of the stored content. If the Any is empty typeid(void) is returned....
Definition: usAny.h:260
std::string ToString() const
Returns a string representation for the content. If this Any is empty, returns an empty string.
Definition: usAny.h:239
Any()
Creates an empty any type.
Definition: usAny.h:151
friend ValueType * any_cast(Any *)
any_cast operator used to extract the ValueType from an Any*. Will return a pointer to the stored val...
Definition: usAny.h:367
~Any()
Definition: usAny.h:179
Exception thrown when an any_cast fails due to a type mismatch.
Definition: usAny.h:333
const char * what() const override
Definition: usAny.h:342
BadAnyCastException(const std::string &msg="")
Definition: usAny.h:336
~BadAnyCastException() override
Definition: usAny.h:340
void swap(CustomMimeType &l, CustomMimeType &r)
Swap two CustomMimeType objects.
std::string container_to_json(Iterator i1, Iterator i2)
Definition: usAny.h:73
std::string container_to_string(Iterator i1, Iterator i2)
Definition: usAny.h:55
ValueType * any_cast(Any *operand)
any_cast operator used to extract the ValueType from an Any*. Will return a pointer to the stored val...
Definition: usAny.h:367
MITKCPPMICROSERVICES_EXPORT std::string any_value_to_json(const Any &val)
ValueType * unsafe_any_cast(Any *operand)
Definition: usAny.h:472
MITKCPPMICROSERVICES_EXPORT std::string any_value_to_string(const Any &any)
const ValueType & ref_any_cast(const Any &operand)
ref_any_cast operator used to return a const reference to the internal data.
Definition: usAny.h:439