00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef PEEKABOT_ANY_HH_INCLUDED
00012 #define PEEKABOT_ANY_HH_INCLUDED
00013
00014
00015 #include "Visibility.hh"
00016
00017 #include <algorithm>
00018 #include <typeinfo>
00019
00020
00021 namespace peekabot
00022 {
00023 namespace serialization
00024 {
00025 class SerializationInterface;
00026 class DeserializationInterface;
00027 }
00028
00057 class Any
00058 {
00059 template<typename ValueType> friend const ValueType &any_cast(const Any &);
00060 template<typename ValueType> friend ValueType &any_cast(Any &);
00061
00062 friend serialization::SerializationInterface &operator<<(
00063 serialization::SerializationInterface &, const Any &);
00064 friend serialization::DeserializationInterface &operator>>(
00065 serialization::DeserializationInterface &, Any &);
00066
00067 template<typename> friend void register_any_type(boost::uint16_t id);
00068
00069 struct PEEKABOT_API HolderBase
00070 {
00071 virtual HolderBase *clone() = 0;
00072 };
00073
00074 template<typename ValueType>
00075 struct PEEKABOT_API Holder : public HolderBase
00076 {
00077 Holder() {}
00078
00079 Holder(const ValueType &value) : m_held(value) {}
00080
00081 virtual HolderBase *clone()
00082 {
00083 return new Holder<ValueType>(m_held);
00084 }
00085
00086 ValueType m_held;
00087
00088 void save(serialization::SerializationInterface &ar) const
00089 {
00090 ar << m_held;
00091 }
00092
00093 void load(serialization::DeserializationInterface &ar)
00094 {
00095 ar >> m_held;
00096 }
00097 };
00098
00099 public:
00100 Any() : m_content(0) {}
00101
00102 template<typename ValueType>
00103 Any(const ValueType &value)
00104 : m_content(new Holder<ValueType>(value)) {}
00105
00106 Any(const Any &other)
00107 : m_content(other.m_content ? other.m_content->clone() : 0) {}
00108
00109 ~Any()
00110 {
00111 if( m_content )
00112 delete m_content;
00113 }
00114
00115 inline bool empty() const
00116 {
00117 return !m_content;
00118 }
00119
00120 inline Any &swap(Any &rhs)
00121 {
00122 std::swap(m_content, rhs.m_content);
00123 return *this;
00124 }
00125
00126 template<typename ValueType> Any &operator=(const ValueType &rhs)
00127 {
00128 Any(rhs).swap(*this);
00129 return *this;
00130 }
00131
00132 Any &operator=(const Any &rhs)
00133 {
00134 Any(rhs).swap(*this);
00135 return *this;
00136 }
00137
00138 private:
00139 HolderBase *m_content;
00140 };
00141
00142 struct PEEKABOT_API BadAnyCast : public std::bad_cast
00143 {
00144 virtual const char *what() const throw()
00145 {
00146 return "Bad any_cast";
00147 }
00148 };
00149
00156 template<typename ValueType> const ValueType &any_cast(const Any &x)
00157 {
00158 const Any::Holder<ValueType> *tmp =
00159 dynamic_cast<const Any::Holder<ValueType> *>(x.m_content);
00160 if( tmp )
00161 return tmp->m_held;
00162 else
00163 throw BadAnyCast();
00164 }
00165
00172 template<typename ValueType> ValueType &any_cast(Any &x)
00173 {
00174 Any::Holder<ValueType> *tmp =
00175 dynamic_cast<Any::Holder<ValueType> *>(x.m_content);
00176 if( tmp )
00177 return tmp->m_held;
00178 else
00179 throw BadAnyCast();
00180 }
00181 }
00182
00183
00184 #endif // PEEKABOT_ANY_HH_INCLUDED