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(NLIB_CXX11_TEMPLATE_ALIAS) 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
101 :
public IntegralConstant<bool, (sizeof(S) != 0 || sizeof(S) == 0)> {};
104 struct IsCompleteType<void> :
public TrueType {};
108 template <
class T,
class DEL = DefaultDelete<T> >
110 typedef detail::UniquePtrBase<T, DEL, IsEmpty<DEL>::value> BaseType;
121 NLIB_MOVE_MEMBER_HELPER_1(
UniquePtr, BaseType)
126 if (this->ptr_) get_deleter()(this->ptr_);
131 if (p != this->ptr_) {
134 if (old) get_deleter()(old);
138 NLIB_ASSERT(this->ptr_ != NULL);
142 NLIB_ASSERT(this->ptr_ != NULL);
158 size_t GetHash()
const {
return Hash<T*>()(this->
get()); }
160 const DEL&
get_deleter()
const {
return BaseType::get_deleter(); }
165 template <
class S,
class D>
167 template <
class S,
class D>
172 template <
class T,
class DEL>
173 class UniquePtr<T[], DEL> :
public detail::UniquePtrBase<T, DEL, IsEmpty<DEL>::value> {
174 typedef detail::UniquePtrBase<T, DEL, IsEmpty<DEL>::value> BaseType;
184 UniquePtr(T* p,
const DEL& del) : BaseType(p, del) {}
185 NLIB_MOVE_MEMBER_HELPER_1(
UniquePtr, BaseType)
188 get_deleter()(this->ptr_);
193 if (p != this->ptr_) {
196 if (old) get_deleter()(old);
200 NLIB_ASSERT(this->ptr_ != NULL);
204 NLIB_ASSERT(this->ptr_ != NULL);
216 T& operator[](
size_t n) {
return get()[n]; }
217 const T& operator[](
size_t n)
const {
return get()[n]; }
218 size_t GetHash()
const {
return Hash<T*>()(this->
get()); }
219 DEL& get_deleter() {
return BaseType::get_deleter(); }
220 const DEL& get_deleter()
const {
return BaseType::get_deleter(); }
225 template <
class S,
class D>
227 template <
class S,
class D>
232 template <
class T1,
class D1,
class T2,
class D2>
234 return rhs.get() == lhs.get();
237 template <
class T1,
class D1>
242 template <
class T1,
class D1>
247 template <
class T1,
class D1,
class T2,
class D2>
249 return rhs.get() != lhs.get();
252 template <
class T1,
class D1>
254 return static_cast<bool>(lhs);
257 template <
class T1,
class D1>
259 return static_cast<bool>(rhs);
264 #ifndef NLIB_STD_SWAP_WORKAROUND 267 NLIB_DEFINE_STD_SWAP_T_BEGIN1(
std)
270 NLIB_DEFINE_STD_SWAP_T2(T, DEL, NLIB_NS::UniquePtr)
272 #ifndef NLIB_STD_SWAP_WORKAROUND 275 NLIB_DEFINE_STD_SWAP_T_END1(
std)
278 #ifndef NLIB_CXX11_TEMPLATE_ALIAS 281 NLIB_DEFINE_STD_HASH_T_BEGIN1(
std)
284 NLIB_DEFINE_STD_HASH_T2(T, DEL, NLIB_NS::UniquePtr)
286 #ifndef NLIB_CXX11_TEMPLATE_ALIAS 289 NLIB_DEFINE_STD_HASH_T_END1(
std)
309 template <
class T,
class ALLOC,
bool DEL_EMPTY>
310 class DefaultDeleteExBase {
312 DefaultDeleteExBase() : al() {}
313 explicit DefaultDeleteExBase(
const ALLOC& al_) : al(al_) {}
316 ALLOC& get_allocator() {
return al; }
323 template <
class T,
class ALLOC>
324 class DefaultDeleteExBase<T, ALLOC, true> :
public ALLOC {
326 DefaultDeleteExBase() {}
327 explicit DefaultDeleteExBase(
const ALLOC& al_) { NLIB_UNUSED(al_); }
330 ALLOC& get_allocator() {
return *
this; }
335 template <
class T,
class ALLOC = std::allocator<T> >
336 struct DefaultDeleteEx :
public detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> {
340 typedef detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> BaseType;
342 ALLOC& al = BaseType::get_allocator();
349 template <
class T,
class ALLOC>
350 struct DefaultDeleteEx<T[], ALLOC>
351 :
public detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> {
359 typedef detail::DefaultDeleteExBase<T, ALLOC, IsEmpty<ALLOC>::value> BaseType;
363 ALLOC& al = BaseType::get_allocator();
372 #ifdef NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS 373 template<
class T,
class DEL>
376 template<
class T,
class DEL>
380 #endif // INCLUDE_NN_NLIB_UNIQUEPTR_H_ ~UniquePtr() noexcept
Destructor. If the pointer is not NULL, executes the deleter and deletes.
UniquePtr(T *p) noexcept
Sets a pointer.
Substitute definitions for the C++11 standard header type_traits. These substitute definitions are us...
DEL & get_deleter()
Gets the deleter.
constexpr UniquePtr(nullptr_t) noexcept
This function is called if nullptr has been passed to a parameter.
#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...
T element_type
Defines T using typedef.
UniquePtr owns the pointer, and when it goes out of scope, the pointer is released by the destructor ...
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.
void reset(T *p=0) noexcept
Replaces a pointer. The replaced pointer is deleted.
constexpr UniquePtr() noexcept
Instantiates the object with default parameters (default constructor).
size_t GetHash() const
Computes the hash value for the pointer and returns the calculation result.
UniquePtr & operator=(nullptr_t) noexcept
Substitutes for nullptr.
AddRef< T >::type operator*() const
Dereferences the pointer.
void swap(UniquePtr &rhs) noexcept
Swaps the pointer that is being stored.
T * operator->() const noexcept
Returns the pointer.
DEL deleter_type
Defines DEL using typedef.
const DEL & get_deleter() const
Gets the deleter.
#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.
UniquePtr(T *p, const DEL &del)
Sets a pointer and a deleter.
#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.
T * pointer_type
Defines T* using typedef.
T * release() noexcept
Release ownership of the pointer and returns the pointer.