Bytemaster's Boost Libraries
/Users/dlarimer/dev/libs/dynamic_any/include/boost/any_ref.hpp
00001 #ifndef _BOOST_ANY_REF_HPP_
00002 #define _BOOST_ANY_REF_HPP_
00003 #include <typeinfo>
00004 #include <new>
00005 #include <string.h>
00006 #include <boost/throw_exception.hpp>
00007 
00008 namespace boost {
00009 
00010 namespace detail {
00011     namespace any_ref {
00012         struct place_holder {
00013             virtual ~place_holder(){}
00014             virtual const std::type_info & type() const { 
00015                 return typeid(place_holder); 
00016             }
00017         };
00018 
00019         template<typename T>
00020         struct place_holder_impl : private place_holder {
00021         };
00022 
00023         template<typename T>
00024         struct place_holder_impl<const T&> : public place_holder {
00025             place_holder_impl( const T& v ):m_ref(v){}
00026             virtual const std::type_info & type() const {
00027                 return typeid(const T&);
00028             }
00029             const T& m_ref;
00030         };
00031 
00032         template<typename T>
00033         struct place_holder_impl<T&> : public place_holder_impl<const T&> {
00034             place_holder_impl( T& v )
00035             :place_holder_impl<const T&>(v){}
00036 
00037             virtual const std::type_info & type() const {
00038                 return typeid(T&);
00039             }
00040         };
00041    } // namespace any_ref
00042 } // namespace detail
00043 
00044     class bad_any_ref_cast : public std::bad_cast
00045     {
00046     public:
00047         virtual const char * what() const throw() {
00048             return "boost::bad_any_ref_cast: "
00049                    "failed conversion using boost::any_ref";
00050         }
00051     };
00052 
00060 class any_ref 
00061 {
00062     public:
00063         any_ref() {
00064             new (held) detail::any_ref::place_holder();
00065         }
00066 
00067         template<typename T>
00068         any_ref( const T& v ) {
00069             new (held) detail::any_ref::place_holder_impl<const T&>(v);
00070         }
00071 
00072         template<typename T>
00073         any_ref( T& v ) {
00074             new (held) detail::any_ref::place_holder_impl<T&>(v);
00075         }
00076 
00077         const std::type_info& type()const { return ((detail::any_ref::place_holder*)held)->type(); }
00078 
00079         template<typename T>
00080         inline operator const T&()const {
00081             const T* v = const_ptr<T>();
00082             if( !v )
00083                 boost::throw_exception(bad_any_ref_cast());
00084             return *v;
00085         }
00086         template<typename T>
00087         inline const T* const_ptr()const {
00088             detail::any_ref::place_holder_impl<const T&>* p = 
00089                 dynamic_cast<detail::any_ref::place_holder_impl<const T&>* >((detail::any_ref::place_holder*)held);
00090             if( p ) 
00091                 return &p->m_ref;
00092             return 0;
00093         }
00094 
00095         template<typename T>
00096         inline operator T&()const {
00097             T* v = ptr<T>();
00098             if( !v )
00099                 boost::throw_exception(bad_any_ref_cast());
00100             return *v;
00101         }
00102         template<typename T>
00103         inline T* ptr()const {
00104             detail::any_ref::place_holder_impl<T&>* p = 
00105                 dynamic_cast<detail::any_ref::place_holder_impl<T&>* >((detail::any_ref::place_holder*)held);
00106             if( p ) 
00107                 return const_cast<T*>(&p->m_ref);
00108             return 0;
00109         }
00110 
00111         any_ref& operator=( const any_ref& r ) {
00112             if( this != &r )
00113                 memcpy(held,r.held,sizeof(held));
00114             return *this;
00115         }
00116         template<typename T>
00117         any_ref& operator=( const T& v ) {
00118             new (held) detail::any_ref::place_holder_impl<const T&>(v);
00119             return *this;
00120         }
00121         template<typename T>
00122         any_ref& operator=( T& v ) {
00123             new (held) detail::any_ref::place_holder_impl<T&>(v);
00124             return *this;
00125         }
00126 
00127     private:
00128 
00129         char held[sizeof(detail::any_ref::place_holder_impl<const int&>)];
00130 };
00131 
00132 } // namespace boost
00133 
00134 #endif
 All Classes Namespaces Files Functions Variables Typedefs Defines