• Main Page
  • Related Pages
  • Classes
  • Files
  • File List

src/Any.hh

00001 /*
00002  * Copyright Staffan Gimåker 2009.
00003  *
00004  * ---
00005  *
00006  * Distributed under the Boost Software License, Version 1.0.
00007  * (See accompanying file LICENSE_1_0.txt or copy at
00008  * http://www.boost.org/LICENSE_1_0.txt)
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

Generated on Sun Jan 30 2011 for peekabot by  doxygen 1.7.1