00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012 #ifndef LOKI_PIMPL_INC_
00013 #define LOKI_PIMPL_INC_
00014
00015
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
00087
00088
00089
00090
00091
00092
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
00170 typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type;
00171
00172
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