1 #ifndef CASM_cloneable_ptr_HH
2 #define CASM_cloneable_ptr_HH
12 #define ABSTRACT_CLONEABLE(T) \
16 std::unique_ptr<T> clone() const { \
17 return std::unique_ptr<T>(this->_clone()); \
19 std::unique_ptr<T> move() { return std::unique_ptr<T>(this->_move()); } \
22 virtual T *_clone() const = 0; \
23 virtual T *_move() = 0; \
29 #define ABSTRACT_CLONEABLE_DERIVED(T) \
33 std::unique_ptr<T> clone() const { \
34 return std::unique_ptr<T>(this->_clone()); \
36 std::unique_ptr<T> move() { return std::unique_ptr<T>(this->_move()); } \
39 virtual T *_clone() const override = 0; \
40 virtual T *_move() override = 0; \
46 #define CLONEABLE(T) \
50 std::unique_ptr<T> clone() const { \
51 return std::unique_ptr<T>(this->_clone()); \
53 std::unique_ptr<T> move() { return std::unique_ptr<T>(this->_move()); } \
56 virtual T *_clone() const override { return new T(*this); } \
57 virtual T *_move() override { return new T(std::move(*this)); } \
63 #define CLONEABLE_NEEDS_DESTRUCTOR_DEF(T) \
67 std::unique_ptr<T> clone() const { \
68 return std::unique_ptr<T>(this->_clone()); \
70 std::unique_ptr<T> move() { return std::unique_ptr<T>(this->_move()); } \
73 virtual T *_clone() const override { return new T(*this); } \
74 virtual T *_move() override { return new T(std::move(*this)); } \
82 template <
typename T,
typename... Args>
84 return std::unique_ptr<T>(
new T(std::forward<Args>(args)...));
92 std::unique_ptr<Cloneable>
clone()
const {
93 return std::unique_ptr<Cloneable>(this->
_clone());
95 std::unique_ptr<Cloneable>
move() {
96 return std::unique_ptr<Cloneable>(this->
_move());
104 template <
typename Type>
108 template <
typename T,
typename... Args>
115 template <
typename T,
typename =
void>
120 template <
typename T>
123 template <
typename T,
124 typename std::enable_if<!has_clone<T>::value,
void>::type * =
nullptr>
125 std::unique_ptr<T>
clone(
const T &obj);
127 template <
typename T,
128 typename std::enable_if<has_clone<T>::value,
void>::type * =
nullptr>
129 std::unique_ptr<T>
clone(
const T &obj);
133 template <
typename T,
typename =
void>
138 template <
typename T>
142 template <
typename T,
143 typename std::enable_if<!has_move<T>::value,
void>::type * =
nullptr>
147 template <
typename T,
148 typename std::enable_if<has_move<T>::value,
void>::type * =
nullptr>
162 template <
typename Type>
179 template <
typename U>
186 template <
typename U>
190 template <
typename U>
194 template <
typename U>
203 template <
typename U>
207 template <
typename U>
211 template <
typename U>
225 const std::unique_ptr<Type> &
unique()
const;
228 explicit operator bool()
const;
234 template <
typename Type>
237 template <
typename Type>
240 template <
typename Type>
243 template <
typename Type>
246 template <
typename Type>
249 template <
typename Type>
252 template <
typename Type>
255 template <
typename Type>
260 template <
typename T,
261 typename std::enable_if<!has_clone<T>::value,
void>::type *>
262 std::unique_ptr<T>
clone(
const T &obj) {
263 return std::unique_ptr<T>(
new T(obj));
266 template <
typename T,
267 typename std::enable_if<has_clone<T>::value,
void>::type *>
268 std::unique_ptr<T>
clone(
const T &obj) {
277 template <
typename T,
278 typename std::enable_if<!has_move<T>::value,
void>::type *>
280 return clone(std::move(obj));
288 template <typename T, typename std::enable_if<has_move<T>::value,
void>::type *>
294 template <
typename Type>
298 template <
typename Type>
306 template <
typename Type>
307 template <
typename U>
315 template <
typename Type>
317 : m_unique(
std::move(other.unique())) {}
320 template <
typename Type>
321 template <
typename U>
323 : m_unique(
std::move(other.unique())) {}
326 template <
typename Type>
327 template <
typename U>
336 template <
typename Type>
337 template <
typename U>
339 : m_unique(
std::move(other)) {}
341 template <
typename Type>
345 template <
typename Type>
352 template <
typename Type>
353 template <
typename U>
355 unique() = std::move(other.unique());
360 template <
typename Type>
361 template <
typename U>
363 const std::unique_ptr<U> &other) {
365 unique() =
clone(*other);
373 template <
typename Type>
374 template <
typename U>
376 std::unique_ptr<U> &&other) {
377 unique() = std::move(other);
381 template <
typename Type>
386 template <
typename Type>
392 template <
typename Type>
394 return m_unique.reset();
398 template <
typename Type>
404 template <
typename Type>
410 template <
typename Type>
412 return static_cast<bool>(m_unique);
415 template <
typename Type>
420 template <
typename Type>
425 template <
typename Type>
430 template <
typename Type>
435 template <
typename Type>
437 return B.
unique() ==
nullptr;
440 template <
typename Type>
442 return B.
unique() !=
nullptr;
445 template <
typename Type>
447 return A.
unique() ==
nullptr;
450 template <
typename Type>
452 return A.
unique() !=
nullptr;
std::unique_ptr< Cloneable > clone() const
virtual Cloneable * _clone() const =0
virtual Cloneable * _move()=0
std::unique_ptr< Cloneable > move()
A 'cloneable_ptr' can be used in place of 'unique_ptr'.
cloneable_ptr(pointer ptr)
Construct by taking ownership of ptr.
cloneable_ptr(const cloneable_ptr< U > &other)
Construct by cloning other.
cloneable_ptr(cloneable_ptr< U > &&other)
Construct by moving other.
cloneable_ptr & operator=(cloneable_ptr< U > &&other)
Assignment via move.
const std::unique_ptr< Type > & unique() const
const Access contained unique_ptr
std::unique_ptr< Type > m_unique
cloneable_ptr(cloneable_ptr &&other)
Construct by moving other.
cloneable_ptr(const cloneable_ptr &other)
Construct by cloning other.
std::unique_ptr< Type > & unique()
Access contained unique_ptr.
pointer operator->() const
cloneable_ptr()
Default constructor.
void reset()
Reset contained unique_ptr.
cloneable_ptr(std::unique_ptr< U > &&other)
Construct by moving.
cloneable_ptr & operator=(cloneable_ptr other)
Assignment via copy-swap.
cloneable_ptr(const std::unique_ptr< U > &other)
Construct by cloning other.
reference operator*() const
cloneable_ptr & operator=(std::unique_ptr< U > &&other)
Assignment via move.
cloneable_ptr & operator=(const std::unique_ptr< U > &other)
Assignment via clone.
BasisSet operator*(const SymOp &LHS, const BasisSet &RHS)
Non-std smart pointer classes and functions.
std::unique_ptr< T > clone(const T &obj)
bool operator!=(const cloneable_ptr< Type > &A, const cloneable_ptr< Type > &B)
cloneable_ptr< T > make_cloneable(Args &&... args)
make a cloneable_ptr<T> via T(Args... args)
typename make_void< Ts... >::type void_t
Alias for void, to help SFINAE work.
bool operator==(const cloneable_ptr< Type > &A, const cloneable_ptr< Type > &B)
bool operator<(const cloneable_ptr< Type > &A, const cloneable_ptr< Type > &B)
std::unique_ptr< T > clone_move(T &&obj)
Construct std::unique_ptr<T> from rvalue reference.
std::unique_ptr< T > make_unique(Args &&... args)
c++17 does not include 'make_unique'
void swap(cloneable_ptr< Type > &A, cloneable_ptr< Type > &B)
Base type inherits from std::false_type if T does not have clone method.
Base type inherits from std::false_type if T does not have move method.