| 57 | */ |
| 58 | template <typename Base> |
| 59 | class deep_unique_ptr |
| 60 | { |
| 61 | public: |
| 62 | using CopyFunc = std::function<Base *(const Base *)>; |
| 63 | |
| 64 | deep_unique_ptr(std::nullptr_t val = nullptr) noexcept : _val{val}, _copy{} |
| 65 | { |
| 66 | } |
| 67 | template <typename Derived, typename CopyFuncDerived> |
| 68 | deep_unique_ptr(Derived *value, const CopyFuncDerived ©) noexcept : _val{value}, _copy{std::move(copy)} |
| 69 | { |
| 70 | static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base"); |
| 71 | static_assert(std::is_constructible<CopyFunc, CopyFuncDerived>::value, |
| 72 | "CopyFuncDerived is not valid for a copy functor"); |
| 73 | } |
| 74 | |
| 75 | deep_unique_ptr(const deep_unique_ptr<Base> &ptr) : deep_unique_ptr(ptr.clone()) |
| 76 | { |
| 77 | } |
| 78 | deep_unique_ptr &operator=(const deep_unique_ptr<Base> &ptr) |
| 79 | { |
| 80 | deep_unique_ptr<Base> tmp(ptr); |
| 81 | swap(*this, tmp); |
| 82 | return *this; |
| 83 | } |
| 84 | |
| 85 | deep_unique_ptr(deep_unique_ptr<Base> &&ptr) = default; |
| 86 | deep_unique_ptr &operator=(deep_unique_ptr<Base> &&ptr) = default; |
| 87 | ~deep_unique_ptr() = default; |
| 88 | friend void swap(deep_unique_ptr &ptr0, deep_unique_ptr<Base> &ptr1) noexcept |
| 89 | { |
| 90 | using std::swap; |
| 91 | swap(ptr0._val, ptr1._val); |
| 92 | swap(ptr0._copy, ptr1._copy); |
| 93 | } |
| 94 | Base &operator*() noexcept |
| 95 | { |
| 96 | return *_val; |
| 97 | } |
| 98 | |
| 99 | const Base &operator*() const noexcept |
| 100 | { |
| 101 | return *_val; |
| 102 | } |
| 103 | |
| 104 | Base *operator->() noexcept |
| 105 | { |
| 106 | return _val.operator->(); |
| 107 | } |
| 108 | |
| 109 | const Base *operator->() const noexcept |
| 110 | { |
| 111 | return _val.operator->(); |
| 112 | } |
| 113 | |
| 114 | Base *get() noexcept |
| 115 | { |
| 116 | return _val.get(); |