Boost Reflect Library 0.1.0
any_ptr.hpp
Go to the documentation of this file.
00001 #ifndef _BOOST_REFLECT_ANY_PTR_HPP
00002 #define _BOOST_REFLECT_ANY_PTR_HPP
00003 #include <boost/shared_ptr.hpp>
00004 #include <boost/any.hpp>
00005 #include <boost/reflect/vtable.hpp>
00006 #include <boost/reflect/mirror_interface.hpp>
00007 
00008 namespace boost { namespace reflect {
00009 
00010     /**
00011      *  @class any_ptr
00012      *  @brief Behaves like a smart pointer that can handle any type with the same interface.
00013      *
00014      *  If constructed from a shared pointer, then a copy of the shared pointer will go with
00015      *  every any_ptr.  If constructed from a regular pointer, then the pointer must be valid
00016      *  for the life of all copies of the any_ptr.
00017      *
00018      */
00019     template<typename InterfaceType, typename InterfaceDelegate = boost::reflect::mirror_interface>
00020     class any_ptr {
00021         public:
00022             typedef boost::reflect::vtable<InterfaceType,InterfaceDelegate> vtable_type;
00023             typedef InterfaceType                                           interface_type;
00024             typedef InterfaceDelegate                                       delegate_type;
00025 
00026             any_ptr()
00027             :m_vtable(new vtable_type()) {}
00028 
00029             operator bool()const  { return m_vtable; }
00030             bool operator!()const { return !m_vtable; }
00031 
00032             template<typename T>
00033             any_ptr( T* v )
00034             :m_ptr(v),m_vtable(new vtable_type()) {
00035               InterfaceDelegate::set_vtable(*m_vtable,*v);
00036             }
00037             template<typename T>
00038             any_ptr( const boost::shared_ptr<T>& v )
00039             :m_ptr(v),m_vtable(new vtable_type()) {
00040               InterfaceDelegate::set_vtable(*m_vtable,*v);
00041             }
00042 
00043             /**
00044              *  @brief constructs an any_ptr from another any_ptr with compatible interface.
00045              */
00046             template<typename OtherInterface,typename OtherDelegate>
00047             any_ptr( const any_ptr<OtherInterface,OtherDelegate>& p )
00048             :m_ptr(p),m_vtable(new vtable_type()) {
00049               InterfaceDelegate::set_vtable( *m_vtable, *boost::any_cast<any_ptr<OtherInterface,OtherDelegate>&>(m_ptr) );
00050             }
00051 
00052             const vtable_type& operator*()const  { return *m_vtable;  } 
00053             vtable_type&       operator*()       { return *m_vtable;  } 
00054 
00055             const vtable_type* operator->()const { return m_vtable.get(); } 
00056             vtable_type*       operator->()      { return m_vtable.get(); } 
00057              
00058         protected:
00059 
00060             boost::any                          m_ptr;
00061             boost::shared_ptr<vtable_type>      m_vtable;
00062     };
00063     /**
00064      * @brief Helper function to enable automatic type deduction.
00065      *
00066      * Calls visitor with each member of the vtable of the any_ptr.
00067      */
00068     template<typename InterfaceType,typename InterfaceDelegate, typename Visitor>
00069     void visit( const any_ptr<InterfaceType,InterfaceDelegate>& aptr, Visitor v ) {
00070         boost::reflect::vtable_reflector<InterfaceType>::visit( &*aptr, v );
00071     }
00072 
00073 } }
00074 
00075 #endif

© Daniel Larimer 2010-2011 - Licensed under Boost Software License, Version 1.0 Boost Reflect Library