00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef ACEDIA_ANY_HPP
00031 #define ACEDIA_ANY_HPP
00032
00033 #include <boost/cstdint.hpp>
00034
00035 #include "unit.hpp"
00036 #include "metaclass.hpp"
00037 #include "exceptions.hpp"
00038 #include "acedia_string.hpp"
00039 #include "metaclassimpl.hpp"
00040 #include "anyvalimpl.hpp"
00041 #include "acedia_util.hpp"
00042 #include "acedia_stringlist.hpp"
00043 #include "announce.hpp"
00044
00045 namespace acedia
00046 {
00047 namespace details
00048 {
00049
00050 template<>
00051 class MetaClassImpl<void> : public MetaClass
00052 {
00053 MetaClassImpl() { }
00054 public:
00055 const String &name() const { static String n = "void"; return n; }
00056 AnyVal *deserialize(boost::archive::text_iarchive&) const
00057 {
00058
00059 return NULL;
00060 }
00061 static MetaClassImpl* instance()
00062 {
00063 static MetaClassImpl *lw = new MetaClassImpl();
00064 return lw;
00065 }
00066 };
00067 }
00068
00069 namespace details
00070 {
00071 template<>
00072 class MetaClassImpl<Unit> : public MetaClass
00073 {
00074 MetaClassImpl() { }
00075
00076 public:
00077
00078 const String &name() const
00079 {
00080 static String n = "Unit";
00081 return n;
00082 }
00083 AnyVal *deserialize(boost::archive::text_iarchive&) const
00084 {
00085 return new AnyValImpl<Unit>();
00086 }
00087 static MetaClass* instance()
00088 {
00089 static MetaClassImpl *lw = new MetaClassImpl;
00090 return lw;
00091 }
00092 virtual bool isCaseTuple() const { return false; }
00093 };
00094 }
00095
00122 class Any
00123 {
00124 friend class AnyArray;
00125 friend class Message;
00126
00127 details::AnyVal *val;
00128
00129 template<typename T>
00130 T *get_value_as() const
00131 {
00132 if (util::IsUnit<T>::VALUE)
00133 {
00134
00135 return reinterpret_cast<T *>(&(Unit::instance()));
00136 }
00137 else if (!val) ACEDIA_THROW(NullPointerException, "isNull() == true");
00138 else if (!instanceOf<T>())
00139 {
00140 throw ClassCastException(ACEDIA_FILE_AND_LINE(),
00141 details::MetaClassImpl<T>::instance(),
00142 val->metaClass());
00143 }
00144 else return reinterpret_cast<T*>(val->value());
00145 }
00146
00147 public:
00148
00149
00150 template<typename T>
00151 inline const T &uncheckedValue() const
00152 {
00153 if (util::IsUnit<T>::VALUE)
00154 {
00155 return reinterpret_cast<const T &>(Unit::instance());
00156 }
00157 return *(reinterpret_cast<T*>(val->value()));
00158 }
00159
00160
00161
00162
00163
00164 Any(details::AnyVal *value);
00165
00170 inline bool valid() throw() { return NULL != val; }
00171
00175 Any();
00176
00180 Any(bool);
00181
00185 Any(boost::int8_t);
00186
00190 Any(boost::uint8_t);
00191
00195 Any(boost::int16_t);
00196
00200 Any(boost::uint16_t);
00201
00205 Any(boost::int32_t);
00206
00210 Any(boost::uint32_t);
00211
00215 Any(boost::int64_t);
00216
00220 Any(boost::uint64_t);
00221
00225 Any(float);
00226
00230 Any(double);
00231
00235 Any(const char *cstr);
00236
00240 Any(const String &str);
00241
00245 Any(const StringList &strList);
00246
00251 Any(const Any &other);
00252
00256 ~Any();
00257
00262 Any &operator=(const Any &other);
00263
00267 template<typename T>
00268 void setValue(const T &t)
00269 {
00270 if (val) delete val;
00271 val = new details::AnyValImpl<T>(t);
00272 }
00273
00284 template<typename T>
00285 bool instanceOf() const throw()
00286 {
00287
00288 if (!val) return false;
00289 return details::MetaClassImpl<T>::instance() == val->metaClass();
00290 }
00291
00292 inline bool instanceOf(MetaClass* mc) const throw()
00293 {
00294 return NULL == val ? false : val->metaClass() == mc;
00295 }
00296
00303 template<typename T>
00304 inline const T &value() const
00305 {
00306 return *get_value_as<T>();
00307 }
00308
00315 template<typename T>
00316 T &value()
00317 {
00318 return *get_value_as<T>();
00319 }
00320
00321 void serialize(boost::archive::text_oarchive &ar, const unsigned int unused);
00322 void serialize(boost::archive::text_iarchive &ar, const unsigned int unused);
00323
00332 MetaClass *metaClass() const;
00333
00338 inline const String &typeName() const { return metaClass()->name(); }
00339
00346 template<typename T>
00347 inline static Any from(const T &val)
00348 {
00349 Any v;
00350 v.setValue(val);
00351 return v;
00352 }
00353
00363 String toString(bool verbose = false) const;
00364
00369 bool operator==(const Any &other) const;
00370
00371 inline bool operator!=(const Any &other) const
00372 {
00373 return !((*this) == other);
00374 }
00375
00376 };
00377
00378 }
00379
00380 #endif