diff options
Diffstat (limited to 'shared/loki/SPCachedFactory.h')
-rw-r--r-- | shared/loki/SPCachedFactory.h | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/shared/loki/SPCachedFactory.h b/shared/loki/SPCachedFactory.h new file mode 100644 index 00000000..71c72644 --- /dev/null +++ b/shared/loki/SPCachedFactory.h @@ -0,0 +1,204 @@ +//////////////////////////////////////////////////////////////////////////////// +// The Loki Library +// Copyright (c) 2006 by Guillaume Chatelet +// +// Code covered by the MIT License +// +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this +// permission notice appear in supporting documentation. +// +// The authors make no representations about the suitability of this software +// for any purpose. It is provided "as is" without express or implied warranty. +// +// This code DOES NOT accompany the book: +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// Patterns Applied". Copyright (c) 2001. Addison-Wesley. +// +//////////////////////////////////////////////////////////////////////////////// + +// $Id: SPCachedFactory.h 896 2008-08-08 22:20:05Z syntheticpp $ + +#ifndef SPCACHEDFACTORY_H_ +#define SPCACHEDFACTORY_H_ + +/** + * This file is intented to be used if you want a CachedFactory with + * a SmartPointer encapsulation policy. + * It as been defined in a separate file because of the many introduced + * dependencies (SmartPtr.h would depend on Functor.h and CachedFactory.h + * would depend on SmartPtr.h). By defining another header you pay for those + * extra dependencies only if you need it. + * + * This file defines FunctionStorage a new SmartPointer storage policy and + * SmartPointer a new CachedFactory encapsulation policy. + */ + +#include <loki/Functor.h> +#include <loki/SmartPtr.h> +#include <loki/CachedFactory.h> + +namespace Loki +{ + +//////////////////////////////////////////////////////////////////////////////// +/// \class FunctionStorage +/// +/// \ingroup SmartPointerStorageGroup +/// \brief Implementation of the StoragePolicy used by SmartPtr. +/// +/// This storage policy is used by SmartPointer CachedFactory's encapsulation +/// policy. It's purpose is to call a Functor instead of deleting the +/// underlying pointee object. You have to set the callback functor by calling +/// SetCallBackFunction(const FunctorType &functor). +/// +/// Unfortunately, the functor argument is not a reference to the SmartPtr but +/// a void *. Making functor argument a reference to the pointer would require +/// the FunctionStorage template to know the full definition of the SmartPtr. +//////////////////////////////////////////////////////////////////////////////// + + template <class T> + class FunctionStorage + { + public: + /// the type of the pointee_ object + typedef T* StoredType; + /// type used to declare OwnershipPolicy type. + typedef T* InitPointerType; + /// type returned by operator-> + typedef T* PointerType; + /// type returned by operator* + typedef T& ReferenceType; + /// type of the Functor to set + typedef Functor< void , Seq< void* > > FunctorType; + + FunctionStorage() : pointee_(Default()), functor_() + {} + + // The storage policy doesn't initialize the stored pointer + // which will be initialized by the OwnershipPolicy's Clone fn + FunctionStorage(const FunctionStorage& rsh) : pointee_(0), functor_(rsh.functor_) + {} + + template <class U> + FunctionStorage(const FunctionStorage<U>& rsh) : pointee_(0), functor_(rsh.functor_) + {} + + FunctionStorage(const StoredType& p) : pointee_(p), functor_() {} + + PointerType operator->() const { return pointee_; } + + ReferenceType operator*() const { return *pointee_; } + + void Swap(FunctionStorage& rhs) + { + std::swap(pointee_, rhs.pointee_); + std::swap(functor_, rhs.functor_); + } + + /// Sets the callback function to call. You have to specify it or + /// the smartPtr will throw a bad_function_call exception. + void SetCallBackFunction(const FunctorType &functor) + { + functor_ = functor; + } + + // Accessors + template <class F> + friend typename FunctionStorage<F>::PointerType GetImpl(const FunctionStorage<F>& sp); + + template <class F> + friend const typename FunctionStorage<F>::StoredType& GetImplRef(const FunctionStorage<F>& sp); + + template <class F> + friend typename FunctionStorage<F>::StoredType& GetImplRef(FunctionStorage<F>& sp); + + protected: + // Destroys the data stored + // (Destruction might be taken over by the OwnershipPolicy) + void Destroy() + { + functor_(this); + } + + // Default value to initialize the pointer + static StoredType Default() + { return 0; } + + private: + // Data + StoredType pointee_; + FunctorType functor_; + }; + + template <class T> + inline typename FunctionStorage<T>::PointerType GetImpl(const FunctionStorage<T>& sp) + { return sp.pointee_; } + + template <class T> + inline const typename FunctionStorage<T>::StoredType& GetImplRef(const FunctionStorage<T>& sp) + { return sp.pointee_; } + + template <class T> + inline typename FunctionStorage<T>::StoredType& GetImplRef(FunctionStorage<T>& sp) + { return sp.pointee_; } + + /** + * \class SmartPointer + * \ingroup EncapsulationPolicyCachedFactoryGroup + * \brief Encapsulate the object in a SmartPtr with FunctionStorage policy. + * + * The object will come back to the Cache as soon as no more SmartPtr are + * referencing this object. You can customize the SmartPointer with the standard + * SmartPtr policies (OwnershipPolicy, ConversionPolicy, CheckingPolicy, + * ConstnessPolicy) but StoragePolicy is forced to FunctionStorage. + */ + template + < + class AbstractProduct, + template <class> class OwnershipPolicy = RefCounted, + class ConversionPolicy = DisallowConversion, + template <class> class CheckingPolicy = AssertCheck, + template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS + > + class SmartPointer + { + private: + typedef SmartPtr< AbstractProduct,OwnershipPolicy, + ConversionPolicy, CheckingPolicy, + FunctionStorage, ConstnessPolicy > CallBackSP; + protected: + typedef CallBackSP ProductReturn; + SmartPointer() : fun(this, &SmartPointer::smartPointerCallbackFunction) {} + virtual ~SmartPointer(){} + + ProductReturn encapsulate(AbstractProduct* pProduct) + { + CallBackSP SP(pProduct); + SP.SetCallBackFunction(fun); + return SP; + } + + AbstractProduct* release(ProductReturn &pProduct) + { + return GetImpl(pProduct); + } + + const char* name(){return "smart pointer";} + + private: + SmartPointer& operator=(const SmartPointer&); + SmartPointer(const SmartPointer&); + void smartPointerCallbackFunction(void* pSP) + { + CallBackSP &SP(*reinterpret_cast<CallBackSP*>(pSP)); + ReleaseObject(SP); + } + virtual void ReleaseObject(ProductReturn &object)=0; + const typename CallBackSP::FunctorType fun; + }; + +} // namespace Loki + +#endif /*SPCACHEDFACTORY_H_*/ |