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