]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/SPCachedFactory.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / SPCachedFactory.h
1 ////////////////////////////////////////////////////////////////////////////////
2 // The Loki Library
3 // Copyright (c) 2006 by Guillaume Chatelet
4 //
5 // Code covered by the MIT License
6 //
7 // Permission to use, copy, modify, distribute and sell this software for any
8 // purpose is hereby granted without fee, provided that the above copyright
9 // notice appear in all copies and that both that copyright notice and this
10 // permission notice appear in supporting documentation.
11 //
12 // The authors make no representations about the suitability of this software
13 // for any purpose. It is provided "as is" without express or implied warranty.
14 //
15 // This code DOES NOT accompany the book:
16 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
17 //     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
18 //
19 ////////////////////////////////////////////////////////////////////////////////
20
21 // $Id: SPCachedFactory.h 896 2008-08-08 22:20:05Z syntheticpp $
22
23 #ifndef SPCACHEDFACTORY_H_
24 #define SPCACHEDFACTORY_H_
25
26 /**
27  * This file is intented to be used if you want a CachedFactory with
28  * a SmartPointer encapsulation policy.
29  * It as been defined in a separate file because of the many introduced
30  * dependencies (SmartPtr.h would depend on Functor.h and CachedFactory.h
31  * would depend on SmartPtr.h). By defining another header you pay for those
32  * extra dependencies only if you need it.
33  *
34  * This file defines FunctionStorage a new SmartPointer storage policy and
35  * SmartPointer a new CachedFactory encapsulation policy.
36  */
37
38 #include <loki/Functor.h>
39 #include <loki/SmartPtr.h>
40 #include <loki/CachedFactory.h>
41
42 namespace Loki
43 {
44
45 ////////////////////////////////////////////////////////////////////////////////
46 ///  \class FunctionStorage
47 ///
48 ///  \ingroup  SmartPointerStorageGroup
49 ///  \brief Implementation of the StoragePolicy used by SmartPtr.
50 ///
51 ///  This storage policy is used by SmartPointer CachedFactory's encapsulation
52 ///  policy. It's purpose is to call a Functor instead of deleting the
53 ///  underlying pointee object. You have to set the callback functor by calling
54 ///  SetCallBackFunction(const FunctorType &functor).
55 ///
56 ///  Unfortunately, the functor argument is not a reference to the SmartPtr but
57 ///  a void *. Making functor argument a reference to the pointer would require
58 ///  the FunctionStorage template to know the full definition of the SmartPtr.
59 ////////////////////////////////////////////////////////////////////////////////
60
61 template <class T>
62 class FunctionStorage
63 {
64 public:
65         /// the type of the pointee_ object
66         typedef T *StoredType;
67         /// type used to declare OwnershipPolicy type.
68         typedef T *InitPointerType;
69         /// type returned by operator->
70         typedef T *PointerType;
71         /// type returned by operator*
72         typedef T &ReferenceType;
73         /// type of the Functor to set
74         typedef Functor< void , Seq< void * > > FunctorType;
75
76         FunctionStorage() : pointee_(Default()), functor_()
77         {}
78
79         // The storage policy doesn't initialize the stored pointer
80         //     which will be initialized by the OwnershipPolicy's Clone fn
81         FunctionStorage(const FunctionStorage &rsh) : pointee_(0), functor_(rsh.functor_)
82         {}
83
84         template <class U>
85         FunctionStorage(const FunctionStorage<U>& rsh) : pointee_(0), functor_(rsh.functor_)
86         {}
87
88         FunctionStorage(const StoredType &p) : pointee_(p), functor_() {}
89
90         PointerType operator->() const
91         {
92                 return pointee_;
93         }
94
95         ReferenceType operator*() const
96         {
97                 return *pointee_;
98         }
99
100         void Swap(FunctionStorage &rhs)
101         {
102                 std::swap(pointee_, rhs.pointee_);
103                 std::swap(functor_, rhs.functor_);
104         }
105
106         /// Sets the callback function to call. You have to specify it or
107         /// the smartPtr will throw a bad_function_call exception.
108         void SetCallBackFunction(const FunctorType &functor)
109         {
110                 functor_ = functor;
111         }
112
113         // Accessors
114         template <class F>
115         friend typename FunctionStorage<F>::PointerType GetImpl(const FunctionStorage<F>& sp);
116
117         template <class F>
118         friend const typename FunctionStorage<F>::StoredType &GetImplRef(const FunctionStorage<F>& sp);
119
120         template <class F>
121         friend typename FunctionStorage<F>::StoredType &GetImplRef(FunctionStorage<F>& sp);
122
123 protected:
124         // Destroys the data stored
125         // (Destruction might be taken over by the OwnershipPolicy)
126         void Destroy()
127         {
128                 functor_(this);
129         }
130
131         // Default value to initialize the pointer
132         static StoredType Default()
133         {
134                 return 0;
135         }
136
137 private:
138         // Data
139         StoredType pointee_;
140         FunctorType functor_;
141 };
142
143 template <class T>
144 inline typename FunctionStorage<T>::PointerType GetImpl(const FunctionStorage<T>& sp)
145 {
146         return sp.pointee_;
147 }
148
149 template <class T>
150 inline const typename FunctionStorage<T>::StoredType &GetImplRef(const FunctionStorage<T>& sp)
151 {
152         return sp.pointee_;
153 }
154
155 template <class T>
156 inline typename FunctionStorage<T>::StoredType &GetImplRef(FunctionStorage<T>& sp)
157 {
158         return sp.pointee_;
159 }
160
161 /**
162  * \class       SmartPointer
163  * \ingroup     EncapsulationPolicyCachedFactoryGroup
164  * \brief       Encapsulate the object in a SmartPtr with FunctionStorage policy.
165  *
166  * The object will come back to the Cache as soon as no more SmartPtr are
167  * referencing this object. You can customize the SmartPointer with the standard
168  * SmartPtr policies (OwnershipPolicy, ConversionPolicy, CheckingPolicy,
169  * ConstnessPolicy) but StoragePolicy is forced to FunctionStorage.
170  */
171 template
172 <
173 class AbstractProduct,
174       template <class> class OwnershipPolicy = RefCounted,
175       class ConversionPolicy = DisallowConversion,
176       template <class> class CheckingPolicy = AssertCheck,
177       template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
178       >
179 class SmartPointer
180 {
181 private:
182         typedef SmartPtr< AbstractProduct,OwnershipPolicy,
183                 ConversionPolicy, CheckingPolicy,
184                 FunctionStorage, ConstnessPolicy > CallBackSP;
185 protected:
186         typedef CallBackSP ProductReturn;
187         SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {}
188         virtual ~SmartPointer() {}
189
190         ProductReturn encapsulate(AbstractProduct *pProduct)
191         {
192                 CallBackSP SP(pProduct);
193                 SP.SetCallBackFunction(fun);
194                 return SP;
195         }
196
197         AbstractProduct *release(ProductReturn &pProduct)
198         {
199                 return GetImpl(pProduct);
200         }
201
202         const char *name()
203         {
204                 return "smart pointer";
205         }
206
207 private:
208         SmartPointer &operator=(const SmartPointer &);
209         SmartPointer(const SmartPointer &);
210         void smartPointerCallbackFunction(void *pSP)
211         {
212                 CallBackSP &SP(*reinterpret_cast<CallBackSP *>(pSP));
213                 ReleaseObject(SP);
214         }
215         virtual void ReleaseObject(ProductReturn &object)=0;
216         const typename CallBackSP::FunctorType fun;
217 };
218
219 } // namespace Loki
220
221 #endif /*SPCACHEDFACTORY_H_*/