164 using allocator_traits = std::allocator_traits<A>;
167 template <
class U,
class... Ts>
168 cblock_t* create_control_block(Ts&&... ts)
const {
169 using cb_allocator =
typename std::allocator_traits<
170 A>::template rebind_alloc<detail::direct_control_block<T, U, A>>;
172 using cb_alloc_traits = std::allocator_traits<cb_allocator>;
173 auto mem = cb_alloc_traits::allocate(cb_alloc, 1);
176 std::forward<Ts>(ts)...);
179 cb_alloc_traits::deallocate(cb_alloc, mem, 1);
187 using pointer =
typename allocator_traits::pointer;
190 template <
typename TT = T,
191 typename std::enable_if<std::is_default_constructible<TT>::value,
194 cb_ = create_control_block<T>();
197 template <
typename TT = T,
198 typename std::enable_if<std::is_default_constructible<TT>::value,
201 typename std::enable_if<std::is_default_constructible<AA>::value,
204 cb_ = create_control_block<T>();
208 class U,
class... Ts,
209 typename std::enable_if<std::is_constructible<U, Ts&&...>::value,
211 typename std::enable_if<std::is_copy_constructible<U>::value,
int>::type =
213 typename std::enable_if<std::is_base_of<T, U>::value,
int>::type = 0>
217 cb_ = create_control_block<U>(std::forward<Ts>(ts)...);
221 class U,
class I,
class... Ts,
222 typename std::enable_if<
223 std::is_constructible<U, std::initializer_list<I>, Ts&&...>::value,
225 typename std::enable_if<std::is_copy_constructible<U>::value,
int>::type =
227 typename std::enable_if<std::is_base_of<T, U>::value,
int>::type = 0>
229 std::initializer_list<I> ilist, Ts&&... ts)
231 cb_ = create_control_block<T>(ilist, std::forward<Ts>(ts)...);
235 class U,
class I,
class... Ts,
236 typename std::enable_if<
237 std::is_constructible<U, std::initializer_list<I>, Ts&&...>::value,
239 typename std::enable_if<std::is_copy_constructible<U>::value,
int>::type =
241 typename std::enable_if<std::is_base_of<T, U>::value,
int>::type = 0,
243 typename std::enable_if<std::is_default_constructible<AA>::value,
248 std::forward<Ts>(ts)...) {}
251 class U,
class... Ts,
252 typename std::enable_if<std::is_constructible<U, Ts&&...>::value,
254 typename std::enable_if<std::is_copy_constructible<U>::value,
int>::type =
256 typename std::enable_if<std::is_base_of<T, U>::value,
int>::type = 0,
258 typename std::enable_if<std::is_default_constructible<AA>::value,
262 std::forward<Ts>(ts)...) {}
266 typename std::enable_if<
268 typename std::remove_cv<
typename std::remove_reference<
269 U>::type>::type>::value,
271 typename std::enable_if<
272 std::is_copy_constructible<
typename std::remove_cv<
273 typename std::remove_reference<U>::type>::type>::value,
275 typename std::enable_if<
277 T,
typename std::remove_cv<
278 typename std::remove_reference<U>::type>::type>::value,
283 typename std::remove_reference<U>::type>::type>{},
284 std::forward<U>(u)) {}
288 typename std::enable_if<
290 typename std::remove_cv<
typename std::remove_reference<
291 U>::type>::type>::value,
293 typename std::enable_if<
294 std::is_copy_constructible<
typename std::remove_cv<
295 typename std::remove_reference<U>::type>::type>::value,
297 typename std::enable_if<
299 T,
typename std::remove_cv<
300 typename std::remove_reference<U>::type>::type>::value,
305 typename std::remove_reference<U>::type>::type>{},
306 std::forward<U>(u)) {}
319 allocator_traits::select_on_container_copy_construction(
324 std::allocator_arg_t,
const A& alloc,
325 polymorphic&& other)
noexcept(allocator_traits::is_always_equal::value)
327 if (allocator_traits::propagate_on_container_copy_assignment::value) {
335 if (!other.valueless_after_move()) {
345 :
polymorphic(std::allocator_arg, other.get_allocator(),
351 if (
this == &other)
return *
this;
357 allocator_traits::propagate_on_container_copy_assignment::value;
364 auto tmp = other.cb_->
clone(update_alloc ? other.alloc_base::get()
376 allocator_traits::propagate_on_container_move_assignment::value ||
377 allocator_traits::is_always_equal::value) {
378 if (
this == &other)
return *
this;
384 allocator_traits::propagate_on_container_move_assignment::value;
386 if (other.valueless_after_move()) {
390 std::swap(cb_, other.cb_);
395 auto tmp = other.cb_->move(update_alloc ? other.alloc_base::get()
429 return cb_ ==
nullptr;
435 std::allocator_traits<A>::propagate_on_container_swap::value ||
436 std::allocator_traits<A>::is_always_equal::value) {
437 if (allocator_traits::propagate_on_container_swap::value) {
440 std::swap(cb_, other.cb_);
444 std::swap(cb_, other.cb_);
452 polymorphic& rhs)
noexcept(
noexcept(lhs.swap(rhs))) {
457 void reset() noexcept {
458 if (cb_ !=
nullptr) {