Main Page   Reference Manual   Namespace List   Compound List   Namespace Members   Compound Members   File Members  

libcwd/lockable_auto_ptr.h

Go to the documentation of this file.
00001 // $Header$
00002 //
00003 // Copyright (C) 2000 - 2004, by
00004 // 
00005 // Carlo Wood, Run on IRC <carlo@alinoe.com>
00006 // RSA-1024 0x624ACAD5 1997-01-26                    Sign & Encrypt
00007 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6  F6 F6 55 DD 1C DC FF 61
00008 //
00009 // This file may be distributed under the terms of the Q Public License
00010 // version 1.0 as appearing in the file LICENSE.QPL included in the
00011 // packaging of this file.
00012 //
00013 
00018 #ifndef LIBCWD_LOCKABLE_AUTO_PTR_H
00019 #define LIBCWD_LOCKABLE_AUTO_PTR_H
00020 
00021 // This header file is really part of libcw, and must be allowed to be used
00022 // without that libcwd installed or used.
00023 #ifndef CWDEBUG
00024 #ifndef LIBCWD_ASSERT
00025 #define LIBCWD_ASSERT(x)
00026 #endif
00027 #else // CWDEBUG
00028 #ifndef LIBCWD_PRIVATE_ASSERT_H
00029 #include <libcwd/private_assert.h>
00030 #endif
00031 #endif // CWDEBUG
00032 
00033 namespace libcwd {
00034 
00035 //===================================================================================================
00036 // class lockable_auto_ptr
00037 //
00038 // An 'auto_ptr' with lockable ownership.
00039 //
00040 // When the `lockable_auto_ptr' is not locked it behaves the same as
00041 // an 'auto_ptr': Ownership of the object it points to is transfered
00042 // when the `lockable_auto_ptr' is copied or assigned to another
00043 // `lockable_auto_ptr'.  The object it points to is deleted when the
00044 // `lockable_auto_ptr' that owns it is destructed.
00045 //
00046 // When the `lockable_auto_ptr' is locked, then the ownership is
00047 // not transfered, but stays on the same (locked) `lockable_auto_ptr'.
00048 //
00049 
00050 template<class X, bool array = false>   // Use array == true when `ptr' was allocated with new [].
00051   class lockable_auto_ptr {
00052     typedef X element_type;
00053 
00054     private:
00055     template<class Y, bool ARRAY> friend class lockable_auto_ptr;
00056     X* ptr;             // Pointer to object of type X, or NULL when not pointing to anything.
00057     bool locked;        // Set if this lockable_auto_ptr object is locked.
00058     mutable bool owner; // Set if this lockable_auto_ptr object is the owner of the object that
00059                         // `ptr' points too.
00060 
00061   public:
00062     //-----------------------------------------------------------------------------------------------
00063     // Constructors
00064     //
00065 
00066     explicit lockable_auto_ptr(X* p = 0) : ptr(p), locked(false), owner(p) { }
00067         // Explicit constructor that creates a lockable_auto_ptr pointing to `p'.
00068 
00069     lockable_auto_ptr(lockable_auto_ptr const& r) :
00070         ptr(r.ptr), locked(false), owner(r.owner && !r.locked)
00071         { if (!r.locked) r.owner = 0; }
00072         // The default copy constructor.
00073 
00074     template<class Y>
00075       lockable_auto_ptr(lockable_auto_ptr<Y, array> const& r) :
00076           ptr(r.ptr), locked(false), owner(r.owner && !r.locked)
00077           { if (!r.locked) r.owner = 0; }
00078         // Constructor to copy a lockable_auto_ptr that point to an object derived from X.
00079 
00080     //-----------------------------------------------------------------------------------------------
00081     // Operators
00082     //
00083 
00084     template<class Y>
00085     lockable_auto_ptr& operator=(lockable_auto_ptr<Y, array> const& r);
00086 
00087     lockable_auto_ptr& operator=(lockable_auto_ptr const& r) { return operator= <X> (r); }
00088         // The default assignment operator.
00089 
00090     //-----------------------------------------------------------------------------------------------
00091     // Destructor
00092     //
00093 
00094     ~lockable_auto_ptr() { if (owner) { if (array) delete [] ptr; else delete ptr; } }
00095 
00096     //-----------------------------------------------------------------------------------------------
00097     // Accessors
00098     //
00099 
00100     X& operator*() const { return *ptr; }
00101       // Access the object that this `lockable_auto_ptr' points to.
00102 
00103     X* operator->() const { return ptr; }
00104       // Access the object that this `lockable_auto_ptr' points to.
00105 
00106     X* get() const { return ptr; }
00107       // Return the pointer itself.
00108 
00109     bool strict_owner() const { LIBCWD_ASSERT(is_owner()); return locked; }
00110       // Returns `true' when this object is the strict owner.
00111       // You should only call this when this object is the owner.
00112 
00113 #ifdef CWDEBUG
00114     bool is_owner(void) const { return owner; }
00115       // Don't use this except for debug testing.
00116 #endif
00117 
00118     //-----------------------------------------------------------------------------------------------
00119     // Manipulators
00120     //
00121 
00122     void reset()
00123     {
00124       bool owns = owner;
00125       owner = 0;
00126       if (owns)
00127       {
00128         if (array)
00129           delete [] ptr;
00130         else
00131           delete ptr;
00132       }
00133       ptr = NULL;
00134     }
00135       // Get rid of object, if any.
00136 
00137     X* release() const { LIBCWD_ASSERT(is_owner()); owner = 0; return ptr; }
00138       // Release this object of its ownership (the caller is now responsible for deleting it if
00139       // this object was the owner).  You should only call this when this object is the owner.
00140 
00141     void lock() { LIBCWD_ASSERT(is_owner()); locked = true; }
00142       // Lock the ownership.
00143       // You should only call this when this object is the owner.
00144 
00145     void unlock() { locked = false; }
00146       // Unlock the ownership (if any).
00147   };
00148 
00149 template<class X, bool array>
00150   template<class Y>
00151     lockable_auto_ptr<X, array>&
00152     lockable_auto_ptr<X, array>::operator=(lockable_auto_ptr<Y, array> const& r)
00153     {
00154       if ((void*)&r != (void*)this)
00155       {
00156         if (owner) 
00157         {
00158           if (array)
00159             delete [] ptr;
00160           else
00161             delete ptr;
00162         }
00163         ptr = r.ptr;
00164         if (r.locked)
00165           owner = 0;
00166         else
00167         {
00168           owner = r.owner; 
00169           r.owner = 0;
00170         }
00171       }
00172       return *this;
00173     }
00174 
00175 } // namespace libcwd
00176 
00177 #endif // LIBCWD_LOCKABLE_AUTO_PTR_H
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.