summaryrefslogtreecommitdiff
path: root/ACE/ace/Refcounted_Auto_Ptr.h
blob: aa133352a350a4e7204c1505c3c5c33590c48da2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// -*- C++ -*-

//=============================================================================
/**
 *  @file    Refcounted_Auto_Ptr.h
 *
 *  @author John Tucker <JTucker@infoglide.com>
 */
//=============================================================================

#ifndef ACE_REFCOUNTED_AUTO_PTR_H
#define ACE_REFCOUNTED_AUTO_PTR_H

#include /**/ "ace/pre.h"

#include "ace/Auto_Ptr.h"
#include "ace/Atomic_Op.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

// Forward decl.
template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr_Rep;
template <class X, class ACE_LOCK> class ACE_Refcounted_Auto_Ptr;

/**
 * @class ACE_Refcounted_Auto_Ptr
 *
 * @brief This class implements support for a reference counted auto_ptr.
 * Assigning or copying instances of an ACE_Refcounted_Auto_Ptr
 * will automatically increment the reference count. When the last
 * instance that references a ACE_Refcounted_Auto_Ptr instance is
 * destroyed or overwritten, it will invoke delete on its underlying
 * pointer.
 *
 * The ACE_Refcounted_Auto_Ptr works by maintaining a reference to a
 * separate representation object, ACE_Refcounted_Auto_Ptr_Rep. That
 * separate representation object contains the reference count and
 * the actual pointer value.
 */
template <class X, class ACE_LOCK>
class ACE_Refcounted_Auto_Ptr
{
  /// Used to define a proper boolean conversion for "if (sp) ..."
  static void unspecified_bool(ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>***){};
  typedef void (*unspecified_bool_type)(ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>***);

public:
  /// Constructor that initializes an ACE_Refcounted_Auto_Ptr to
  /// the specified pointer value.
  explicit ACE_Refcounted_Auto_Ptr (X *p = 0);

  /// Copy constructor binds the new ACE_Refcounted_Auto_Ptr to the
  /// representation object referenced by @a r.
  /// An ACE_Refcounted_Auto_Ptr_Rep is created if necessary.
  ACE_Refcounted_Auto_Ptr (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r);

  /// Destructor. Releases the reference to the underlying representation.
  /// If the release of that reference causes its reference count to reach 0,
  /// the representation object will also be destroyed.
  virtual ~ACE_Refcounted_Auto_Ptr (void);

  /// Assignment operator that binds the current object and @a r to the same
  /// ACE_Refcounted_Auto_Ptr_Rep. An ACE_Refcounted_Auto_Ptr_Rep
  /// is created if necessary.
  void operator = (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r);

  /// Equality operator that returns @c true if both
  /// ACE_Refcounted_Auto_Ptr objects point to the same underlying
  /// representation. It does not compare the actual pointers.
  /**
   * @note It also returns @c true if both objects have just been
   *       instantiated and not used yet.
   */
  bool operator == (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r) const;

  /// Inequality operator, which is the opposite of equality.
  bool operator != (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r) const;

  /// Redirection operator
  X *operator-> (void) const;

  /// Accessor method.
  X &operator *() const;

  /// Check rep easily.
  bool operator !() const;

  /// Check rep easily.
  operator unspecified_bool_type() const;

  /// Releases the reference to the underlying representation object.
  /// @retval The pointer value prior to releasing it.
  X *release (void);

  /// Releases the current pointer value and then sets a new
  /// pointer value specified by @a p.
  void reset (X *p = 0);

  /// Get the pointer value.
  X *get (void) const;

  /// Get the reference count value.
  long count (void) const;

  /// Returns @c true if this object does not contain a valid pointer.
  bool null (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:
  /// the ACE_Refcounted_Auto_Ptr_Rep
  typedef ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> AUTO_REFCOUNTED_PTR_REP;

  /// Protect operations on the ACE_Refcounted_Auto_Ptr.
  AUTO_REFCOUNTED_PTR_REP *rep_;
};

/**
 * @class ACE_Refcounted_Auto_Ptr_Rep
 *
 * @brief An ACE_Refcounted_Auto_Ptr_Rep object encapsulates a pointer
 * to an object of type X. It uses a lock object of type ACE_LOCK to protect
 * access to the reference count.
 *
 * @internal ACE_Refcounted_Auto_Ptr_Rep is used internally by the
 * ACE_Refcounted_Auto_Ptr class and is only accessible through it.
 */
template <class X, class ACE_LOCK>
class ACE_Refcounted_Auto_Ptr_Rep
{
private:
  friend class ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>;

  /// Get the pointer value.
  X *get (void) const;

  /// Get the reference count value.
  long count (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

  // = Encapsulate reference count and object lifetime of instances.
  // These methods must go after the others to work around a bug with
  // Borland's C++ Builder...

  /// Allocate a new ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> instance,
  /// returning NULL if it cannot be created.
  static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *internal_create (X *p);

  /// Create a ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> and initialize
  /// the reference count.
  static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *create (X *p);

  /// Increase the reference count on @a rep.
  ///
  /// @retval @a rep if success, 0 if there's an error obtaining the lock
  ///         on @a rep.
  static ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *attach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep);

  /// Decreases the reference count and and deletes rep if there are no
  /// more references to rep.
  ///
  /// Precondition (rep != 0)
  static void detach (ACE_Refcounted_Auto_Ptr_Rep<X, ACE_LOCK> *&rep);

  /// Pointer to the result.
  ACE_Auto_Basic_Ptr<X> ptr_;

  /// Reference count.
  mutable ACE_Atomic_Op<ACE_LOCK, long> ref_count_;

private:
  // = Constructor and destructor private.
  ACE_Refcounted_Auto_Ptr_Rep (X *p = 0);
  ~ACE_Refcounted_Auto_Ptr_Rep (void);
};

ACE_END_VERSIONED_NAMESPACE_DECL

#include "ace/Refcounted_Auto_Ptr.inl"

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Refcounted_Auto_Ptr.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Refcounted_Auto_Ptr.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#include /**/ "ace/post.h"

#endif /* ACE_REFCOUNTED_AUTO_PTR_H */