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