1// -*- C++ -*- 2//===-------------------------- scoped_allocator --------------------------===// 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 OuterA1, class OuterA2, class... InnerAllocs> 95 bool 96 operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 97 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 98 99template <class OuterA1, class OuterA2, class... InnerAllocs> 100 bool 101 operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 102 const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 103 104} // std 105 106*/ 107 108#include <__config> 109#include <memory> 110#include <version> 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 122template <class ..._Allocs> 123class scoped_allocator_adaptor; 124 125template <class ..._Allocs> struct __get_poc_copy_assignment; 126 127template <class _A0> 128struct __get_poc_copy_assignment<_A0> 129{ 130 static const bool value = allocator_traits<_A0>:: 131 propagate_on_container_copy_assignment::value; 132}; 133 134template <class _A0, class ..._Allocs> 135struct __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 142template <class ..._Allocs> struct __get_poc_move_assignment; 143 144template <class _A0> 145struct __get_poc_move_assignment<_A0> 146{ 147 static const bool value = allocator_traits<_A0>:: 148 propagate_on_container_move_assignment::value; 149}; 150 151template <class _A0, class ..._Allocs> 152struct __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 159template <class ..._Allocs> struct __get_poc_swap; 160 161template <class _A0> 162struct __get_poc_swap<_A0> 163{ 164 static const bool value = allocator_traits<_A0>:: 165 propagate_on_container_swap::value; 166}; 167 168template <class _A0, class ..._Allocs> 169struct __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 176template <class ..._Allocs> struct __get_is_always_equal; 177 178template <class _A0> 179struct __get_is_always_equal<_A0> 180{ 181 static const bool value = allocator_traits<_A0>::is_always_equal::value; 182}; 183 184template <class _A0, class ..._Allocs> 185struct __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 192template <class ..._Allocs> 193class __scoped_allocator_storage; 194 195template <class _OuterAlloc, class... _InnerAllocs> 196class __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> 197 : public _OuterAlloc 198{ 199 typedef _OuterAlloc outer_allocator_type; 200protected: 201 typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type; 202 203private: 204 inner_allocator_type __inner_; 205 206protected: 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 281template <class _OuterAlloc> 282class __scoped_allocator_storage<_OuterAlloc> 283 : public _OuterAlloc 284{ 285 typedef _OuterAlloc outer_allocator_type; 286protected: 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 348template <class _Alloc> 349decltype(declval<_Alloc>().outer_allocator(), true_type()) 350__has_outer_allocator_test(_Alloc&& __a); 351 352template <class _Alloc> 353false_type 354__has_outer_allocator_test(const volatile _Alloc& __a); 355 356template <class _Alloc> 357struct __has_outer_allocator 358 : public common_type 359 < 360 decltype(__has_outer_allocator_test(declval<_Alloc&>())) 361 >::type 362{ 363}; 364 365template <class _Alloc, bool = __has_outer_allocator<_Alloc>::value> 366struct __outermost 367{ 368 typedef _Alloc type; 369 _LIBCPP_INLINE_VISIBILITY 370 type& operator()(type& __a) const _NOEXCEPT {return __a;} 371}; 372 373template <class _Alloc> 374struct __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 386template <class _OuterAlloc, class... _InnerAllocs> 387class _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; 392public: 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 566private: 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 651template <class _OuterA1, class _OuterA2> 652inline _LIBCPP_INLINE_VISIBILITY 653bool 654operator==(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 660template <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs> 661inline _LIBCPP_INLINE_VISIBILITY 662bool 663operator==(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 670template <class _OuterA1, class _OuterA2, class... _InnerAllocs> 671inline _LIBCPP_INLINE_VISIBILITY 672bool 673operator!=(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