00001
00014 #ifndef ANY_H
00015 #define ANY_H
00016
00017 #include <argos3/core/utility/configuration/argos_exception.h>
00018
00019 #include <cxxabi.h>
00020 #include <typeinfo>
00021 #include <algorithm>
00022
00023 namespace argos {
00024
00025 class CAny {
00026
00027 public:
00028
00032 CAny() :
00033 m_pcRef(NULL) {}
00034
00038 template<typename T>
00039 CAny(const T& t_object) :
00040 m_pcRef(new CReference<T>(t_object)) {}
00041
00046 CAny(const CAny& c_any) :
00047 m_pcRef(c_any.m_pcRef ? c_any.m_pcRef->Clone() : NULL) {}
00048
00052 ~CAny() {
00053 if(m_pcRef != NULL)
00054 delete m_pcRef;
00055 }
00056
00060 CAny& swap(CAny& c_any) {
00061 std::swap(m_pcRef, c_any.m_pcRef);
00062 return *this;
00063 }
00064
00068 template <typename T>
00069 CAny& operator=(const T& t_object) {
00070 CAny(t_object).swap(*this);
00071 return *this;
00072 }
00073
00077 CAny& operator=(const CAny& c_any) {
00078 CAny(c_any).swap(*this);
00079 return *this;
00080 }
00081
00082 public:
00083
00087 class CAbstractReference {
00088 public:
00092 virtual ~CAbstractReference() {}
00096 virtual const std::type_info& GetType() const = 0;
00100 virtual CAbstractReference* Clone() const = 0;
00101 };
00102
00106 template<typename T>
00107 class CReference : public CAbstractReference {
00108 public:
00109 CReference(const T& t_object) : m_tObject(t_object) {}
00113 virtual ~CReference() {}
00117 virtual const std::type_info& GetType() const {
00118 return typeid(T);
00119 }
00123 virtual CAbstractReference* Clone() const {
00124 return new CReference<T>(m_tObject);
00125 }
00126 public:
00127
00131 T m_tObject;
00132 };
00133
00134 public:
00135
00139 CAbstractReference* m_pcRef;
00140
00141 };
00142
00147 template<typename T>
00148 T* any_cast(CAny* pc_any) {
00149
00150 if(pc_any == NULL)
00151 return NULL;
00152
00153 if(pc_any->m_pcRef->GetType() == typeid(T))
00154
00155 return &(static_cast<CAny::CReference<T>*>(pc_any->m_pcRef))->m_tObject;
00156 else
00157
00158 return NULL;
00159 }
00160
00165 template<typename T>
00166 const T* any_cast(const CAny* pc_any) {
00167
00168 if(pc_any == NULL)
00169 return NULL;
00170
00171 if(pc_any->m_pcRef->GetType() == typeid(T))
00172
00173 return &(static_cast<CAny::CReference<T>*>(pc_any->m_pcRef))->m_tObject;
00174 else
00175
00176 return NULL;
00177 }
00178
00183 template<typename T>
00184 const T& any_cast(const CAny& c_any) {
00185
00186 const T* ptResult = any_cast<T>(&c_any);
00187
00188 if(ptResult != NULL)
00189 return *ptResult;
00190 else {
00191 char* pchDemangledOperandType = abi::__cxa_demangle(c_any.m_pcRef->GetType().name(), NULL, NULL, NULL);
00192 char* pchDemangledTargetType = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, NULL);
00193 THROW_ARGOSEXCEPTION("Failed any_cast conversion from " <<
00194 pchDemangledOperandType <<
00195 " to " <<
00196 pchDemangledTargetType);
00197 }
00198 }
00199
00204 template<typename T>
00205 T& any_cast(CAny& c_any) {
00206
00207 T* ptResult = any_cast<T>(&c_any);
00208
00209 if(ptResult != NULL)
00210 return *ptResult;
00211 else {
00212 char* pchDemangledOperandType = abi::__cxa_demangle(c_any.m_pcRef->GetType().name(), NULL, NULL, NULL);
00213 char* pchDemangledTargetType = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, NULL);
00214 THROW_ARGOSEXCEPTION("Failed any_cast conversion from " <<
00215 pchDemangledOperandType <<
00216 " to " <<
00217 pchDemangledTargetType);
00218 }
00219 }
00220
00221 }
00222
00223 #endif