SPH
ClonePtr.h
Go to the documentation of this file.
1 #pragma once
2 
7 
9 
11 
12 template <typename T>
13 class ClonePtr;
14 
15 namespace Detail {
16 struct Cloner : public Polymorphic {
17 
18  virtual void* clonePtr() const = 0;
19 
20  virtual AutoPtr<Cloner> cloneThis() const = 0;
21 };
22 template <typename T>
23 class TypedCloner : public Cloner {
24 private:
25  T* ptr;
26 
27 public:
28  TypedCloner(T* ptr)
29  : ptr(ptr) {}
30 
31  virtual void* clonePtr() const override {
32  if (!ptr) {
33  return nullptr;
34  } else {
35  // clone the resource and itself
36  return alignedNew<T>(*ptr);
37  }
38  }
39 
40  virtual AutoPtr<Cloner> cloneThis() const override {
41  if (!ptr) {
42  return nullptr;
43  } else {
44  return makeAuto<TypedCloner<T>>(*this);
45  }
46  }
47 };
48 } // namespace Detail
49 
50 template <typename T>
51 class ClonePtr {
52  template <typename>
53  friend class ClonePtr;
54 
55 private:
56  AutoPtr<T> ptr;
57 
59 
61  : ptr(std::move(ptr))
62  , cloner(std::move(cloner)) {}
63 
64 public:
65  ClonePtr() = default;
66 
67  ClonePtr(std::nullptr_t) {}
68 
69  template <typename T2, typename = std::enable_if_t<std::is_convertible<T2*, T*>::value>>
70  explicit ClonePtr(T2* ptr)
71  : ptr(ptr)
72  , cloner(makeAuto<Detail::TypedCloner<T2>>(ptr)) {}
73 
74  ClonePtr(const ClonePtr& other)
75  : ClonePtr(other.clone()) {}
76 
77  template <typename T2, typename = std::enable_if_t<std::is_convertible<T2*, T*>::value>>
78  ClonePtr(const ClonePtr<T2>& other)
79  : ClonePtr(other.clone()) {} // delegate move constructor
80 
81  template <typename T2, typename = std::enable_if_t<std::is_convertible<T2*, T*>::value>>
83  : ptr(std::move(other.ptr))
84  , cloner(std::move(other.cloner)) {}
85 
86  ClonePtr& operator=(const ClonePtr& other) {
87  return this->operator=(other.clone());
88  }
89 
90  template <typename T2, typename = std::enable_if_t<std::is_convertible<T2*, T*>::value>>
91  ClonePtr& operator=(const ClonePtr<T2>& other) {
92  return this->operator=(other.clone());
93  }
94 
95  template <typename T2, typename = std::enable_if_t<std::is_convertible<T2*, T*>::value>>
97  ptr = std::move(other.ptr);
98  cloner = std::move(other.cloner);
99  return *this;
100  }
101 
102  template <typename T2, typename = std::enable_if_t<std::is_convertible<T*, T2*>::value>>
103  operator AutoPtr<T2>() && {
104  cloner.reset();
105  return std::move(ptr);
106  }
107 
108  template <typename T2, typename = std::enable_if_t<std::is_convertible<T*, T2*>::value>>
109  operator AutoPtr<T2>() const& {
110  return this->clone();
111  }
112 
114  ClonePtr<T> clone() const {
115  if (!ptr) {
116  return nullptr;
117  } else {
118  AutoPtr<T> cloned(static_cast<T*>(cloner->clonePtr()));
119  return ClonePtr<T>(std::move(cloned), cloner->cloneThis());
120  }
121  }
122 
123  T& operator*() const {
124  SPH_ASSERT(ptr);
125  return *ptr;
126  }
127 
129  SPH_ASSERT(ptr);
130  return ptr.get();
131  }
132 
133  RawPtr<T> get() const {
134  return ptr.get();
135  }
136 
137  explicit operator bool() const {
138  return bool(ptr);
139  }
140 
141  bool operator!() const {
142  return !ptr;
143  }
144 };
145 
146 template <typename T>
147 INLINE bool operator==(const ClonePtr<T>& ptr, const std::nullptr_t&) {
148  return !ptr;
149 }
150 
151 template <typename T>
152 INLINE bool operator==(const std::nullptr_t&, const ClonePtr<T>& ptr) {
153  return !ptr;
154 }
155 
156 template <typename T>
157 INLINE bool operator!=(const ClonePtr<T>& ptr, const std::nullptr_t&) {
158  return (bool)ptr;
159 }
160 
161 template <typename T>
162 INLINE bool operator!=(const std::nullptr_t&, const ClonePtr<T>& ptr) {
163  return (bool)ptr;
164 }
165 
166 template <typename T, typename... TArgs>
167 INLINE ClonePtr<T> makeClone(TArgs&&... args) {
168  return ClonePtr<T>(alignedNew<T>(std::forward<TArgs>(args)...));
169 }
170 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
Simplified implementation of std::unique_ptr, using only default deleter.
INLINE AutoPtr< T > makeAuto(TArgs &&... args)
Definition: AutoPtr.h:124
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
INLINE ClonePtr< T > makeClone(TArgs &&... args)
Definition: ClonePtr.h:167
INLINE bool operator==(const ClonePtr< T > &ptr, const std::nullptr_t &)
Definition: ClonePtr.h:147
INLINE bool operator!=(const ClonePtr< T > &ptr, const std::nullptr_t &)
Definition: ClonePtr.h:157
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
INLINE RawPtr< T > get() const
Definition: AutoPtr.h:69
INLINE void reset()
Definition: AutoPtr.h:87
RawPtr< T > get() const
Definition: ClonePtr.h:133
T & operator*() const
Definition: ClonePtr.h:123
ClonePtr(std::nullptr_t)
Definition: ClonePtr.h:67
ClonePtr< T > clone() const
Explicitly create a new copy.
Definition: ClonePtr.h:114
ClonePtr()=default
ClonePtr & operator=(ClonePtr< T2 > &&other)
Definition: ClonePtr.h:96
friend class ClonePtr
Definition: ClonePtr.h:53
ClonePtr & operator=(const ClonePtr< T2 > &other)
Definition: ClonePtr.h:91
ClonePtr(const ClonePtr &other)
Definition: ClonePtr.h:74
ClonePtr & operator=(const ClonePtr &other)
Definition: ClonePtr.h:86
ClonePtr(ClonePtr< T2 > &&other)
Definition: ClonePtr.h:82
bool operator!() const
Definition: ClonePtr.h:141
RawPtr< T > operator->() const
Definition: ClonePtr.h:128
ClonePtr(const ClonePtr< T2 > &other)
Definition: ClonePtr.h:78
ClonePtr(T2 *ptr)
Definition: ClonePtr.h:70
virtual void * clonePtr() const override
Definition: ClonePtr.h:31
TypedCloner(T *ptr)
Definition: ClonePtr.h:28
virtual AutoPtr< Cloner > cloneThis() const override
Definition: ClonePtr.h:40
Non-owning wrapper of pointer.
Definition: RawPtr.h:19
Overload of std::swap for Sph::Array.
Definition: Array.h:578
virtual void * clonePtr() const =0
virtual AutoPtr< Cloner > cloneThis() const =0
Base class for all polymorphic objects.
Definition: Object.h:88