-
Notifications
You must be signed in to change notification settings - Fork 7
/
scoped_ptr.h
256 lines (208 loc) · 7.25 KB
/
scoped_ptr.h
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// *** Note ***
// *** This code is deprecated in favor of the C++11-conforming ***
// *** eastl::unique_ptr template class found in <eastl/unique_ptr.h> ***
///////////////////////////////////////////////////////////////////////////////
#ifndef EASTL_SCOPED_PTR_H
#define EASTL_SCOPED_PTR_H
#include <eastl/internal/config.h>
#include <eastl/internal/smart_ptr.h> // Defines smart_ptr_deleter
#include <stddef.h>
#if defined(EASTL_PRAGMA_ONCE_SUPPORTED)
#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
#endif
namespace eastl
{
/// class scoped_ptr
///
/// This class is intended to be the same as the C++11 unique_ptr class,
/// but was created before there was such a thing.
///
/// This class implements a scoped_ptr template. This is a class which is
/// similar to the C++ auto_ptr template, except that it prohibits copying
/// of itself, for safety.
///
/// More specifically, the scoped_ptr class template stores a pointer to a
/// dynamically allocated object. The object pointed to is automatically
/// deleted on destructor of scoped_ptr or can be manually deleted via the
/// scopted_ptr::reset function.
///
/// scoped_ptr cannot be used in C++ Standard Library containers; you'll need
/// to use the shared_ptr template if you want to do this. The reason you can't
/// use scoped_ptr is that it prohibits copying. You can't (safely) use auto_ptr
/// in C++ Standard Library containers because copying of an auto_ptr will
/// create a situation whereby objects are multiply freed.
///
/// scoped_ptr cannot be used with arrays of objects. The reason for this is
/// that it calls delete on the owned pointer and not delete[]. The latter
/// allows for the calling of the destructors for the objects of the owned pointer.
/// If you want to use scoped_ptr with a dynamically allocated array, use the
/// scoped_array function instead.
///
template <typename T, typename Deleter = smart_ptr_deleter<T> >
class scoped_ptr
{
protected:
/// this_type
/// This is an alias for scoped_ptr<T>, this class.
typedef scoped_ptr<T> this_type;
/// deleter_type
typedef Deleter deleter_type;
/// mpValue
/// The owned pointer.
T* mpValue;
/// scoped_ptr
/// This function is private in order to prevent copying, for safety.
scoped_ptr(const scoped_ptr&);
/// scoped_ptr
/// This function is private in order to prevent copying, for safety.
scoped_ptr& operator=(const scoped_ptr&);
/// scoped_ptr
/// This function is private in order to prevent copying, for safety.
scoped_ptr& operator=(T* pValue);
public:
typedef T element_type;
/// scoped_ptr
/// Construct a scoped_ptr from a pointer allocated via new.
/// Example usage:
/// scoped_ptr<int> ptr(new int(3));
explicit scoped_ptr(T* pValue = NULL)
: mpValue(pValue) {}
/// ~scoped_ptr
/// Destroys the owned pointer. The destructor for the object
/// referred to by the owned pointer will be called.
~scoped_ptr()
{
Deleter del;
del(mpValue);
}
/// reset
/// Deletes the owned pointer and takes ownership of the
/// passed in pointer. If the passed in pointer is the same
/// as the owned pointer, nothing is done.
/// Example usage:
/// scoped_ptr<int> ptr(new int(3));
/// ptr.reset(new int(4)); // deletes int(3)
/// ptr.reset(NULL); // deletes int(4)
void reset(T* pValue = NULL)
{
if(pValue != mpValue)
{
Deleter del;
del(mpValue);
mpValue = pValue;
}
}
/// detach
/// This simply forgets the owned pointer. It doesn't
/// free it but rather assumes that the user does.
/// Example usage:
/// scoped_ptr<int> ptr(new int(3));
/// int* pInt = ptr.detach();
/// delete pInt;
T* detach()
{
T* const pTemp = mpValue;
mpValue = NULL;
return pTemp;
}
/// swap
/// Exchanges the owned pointer beween two scoped_ptr objects.
void swap(this_type& scopedPtr)
{
// std::swap(mpValue, scopedPtr.mpValue); // Not used so that we can reduce a dependency.
T* const pValue = scopedPtr.mpValue;
scopedPtr.mpValue = mpValue;
mpValue = pValue;
}
/// operator*
/// Returns the owner pointer dereferenced.
/// Example usage:
/// scoped_ptr<int> ptr(new int(3));
/// int x = *ptr;
typename add_lvalue_reference<T>::type operator*() const
{
// assert(mpValue);
return *mpValue;
}
/// operator->
/// Allows access to the owned pointer via operator->()
/// Example usage:
/// struct X{ void DoSomething(); };
/// scoped_ptr<int> ptr(new X);
/// ptr->DoSomething();
T* operator->() const
{
// assert(mpValue);
return mpValue;
}
/// get
/// Returns the owned pointer. Note that this class does
/// not provide an operator T() function. This is because such
/// a thing (automatic conversion) is deemed unsafe.
/// Example usage:
/// struct X{ void DoSomething(); };
/// scoped_ptr<int> ptr(new X);
/// X* pX = ptr.get();
/// pX->DoSomething();
T* get() const
{
return mpValue;
}
/// Implicit operator bool
/// Allows for using a scoped_ptr as a boolean.
/// Example usage:
/// scoped_ptr<int> ptr(new int(3));
/// if(ptr)
/// ++*ptr;
///
/// Note that below we do not use operator bool(). The reason for this
/// is that booleans automatically convert up to short, int, float, etc.
/// The result is that this: if(scopedPtr == 1) would yield true (bad).
typedef T* (this_type::*bool_)() const;
operator bool_() const
{
if(mpValue)
return &this_type::get;
return NULL;
}
/// operator!
/// This returns the opposite of operator bool; it returns true if
/// the owned pointer is null. Some compilers require this and some don't.
/// scoped_ptr<int> ptr(new int(3));
/// if(!ptr)
/// assert(false);
bool operator!() const
{
return (mpValue == NULL);
}
}; // class scoped_ptr
/// get_pointer
/// returns scoped_ptr::get() via the input scoped_ptr.
template <typename T, typename D>
inline T* get_pointer(const scoped_ptr<T, D>& scopedPtr)
{
return scopedPtr.get();
}
/// swap
/// Exchanges the owned pointer beween two scoped_ptr objects.
/// This non-member version is useful for compatibility of scoped_ptr
/// objects with the C++ Standard Library and other libraries.
template <typename T, typename D>
inline void swap(scoped_ptr<T, D>& scopedPtr1, scoped_ptr<T, D>& scopedPtr2)
{
scopedPtr1.swap(scopedPtr2);
}
/// operator<
/// Returns which scoped_ptr is 'less' than the other. Useful when storing
/// sorted containers of scoped_ptr objects.
template <typename T, typename D>
inline bool operator<(const scoped_ptr<T, D>& scopedPtr1, const scoped_ptr<T, D>& scopedPtr2)
{
return (scopedPtr1.get() < scopedPtr2.get()); // Alternatively use: std::less<T*>(scopedPtr1.get(), scopedPtr2.get());
}
} // namespace eastl
#endif // Header include guard