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