Honeycomb  0.1
Component-Model Framework
UniquePtr.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Core/Core.h"
5 #include "Honey/Misc/Debug.h"
6 
7 namespace honey
8 {
9 
12 
14 template<class T, class Fin = finalize<T>>
15 class UniquePtr : mt::NoCopy
16 {
17  template<class, class> friend class UniquePtr;
18 
19  template<class T_> struct Elem_ { typedef T_ type; };
20  template<class T_> struct Elem_<T_[]> { typedef T_ type; };
21  template<class T_, bool = std::is_void<T_>::value> struct Ref_ { typedef T_& type; static type deref(T_* p) { return *p; } };
22  template<class T_> struct Ref_<T_, true> { typedef T_ type; static type deref(T_* p) {} };
23 
24 public:
25  typedef typename Elem_<T>::type Elem;
26  typedef typename Ref_<Elem>::type Ref;
27  typedef Elem* Ptr;
28 
29  UniquePtr() : _ptr(nullptr) {}
30  UniquePtr(nullptr_t) : _ptr(nullptr) {}
31  template<class Fin_ = Fin>
32  explicit UniquePtr(Ptr ptr, Fin_&& f = Fin_()) : _ptr(ptr), _fin(forward<Fin_>(f)) {}
34  UniquePtr(UniquePtr&& rhs) noexcept : _ptr(rhs.release()), _fin(forward<Fin>(rhs._fin)) {}
35  template<class U, class F>
36  UniquePtr(UniquePtr<U,F>&& rhs) : _ptr(rhs.release()), _fin(forward<F>(rhs._fin)) {}
37 
38  ~UniquePtr() { if (_ptr) _fin(_ptr); }
39 
41  UniquePtr& operator=(UniquePtr&& rhs) { return operator=<T,Fin>(move(rhs)); }
42  template<class U, class F>
43  UniquePtr& operator=(UniquePtr<U,F>&& rhs) { set(rhs.release()); _fin = forward<F>(rhs._fin); return *this; }
44 
45  template<class U, class F>
46  bool operator==(const UniquePtr<U,F>& rhs) const { return get() == rhs.get(); }
47  template<class U, class F>
48  bool operator!=(const UniquePtr<U,F>& rhs) const { return !operator==(rhs); }
49  template<class U, class F>
50  bool operator< (const UniquePtr<U,F>& rhs) const { return std::less<typename std::common_type<Ptr, typename UniquePtr<U,F>::Ptr>::type>()(get(), rhs.get()); }
51  template<class U, class F>
52  bool operator> (const UniquePtr<U,F>& rhs) const { return rhs.operator<(*this); }
53  template<class U, class F>
54  bool operator<=(const UniquePtr<U,F>& rhs) const { return !operator>(rhs); }
55  template<class U, class F>
56  bool operator>=(const UniquePtr<U,F>& rhs) const { return !operator<(rhs); }
57 
58  Ptr operator->() const { assert(_ptr); return _ptr; }
59  Ref operator*() const { assert(_ptr); return Ref_<Elem>::deref(_ptr); }
60  operator Ptr() const { return _ptr; }
61 
63  Ptr get() const { return _ptr; }
64 
66  Fin& finalizer() { return _fin; }
67  const Fin& finalizer() const { return _fin; }
68 
70  Ptr release() { Ptr tmp = _ptr; _ptr = nullptr; return tmp; }
71 
73  void set(Ptr p)
74  {
75  if (_ptr != p)
76  {
77  Ptr old = _ptr;
78  _ptr = p;
79  if (old) _fin(old);
80  }
81  }
82 
83 private:
84  Ptr _ptr;
85  Fin _fin;
86 };
87 
89 
90 template<class T, class Alloc, class... Args, class Fin = finalize<T,typename mt::removeRef<Alloc>::type>>
91 UniquePtr<T,Fin> alloc_unique(Alloc&& a, Args&&... args) { return UniquePtr<T,Fin>(new (a.allocate(1)) T(forward<Args>(args)...), Fin(forward<Alloc>(a))); }
93 
94 template<class T, class... Args, typename mt::disable_if<std::is_array<T>::value, int>::type=0, class Alloc = typename DefaultAllocator<T>::type>
95 UniquePtr<T> make_unique(Args&&... args) { return alloc_unique<T>(Alloc(), forward<Args>(args)...); }
97 
98 template<class T, class... Args, typename std::enable_if<std::is_array<T>::value, int>::type=0>
101 
102 template<class T, class... Args, typename std::enable_if<std::is_array<T>::value, int>::type=0>
103 UniquePtr<T> make_unique_auto_size(Args&&... args) { return UniquePtr<T>(new typename UniquePtr<T>::Elem[sizeof...(Args)]{forward<Args>(args)...}); }
104 
106 
107 }
108 
109 namespace std
110 {
112  template<class T, class Fin>
113  struct hash<honey::UniquePtr<T,Fin>>
114  {
115  size_t operator()(const honey::UniquePtr<T,Fin>& val) const { return reinterpret_cast<size_t>(val.get()); };
116  };
117 }
UniquePtr()
Definition: UniquePtr.h:29
Ref operator*() const
Definition: UniquePtr.h:59
bool operator!=(const UniquePtr< U, F > &rhs) const
Definition: UniquePtr.h:48
Fin & finalizer()
Get the finalizer.
Definition: UniquePtr.h:66
UniquePtr(nullptr_t)
Definition: UniquePtr.h:30
std::enable_if<!b, T > disable_if
Opposite of std::enable_if.
Definition: Meta.h:62
STL namespace.
void set(Ptr p)
Finalize old pointer and assign new. Does not finalize if old pointer is the same or null...
Definition: UniquePtr.h:73
Elem * Ptr
Definition: UniquePtr.h:27
UniquePtr< T, Fin > alloc_unique(Alloc &&a, Args &&...args)
Create a unique ptr to an object of type T constructed with args.
Definition: UniquePtr.h:91
UniquePtr< T > make_unique_auto_size(Args &&...args)
Create a unique ptr to an array with deduced size.
Definition: UniquePtr.h:103
UniquePtr< T > make_unique(szt size)
Create a unique ptr to an array of size number of elements.
Definition: UniquePtr.h:99
Elem_< T >::type Elem
Definition: UniquePtr.h:25
bool operator>=(const UniquePtr< U, F > &rhs) const
Definition: UniquePtr.h:56
UniquePtr(UniquePtr &&rhs) noexcept
Moves pointer and finalizer out of rhs. To set a new finalizer into rhs use move assign: rhs = Unique...
Definition: UniquePtr.h:34
size_t operator()(const honey::UniquePtr< T, Fin > &val) const
Definition: UniquePtr.h:115
Ptr get() const
Get the raw pointer to the object.
Definition: UniquePtr.h:63
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
bool operator<(const UniquePtr< U, F > &rhs) const
Definition: UniquePtr.h:50
UniquePtr & operator=(UniquePtr &&rhs)
Moves pointer and finalizer out of rhs.
Definition: UniquePtr.h:41
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
int size(const StdContainer &cont)
Safely get the size of a std container as a signed integer.
Definition: StdUtil.h:19
Ref_< Elem >::type Ref
Definition: UniquePtr.h:26
UniquePtr(UniquePtr< U, F > &&rhs)
Definition: UniquePtr.h:36
Ptr operator->() const
Definition: UniquePtr.h:58
bool operator==(const UniquePtr< U, F > &rhs) const
Definition: UniquePtr.h:46
Ptr release()
Give up ownership of pointer without finalizing and set to null.
Definition: UniquePtr.h:70
Pointer to a unique, non-shared, object. Finalizer is run upon destruction (deletes object by default...
Definition: SharedPtr.h:164
UniquePtr & operator=(UniquePtr< U, F > &&rhs)
Definition: UniquePtr.h:43
UniquePtr< T > make_unique(Args &&...args)
alloc_unique() using T::Allocator if available, otherwise std::allocator
Definition: UniquePtr.h:95
~UniquePtr()
Definition: UniquePtr.h:38
std::allocator< T > type
Definition: Allocator.h:152
Global Honeycomb namespace.
const Fin & finalizer() const
Definition: UniquePtr.h:67
bool operator>(const UniquePtr< U, F > &rhs) const
Definition: UniquePtr.h:52
UniquePtr(Ptr ptr, Fin_ &&f=Fin_())
Definition: UniquePtr.h:32