any.h
Go to the documentation of this file.
1 
14 #ifndef ANY_H
15 #define ANY_H
16 
17 #include <argos3/core/utility/configuration/argos_exception.h>
18 
19 #include <cxxabi.h>
20 #include <typeinfo>
21 #include <algorithm>
22 
23 namespace argos {
24 
25  class CAny {
26 
27  public:
28 
32  CAny() :
33  m_pcRef(NULL) {}
34 
38  template<typename T>
39  CAny(const T& t_object) :
40  m_pcRef(new CReference<T>(t_object)) {}
41 
46  CAny(const CAny& c_any) :
47  m_pcRef(c_any.m_pcRef ? c_any.m_pcRef->Clone() : NULL) {}
48 
52  ~CAny() {
53  if(m_pcRef != NULL)
54  delete m_pcRef;
55  }
56 
60  CAny& swap(CAny& c_any) {
61  std::swap(m_pcRef, c_any.m_pcRef);
62  return *this;
63  }
64 
68  template <typename T>
69  CAny& operator=(const T& t_object) {
70  CAny(t_object).swap(*this);
71  return *this;
72  }
73 
77  CAny& operator=(const CAny& c_any) {
78  CAny(c_any).swap(*this);
79  return *this;
80  }
81 
82  public:
83 
88  public:
92  virtual ~CAbstractReference() {}
96  virtual const std::type_info& GetType() const = 0;
100  virtual CAbstractReference* Clone() const = 0;
101  };
102 
106  template<typename T>
108  public:
109  CReference(const T& t_object) : m_tObject(t_object) {}
113  virtual ~CReference() {}
117  virtual const std::type_info& GetType() const {
118  return typeid(T);
119  }
123  virtual CAbstractReference* Clone() const {
124  return new CReference<T>(m_tObject);
125  }
126  public:
127 
132  };
133 
134  public:
135 
140 
141  };
142 
147  template<typename T>
148  T* any_cast(CAny* pc_any) {
149  /* NULL pointer passed? */
150  if(pc_any == NULL)
151  return NULL;
152  /* OK, Non-NULL pointer; do types match? */
153  if(pc_any->m_pcRef->GetType() == typeid(T))
154  /* Types match -> return cast object */
155  return &(static_cast<CAny::CReference<T>*>(pc_any->m_pcRef))->m_tObject;
156  else
157  /* Types don't match -> return NULL */
158  return NULL;
159  }
160 
165  template<typename T>
166  const T* any_cast(const CAny* pc_any) {
167  /* NULL pointer passed? */
168  if(pc_any == NULL)
169  return NULL;
170  /* OK, Non-NULL pointer; do types match? */
171  if(pc_any->m_pcRef->GetType() == typeid(T))
172  /* Types match -> return cast object */
173  return &(static_cast<CAny::CReference<T>*>(pc_any->m_pcRef))->m_tObject;
174  else
175  /* Types don't match -> return NULL */
176  return NULL;
177  }
178 
183  template<typename T>
184  const T& any_cast(const CAny& c_any) {
185  /* Fall back to using pass-by-pointer version */
186  const T* ptResult = any_cast<T>(&c_any);
187  /* Did the cast succeed? */
188  if(ptResult != NULL)
189  return *ptResult;
190  else {
191  char* pchDemangledOperandType = abi::__cxa_demangle(c_any.m_pcRef->GetType().name(), NULL, NULL, NULL);
192  char* pchDemangledTargetType = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, NULL);
193  THROW_ARGOSEXCEPTION("Failed any_cast conversion from " <<
194  pchDemangledOperandType <<
195  " to " <<
196  pchDemangledTargetType);
197  }
198  }
199 
204  template<typename T>
205  T& any_cast(CAny& c_any) {
206  /* Fall back to using pass-by-pointer version */
207  T* ptResult = any_cast<T>(&c_any);
208  /* Did the cast succeed? */
209  if(ptResult != NULL)
210  return *ptResult;
211  else {
212  char* pchDemangledOperandType = abi::__cxa_demangle(c_any.m_pcRef->GetType().name(), NULL, NULL, NULL);
213  char* pchDemangledTargetType = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, NULL);
214  THROW_ARGOSEXCEPTION("Failed any_cast conversion from " <<
215  pchDemangledOperandType <<
216  " to " <<
217  pchDemangledTargetType);
218  }
219  }
220 
221 }
222 
223 #endif
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
T * any_cast(CAny *pc_any)
Performs a cast on the any type to the desired type, when the any type is passed by non-const pointer...
Definition: any.h:148
CAny & swap(CAny &c_any)
Redefinition of the swap function of the std library.
Definition: any.h:60
CAny(const T &t_object)
Constructor with templetized argument.
Definition: any.h:39
CAbstractReference * m_pcRef
Pointer to object reference.
Definition: any.h:139
CAny & operator=(const CAny &c_any)
Assignment operator when any type is operand.
Definition: any.h:77
CAny(const CAny &c_any)
Copy constructor Clone the reference to the object, if the reference is not NULL.
Definition: any.h:46
CAny()
Constructor.
Definition: any.h:32
~CAny()
Destructor.
Definition: any.h:52
CAny & operator=(const T &t_object)
Assignment operator when object is operand.
Definition: any.h:69
Abstract reference to object.
Definition: any.h:87
virtual ~CAbstractReference()
Destructor.
Definition: any.h:92
virtual CAbstractReference * Clone() const =0
Clone the reference.
virtual const std::type_info & GetType() const =0
Returns the type info on the referenced object.
Actual templetized reference to object.
Definition: any.h:107
virtual CAbstractReference * Clone() const
Clone the reference.
Definition: any.h:123
virtual const std::type_info & GetType() const
Definition: any.h:117
virtual ~CReference()
Destructor.
Definition: any.h:113
CReference(const T &t_object)
Definition: any.h:109
T m_tObject
Actual referenced object.
Definition: any.h:131