//+----------------------------------------------------------------------------+ //| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" | //| License: GNU General Public License 2 or later (see file COPYING) | //+----------------------------------------------------------------------------+ #ifndef HEADER_UTIL_SMART_PTR #define HEADER_UTIL_SMART_PTR /** @file util/smart_ptr.hpp * * @brief Utilities related to boost smart pointers */ // ----------------------------------------------------------------------------- : Includes #include #ifdef HAVE_FAST_ATOMIC /// Using intrusive_ptr where possible? (as opposed to smart_ptr) #define USE_INTRUSIVE_PTR #endif #include #ifdef USE_INTRUSIVE_PTR #include #endif using namespace boost; // ----------------------------------------------------------------------------- : Declaring /// Declares the type TypeP as a shared_ptr #define DECLARE_SHARED_POINTER_TYPE(Type) \ class Type; \ typedef shared_ptr Type##P; // ----------------------------------------------------------------------------- : Creating /// Allocate a new shared-pointed object template inline shared_ptr new_shared() { return shared_ptr(new T()); } /// Allocate a new shared-pointed object, given one argument to pass to the ctor of T template inline shared_ptr new_shared1(const A0& a0) { return shared_ptr(new T(a0)); } /// Allocate a new shared-pointed object, given two arguments to pass to the ctor of T template inline shared_ptr new_shared2(const A0& a0, const A1& a1) { return shared_ptr(new T(a0, a1)); } /// Allocate a new shared-pointed object, given three arguments to pass to the ctor of T template inline shared_ptr new_shared3(const A0& a0, const A1& a1, const A2& a2) { return shared_ptr(new T(a0, a1, a2)); } /// Allocate a new shared-pointed object, given four arguments to pass to the ctor of T template inline shared_ptr new_shared4(const A0& a0, const A1& a1, const A2& a2, const A3& a3) { return shared_ptr(new T(a0, a1, a2, a3)); } /// Allocate a new shared-pointed object, given five arguments to pass to the ctor of T template inline shared_ptr new_shared5(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return shared_ptr(new T(a0, a1, a2, a3, a4)); } /// Allocate a new shared-pointed object, given six arguments to pass to the ctor of T template inline shared_ptr new_shared6(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { return shared_ptr(new T(a0, a1, a2, a3, a4, a5)); } /// Allocate a new shared-pointed object, given seven arguments to pass to the ctor of T template inline shared_ptr new_shared7(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { return shared_ptr(new T(a0, a1, a2, a3, a4, a5, a6)); } /// Allocate a new shared-pointed object, given eight arguments to pass to the ctor of T template inline shared_ptr new_shared8(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { return shared_ptr(new T(a0, a1, a2, a3, a4, a5, a6, a7)); } /// Allocate a new shared-pointed object, given nine arguments to pass to the ctor of T template inline shared_ptr new_shared9(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { return shared_ptr(new T(a0, a1, a2, a3, a4, a5, a6, a7, a8)); } // ----------------------------------------------------------------------------- : Intrusive pointers #ifdef USE_INTRUSIVE_PTR /// Declares the type TypeP as a intrusive_ptr #define DECLARE_POINTER_TYPE(Type) \ class Type; \ typedef intrusive_ptr Type##P; /// Allocate a new intrusive-pointed object template inline intrusive_ptr new_intrusive() { return intrusive_ptr(new T()); } /// Allocate a new intrusive-pointed object, given one argument to pass to the ctor of T template inline intrusive_ptr new_intrusive1(const A0& a0) { return intrusive_ptr(new T(a0)); } /// Allocate a new intrusive-pointed object, given two arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive2(const A0& a0, const A1& a1) { return intrusive_ptr(new T(a0, a1)); } /// Allocate a new intrusive-pointed object, given three arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive3(const A0& a0, const A1& a1, const A2& a2) { return intrusive_ptr(new T(a0, a1, a2)); } /// Allocate a new intrusive-pointed object, given four arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive4(const A0& a0, const A1& a1, const A2& a2, const A3& a3) { return intrusive_ptr(new T(a0, a1, a2, a3)); } /// Allocate a new intrusive-pointed object, given five arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive5(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4) { return intrusive_ptr(new T(a0, a1, a2, a3, a4)); } /// Allocate a new intrusive-pointed object, given six arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive6(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5) { return intrusive_ptr(new T(a0, a1, a2, a3, a4, a5)); } /// Allocate a new intrusive-pointed object, given seven arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive7(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6) { return intrusive_ptr(new T(a0, a1, a2, a3, a4, a5, a6)); } /// Allocate a new intrusive-pointed object, given eight arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive8(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7) { return intrusive_ptr(new T(a0, a1, a2, a3, a4, a5, a6, a7)); } /// Allocate a new intrusive-pointed object, given nine arguments to pass to the ctor of T template inline intrusive_ptr new_intrusive9(const A0& a0, const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8) { return intrusive_ptr(new T(a0, a1, a2, a3, a4, a5, a6, a7, a8)); } // ----------------------------------------------------------------------------- : Intrusive pointer base template class IntrusivePtrBase; template void intrusive_ptr_add_ref(IntrusivePtrBase*); template void intrusive_ptr_release(IntrusivePtrBase*); /// Base class for objects wishing to use intrusive_ptrs. /** There is no implicit virtual destructor, objects are destructed as type T * Usage: * @code * DECLARE_POINTER_TYPE(MyClass); * class MyClass : public IntrusivePtrBase { ... } * @endcode */ template class IntrusivePtrBase { public: inline IntrusivePtrBase() : ref_count(0) {} // don't copy construct the reference count! inline IntrusivePtrBase(const IntrusivePtrBase&) : ref_count(0) {} // don't assign the reference count! inline void operator = (const IntrusivePtrBase&) { } protected: /// Delete this object, can be overloaded inline void destroy() { delete static_cast(this); } private: AtomicInt ref_count; friend void intrusive_ptr_add_ref <> (IntrusivePtrBase*); friend void intrusive_ptr_release <> (IntrusivePtrBase*); }; template void intrusive_ptr_add_ref(IntrusivePtrBase* p) { ++(p->ref_count); } template void intrusive_ptr_release(IntrusivePtrBase* p) { if (--p->ref_count == 0) { static_cast(p)->destroy(); } } // ----------------------------------------------------------------------------- : Intrusive pointer base : virtual /// IntrusivePtrBase with a virtual destructor class IntrusivePtrVirtualBase : public IntrusivePtrBase { public: virtual ~IntrusivePtrVirtualBase() {} }; // ----------------------------------------------------------------------------- : Intrusive pointer base : with delete /// Base class for objects wishing to use intrusive_ptrs, using a manual delete function class IntrusivePtrBaseWithDelete : public IntrusivePtrBase { public: virtual ~IntrusivePtrBaseWithDelete() {} protected: /// Delete this object virtual void destroy() { delete this; } template friend void intrusive_ptr_release(IntrusivePtrBase*); }; #else #define DECLARE_POINTER_TYPE DECLARE_SHARED_POINTER_TYPE #define intrusive_ptr shared_ptr #define new_intrusive new_shared #define new_intrusive1 new_shared1 #define new_intrusive2 new_shared2 #define new_intrusive3 new_shared3 #define new_intrusive4 new_shared4 #define new_intrusive5 new_shared5 #define new_intrusive6 new_shared6 #define new_intrusive7 new_shared7 #define new_intrusive8 new_shared8 #define new_intrusive9 new_shared9 template class IntrusivePtrBase {}; /// IntrusivePtrBase with a virtual destructor class IntrusivePtrVirtualBase : public IntrusivePtrBase { public: virtual ~IntrusivePtrVirtualBase() {} }; class IntrusivePtrBaseWithDelete : public IntrusivePtrBase { public: virtual ~IntrusivePtrBaseWithDelete() {} protected: /// Delete this object virtual void destroy() { delete this; } }; #endif /// Pointer to 'anything' typedef intrusive_ptr VoidP; // ----------------------------------------------------------------------------- : EOF #endif