16 #ifndef INCLUDE_NN_NLIB_UNIQUEPTR_H_ 17 #define INCLUDE_NN_NLIB_UNIQUEPTR_H_ 23 #include "nn/nlib/Swap.h" 24 #include "nn/nlib/Hash.h" 27 #if defined(NLIB_CXX11_UNIQUEPTR) && defined(__cpp_alias_templates) 30 template<
class T,
class DEL = std::default_delete<T> >
31 using UniquePtr = std::unique_ptr<T, DEL>;
33 using DefaultDelete = std::default_delete<T>;
42 struct DefaultDelete {
50 struct DefaultDelete<T[]> {
57 NLIB_STATIC_ASSERT(IsEmpty<DefaultDelete<int> >::value&& IsEmpty<DefaultDelete<
int[]> >::value);
61 template<
class T,
class DEL,
bool DEL_EMPTY>
64 UniquePtrBase() : ptr_(NULL), deleter_() {}
65 explicit UniquePtrBase(T* ptr) : ptr_(ptr), deleter_() {}
66 UniquePtrBase(T* ptr,
const DEL& del) : ptr_(ptr), deleter_(del) {}
69 DEL& get_deleter() {
return deleter_; }
70 const DEL& get_deleter()
const {
return deleter_; }
75 swap(this->ptr_, rhs.ptr_);
76 swap(this->deleter_, rhs.deleter_);
81 template<
class T,
class DEL>
82 class UniquePtrBase<T, DEL, true> :
public DEL {
84 UniquePtrBase() : ptr_(NULL) {}
85 explicit UniquePtrBase(T* ptr) : ptr_(ptr) {}
86 UniquePtrBase(T* ptr,
const DEL& del) : DEL(del), ptr_(ptr) {}
89 DEL& get_deleter() {
return *
this; }
90 const DEL& get_deleter()
const {
return *
this; }
94 swap(this->ptr_, rhs.ptr_);
100 struct IsCompleteType :
public IntegralConstant<bool, (sizeof(S) != 0 || sizeof(S) == 0)> {};
103 struct IsCompleteType<void> :
public TrueType {};
107 template<
class T,
class DEL = DefaultDelete<T> >
109 typedef detail::UniquePtrBase<T, DEL, IsEmpty<DEL>::value> BaseType;
112 typedef T* pointer_type;
113 typedef DEL deleter_type;
114 typedef T element_type;
119 UniquePtr(T* p,
const DEL& del) : BaseType(p, del) {}
131 if (this->ptr_) get_deleter()(this->ptr_);
136 if (p != this->ptr_) {
139 if (old) get_deleter()(old);
142 typename AddRef<T>::type
operator*()
const {
143 NLIB_ASSERT(this->ptr_ != NULL);
147 NLIB_ASSERT(this->ptr_ != NULL);
160 size_t GetHash()
const {
return Hash<T*>()(this->
get()); }
161 DEL& get_deleter() {
return BaseType::get_deleter(); }
162 const DEL& get_deleter()
const {
return BaseType::get_deleter(); }
167 template<
class S,
class D>
169 template<
class S,
class D>
174 template<
class T,
class DEL>
175 class UniquePtr<T[], DEL> :
public detail::UniquePtrBase<T, DEL, IsEmpty<DEL>::value> {
176 typedef detail::UniquePtrBase<T, DEL, IsEmpty<DEL>::value> BaseType;
179 typedef T* pointer_type;
180 typedef DEL deleter_type;
181 typedef T element_type;
186 UniquePtr(T* p,
const DEL& del) : BaseType(p, del) {}
187 UniquePtr(UniquePtr& rhs, move_tag)
NLIB_NOEXCEPT : BaseType() { swap(rhs); }
189 UniquePtr tmp(release());
196 get_deleter()(this->ptr_);
201 if (p != this->ptr_) {
204 if (old) get_deleter()(old);
208 NLIB_ASSERT(this->ptr_ != NULL);
212 NLIB_ASSERT(this->ptr_ != NULL);
221 T& operator[](
size_t n) {
return get()[n]; }
222 const T& operator[](
size_t n)
const {
return get()[n]; }
223 size_t GetHash()
const {
return Hash<T*>()(this->
get()); }
224 DEL& get_deleter() {
return BaseType::get_deleter(); }
225 const DEL& get_deleter()
const {
return BaseType::get_deleter(); }
230 template<
class S,
class D>
231 bool operator==(
const UniquePtr<S, D>& p)
const;
232 template<
class S,
class D>
233 bool operator!=(
const UniquePtr<S, D>& p)
const;
237 template<
class T1,
class D1,
class T2,
class D2>
239 return rhs.get() == lhs.get();
242 template<
class T1,
class D1>
247 template<
class T1,
class D1>
252 template<
class T1,
class D1,
class T2,
class D2>
254 return rhs.get() != lhs.get();
257 template<
class T1,
class D1>
259 return static_cast<bool>(lhs);
262 template<
class T1,
class D1>
264 return static_cast<bool>(rhs);
269 NLIB_DEFINE_STD_SWAP_T_BEGIN2(
nn, nlib)
270 NLIB_DEFINE_STD_SWAP_T2(T, DEL, NLIB_NS::UniquePtr)
271 NLIB_DEFINE_STD_SWAP_T_END2(
nn, nlib)
273 NLIB_DEFINE_STD_HASH_BEGIN2(
nn, nlib)
274 NLIB_DEFINE_STD_HASH_T2(T, DEL, NLIB_NS::UniquePtr)
275 NLIB_DEFINE_STD_HASH_END2(
nn, nlib)
294 template<
class T,
class ALLOC,
bool DEL_EMPTY>
295 class DefaultDeleteExBase {
297 DefaultDeleteExBase() : al() {}
298 explicit DefaultDeleteExBase(
const ALLOC& al_) : al(al_) {}
301 ALLOC& get_allocator() {
return al; }
308 template<
class T,
class ALLOC>
309 class DefaultDeleteExBase<T, ALLOC, true> :
public ALLOC {
311 DefaultDeleteExBase() {}
312 explicit DefaultDeleteExBase(
const ALLOC& al_) { NLIB_UNUSED(al_); }
315 ALLOC& get_allocator() {
return *
this; }
320 template<
class T,
class ALLOC = std::allocator<T> >
321 struct DefaultDeleteEx :
public detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> {
325 typedef detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> BaseType;
327 ALLOC& al = BaseType::get_allocator();
334 template<
class T,
class ALLOC>
335 struct DefaultDeleteEx<T[], ALLOC>
336 :
public detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> {
344 typedef detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> BaseType;
348 ALLOC& al = BaseType::get_allocator();
357 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS 358 template<
class T,
class DEL>
361 template<
class T,
class DEL>
365 #endif // INCLUDE_NN_NLIB_UNIQUEPTR_H_ Substitute definitions for the C++11 standard header type_traits. These substitute definitions are us...
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
Prohibits use of the copy constructor and assignment operator for the class specified by TypeName...
#define NLIB_SAFE_BOOL(class_name, exp)
Defines a safe operator bool function in the class. Uses the C++11 explicit bool if it is available f...
In the C++11 environment (which supports alias templates), std::unique_ptr is made an alias template...
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are equal.
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
Returns true if the two compared summaries are not equal.
An empty structure indicating that an argument to a function needs to be moved.
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
#define NLIB_CEXPR
Defines constexpr if it is available for use. If not, holds an empty string.
A file that contains the configuration information for each development environment.
TimeSpan operator*(int i, const TimeSpan &rhs) noexcept
Increases rhs by a factor of i.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
#define NLIB_STATIC_ASSERT(exp)
Defines a static assertion. Uses static_assert if it is available for use.