]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/Pimpl.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / Pimpl.h
1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2006 Peter Kümmel
4 // Permission to use, copy, modify, distribute and sell this software for any
5 //     purpose is hereby granted without fee, provided that the above copyright
6 //     notice appear in all copies and that both that copyright notice and this
7 //     permission notice appear in supporting documentation.
8 // The author makes no representations about the
9 //     suitability of this software for any purpose. It is provided "as is"
10 //     without express or implied warranty.
11 ////////////////////////////////////////////////////////////////////////////////
12 #ifndef LOKI_PIMPL_INC_
13 #define LOKI_PIMPL_INC_
14
15 // $Id: Pimpl.h 751 2006-10-17 19:50:37Z syntheticpp $
16
17
18 ///  \defgroup PimplGroup Pimpl
19
20 #ifndef LOKI_INHERITED_PIMPL_NAME
21 #define LOKI_INHERITED_PIMPL_NAME d
22 #endif
23
24 #ifndef LOKI_INHERITED_RIMPL_NAME
25 #define LOKI_INHERITED_RIMPL_NAME d
26 #endif
27
28 namespace Loki
29 {
30
31 //////////////////////////////////////////
32 ///  \class ConstPropPtr
33 ///
34 ///  \ingroup PimplGroup
35 ///   Simple const propagating smart pointer
36 ///   Is the default smart pointer of Pimpl.
37 //////////////////////////////////////////
38
39 template<class T>
40 struct ConstPropPtr
41 {
42         explicit ConstPropPtr(T *p) : ptr_(p) {}
43         ~ConstPropPtr()
44         {
45                 delete  ptr_;
46                 ptr_ = 0;
47         }
48         T *operator->()
49         {
50                 return  ptr_;
51         }
52         T &operator*()
53         {
54                 return *ptr_;
55         }
56         const T *operator->() const
57         {
58                 return  ptr_;
59         }
60         const T &operator*()  const
61         {
62                 return *ptr_;
63         }
64
65 private:
66         ConstPropPtr();
67         ConstPropPtr(const ConstPropPtr &);
68         ConstPropPtr &operator=(const ConstPropPtr &);
69         T *ptr_;
70 };
71
72
73 ////////////////////////////////////////////////////////////////////////////////
74 ///  \class Pimpl
75 ///
76 ///  \ingroup PimplGroup
77 ///
78 ///  Implements the Pimpl idiom. It's a wrapper for a smart pointer which
79 ///  automatically creates and deletes the implementation object and adds
80 ///  const propagation to the smart pointer.
81 ///
82 ///  \par Usage
83 ///  see test/Pimpl
84 ////////////////////////////////////////////////////////////////////////////////
85
86 template
87 <
88 class T,
89       typename Pointer = ConstPropPtr<T>
90       >
91 class Pimpl
92 {
93 public:
94
95         typedef T Impl;
96
97         Pimpl() : ptr_(new T)
98         {}
99
100         ~Pimpl()
101         {
102                 // Don't compile with incomplete type
103                 //
104                 // If compilation breaks here make sure
105                 // the compiler does not auto-generate the
106                 // destructor of the class hosting the pimpl:
107                 // - implement the destructor of the class
108                 // - don't inline the destructor
109                 typedef char T_must_be_defined[sizeof(T) ? 1 : -1 ];
110         }
111
112
113         T *operator->()
114         {
115                 return ptr_.operator->();
116         }
117
118         T &operator*()
119         {
120                 return ptr_.operator*();
121         }
122
123         const T *operator->() const
124         {
125                 return ptr_.operator->();
126         }
127
128         const T &operator*() const
129         {
130                 return ptr_.operator*();
131         }
132
133         Pointer &wrapped()
134         {
135                 return ptr_;
136         }
137
138         const Pointer &wrapped() const
139         {
140                 return ptr_;
141         }
142
143
144 private:
145         Pimpl(const Pimpl &);
146         Pimpl &operator=(const Pimpl &);
147
148         Pointer ptr_;
149 };
150
151
152 template<class T, typename Pointer = ConstPropPtr<T> >
153 struct PimplOwner
154 {
155         Pimpl<T,Pointer> LOKI_INHERITED_PIMPL_NAME;
156 };
157
158
159 //////////////////////////////////////////
160 /// \class  ImplOf
161 ///
162 /// \ingroup PimplGroup
163 /// Convenience template for the
164 /// implementations which Pimpl points to.
165 //////////////////////////////////////////
166
167 template<class T>
168 struct ImplOf;
169
170
171 //////////////////////////////////////////
172 /// \class  PImplOf
173 ///
174 /// \ingroup PimplGroup
175 /// Convenience template which uses ImplOf
176 /// as implementation structure
177 //////////////////////////////////////////
178
179
180 template<class T, template<class> class Ptr = ConstPropPtr>
181 struct PimplOf
182 {
183         typedef T Impl;
184
185         // declare pimpl
186         typedef Pimpl<ImplOf<T>, Ptr<ImplOf<T> > > Type;
187
188         // inherit pimpl
189         typedef PimplOwner<ImplOf<T>, Ptr<ImplOf<T> > > Owner;
190 };
191
192
193 template<class T, class UsedPimpl = typename PimplOf<T>::Type >
194 struct RimplOf
195 {
196         typedef typename UsedPimpl::Impl &Type;
197
198         class Owner
199         {
200                 UsedPimpl pimpl;
201
202         public:
203                 Owner() : LOKI_INHERITED_RIMPL_NAME(*pimpl)
204                 {}
205
206                 Type LOKI_INHERITED_RIMPL_NAME;
207         };
208
209 };
210
211 }
212
213 #endif // end file guardian
214