1 ////////////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2006 by Guillaume Chatelet
5 // Code covered by the MIT License
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.
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.
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.
19 ////////////////////////////////////////////////////////////////////////////////
21 // $Id: SPCachedFactory.h 896 2008-08-08 22:20:05Z syntheticpp $
23 #ifndef SPCACHEDFACTORY_H_
24 #define SPCACHEDFACTORY_H_
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.
34 * This file defines FunctionStorage a new SmartPointer storage policy and
35 * SmartPointer a new CachedFactory encapsulation policy.
38 #include <loki/Functor.h>
39 #include <loki/SmartPtr.h>
40 #include <loki/CachedFactory.h>
45 ////////////////////////////////////////////////////////////////////////////////
46 /// \class FunctionStorage
48 /// \ingroup SmartPointerStorageGroup
49 /// \brief Implementation of the StoragePolicy used by SmartPtr.
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).
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 ////////////////////////////////////////////////////////////////////////////////
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;
76 FunctionStorage() : pointee_(Default()), functor_()
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_)
85 FunctionStorage(const FunctionStorage<U>& rsh) : pointee_(0), functor_(rsh.functor_)
88 FunctionStorage(const StoredType &p) : pointee_(p), functor_() {}
90 PointerType operator->() const
95 ReferenceType operator*() const
100 void Swap(FunctionStorage &rhs)
102 std::swap(pointee_, rhs.pointee_);
103 std::swap(functor_, rhs.functor_);
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)
115 friend typename FunctionStorage<F>::PointerType GetImpl(const FunctionStorage<F>& sp);
118 friend const typename FunctionStorage<F>::StoredType &GetImplRef(const FunctionStorage<F>& sp);
121 friend typename FunctionStorage<F>::StoredType &GetImplRef(FunctionStorage<F>& sp);
124 // Destroys the data stored
125 // (Destruction might be taken over by the OwnershipPolicy)
131 // Default value to initialize the pointer
132 static StoredType Default()
140 FunctorType functor_;
144 inline typename FunctionStorage<T>::PointerType GetImpl(const FunctionStorage<T>& sp)
150 inline const typename FunctionStorage<T>::StoredType &GetImplRef(const FunctionStorage<T>& sp)
156 inline typename FunctionStorage<T>::StoredType &GetImplRef(FunctionStorage<T>& sp)
162 * \class SmartPointer
163 * \ingroup EncapsulationPolicyCachedFactoryGroup
164 * \brief Encapsulate the object in a SmartPtr with FunctionStorage policy.
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.
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
182 typedef SmartPtr< AbstractProduct,OwnershipPolicy,
183 ConversionPolicy, CheckingPolicy,
184 FunctionStorage, ConstnessPolicy > CallBackSP;
186 typedef CallBackSP ProductReturn;
187 SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {}
188 virtual ~SmartPointer() {}
190 ProductReturn encapsulate(AbstractProduct *pProduct)
192 CallBackSP SP(pProduct);
193 SP.SetCallBackFunction(fun);
197 AbstractProduct *release(ProductReturn &pProduct)
199 return GetImpl(pProduct);
204 return "smart pointer";
208 SmartPointer &operator=(const SmartPointer &);
209 SmartPointer(const SmartPointer &);
210 void smartPointerCallbackFunction(void *pSP)
212 CallBackSP &SP(*reinterpret_cast<CallBackSP *>(pSP));
215 virtual void ReleaseObject(ProductReturn &object)=0;
216 const typename CallBackSP::FunctorType fun;
221 #endif /*SPCACHEDFACTORY_H_*/