34#ifndef LA_DECLSPEC_EMPTY_BASES
36 #define LA_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
38 #define LA_DECLSPEC_EMPTY_BASES
59template <
class T,
class Deleter,
class T2>
60struct LA_DECLSPEC_EMPTY_BASES compressed_ptr : std::unique_ptr<T, Deleter>, T2
62 using T1 = std::unique_ptr<T, Deleter>;
63 compressed_ptr() =
default;
64 compressed_ptr(compressed_ptr&&) =
default;
65 compressed_ptr(
const compressed_ptr&) =
default;
66 compressed_ptr(T2&& a2)
69 compressed_ptr(
const T2& a2)
72 template <
typename A1>
73 compressed_ptr(A1&& a1)
76 class_tag<typename std::decay<A1>::type>(),
80 template <
typename A1,
typename A2>
81 compressed_ptr(A1&& a1, A2&& a2)
85 class_tag<typename std::decay<A2>::type>(),
88 template <
typename A1,
typename A2,
typename A3>
89 compressed_ptr(A1&& a1, A2&& a2, A3&& a3)
90 : T1(std::forward<A1>(a1), std::forward<A2>(a2))
91 , T2(std::forward<A3>(a3))
94 template <
typename A1>
95 compressed_ptr(A1&& a1, class_tag<
typename std::decay<A1>::type>, spacer, spacer)
96 : T1(std::forward<A1>(a1))
98 template <
typename A1,
typename A2>
99 compressed_ptr(A1&& a1, A2&& a2, class_tag<Deleter>, spacer)
100 : T1(std::forward<A1>(a1), std::forward<A2>(a2))
102 template <
typename A1,
typename A2>
103 compressed_ptr(A1&& a1, A2&& a2, class_tag<T2>, spacer)
104 : T1(std::forward<A1>(a1))
105 , T2(std::forward<A2>(a2))
114 default_clone() =
default;
115 T* operator()(T
const& x)
const {
return new T(x); }
116 T* operator()(T&& x)
const {
return new T(std::move(x)); }
131template <
class T,
class Cloner = default_clone<T>,
class Deleter = std::default_delete<T>>
134 ::lagrange::detail::compressed_ptr<T, Deleter, Cloner> ptr_;
136 std::unique_ptr<T, Deleter>& ptr() {
return ptr_; }
137 std::unique_ptr<T, Deleter>
const& ptr()
const {
return ptr_; }
139 T* clone(T
const& x)
const {
return get_cloner()(x); }
143 using element_type = T;
144 using cloner_type = Cloner;
145 using deleter_type = Deleter;
147 value_ptr() =
default;
149 value_ptr(
const T& value)
150 : ptr_(cloner_type()(value))
153 : ptr_(cloner_type()(std::move(value)))
156 value_ptr(
const Cloner& value)
159 value_ptr(Cloner&& value)
163 template <
typename V,
typename ClonerOrDeleter>
164 value_ptr(V&& value, ClonerOrDeleter&& a2)
165 : ptr_(std::forward<V>(value), std::forward<ClonerOrDeleter>(a2))
168 template <
typename V,
typename C,
typename D>
169 value_ptr(V&& value, C&& cloner, D&& deleter)
170 : ptr_(std::forward<V>(value), std::forward<D>(deleter), std::forward<C>(cloner))
173 value_ptr(value_ptr
const& v)
174 : ptr_{
nullptr, v.get_cloner()}
177 ptr().reset(clone(*v));
180 value_ptr(value_ptr&& v) =
default;
182 explicit value_ptr(pointer value)
185 pointer release() {
return ptr().release(); }
187 T* get()
noexcept {
return ptr().get(); }
188 T
const* get()
const noexcept {
return ptr().get(); }
190 Cloner& get_cloner()
noexcept {
return ptr_; }
191 Cloner
const& get_cloner()
const noexcept {
return ptr_; }
193 Deleter& get_deleter()
noexcept {
return ptr_; }
194 Deleter
const& get_deleter()
const noexcept {
return ptr_; }
196 T& operator*() {
return *get(); }
197 T
const& operator*()
const {
return *get(); }
199 T
const* operator->()
const noexcept {
return get(); }
200 T* operator->()
noexcept {
return get(); }
202 value_ptr<T>& operator=(value_ptr&& v)
noexcept
204 ptr() = std::move(v.ptr());
205 get_cloner() = std::move(v.get_cloner());
209 value_ptr<T>& operator=(value_ptr
const& v)
211 ptr().reset(v.get_cloner()(*v));
212 get_cloner() = v.get_cloner();
216 operator bool()
const noexcept {
return !!ptr(); }
217 ~value_ptr() =
default;
232template <
class T,
class...
Args>
235 return value_ptr<T>(
new T(std::forward<Args>(args)...));
Smart pointer with value semantics.
Definition value_ptr.h:133
value_ptr< T > make_value_ptr(Args &&... args)
Helper function to create a value_ptr for a given type.
Definition value_ptr.h:233
Main namespace for Lagrange.
Definition project.cpp:27