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