Pimpl.h

00001 
00002 // The Loki Library
00003 // Copyright (c) 2006 Peter Kümmel
00004 // Permission to use, copy, modify, distribute and sell this software for any 
00005 //     purpose is hereby granted without fee, provided that the above copyright 
00006 //     notice appear in all copies and that both that copyright notice and this 
00007 //     permission notice appear in supporting documentation.
00008 // The author makes no representations about the 
00009 //     suitability of this software for any purpose. It is provided "as is" 
00010 //     without express or implied warranty.
00012 #ifndef LOKI_PIMPL_INC_
00013 #define LOKI_PIMPL_INC_
00014 
00015 // $Id: Pimpl.h 751 2006-10-17 19:50:37Z syntheticpp $
00016 
00017 
00019 
00020 #ifndef LOKI_INHERITED_PIMPL_NAME
00021 #define LOKI_INHERITED_PIMPL_NAME d
00022 #endif
00023 
00024 #ifndef LOKI_INHERITED_RIMPL_NAME
00025 #define LOKI_INHERITED_RIMPL_NAME d
00026 #endif
00027 
00028 namespace Loki
00029 {
00030 
00038 
00039     template<class T>
00040     struct ConstPropPtr
00041     {
00042         explicit ConstPropPtr(T* p) : ptr_(p) {}
00043         ~ConstPropPtr() { delete  ptr_; ptr_ = 0; }
00044         T* operator->()    { return  ptr_; }
00045         T& operator*()    { return *ptr_; }
00046         const T* operator->() const    { return  ptr_; }
00047         const T& operator*()  const    { return *ptr_; }
00048     
00049     private:
00050         ConstPropPtr();
00051         ConstPropPtr(const ConstPropPtr&);
00052         ConstPropPtr& operator=(const ConstPropPtr&);
00053         T* ptr_;
00054     };
00055 
00056 
00069 
00070     template
00071     <    
00072         class T, 
00073         typename Pointer = ConstPropPtr<T>
00074     >
00075     class Pimpl 
00076     {
00077     public:
00078 
00079         typedef T Impl;
00080 
00081         Pimpl() : ptr_(new T)
00082         {}
00083 
00084         ~Pimpl()
00085         {
00086             // Don't compile with incomplete type
00087             //
00088             // If compilation breaks here make sure
00089             // the compiler does not auto-generate the 
00090             // destructor of the class hosting the pimpl:
00091             // - implement the destructor of the class 
00092             // - don't inline the destructor
00093             typedef char T_must_be_defined[sizeof(T) ? 1 : -1 ];
00094         }
00095 
00096 
00097         T* operator->()
00098         {
00099             return ptr_.operator->();
00100         }
00101 
00102         T& operator*()
00103         {
00104             return ptr_.operator*();
00105         }
00106 
00107         const T* operator->() const
00108         {
00109             return ptr_.operator->();
00110         }
00111 
00112         const T& operator*() const
00113         {
00114             return ptr_.operator*();
00115         }
00116 
00117         Pointer& wrapped()
00118         {
00119             return ptr_;
00120         }
00121 
00122         const Pointer& wrapped() const
00123         {
00124             return ptr_;
00125         }
00126 
00127 
00128     private:
00129         Pimpl(const Pimpl&);
00130         Pimpl& operator=(const Pimpl&);
00131 
00132         Pointer ptr_;
00133     };
00134 
00135 
00136     template<class T, typename Pointer = ConstPropPtr<T> >
00137     struct PimplOwner 
00138     {    
00139         Pimpl<T,Pointer> LOKI_INHERITED_PIMPL_NAME;
00140     };
00141 
00142 
00150 
00151     template<class T>
00152     struct ImplOf;
00153 
00154 
00162 
00163 
00164     template<class T, template<class> class Ptr = ConstPropPtr>
00165     struct PimplOf
00166     {
00167         typedef T Impl;
00168 
00169         // declare pimpl
00170         typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type;
00171 
00172         // inherit pimpl
00173         typedef PimplOwner<ImplOf<T>, Ptr<ImplOf<T> > > Owner;
00174     };
00175 
00176 
00177     template<class T, class UsedPimpl = typename PimplOf<T>::Type >
00178     struct RimplOf
00179     {
00180         typedef typename UsedPimpl::Impl & Type;
00181 
00182         class Owner
00183         {
00184             UsedPimpl pimpl;
00185 
00186         public:
00187             Owner() : LOKI_INHERITED_RIMPL_NAME(*pimpl)
00188             {}
00189 
00190             Type LOKI_INHERITED_RIMPL_NAME;
00191         };
00192 
00193     };
00194   
00195 }
00196 
00197 #endif // end file guardian
00198 

Generated on Sun Feb 25 16:52:26 2007 for Loki by  doxygen 1.5.1-p1