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

lockable_auto_ptr.h
Go to the documentation of this file.
1 // $Header$
2 //
3 // Copyright (C) 2000 - 2004, by
4 //
5 // Carlo Wood, Run on IRC <carlo@alinoe.com>
6 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
8 //
9 // This file may be distributed under the terms of the Q Public License
10 // version 1.0 as appearing in the file LICENSE.QPL included in the
11 // packaging of this file.
12 //
13 
18 #ifndef LIBCWD_LOCKABLE_AUTO_PTR_H
19 #define LIBCWD_LOCKABLE_AUTO_PTR_H
20 
21 // This header file is really part of libcw, and must be allowed to be used
22 // without that libcwd installed or used.
23 #ifndef CWDEBUG
24 #ifndef LIBCWD_ASSERT
25 #define LIBCWD_ASSERT(x)
26 #endif
27 #else // CWDEBUG
28 #ifndef LIBCWD_PRIVATE_ASSERT_H
29 #include <libcwd/private_assert.h>
30 #endif
31 #endif // CWDEBUG
32 
33 namespace libcwd {
34 
35 //===================================================================================================
36 // class lockable_auto_ptr
37 //
38 // An 'auto_ptr' with lockable ownership.
39 //
40 // When the `lockable_auto_ptr' is not locked it behaves the same as
41 // an 'auto_ptr': Ownership of the object it points to is transfered
42 // when the `lockable_auto_ptr' is copied or assigned to another
43 // `lockable_auto_ptr'. The object it points to is deleted when the
44 // `lockable_auto_ptr' that owns it is destructed.
45 //
46 // When the `lockable_auto_ptr' is locked, then the ownership is
47 // not transfered, but stays on the same (locked) `lockable_auto_ptr'.
48 //
49 
50 template<class X, bool array = false> // Use array == true when `ptr' was allocated with new [].
51  class lockable_auto_ptr {
52  typedef X element_type;
53 
54  private:
55  template<class Y, bool ARRAY> friend class lockable_auto_ptr;
56  X* ptr; // Pointer to object of type X, or NULL when not pointing to anything.
57  bool locked; // Set if this lockable_auto_ptr object is locked.
58  mutable bool owner; // Set if this lockable_auto_ptr object is the owner of the object that
59  // `ptr' points too.
60 
61  public:
62  //-----------------------------------------------------------------------------------------------
63  // Constructors
64  //
65 
66  explicit lockable_auto_ptr(X* p = 0) : ptr(p), locked(false), owner(p) { }
67  // Explicit constructor that creates a lockable_auto_ptr pointing to `p'.
68 
69  lockable_auto_ptr(lockable_auto_ptr const& r) :
70  ptr(r.ptr), locked(false), owner(r.owner && !r.locked)
71  { if (!r.locked) r.owner = 0; }
72  // The default copy constructor.
73 
74  template<class Y>
75  lockable_auto_ptr(lockable_auto_ptr<Y, array> const& r) :
76  ptr(r.ptr), locked(false), owner(r.owner && !r.locked)
77  { if (!r.locked) r.owner = 0; }
78  // Constructor to copy a lockable_auto_ptr that point to an object derived from X.
79 
80  //-----------------------------------------------------------------------------------------------
81  // Operators
82  //
83 
84  template<class Y>
85  lockable_auto_ptr& operator=(lockable_auto_ptr<Y, array> const& r);
86 
87  lockable_auto_ptr& operator=(lockable_auto_ptr const& r) { return operator= <X> (r); }
88  // The default assignment operator.
89 
90  //-----------------------------------------------------------------------------------------------
91  // Destructor
92  //
93 
94  ~lockable_auto_ptr() { if (owner) { if (array) delete [] ptr; else delete ptr; } }
95 
96  //-----------------------------------------------------------------------------------------------
97  // Accessors
98  //
99 
100  X& operator*() const { return *ptr; }
101  // Access the object that this `lockable_auto_ptr' points to.
102 
103  X* operator->() const { return ptr; }
104  // Access the object that this `lockable_auto_ptr' points to.
105 
106  X* get() const { return ptr; }
107  // Return the pointer itself.
108 
109  bool strict_owner() const { LIBCWD_ASSERT(is_owner()); return locked; }
110  // Returns `true' when this object is the strict owner.
111  // You should only call this when this object is the owner.
112 
113 #ifdef CWDEBUG
114  bool is_owner(void) const { return owner; }
115  // Don't use this except for debug testing.
116 #endif
117 
118  //-----------------------------------------------------------------------------------------------
119  // Manipulators
120  //
121 
122  void reset()
123  {
124  bool owns = owner;
125  owner = 0;
126  if (owns)
127  {
128  if (array)
129  delete [] ptr;
130  else
131  delete ptr;
132  }
133  ptr = NULL;
134  }
135  // Get rid of object, if any.
136 
137  X* release() const { LIBCWD_ASSERT(is_owner()); owner = 0; return ptr; }
138  // Release this object of its ownership (the caller is now responsible for deleting it if
139  // this object was the owner). You should only call this when this object is the owner.
140 
141  void lock() { LIBCWD_ASSERT(is_owner()); locked = true; }
142  // Lock the ownership.
143  // You should only call this when this object is the owner.
144 
145  void unlock() { locked = false; }
146  // Unlock the ownership (if any).
147  };
148 
149 template<class X, bool array>
150  template<class Y>
151  lockable_auto_ptr<X, array>&
152  lockable_auto_ptr<X, array>::operator=(lockable_auto_ptr<Y, array> const& r)
153  {
154  if ((void*)&r != (void*)this)
155  {
156  if (owner)
157  {
158  if (array)
159  delete [] ptr;
160  else
161  delete ptr;
162  }
163  ptr = r.ptr;
164  if (r.locked)
165  owner = 0;
166  else
167  {
168  owner = r.owner;
169  r.owner = 0;
170  }
171  }
172  return *this;
173  }
174 
175 } // namespace libcwd
176 
177 #endif // LIBCWD_LOCKABLE_AUTO_PTR_H
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.