summaryrefslogtreecommitdiff
path: root/ace/Refcounted_Auto_Ptr.h
blob: d480c125c686aa02bf7edad734263bb248630299 (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
199
200
201
202
203
204
205
206
207
// -*- C++ -*-

//=============================================================================
/**
 *  @file    Refcounted_Auto_Ptr.h
 *
 *  $Id$
 *
 *  @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"

#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.
 */
template <class X, class ACE_LOCK>
class ACE_Refcounted_Auto_Ptr
{
public:

  // = Initialization and termination methods.

  /// Constructor that initializes an @c ACE_Refcounted_Auto_Ptr to
  /// point to the result immediately.
  ACE_Refcounted_Auto_Ptr (X *p = 0);

  /// Copy constructor binds the created object and @c r to the same
  /// @c ACE_Refcounted_Auto_Ptr_Rep. An @c ACE_Refcounted_Auto_Ptr_Rep
  /// is created if necessary.
  ACE_Refcounted_Auto_Ptr (const ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> &r);

  /// Destructor.
  virtual ~ACE_Refcounted_Auto_Ptr (void);

  /// Assignment operator that binds the current object and @c r to the same
  /// @c ACE_Refcounted_Auto_Ptr_Rep. An @c 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@<X, ACE_LOCK@> objects point to the same
  /// ACE_Refcounted_Auto_Ptr_Rep@<X, ACE_LOCK@> object
  /**
   * @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 methods.

  X &operator *() const;

  /// Sets the pointer value to 0 and returns its old value.
  X *release (void);

  /// Invokes delete on the previous pointer value and then sets the
  /// pointer value to the specified value.
  void reset (X *p = 0);

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

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

  // = Utility method.

  /// Allows us to check for NULL on all ACE_Refcounted_Auto_Ptr objects.
  int 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<X, ACE_LOCK> object
 * encapsulates a pointer to an object of type X.  It is pointed to by
 * ACE_Refcounted_Auto_Ptr<X, ACE_LOCK> object[s] and only accessible
 * through them.
 */
template <class X, class ACE_LOCK>
class ACE_Refcounted_Auto_Ptr_Rep
{
private:
  friend class ACE_Refcounted_Auto_Ptr<X, ACE_LOCK>;

  /// Sets the pointer value to 0 and returns its old value.
  X *release (void);

  /// Invokes delete on the previous pointer value and then
  /// sets the pointer value to the specified value.
  void reset (X *p = 0);

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

  /// Get the reference count value.
  int 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 and return argument. Uses the
  /// attribute "ace_lock_" to synchronize reference count updating.
  ///
  /// Precondition (rep != 0).
  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);

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

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

  /// Reference count.
  int ref_count_;

  // = Mutex variable to protect the <ptr_>.

  /// Synchronization variable for the MT_SAFE <ACE_Hash_Map_Manager_Ex>.
  mutable ACE_LOCK lock_;

private:
  /// Allows us to check for NULL on all ACE_Refcounted_Auto_Ptr objects.
  int null (void) const;

  // = 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 */