1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_SCOPED_ALLOCATOR 11#define _LIBCPP_SCOPED_ALLOCATOR 12 13/* 14 scoped_allocator synopsis 15 16namespace std 17{ 18 19template <class OuterAlloc, class... InnerAllocs> 20class scoped_allocator_adaptor : public OuterAlloc 21{ 22 typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only 23 scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only 24public: 25 26 typedef OuterAlloc outer_allocator_type; 27 typedef see below inner_allocator_type; 28 29 typedef typename OuterTraits::value_type value_type; 30 typedef typename OuterTraits::size_type size_type; 31 typedef typename OuterTraits::difference_type difference_type; 32 typedef typename OuterTraits::pointer pointer; 33 typedef typename OuterTraits::const_pointer const_pointer; 34 typedef typename OuterTraits::void_pointer void_pointer; 35 typedef typename OuterTraits::const_void_pointer const_void_pointer; 36 37 typedef see below propagate_on_container_copy_assignment; 38 typedef see below propagate_on_container_move_assignment; 39 typedef see below propagate_on_container_swap; 40 typedef see below is_always_equal; 41 42 template <class Tp> 43 struct rebind 44 { 45 typedef scoped_allocator_adaptor< 46 OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other; 47 }; 48 49 scoped_allocator_adaptor(); 50 template <class OuterA2> 51 scoped_allocator_adaptor(OuterA2&& outerAlloc, 52 const InnerAllocs&... innerAllocs) noexcept; 53 scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; 54 scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; 55 template <class OuterA2> 56 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept; 57 template <class OuterA2> 58 scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept; 59 60 scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; 61 scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; 62 ~scoped_allocator_adaptor(); 63 64 inner_allocator_type& inner_allocator() noexcept; 65 const inner_allocator_type& inner_allocator() const noexcept; 66 67 outer_allocator_type& outer_allocator() noexcept; 68 const outer_allocator_type& outer_allocator() const noexcept; 69 70 pointer allocate(size_type n); // [[nodiscard]] in C++20 71 pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20 72 void deallocate(pointer p, size_type n) noexcept; 73 74 size_type max_size() const; 75 template <class T, class... Args> void construct(T* p, Args&& args); 76 template <class T1, class T2, class... Args1, class... Args2> 77 void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x, 78 tuple<Args2...> y); 79 template <class T1, class T2> 80 void construct(pair<T1, T2>* p); 81 template <class T1, class T2, class U, class V> 82 void construct(pair<T1, T2>* p, U&& x, V&& y); 83 template <class T1, class T2, class U, class V> 84 void construct(pair<T1, T2>* p, const pair<U, V>& x); 85 template <class T1, class T2, class U, class V> 86 void construct(pair<T1, T2>* p, pair<U, V>&& x); 87 template <class T> void destroy(T* p); 88 89 template <class T> void destroy(T* p) noexcept; 90 91 scoped_allocator_adaptor select_on_container_copy_construction() const noexcept; 92}; 93 94template<class OuterAlloc, class... InnerAllocs> 95 scoped_allocator_adaptor(OuterAlloc, InnerAllocs...) 96 -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>; 97 98template <class OuterA1, class OuterA2, class... InnerAllocs> 99 bool 100 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 101 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 102 103template <class OuterA1, class OuterA2, class... InnerAllocs> 104 bool 105 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 106 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 107 108} // std 109 110*/ 111 112#include <__assert> // all public C++ headers provide the assertion handler 113#include <__config> 114#include <__memory/allocator_traits.h> 115#include <__memory/uses_allocator_construction.h> 116#include <__type_traits/common_type.h> 117#include <__type_traits/enable_if.h> 118#include <__type_traits/integral_constant.h> 119#include <__type_traits/is_constructible.h> 120#include <__type_traits/remove_reference.h> 121#include <__utility/declval.h> 122#include <__utility/forward.h> 123#include <__utility/move.h> 124#include <__utility/pair.h> 125#include <__utility/piecewise_construct.h> 126#include <tuple> 127#include <version> 128 129#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 130# pragma GCC system_header 131#endif 132 133_LIBCPP_BEGIN_NAMESPACE_STD 134 135#if !defined(_LIBCPP_CXX03_LANG) 136 137// scoped_allocator_adaptor 138 139template <class ..._Allocs> 140class scoped_allocator_adaptor; 141 142template <class ..._Allocs> struct __get_poc_copy_assignment; 143 144template <class _A0> 145struct __get_poc_copy_assignment<_A0> 146{ 147 static const bool value = allocator_traits<_A0>:: 148 propagate_on_container_copy_assignment::value; 149}; 150 151template <class _A0, class ..._Allocs> 152struct __get_poc_copy_assignment<_A0, _Allocs...> 153{ 154 static const bool value = 155 allocator_traits<_A0>::propagate_on_container_copy_assignment::value || 156 __get_poc_copy_assignment<_Allocs...>::value; 157}; 158 159template <class ..._Allocs> struct __get_poc_move_assignment; 160 161template <class _A0> 162struct __get_poc_move_assignment<_A0> 163{ 164 static const bool value = allocator_traits<_A0>:: 165 propagate_on_container_move_assignment::value; 166}; 167 168template <class _A0, class ..._Allocs> 169struct __get_poc_move_assignment<_A0, _Allocs...> 170{ 171 static const bool value = 172 allocator_traits<_A0>::propagate_on_container_move_assignment::value || 173 __get_poc_move_assignment<_Allocs...>::value; 174}; 175 176template <class ..._Allocs> struct __get_poc_swap; 177 178template <class _A0> 179struct __get_poc_swap<_A0> 180{ 181 static const bool value = allocator_traits<_A0>:: 182 propagate_on_container_swap::value; 183}; 184 185template <class _A0, class ..._Allocs> 186struct __get_poc_swap<_A0, _Allocs...> 187{ 188 static const bool value = 189 allocator_traits<_A0>::propagate_on_container_swap::value || 190 __get_poc_swap<_Allocs...>::value; 191}; 192 193template <class ..._Allocs> struct __get_is_always_equal; 194 195template <class _A0> 196struct __get_is_always_equal<_A0> 197{ 198 static const bool value = allocator_traits<_A0>::is_always_equal::value; 199}; 200 201template <class _A0, class ..._Allocs> 202struct __get_is_always_equal<_A0, _Allocs...> 203{ 204 static const bool value = 205 allocator_traits<_A0>::is_always_equal::value && 206 __get_is_always_equal<_Allocs...>::value; 207}; 208 209template <class ..._Allocs> 210class __scoped_allocator_storage; 211 212template <class _OuterAlloc, class... _InnerAllocs> 213class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> 214 : public _OuterAlloc 215{ 216 typedef _OuterAlloc outer_allocator_type; 217protected: 218 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type; 219 220private: 221 inner_allocator_type __inner_; 222 223protected: 224 225 _LIBCPP_INLINE_VISIBILITY 226 __scoped_allocator_storage() _NOEXCEPT {} 227 228 template <class _OuterA2, 229 class = typename enable_if< 230 is_constructible<outer_allocator_type, _OuterA2>::value 231 >::type> 232 _LIBCPP_INLINE_VISIBILITY 233 __scoped_allocator_storage(_OuterA2&& __outer_alloc, 234 const _InnerAllocs& ...__inner_allocs) _NOEXCEPT 235 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)), 236 __inner_(__inner_allocs...) {} 237 238 template <class _OuterA2, 239 class = typename enable_if< 240 is_constructible<outer_allocator_type, const _OuterA2&>::value 241 >::type> 242 _LIBCPP_INLINE_VISIBILITY 243 __scoped_allocator_storage( 244 const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT 245 : outer_allocator_type(__other.outer_allocator()), 246 __inner_(__other.inner_allocator()) {} 247 248 template <class _OuterA2, 249 class = typename enable_if< 250 is_constructible<outer_allocator_type, _OuterA2>::value 251 >::type> 252 _LIBCPP_INLINE_VISIBILITY 253 __scoped_allocator_storage( 254 __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT 255 : outer_allocator_type(_VSTD::move(__other.outer_allocator())), 256 __inner_(_VSTD::move(__other.inner_allocator())) {} 257 258 template <class _OuterA2, 259 class = typename enable_if< 260 is_constructible<outer_allocator_type, _OuterA2>::value 261 >::type> 262 _LIBCPP_INLINE_VISIBILITY 263 __scoped_allocator_storage(_OuterA2&& __o, 264 const inner_allocator_type& __i) _NOEXCEPT 265 : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)), 266 __inner_(__i) 267 { 268 } 269 270 _LIBCPP_INLINE_VISIBILITY 271 inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;} 272 _LIBCPP_INLINE_VISIBILITY 273 const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;} 274 275 _LIBCPP_INLINE_VISIBILITY 276 outer_allocator_type& outer_allocator() _NOEXCEPT 277 {return static_cast<outer_allocator_type&>(*this);} 278 _LIBCPP_INLINE_VISIBILITY 279 const outer_allocator_type& outer_allocator() const _NOEXCEPT 280 {return static_cast<const outer_allocator_type&>(*this);} 281 282 scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> 283 _LIBCPP_INLINE_VISIBILITY 284 select_on_container_copy_construction() const _NOEXCEPT 285 { 286 return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> 287 ( 288 allocator_traits<outer_allocator_type>:: 289 select_on_container_copy_construction(outer_allocator()), 290 allocator_traits<inner_allocator_type>:: 291 select_on_container_copy_construction(inner_allocator()) 292 ); 293 } 294 295 template <class...> friend class __scoped_allocator_storage; 296}; 297 298template <class _OuterAlloc> 299class __scoped_allocator_storage<_OuterAlloc> 300 : public _OuterAlloc 301{ 302 typedef _OuterAlloc outer_allocator_type; 303protected: 304 typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type; 305 306 _LIBCPP_INLINE_VISIBILITY 307 __scoped_allocator_storage() _NOEXCEPT {} 308 309 template <class _OuterA2, 310 class = typename enable_if< 311 is_constructible<outer_allocator_type, _OuterA2>::value 312 >::type> 313 _LIBCPP_INLINE_VISIBILITY 314 __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT 315 : outer_allocator_type(_VSTD::forward<_OuterA2>(__outer_alloc)) {} 316 317 template <class _OuterA2, 318 class = typename enable_if< 319 is_constructible<outer_allocator_type, const _OuterA2&>::value 320 >::type> 321 _LIBCPP_INLINE_VISIBILITY 322 __scoped_allocator_storage( 323 const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT 324 : outer_allocator_type(__other.outer_allocator()) {} 325 326 template <class _OuterA2, 327 class = typename enable_if< 328 is_constructible<outer_allocator_type, _OuterA2>::value 329 >::type> 330 _LIBCPP_INLINE_VISIBILITY 331 __scoped_allocator_storage( 332 __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT 333 : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {} 334 335 _LIBCPP_INLINE_VISIBILITY 336 inner_allocator_type& inner_allocator() _NOEXCEPT 337 {return static_cast<inner_allocator_type&>(*this);} 338 _LIBCPP_INLINE_VISIBILITY 339 const inner_allocator_type& inner_allocator() const _NOEXCEPT 340 {return static_cast<const inner_allocator_type&>(*this);} 341 342 _LIBCPP_INLINE_VISIBILITY 343 outer_allocator_type& outer_allocator() _NOEXCEPT 344 {return static_cast<outer_allocator_type&>(*this);} 345 _LIBCPP_INLINE_VISIBILITY 346 const outer_allocator_type& outer_allocator() const _NOEXCEPT 347 {return static_cast<const outer_allocator_type&>(*this);} 348 349 _LIBCPP_INLINE_VISIBILITY 350 scoped_allocator_adaptor<outer_allocator_type> 351 select_on_container_copy_construction() const _NOEXCEPT 352 {return scoped_allocator_adaptor<outer_allocator_type>( 353 allocator_traits<outer_allocator_type>:: 354 select_on_container_copy_construction(outer_allocator()) 355 );} 356 357 __scoped_allocator_storage(const outer_allocator_type& __o, 358 const inner_allocator_type& __i) _NOEXCEPT; 359 360 template <class...> friend class __scoped_allocator_storage; 361}; 362 363// __outermost 364 365template <class _Alloc> 366decltype(std::declval<_Alloc>().outer_allocator(), true_type()) 367__has_outer_allocator_test(_Alloc&& __a); 368 369template <class _Alloc> 370false_type 371__has_outer_allocator_test(const volatile _Alloc& __a); 372 373template <class _Alloc> 374struct __has_outer_allocator 375 : public common_type 376 < 377 decltype(std::__has_outer_allocator_test(std::declval<_Alloc&>())) 378 >::type 379{ 380}; 381 382template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value> 383struct __outermost 384{ 385 typedef _Alloc type; 386 _LIBCPP_INLINE_VISIBILITY 387 type& operator()(type& __a) const _NOEXCEPT {return __a;} 388}; 389 390template <class _Alloc> 391struct __outermost<_Alloc, true> 392{ 393 typedef __libcpp_remove_reference_t 394 < 395 decltype(std::declval<_Alloc>().outer_allocator()) 396 > _OuterAlloc; 397 typedef typename __outermost<_OuterAlloc>::type type; 398 _LIBCPP_INLINE_VISIBILITY 399 type& operator()(_Alloc& __a) const _NOEXCEPT 400 {return __outermost<_OuterAlloc>()(__a.outer_allocator());} 401}; 402 403template <class _OuterAlloc, class... _InnerAllocs> 404class _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...> 405 : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> 406{ 407 typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base; 408 typedef allocator_traits<_OuterAlloc> _OuterTraits; 409public: 410 typedef _OuterAlloc outer_allocator_type; 411 typedef typename base::inner_allocator_type inner_allocator_type; 412 typedef typename _OuterTraits::size_type size_type; 413 typedef typename _OuterTraits::difference_type difference_type; 414 typedef typename _OuterTraits::pointer pointer; 415 typedef typename _OuterTraits::const_pointer const_pointer; 416 typedef typename _OuterTraits::void_pointer void_pointer; 417 typedef typename _OuterTraits::const_void_pointer const_void_pointer; 418 419 typedef integral_constant 420 < 421 bool, 422 __get_poc_copy_assignment<outer_allocator_type, 423 _InnerAllocs...>::value 424 > propagate_on_container_copy_assignment; 425 typedef integral_constant 426 < 427 bool, 428 __get_poc_move_assignment<outer_allocator_type, 429 _InnerAllocs...>::value 430 > propagate_on_container_move_assignment; 431 typedef integral_constant 432 < 433 bool, 434 __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value 435 > propagate_on_container_swap; 436 typedef integral_constant 437 < 438 bool, 439 __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value 440 > is_always_equal; 441 442 template <class _Tp> 443 struct rebind 444 { 445 typedef scoped_allocator_adaptor 446 < 447 typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs... 448 > other; 449 }; 450 451 _LIBCPP_INLINE_VISIBILITY 452 scoped_allocator_adaptor() _NOEXCEPT {} 453 template <class _OuterA2, 454 class = typename enable_if< 455 is_constructible<outer_allocator_type, _OuterA2>::value 456 >::type> 457 _LIBCPP_INLINE_VISIBILITY 458 scoped_allocator_adaptor(_OuterA2&& __outer_alloc, 459 const _InnerAllocs& ...__inner_allocs) _NOEXCEPT 460 : base(_VSTD::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {} 461 // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default; 462 template <class _OuterA2, 463 class = typename enable_if< 464 is_constructible<outer_allocator_type, const _OuterA2&>::value 465 >::type> 466 _LIBCPP_INLINE_VISIBILITY 467 scoped_allocator_adaptor( 468 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT 469 : base(__other) {} 470 template <class _OuterA2, 471 class = typename enable_if< 472 is_constructible<outer_allocator_type, _OuterA2>::value 473 >::type> 474 _LIBCPP_INLINE_VISIBILITY 475 scoped_allocator_adaptor( 476 scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT 477 : base(_VSTD::move(__other)) {} 478 479 // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; 480 // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; 481 // ~scoped_allocator_adaptor() = default; 482 483 _LIBCPP_INLINE_VISIBILITY 484 inner_allocator_type& inner_allocator() _NOEXCEPT 485 {return base::inner_allocator();} 486 _LIBCPP_INLINE_VISIBILITY 487 const inner_allocator_type& inner_allocator() const _NOEXCEPT 488 {return base::inner_allocator();} 489 490 _LIBCPP_INLINE_VISIBILITY 491 outer_allocator_type& outer_allocator() _NOEXCEPT 492 {return base::outer_allocator();} 493 _LIBCPP_INLINE_VISIBILITY 494 const outer_allocator_type& outer_allocator() const _NOEXCEPT 495 {return base::outer_allocator();} 496 497 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 498 pointer allocate(size_type __n) 499 {return allocator_traits<outer_allocator_type>:: 500 allocate(outer_allocator(), __n);} 501 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 502 pointer allocate(size_type __n, const_void_pointer __hint) 503 {return allocator_traits<outer_allocator_type>:: 504 allocate(outer_allocator(), __n, __hint);} 505 506 _LIBCPP_INLINE_VISIBILITY 507 void deallocate(pointer __p, size_type __n) _NOEXCEPT 508 {allocator_traits<outer_allocator_type>:: 509 deallocate(outer_allocator(), __p, __n);} 510 511 _LIBCPP_INLINE_VISIBILITY 512 size_type max_size() const 513 {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());} 514 515#if _LIBCPP_STD_VER >= 20 516 template <class _Type, class... _Args> 517 _LIBCPP_HIDE_FROM_ABI void construct(_Type* __ptr, _Args&&... __args) { 518 using _OM = __outermost<outer_allocator_type>; 519 std::apply( 520 [__ptr, this](auto&&... __newargs) { 521 allocator_traits<typename _OM::type>::construct( 522 _OM()(outer_allocator()), __ptr, std::forward<decltype(__newargs)>(__newargs)...); 523 }, 524 std::uses_allocator_construction_args<_Type>(inner_allocator(), std::forward<_Args>(__args)...)); 525 } 526#else 527 template <class _Tp, class... _Args> 528 _LIBCPP_INLINE_VISIBILITY 529 void construct(_Tp* __p, _Args&& ...__args) 530 {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(), 531 __p, _VSTD::forward<_Args>(__args)...);} 532 533 template <class _T1, class _T2, class... _Args1, class... _Args2> 534 void construct(pair<_T1, _T2>* __p, piecewise_construct_t, 535 tuple<_Args1...> __x, tuple<_Args2...> __y) 536 { 537 typedef __outermost<outer_allocator_type> _OM; 538 allocator_traits<typename _OM::type>::construct( 539 _OM()(outer_allocator()), __p, piecewise_construct 540 , __transform_tuple( 541 typename __uses_alloc_ctor< 542 _T1, inner_allocator_type&, _Args1... 543 >::type() 544 , _VSTD::move(__x) 545 , typename __make_tuple_indices<sizeof...(_Args1)>::type{} 546 ) 547 , __transform_tuple( 548 typename __uses_alloc_ctor< 549 _T2, inner_allocator_type&, _Args2... 550 >::type() 551 , _VSTD::move(__y) 552 , typename __make_tuple_indices<sizeof...(_Args2)>::type{} 553 ) 554 ); 555 } 556 557 template <class _T1, class _T2> 558 void construct(pair<_T1, _T2>* __p) 559 { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); } 560 561 template <class _T1, class _T2, class _Up, class _Vp> 562 void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { 563 construct(__p, piecewise_construct, 564 _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)), 565 _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y))); 566 } 567 568 template <class _T1, class _T2, class _Up, class _Vp> 569 void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { 570 construct(__p, piecewise_construct, 571 _VSTD::forward_as_tuple(__x.first), 572 _VSTD::forward_as_tuple(__x.second)); 573 } 574 575 template <class _T1, class _T2, class _Up, class _Vp> 576 void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { 577 construct(__p, piecewise_construct, 578 _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)), 579 _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second))); 580 } 581#endif 582 583 template <class _Tp> 584 _LIBCPP_INLINE_VISIBILITY 585 void destroy(_Tp* __p) 586 { 587 typedef __outermost<outer_allocator_type> _OM; 588 allocator_traits<typename _OM::type>:: 589 destroy(_OM()(outer_allocator()), __p); 590 } 591 592 _LIBCPP_INLINE_VISIBILITY 593 scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT 594 {return base::select_on_container_copy_construction();} 595 596private: 597 598 599 template <class _OuterA2, 600 class = typename enable_if< 601 is_constructible<outer_allocator_type, _OuterA2>::value 602 >::type> 603 _LIBCPP_INLINE_VISIBILITY 604 scoped_allocator_adaptor(_OuterA2&& __o, 605 const inner_allocator_type& __i) _NOEXCEPT 606 : base(_VSTD::forward<_OuterA2>(__o), __i) {} 607 608 template <class _Tp, class... _Args> 609 _LIBCPP_INLINE_VISIBILITY 610 void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args) 611 { 612 typedef __outermost<outer_allocator_type> _OM; 613 allocator_traits<typename _OM::type>::construct 614 ( 615 _OM()(outer_allocator()), 616 __p, 617 _VSTD::forward<_Args>(__args)... 618 ); 619 } 620 621 template <class _Tp, class... _Args> 622 _LIBCPP_INLINE_VISIBILITY 623 void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args) 624 { 625 typedef __outermost<outer_allocator_type> _OM; 626 allocator_traits<typename _OM::type>::construct 627 ( 628 _OM()(outer_allocator()), 629 __p, allocator_arg, inner_allocator(), 630 _VSTD::forward<_Args>(__args)... 631 ); 632 } 633 634 template <class _Tp, class... _Args> 635 _LIBCPP_INLINE_VISIBILITY 636 void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args) 637 { 638 typedef __outermost<outer_allocator_type> _OM; 639 allocator_traits<typename _OM::type>::construct 640 ( 641 _OM()(outer_allocator()), 642 __p, 643 _VSTD::forward<_Args>(__args)..., 644 inner_allocator() 645 ); 646 } 647 648 template <class ..._Args, size_t ..._Idx> 649 _LIBCPP_INLINE_VISIBILITY 650 tuple<_Args&&...> 651 __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, 652 __tuple_indices<_Idx...>) 653 { 654 return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); 655 } 656 657 template <class ..._Args, size_t ..._Idx> 658 _LIBCPP_INLINE_VISIBILITY 659 tuple<allocator_arg_t, inner_allocator_type&, _Args&&...> 660 __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, 661 __tuple_indices<_Idx...>) 662 { 663 using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>; 664 return _Tup(allocator_arg, inner_allocator(), 665 _VSTD::get<_Idx>(_VSTD::move(__t))...); 666 } 667 668 template <class ..._Args, size_t ..._Idx> 669 _LIBCPP_INLINE_VISIBILITY 670 tuple<_Args&&..., inner_allocator_type&> 671 __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, 672 __tuple_indices<_Idx...>) 673 { 674 using _Tup = tuple<_Args&&..., inner_allocator_type&>; 675 return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator()); 676 } 677 678 template <class...> friend class __scoped_allocator_storage; 679}; 680 681#if _LIBCPP_STD_VER > 14 682template<class _OuterAlloc, class... _InnerAllocs> 683 scoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...) 684 -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>; 685#endif 686 687template <class _OuterA1, class _OuterA2> 688inline _LIBCPP_INLINE_VISIBILITY 689bool 690operator==(const scoped_allocator_adaptor<_OuterA1>& __a, 691 const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT 692{ 693 return __a.outer_allocator() == __b.outer_allocator(); 694} 695 696template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs> 697inline _LIBCPP_INLINE_VISIBILITY 698bool 699operator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a, 700 const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT 701{ 702 return __a.outer_allocator() == __b.outer_allocator() && 703 __a.inner_allocator() == __b.inner_allocator(); 704} 705 706template <class _OuterA1, class _OuterA2, class... _InnerAllocs> 707inline _LIBCPP_INLINE_VISIBILITY 708bool 709operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a, 710 const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT 711{ 712 return !(__a == __b); 713} 714 715#endif // !defined(_LIBCPP_CXX03_LANG) 716 717_LIBCPP_END_NAMESPACE_STD 718 719#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 720# include <atomic> 721# include <climits> 722# include <concepts> 723# include <cstring> 724# include <ctime> 725# include <iterator> 726# include <memory> 727# include <ratio> 728# include <stdexcept> 729# include <type_traits> 730# include <variant> 731#endif 732 733#endif // _LIBCPP_SCOPED_ALLOCATOR 734