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_ANNOUNCE_HPP
00031 #define ACEDIA_ANNOUNCE_HPP
00032
00033 #include <boost/cstdint.hpp>
00034 #include <boost/preprocessor/control/if.hpp>
00035 #include <boost/preprocessor/cat.hpp>
00036 #include <boost/preprocessor/arithmetic/sub.hpp>
00037 #include <boost/preprocessor/seq.hpp>
00038 #include <boost/preprocessor/punctuation/paren.hpp>
00039
00040 #include "unit.hpp"
00041 #include "metaclass.hpp"
00042 #include "exceptions.hpp"
00043 #include "acedia_string.hpp"
00044 #include "metaclassimpl.hpp"
00045 #include "anyvalimpl.hpp"
00046 #include "acedia_util.hpp"
00047 #include "acedia_stringlist.hpp"
00048
00049 #define ACEDIA_ANY_VAL_CASE_CLASS_IMPL(class_name) \
00050 namespace acedia { namespace details { \
00051 template<> \
00052 struct AnyValImpl< class_name > : public AnyVal \
00053 { \
00054 virtual MetaClass* metaClass() const \
00055 { \
00056 return MetaClassImpl< class_name >::instance(); \
00057 } \
00058 virtual void* value() const \
00059 { \
00060 return (void*) &( class_name ::instance()); \
00061 } \
00062 virtual AnyVal* copy() const \
00063 { \
00064 return new AnyValImpl; \
00065 } \
00066 virtual bool equals(const AnyVal *other) const \
00067 { \
00068 if (!other) return false; \
00069 return metaClass() == other->metaClass(); \
00070 } \
00071 virtual void serialize(boost::archive::text_oarchive& ar) const \
00072 { \
00073 ar << metaClass()->name(); \
00074 } \
00075 static String getInstanceName() \
00076 { \
00077 String s = acedia::util::eraseWhitespaces( #class_name ); \
00078 s += "()"; \
00079 } \
00080 virtual String toString() const \
00081 { \
00082 static String s = getInstanceName(); \
00083 return s; \
00084 } \
00085 }; \
00086 } }
00087
00088 #define ACEDIA_ANNOUNCE_CLASS_IMPL(class_name, tuple_len) \
00089 namespace acedia { namespace details { \
00090 template<> \
00091 class MetaClassImpl< class_name > : public MetaClass { \
00092 MetaClassImpl() { } \
00093 static int zero; \
00094 public: \
00095 const String& name() const { \
00096 static String n = util::eraseWhitespaces( #class_name ); \
00097 return n; \
00098 } \
00099 AnyVal* deserialize(boost::archive::text_iarchive &ar) const { \
00100 AnyValImpl< class_name >* val = \
00101 new AnyValImpl< class_name >(); \
00102 ar >> val->v; \
00103 return val; \
00104 } \
00105 static MetaClassImpl* instance() { \
00106 static MetaClassImpl* lw = new MetaClassImpl; \
00107 return lw; \
00108 } \
00109 virtual bool isCaseTuple() const { return tuple_len > 0 ; } \
00110 virtual unsigned int tupleLenght() const { return tuple_len; } \
00111 }; } }
00112
00113 #ifdef ACEDIA_REDUCED_ANNOUNCE
00114 # define ACEDIA_ANNOUNCE_IMPL(class_name_seq, tuple_len) \
00115 ACEDIA_EVAL2(ACEDIA_ANNOUNCE_CLASS_IMPL, ACEDIA_REDUCE_SEQ(ACEDIA_PUSH_DDOTS,class_name_seq), tuple_len)
00116 #else
00117 # define ACEDIA_ANNOUNCE_IMPL(class_name_seq, tuple_len) \
00118 ACEDIA_EVAL2(ACEDIA_ANNOUNCE_CLASS_IMPL, ACEDIA_REDUCE_SEQ(ACEDIA_PUSH_DDOTS,class_name_seq), tuple_len) \
00119 static const boost::int8_t BOOST_PP_CAT(acedia_ignored_value,ACEDIA_REDUCE_SEQ(ACEDIA_DLINES_IMPLODE,class_name_seq)) = \
00120 (boost::int8_t) registerMetaClass BOOST_PP_LPAREN() acedia::details::MetaClassImpl< ACEDIA_REDUCE_SEQ(ACEDIA_PUSH_DDOTS,class_name_seq) >::instance() BOOST_PP_RPAREN();
00121 #endif
00122
00138 #define ACEDIA_ANNOUNCE(class_name_seq) ACEDIA_ANNOUNCE_IMPL(class_name_seq, 0)
00139
00155 #define ACEDIA_DECLARE_CASE_CLASS(seq) \
00156 ACEDIA_OPEN_NAMESPACES_BY(seq) \
00157 struct ACEDIA_SEQ_LAST(seq) { \
00158 inline operator acedia::Any() const { return acedia::Any::from(*this); } \
00159 inline bool operator==(const \
00160 ACEDIA_SEQ_LAST(seq) &) const { return true; } \
00161 void serialize(boost::archive::text_oarchive&, \
00162 const unsigned int) const { } \
00163 void serialize(boost::archive::text_iarchive&, \
00164 const unsigned int) { } \
00165 }; ACEDIA_CLOSE_NAMESPACES(BOOST_PP_SEQ_POP_BACK(seq)) \
00166 namespace acedia { namespace util { \
00167 template<> struct IsCaseClass< \
00168 ACEDIA_REDUCE_SEQ(ACEDIA_PUSH_DDOTS,seq) \
00169 > { enum { VALUE = 1 }; }; \
00170 } } \
00171 ACEDIA_ANNOUNCE( seq )
00172
00173 ACEDIA_ANNOUNCE((bool))
00174 ACEDIA_ANNOUNCE((boost)(int8_t))
00175 ACEDIA_ANNOUNCE((boost)(uint8_t))
00176 ACEDIA_ANNOUNCE((boost)(int16_t))
00177 ACEDIA_ANNOUNCE((boost)(uint16_t))
00178 ACEDIA_ANNOUNCE((boost)(int32_t))
00179 ACEDIA_ANNOUNCE((boost)(uint32_t))
00180 ACEDIA_ANNOUNCE((boost)(int64_t))
00181 ACEDIA_ANNOUNCE((boost)(uint64_t))
00182 ACEDIA_ANNOUNCE((float))
00183 ACEDIA_ANNOUNCE((double))
00184 ACEDIA_ANNOUNCE((acedia)(String))
00185 ACEDIA_ANNOUNCE((acedia)(StringList))
00186
00187 #endif