Smart Pointers

clone_ptr.hpp

00001 #ifndef clone_ptr_H_HEADER_GUARD_
00002 #define clone_ptr_H_HEADER_GUARD_
00003 
00004 /*
00005 // clone_ptr class by David Maisonave (Axter)
00006 // Copyright (C) 2005
00007 // David Maisonave (Axter) (609-345-1007) (www.axter.com)
00008 //
00009 // Permission to use, copy, modify, distribute and sell this software
00010 // and its documentation for any purpose is hereby granted without fee,
00011 // provided that the above copyright notice appear in all copies and
00012 // that both that copyright notice and this permission notice appear
00013 // in supporting documentation.  David Maisonave (Axter) makes no representations
00014 // about the suitability of this software for any purpose.
00015 // It is provided "as is" without express or implied warranty.
00016 Description:
00017 The clone_ptr class is a smart pointer class that can be used
00018 with an STL container to create a container of smart pointers.
00019 The main purpose of the clone_ptr, is to make it easier to create
00020 a container of abstract based objects.
00021 The clone_ptr does not share it's pointer, nor does it move it's pointer,
00022 and moreover, it's based on the idea of strict pointer ownership logic.
00023 The main difference between clone_ptr and other similar smart pointers
00024 is that the clone_ptr has a clone interface, which is used to create
00025 a copy of the derived object.  The clone interface is used in
00026 the clone_ptr copy constructor and in the assignment operator.
00027 
00028 The clone_ptr can also be used with sorted containers (std::map, std::set).
00029 When used with sorted containers, the base class must have an operator<() function. (See example code.)
00030 
00031 ****** For more detailed description and example usage see following links: *******
00032 Example Program:
00033 http://code.axter.com/clone_ptr_demo.zip
00034 Detail description:
00035 http://axter.com/lib/
00036 
00037 See example program for example usage.
00038 
00039 */
00040 // @cond INCLUDE_ALL_OBJS_
00041 
00042 #include "value_semantic_ptr.h"
00043 #include "pointer_semantic_ptr.h"
00044 
00045 typedef void clone_smart_ptr_default_allocate;
00046 
00047 template<class T, class ALLOCATE_POLICY = clone_smart_ptr_default_allocate >
00048 class clone_ptr
00049 {
00050         typedef T * ( *clone_fct_Type ) ( T *, bool);
00051         clone_fct_Type m_clone_fct;
00052         T* m_type;
00053 public:
00054         //clone_ptr will only clone type that is pass to the constructor
00055         template<typename T_obj>
00056                 clone_ptr(T_obj* type):m_type(type), m_clone_fct(get_clone_funct(type, (ALLOCATE_POLICY*)0)){}
00057         //Destructor
00058         ~clone_ptr()throw(){m_type=m_clone_fct(m_type, false);}
00059         //Copy constructor
00060         clone_ptr(const clone_ptr& Src):m_type(Src.m_clone_fct(Src.m_type, true)), m_clone_fct(Src.m_clone_fct){}
00061         //Assignment operator
00062         clone_ptr& operator=(const clone_ptr& Src){return assign(Src);}
00063         template<class CompatibleT>
00064                 clone_ptr& operator=(const clone_ptr<CompatibleT>& Src){return assign(Src);}
00065         T* operator->() const{return m_type;}
00066         T& operator*() const{return *m_type;}
00067         const T* const c_ptr()const{return  m_type;}
00068         const T& c_ref()const{return  *m_type;}
00069         T* get_ptr(){return m_type;}
00070         //Other Misc methods
00071         void swap(clone_ptr<T> & other)throw(){std::swap(m_type, other.m_type);std::swap(m_func_ptr_interface, other.m_func_ptr_interface);}
00072 private:
00073         template<class CompatibleSmartPtr>
00074                 clone_ptr& assign(CompatibleSmartPtr& Src)
00075         {
00076                 if (m_type != Src.m_type)
00077                 {
00078                         m_clone_fct(m_type, false);
00079                         m_type = Src.m_clone_fct(Src.m_type, true);
00080                         m_clone_fct = Src.m_clone_fct;
00081                 }
00082                 return *this;
00083         }
00084         template <typename D>
00085         clone_fct_Type get_clone_funct(D* , clone_smart_ptr_default_allocate*){return  construct_and_destruct_default_allocator<T, D>;}
00086         template <typename D, class FUNC_ALLOC_POLICY>
00087         clone_fct_Type get_clone_funct(D* , FUNC_ALLOC_POLICY*){return  construct_and_destruct<T,D, FUNC_ALLOC_POLICY>;}
00088         // The clone function: (Thanks to Kai-Uwe Bux)
00089         template < typename T, typename DT> static T *  construct_and_destruct_default_allocator(T *  ptr, bool bConstruct) {
00090                 if (bConstruct){return new DT(*static_cast<DT*>(ptr));}
00091                 delete ptr;
00092                 return NULL;
00093         } 
00094         template < typename T, typename D, class FUNC_ALLOC_POLICY> T *  construct_and_destruct(T *  ptr, bool bConstruct) {
00095                 D * Obj = static_cast<D*>( ptr );
00096                 if (bConstruct)
00097                 {
00098                         D* tmp_ptr = NULL;
00099                         FUNC_ALLOC_POLICY::allocate(tmp_ptr);
00100                         FUNC_ALLOC_POLICY::construct(tmp_ptr, *(Obj));
00101                         return tmp_ptr;
00102                 }
00103                 FUNC_ALLOC_POLICY::destroy(Obj);
00104                 FUNC_ALLOC_POLICY::deallocate(Obj);
00105                 return NULL;
00106         } 
00107 };
00108 // @endcond 
00109 
00110 #endif 
00111 

Generated on Wed Mar 29 21:58:58 2006 for Smart Pointers by  doxygen 1.4.6.Axter [Axter-Extended-Version]