148fb7bfaSmrg// <scoped_allocator> -*- C++ -*- 248fb7bfaSmrg 3b1e83836Smrg// Copyright (C) 2011-2022 Free Software Foundation, Inc. 448fb7bfaSmrg// 548fb7bfaSmrg// This file is part of the GNU ISO C++ Library. This library is free 648fb7bfaSmrg// software; you can redistribute it and/or modify it under the 748fb7bfaSmrg// terms of the GNU General Public License as published by the 848fb7bfaSmrg// Free Software Foundation; either version 3, or (at your option) 948fb7bfaSmrg// any later version. 1048fb7bfaSmrg 1148fb7bfaSmrg// This library is distributed in the hope that it will be useful, 1248fb7bfaSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 1348fb7bfaSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1448fb7bfaSmrg// GNU General Public License for more details. 1548fb7bfaSmrg 1648fb7bfaSmrg// Under Section 7 of GPL version 3, you are granted additional 1748fb7bfaSmrg// permissions described in the GCC Runtime Library Exception, version 1848fb7bfaSmrg// 3.1, as published by the Free Software Foundation. 1948fb7bfaSmrg 2048fb7bfaSmrg// You should have received a copy of the GNU General Public License and 2148fb7bfaSmrg// a copy of the GCC Runtime Library Exception along with this program; 2248fb7bfaSmrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2348fb7bfaSmrg// <http://www.gnu.org/licenses/>. 2448fb7bfaSmrg 2548fb7bfaSmrg/** @file include/scoped_allocator 2648fb7bfaSmrg * This is a Standard C++ Library header. 2748fb7bfaSmrg */ 2848fb7bfaSmrg 2948fb7bfaSmrg#ifndef _SCOPED_ALLOCATOR 3048fb7bfaSmrg#define _SCOPED_ALLOCATOR 1 3148fb7bfaSmrg 3248fb7bfaSmrg#pragma GCC system_header 3348fb7bfaSmrg 3448fb7bfaSmrg#if __cplusplus < 201103L 3548fb7bfaSmrg# include <bits/c++0x_warning.h> 3648fb7bfaSmrg#else 3748fb7bfaSmrg 3848fb7bfaSmrg#include <tuple> 3948fb7bfaSmrg#include <bits/alloc_traits.h> 40b1e83836Smrg#include <bits/stl_pair.h> 41b1e83836Smrg#include <bits/uses_allocator.h> 42b1e83836Smrg#if __cplusplus > 201703L 43b1e83836Smrg# include <bits/uses_allocator_args.h> 44b1e83836Smrg#endif 4548fb7bfaSmrg 4648fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default) 4748fb7bfaSmrg{ 4848fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 4948fb7bfaSmrg 5048fb7bfaSmrg /** 5148fb7bfaSmrg * @addtogroup allocators 5248fb7bfaSmrg * @{ 5348fb7bfaSmrg */ 5448fb7bfaSmrg 55b1e83836Smrg template<typename _OuterAlloc, typename... _InnerAllocs> 56b1e83836Smrg class scoped_allocator_adaptor; 57b1e83836Smrg 58fb8a8121Smrg /// @cond undocumented 59fb8a8121Smrg 6048fb7bfaSmrg template<typename _Alloc> 613f4ceed9Smrg using __outer_allocator_t 623f4ceed9Smrg = decltype(std::declval<_Alloc>().outer_allocator()); 633f4ceed9Smrg 643f4ceed9Smrg template<typename _Alloc, typename = void> 653f4ceed9Smrg struct __outermost_type 663f4ceed9Smrg { 673f4ceed9Smrg using type = _Alloc; 68*0a307195Smrg static type& _S_outermost(_Alloc& __a) noexcept { return __a; } 693f4ceed9Smrg }; 7048fb7bfaSmrg 7148fb7bfaSmrg template<typename _Alloc> 723f4ceed9Smrg struct __outermost_type<_Alloc, __void_t<__outer_allocator_t<_Alloc>>> 733f4ceed9Smrg : __outermost_type< 743f4ceed9Smrg typename remove_reference<__outer_allocator_t<_Alloc>>::type 753f4ceed9Smrg > 763f4ceed9Smrg { 773f4ceed9Smrg using __base = __outermost_type< 783f4ceed9Smrg typename remove_reference<__outer_allocator_t<_Alloc>>::type 793f4ceed9Smrg >; 803f4ceed9Smrg 813f4ceed9Smrg static typename __base::type& 82*0a307195Smrg _S_outermost(_Alloc& __a) noexcept 833f4ceed9Smrg { return __base::_S_outermost(__a.outer_allocator()); } 843f4ceed9Smrg }; 8548fb7bfaSmrg 86b1e83836Smrg // Implementation of the OUTERMOST pseudofunction 8748fb7bfaSmrg template<typename _Alloc> 883f4ceed9Smrg inline typename __outermost_type<_Alloc>::type& 893f4ceed9Smrg __outermost(_Alloc& __a) 903f4ceed9Smrg { return __outermost_type<_Alloc>::_S_outermost(__a); } 9148fb7bfaSmrg 9248fb7bfaSmrg template<typename...> 9348fb7bfaSmrg struct __inner_type_impl; 9448fb7bfaSmrg 9548fb7bfaSmrg template<typename _Outer> 9648fb7bfaSmrg struct __inner_type_impl<_Outer> 9748fb7bfaSmrg { 9848fb7bfaSmrg typedef scoped_allocator_adaptor<_Outer> __type; 9948fb7bfaSmrg 10048fb7bfaSmrg __inner_type_impl() = default; 10148fb7bfaSmrg __inner_type_impl(const __inner_type_impl&) = default; 10248fb7bfaSmrg __inner_type_impl(__inner_type_impl&&) = default; 1037e9e220aSmrg __inner_type_impl& operator=(const __inner_type_impl&) = default; 1047e9e220aSmrg __inner_type_impl& operator=(__inner_type_impl&&) = default; 10548fb7bfaSmrg 10648fb7bfaSmrg template<typename _Alloc> 107*0a307195Smrg __inner_type_impl(const __inner_type_impl<_Alloc>& __other) noexcept 10848fb7bfaSmrg { } 10948fb7bfaSmrg 11048fb7bfaSmrg template<typename _Alloc> 111*0a307195Smrg __inner_type_impl(__inner_type_impl<_Alloc>&& __other) noexcept 11248fb7bfaSmrg { } 11348fb7bfaSmrg 11448fb7bfaSmrg __type& 11548fb7bfaSmrg _M_get(__type* __p) noexcept { return *__p; } 11648fb7bfaSmrg 11748fb7bfaSmrg const __type& 11848fb7bfaSmrg _M_get(const __type* __p) const noexcept { return *__p; } 11948fb7bfaSmrg 12048fb7bfaSmrg tuple<> 12148fb7bfaSmrg _M_tie() const noexcept { return tuple<>(); } 12248fb7bfaSmrg 12348fb7bfaSmrg bool 12448fb7bfaSmrg operator==(const __inner_type_impl&) const noexcept 12548fb7bfaSmrg { return true; } 12648fb7bfaSmrg }; 12748fb7bfaSmrg 12848fb7bfaSmrg template<typename _Outer, typename _InnerHead, typename... _InnerTail> 12948fb7bfaSmrg struct __inner_type_impl<_Outer, _InnerHead, _InnerTail...> 13048fb7bfaSmrg { 13148fb7bfaSmrg typedef scoped_allocator_adaptor<_InnerHead, _InnerTail...> __type; 13248fb7bfaSmrg 13348fb7bfaSmrg __inner_type_impl() = default; 13448fb7bfaSmrg __inner_type_impl(const __inner_type_impl&) = default; 13548fb7bfaSmrg __inner_type_impl(__inner_type_impl&&) = default; 1367e9e220aSmrg __inner_type_impl& operator=(const __inner_type_impl&) = default; 1377e9e220aSmrg __inner_type_impl& operator=(__inner_type_impl&&) = default; 13848fb7bfaSmrg 13948fb7bfaSmrg template<typename... _Allocs> 140*0a307195Smrg __inner_type_impl(const __inner_type_impl<_Allocs...>& __other) noexcept 14148fb7bfaSmrg : _M_inner(__other._M_inner) { } 14248fb7bfaSmrg 14348fb7bfaSmrg template<typename... _Allocs> 144*0a307195Smrg __inner_type_impl(__inner_type_impl<_Allocs...>&& __other) noexcept 14548fb7bfaSmrg : _M_inner(std::move(__other._M_inner)) { } 14648fb7bfaSmrg 14748fb7bfaSmrg template<typename... _Args> 14848fb7bfaSmrg explicit 149*0a307195Smrg __inner_type_impl(_Args&&... __args) noexcept 15048fb7bfaSmrg : _M_inner(std::forward<_Args>(__args)...) { } 15148fb7bfaSmrg 15248fb7bfaSmrg __type& 15348fb7bfaSmrg _M_get(void*) noexcept { return _M_inner; } 15448fb7bfaSmrg 15548fb7bfaSmrg const __type& 15648fb7bfaSmrg _M_get(const void*) const noexcept { return _M_inner; } 15748fb7bfaSmrg 15848fb7bfaSmrg tuple<const _InnerHead&, const _InnerTail&...> 15948fb7bfaSmrg _M_tie() const noexcept 16048fb7bfaSmrg { return _M_inner._M_tie(); } 16148fb7bfaSmrg 16248fb7bfaSmrg bool 16348fb7bfaSmrg operator==(const __inner_type_impl& __other) const noexcept 16448fb7bfaSmrg { return _M_inner == __other._M_inner; } 16548fb7bfaSmrg 16648fb7bfaSmrg private: 167*0a307195Smrg template<typename...> friend struct __inner_type_impl; 16848fb7bfaSmrg template<typename, typename...> friend class scoped_allocator_adaptor; 16948fb7bfaSmrg 17048fb7bfaSmrg __type _M_inner; 17148fb7bfaSmrg }; 17248fb7bfaSmrg 173fb8a8121Smrg /// @endcond 174fb8a8121Smrg 175fb8a8121Smrg /// An adaptor to recursively pass an allocator to the objects it constructs 17648fb7bfaSmrg template<typename _OuterAlloc, typename... _InnerAllocs> 17748fb7bfaSmrg class scoped_allocator_adaptor 17848fb7bfaSmrg : public _OuterAlloc 17948fb7bfaSmrg { 18048fb7bfaSmrg typedef allocator_traits<_OuterAlloc> __traits; 18148fb7bfaSmrg 18248fb7bfaSmrg typedef __inner_type_impl<_OuterAlloc, _InnerAllocs...> __inner_type; 18348fb7bfaSmrg __inner_type _M_inner; 18448fb7bfaSmrg 18548fb7bfaSmrg template<typename _Outer, typename... _Inner> 18648fb7bfaSmrg friend class scoped_allocator_adaptor; 18748fb7bfaSmrg 18848fb7bfaSmrg template<typename...> 189*0a307195Smrg friend struct __inner_type_impl; 19048fb7bfaSmrg 19148fb7bfaSmrg tuple<const _OuterAlloc&, const _InnerAllocs&...> 19248fb7bfaSmrg _M_tie() const noexcept 19348fb7bfaSmrg { return std::tuple_cat(std::tie(outer_allocator()), _M_inner._M_tie()); } 19448fb7bfaSmrg 19548fb7bfaSmrg template<typename _Alloc> 19648fb7bfaSmrg using __outermost_alloc_traits 1973f4ceed9Smrg = allocator_traits<typename __outermost_type<_Alloc>::type>; 19848fb7bfaSmrg 199b1e83836Smrg#if ! __cpp_lib_make_obj_using_allocator 20048fb7bfaSmrg template<typename _Tp, typename... _Args> 20148fb7bfaSmrg void 20248fb7bfaSmrg _M_construct(__uses_alloc0, _Tp* __p, _Args&&... __args) 20348fb7bfaSmrg { 20448fb7bfaSmrg typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits; 20548fb7bfaSmrg _O_traits::construct(__outermost(*this), __p, 20648fb7bfaSmrg std::forward<_Args>(__args)...); 20748fb7bfaSmrg } 20848fb7bfaSmrg 20948fb7bfaSmrg typedef __uses_alloc1<typename __inner_type::__type> __uses_alloc1_; 21048fb7bfaSmrg typedef __uses_alloc2<typename __inner_type::__type> __uses_alloc2_; 21148fb7bfaSmrg 21248fb7bfaSmrg template<typename _Tp, typename... _Args> 21348fb7bfaSmrg void 21448fb7bfaSmrg _M_construct(__uses_alloc1_, _Tp* __p, _Args&&... __args) 21548fb7bfaSmrg { 21648fb7bfaSmrg typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits; 21748fb7bfaSmrg _O_traits::construct(__outermost(*this), __p, 21848fb7bfaSmrg allocator_arg, inner_allocator(), 21948fb7bfaSmrg std::forward<_Args>(__args)...); 22048fb7bfaSmrg } 22148fb7bfaSmrg 22248fb7bfaSmrg template<typename _Tp, typename... _Args> 22348fb7bfaSmrg void 22448fb7bfaSmrg _M_construct(__uses_alloc2_, _Tp* __p, _Args&&... __args) 22548fb7bfaSmrg { 22648fb7bfaSmrg typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits; 22748fb7bfaSmrg _O_traits::construct(__outermost(*this), __p, 22848fb7bfaSmrg std::forward<_Args>(__args)..., 22948fb7bfaSmrg inner_allocator()); 23048fb7bfaSmrg } 231b1e83836Smrg#endif // ! make_obj_using_allocator 23248fb7bfaSmrg 23348fb7bfaSmrg template<typename _Alloc> 23448fb7bfaSmrg static _Alloc 23548fb7bfaSmrg _S_select_on_copy(const _Alloc& __a) 23648fb7bfaSmrg { 23748fb7bfaSmrg typedef allocator_traits<_Alloc> __a_traits; 23848fb7bfaSmrg return __a_traits::select_on_container_copy_construction(__a); 23948fb7bfaSmrg } 24048fb7bfaSmrg 24148fb7bfaSmrg template<std::size_t... _Indices> 24248fb7bfaSmrg scoped_allocator_adaptor(tuple<const _OuterAlloc&, 24348fb7bfaSmrg const _InnerAllocs&...> __refs, 24448fb7bfaSmrg _Index_tuple<_Indices...>) 24548fb7bfaSmrg : _OuterAlloc(_S_select_on_copy(std::get<0>(__refs))), 24648fb7bfaSmrg _M_inner(_S_select_on_copy(std::get<_Indices+1>(__refs))...) 24748fb7bfaSmrg { } 24848fb7bfaSmrg 2493f4ceed9Smrg // Used to constrain constructors to disallow invalid conversions. 2503f4ceed9Smrg template<typename _Alloc> 2513f4ceed9Smrg using _Constructible = typename enable_if< 2523f4ceed9Smrg is_constructible<_OuterAlloc, _Alloc>::value 2533f4ceed9Smrg >::type; 2543f4ceed9Smrg 255181254a7Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 256181254a7Smrg // 2975. Missing case for pair construction in scoped [...] allocators 257181254a7Smrg template<typename _Tp> 258181254a7Smrg struct __not_pair { using type = void; }; 259181254a7Smrg 260181254a7Smrg template<typename _Tp, typename _Up> 261181254a7Smrg struct __not_pair<pair<_Tp, _Up>> { }; 262181254a7Smrg 26348fb7bfaSmrg public: 26448fb7bfaSmrg typedef _OuterAlloc outer_allocator_type; 26548fb7bfaSmrg typedef typename __inner_type::__type inner_allocator_type; 26648fb7bfaSmrg 26748fb7bfaSmrg typedef typename __traits::value_type value_type; 26848fb7bfaSmrg typedef typename __traits::size_type size_type; 26948fb7bfaSmrg typedef typename __traits::difference_type difference_type; 27048fb7bfaSmrg typedef typename __traits::pointer pointer; 27148fb7bfaSmrg typedef typename __traits::const_pointer const_pointer; 27248fb7bfaSmrg typedef typename __traits::void_pointer void_pointer; 27348fb7bfaSmrg typedef typename __traits::const_void_pointer const_void_pointer; 27448fb7bfaSmrg 275f9a78e0eSmrg typedef typename __or_< 276f9a78e0eSmrg typename __traits::propagate_on_container_copy_assignment, 277f9a78e0eSmrg typename allocator_traits<_InnerAllocs>:: 278f9a78e0eSmrg propagate_on_container_copy_assignment...>::type 279f9a78e0eSmrg propagate_on_container_copy_assignment; 280f9a78e0eSmrg 281f9a78e0eSmrg typedef typename __or_< 282f9a78e0eSmrg typename __traits::propagate_on_container_move_assignment, 283f9a78e0eSmrg typename allocator_traits<_InnerAllocs>:: 284f9a78e0eSmrg propagate_on_container_move_assignment...>::type 285f9a78e0eSmrg propagate_on_container_move_assignment; 286f9a78e0eSmrg 287f9a78e0eSmrg typedef typename __or_< 288f9a78e0eSmrg typename __traits::propagate_on_container_swap, 289f9a78e0eSmrg typename allocator_traits<_InnerAllocs>:: 290f9a78e0eSmrg propagate_on_container_swap...>::type 291f9a78e0eSmrg propagate_on_container_swap; 292f9a78e0eSmrg 293f9a78e0eSmrg typedef typename __and_< 294f9a78e0eSmrg typename __traits::is_always_equal, 295f9a78e0eSmrg typename allocator_traits<_InnerAllocs>::is_always_equal...>::type 296f9a78e0eSmrg is_always_equal; 29748fb7bfaSmrg 29848fb7bfaSmrg template <class _Tp> 29948fb7bfaSmrg struct rebind 30048fb7bfaSmrg { 30148fb7bfaSmrg typedef scoped_allocator_adaptor< 30248fb7bfaSmrg typename __traits::template rebind_alloc<_Tp>, 30348fb7bfaSmrg _InnerAllocs...> other; 30448fb7bfaSmrg }; 30548fb7bfaSmrg 30648fb7bfaSmrg scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { } 30748fb7bfaSmrg 3083f4ceed9Smrg template<typename _Outer2, typename = _Constructible<_Outer2>> 30948fb7bfaSmrg scoped_allocator_adaptor(_Outer2&& __outer, 310*0a307195Smrg const _InnerAllocs&... __inner) noexcept 31148fb7bfaSmrg : _OuterAlloc(std::forward<_Outer2>(__outer)), 31248fb7bfaSmrg _M_inner(__inner...) 31348fb7bfaSmrg { } 31448fb7bfaSmrg 315*0a307195Smrg scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) noexcept 31648fb7bfaSmrg : _OuterAlloc(__other.outer_allocator()), 31748fb7bfaSmrg _M_inner(__other._M_inner) 31848fb7bfaSmrg { } 31948fb7bfaSmrg 320*0a307195Smrg scoped_allocator_adaptor(scoped_allocator_adaptor&& __other) noexcept 32148fb7bfaSmrg : _OuterAlloc(std::move(__other.outer_allocator())), 32248fb7bfaSmrg _M_inner(std::move(__other._M_inner)) 32348fb7bfaSmrg { } 32448fb7bfaSmrg 3253f4ceed9Smrg template<typename _Outer2, typename = _Constructible<const _Outer2&>> 32648fb7bfaSmrg scoped_allocator_adaptor( 327*0a307195Smrg const scoped_allocator_adaptor<_Outer2, _InnerAllocs...>& __other 328*0a307195Smrg ) noexcept 32948fb7bfaSmrg : _OuterAlloc(__other.outer_allocator()), 33048fb7bfaSmrg _M_inner(__other._M_inner) 33148fb7bfaSmrg { } 33248fb7bfaSmrg 3333f4ceed9Smrg template<typename _Outer2, typename = _Constructible<_Outer2>> 33448fb7bfaSmrg scoped_allocator_adaptor( 335*0a307195Smrg scoped_allocator_adaptor<_Outer2, _InnerAllocs...>&& __other) noexcept 33648fb7bfaSmrg : _OuterAlloc(std::move(__other.outer_allocator())), 33748fb7bfaSmrg _M_inner(std::move(__other._M_inner)) 33848fb7bfaSmrg { } 33948fb7bfaSmrg 3407e9e220aSmrg scoped_allocator_adaptor& 3417e9e220aSmrg operator=(const scoped_allocator_adaptor&) = default; 3427e9e220aSmrg 3437e9e220aSmrg scoped_allocator_adaptor& 3447e9e220aSmrg operator=(scoped_allocator_adaptor&&) = default; 3457e9e220aSmrg 346*0a307195Smrg inner_allocator_type& 347*0a307195Smrg inner_allocator() noexcept 34848fb7bfaSmrg { return _M_inner._M_get(this); } 34948fb7bfaSmrg 350*0a307195Smrg const inner_allocator_type& 351*0a307195Smrg inner_allocator() const noexcept 35248fb7bfaSmrg { return _M_inner._M_get(this); } 35348fb7bfaSmrg 354*0a307195Smrg outer_allocator_type& 355*0a307195Smrg outer_allocator() noexcept 35648fb7bfaSmrg { return static_cast<_OuterAlloc&>(*this); } 35748fb7bfaSmrg 358*0a307195Smrg const outer_allocator_type& 359*0a307195Smrg outer_allocator() const noexcept 36048fb7bfaSmrg { return static_cast<const _OuterAlloc&>(*this); } 36148fb7bfaSmrg 362*0a307195Smrg _GLIBCXX_NODISCARD pointer 363*0a307195Smrg allocate(size_type __n) 36448fb7bfaSmrg { return __traits::allocate(outer_allocator(), __n); } 36548fb7bfaSmrg 366*0a307195Smrg _GLIBCXX_NODISCARD pointer 367*0a307195Smrg allocate(size_type __n, const_void_pointer __hint) 36848fb7bfaSmrg { return __traits::allocate(outer_allocator(), __n, __hint); } 36948fb7bfaSmrg 370*0a307195Smrg void deallocate(pointer __p, size_type __n) noexcept 37148fb7bfaSmrg { return __traits::deallocate(outer_allocator(), __p, __n); } 37248fb7bfaSmrg 37348fb7bfaSmrg size_type max_size() const 37448fb7bfaSmrg { return __traits::max_size(outer_allocator()); } 37548fb7bfaSmrg 376b1e83836Smrg#if ! __cpp_lib_make_obj_using_allocator 37748fb7bfaSmrg template<typename _Tp, typename... _Args> 378181254a7Smrg typename __not_pair<_Tp>::type 379181254a7Smrg construct(_Tp* __p, _Args&&... __args) 38048fb7bfaSmrg { 38148fb7bfaSmrg auto& __inner = inner_allocator(); 38248fb7bfaSmrg auto __use_tag 383181254a7Smrg = std::__use_alloc<_Tp, inner_allocator_type, _Args...>(__inner); 38448fb7bfaSmrg _M_construct(__use_tag, __p, std::forward<_Args>(__args)...); 38548fb7bfaSmrg } 38648fb7bfaSmrg 38748fb7bfaSmrg template<typename _T1, typename _T2, typename... _Args1, 38848fb7bfaSmrg typename... _Args2> 38948fb7bfaSmrg void 39048fb7bfaSmrg construct(pair<_T1, _T2>* __p, piecewise_construct_t, 39148fb7bfaSmrg tuple<_Args1...> __x, tuple<_Args2...> __y) 39248fb7bfaSmrg { 39348fb7bfaSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 39448fb7bfaSmrg // 2203. wrong argument types for piecewise construction 39548fb7bfaSmrg auto& __inner = inner_allocator(); 39648fb7bfaSmrg auto __x_use_tag 397181254a7Smrg = std::__use_alloc<_T1, inner_allocator_type, _Args1...>(__inner); 39848fb7bfaSmrg auto __y_use_tag 399181254a7Smrg = std::__use_alloc<_T2, inner_allocator_type, _Args2...>(__inner); 400b17d1066Smrg typename _Build_index_tuple<sizeof...(_Args1)>::__type __x_indices; 401b17d1066Smrg typename _Build_index_tuple<sizeof...(_Args2)>::__type __y_indices; 40248fb7bfaSmrg typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits; 40348fb7bfaSmrg _O_traits::construct(__outermost(*this), __p, piecewise_construct, 404b17d1066Smrg _M_construct_p(__x_use_tag, __x_indices, __x), 405b17d1066Smrg _M_construct_p(__y_use_tag, __y_indices, __y)); 40648fb7bfaSmrg } 40748fb7bfaSmrg 40848fb7bfaSmrg template<typename _T1, typename _T2> 40948fb7bfaSmrg void 41048fb7bfaSmrg construct(pair<_T1, _T2>* __p) 41148fb7bfaSmrg { construct(__p, piecewise_construct, tuple<>(), tuple<>()); } 41248fb7bfaSmrg 41348fb7bfaSmrg template<typename _T1, typename _T2, typename _Up, typename _Vp> 41448fb7bfaSmrg void 41548fb7bfaSmrg construct(pair<_T1, _T2>* __p, _Up&& __u, _Vp&& __v) 41648fb7bfaSmrg { 41748fb7bfaSmrg construct(__p, piecewise_construct, 41848fb7bfaSmrg std::forward_as_tuple(std::forward<_Up>(__u)), 41948fb7bfaSmrg std::forward_as_tuple(std::forward<_Vp>(__v))); 42048fb7bfaSmrg } 42148fb7bfaSmrg 42248fb7bfaSmrg template<typename _T1, typename _T2, typename _Up, typename _Vp> 42348fb7bfaSmrg void 42448fb7bfaSmrg construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) 42548fb7bfaSmrg { 42648fb7bfaSmrg construct(__p, piecewise_construct, 42748fb7bfaSmrg std::forward_as_tuple(__x.first), 42848fb7bfaSmrg std::forward_as_tuple(__x.second)); 42948fb7bfaSmrg } 43048fb7bfaSmrg 43148fb7bfaSmrg template<typename _T1, typename _T2, typename _Up, typename _Vp> 43248fb7bfaSmrg void 43348fb7bfaSmrg construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) 43448fb7bfaSmrg { 43548fb7bfaSmrg construct(__p, piecewise_construct, 43648fb7bfaSmrg std::forward_as_tuple(std::forward<_Up>(__x.first)), 43748fb7bfaSmrg std::forward_as_tuple(std::forward<_Vp>(__x.second))); 43848fb7bfaSmrg } 439b1e83836Smrg#else // make_obj_using_allocator 440181254a7Smrg template<typename _Tp, typename... _Args> 441181254a7Smrg __attribute__((__nonnull__)) 442181254a7Smrg void 443181254a7Smrg construct(_Tp* __p, _Args&&... __args) 444181254a7Smrg { 445181254a7Smrg typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits; 446181254a7Smrg std::apply([__p, this](auto&&... __newargs) { 447181254a7Smrg _O_traits::construct(__outermost(*this), __p, 448181254a7Smrg std::forward<decltype(__newargs)>(__newargs)...); 449181254a7Smrg }, 450181254a7Smrg uses_allocator_construction_args<_Tp>(inner_allocator(), 451181254a7Smrg std::forward<_Args>(__args)...)); 452181254a7Smrg } 453b1e83836Smrg#endif 45448fb7bfaSmrg 45548fb7bfaSmrg template<typename _Tp> 45648fb7bfaSmrg void destroy(_Tp* __p) 45748fb7bfaSmrg { 45848fb7bfaSmrg typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits; 45948fb7bfaSmrg _O_traits::destroy(__outermost(*this), __p); 46048fb7bfaSmrg } 46148fb7bfaSmrg 46248fb7bfaSmrg scoped_allocator_adaptor 46348fb7bfaSmrg select_on_container_copy_construction() const 46448fb7bfaSmrg { 46548fb7bfaSmrg typedef typename _Build_index_tuple<sizeof...(_InnerAllocs)>::__type 46648fb7bfaSmrg _Indices; 46748fb7bfaSmrg return scoped_allocator_adaptor(_M_tie(), _Indices()); 46848fb7bfaSmrg } 46948fb7bfaSmrg 47048fb7bfaSmrg template <typename _OutA1, typename _OutA2, typename... _InA> 47148fb7bfaSmrg friend bool 47248fb7bfaSmrg operator==(const scoped_allocator_adaptor<_OutA1, _InA...>& __a, 47348fb7bfaSmrg const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept; 47448fb7bfaSmrg 47548fb7bfaSmrg private: 476b1e83836Smrg#if ! __cpp_lib_make_obj_using_allocator 477b17d1066Smrg template<typename _Ind, typename... _Args> 478b17d1066Smrg tuple<_Args&&...> 479b17d1066Smrg _M_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t) 48048fb7bfaSmrg { return std::move(__t); } 48148fb7bfaSmrg 482b17d1066Smrg template<size_t... _Ind, typename... _Args> 483b17d1066Smrg tuple<allocator_arg_t, inner_allocator_type&, _Args&&...> 484b17d1066Smrg _M_construct_p(__uses_alloc1_, _Index_tuple<_Ind...>, 485b17d1066Smrg tuple<_Args...>& __t) 48648fb7bfaSmrg { 487b17d1066Smrg return { allocator_arg, inner_allocator(), 488b17d1066Smrg std::get<_Ind>(std::move(__t))... 489b17d1066Smrg }; 49048fb7bfaSmrg } 49148fb7bfaSmrg 492b17d1066Smrg template<size_t... _Ind, typename... _Args> 493b17d1066Smrg tuple<_Args&&..., inner_allocator_type&> 494b17d1066Smrg _M_construct_p(__uses_alloc2_, _Index_tuple<_Ind...>, 495b17d1066Smrg tuple<_Args...>& __t) 49648fb7bfaSmrg { 497b17d1066Smrg return { std::get<_Ind>(std::move(__t))..., inner_allocator() }; 49848fb7bfaSmrg } 499b1e83836Smrg#endif // ! make_obj_using_allocator 50048fb7bfaSmrg }; 50148fb7bfaSmrg 502fb8a8121Smrg /// @related std::scoped_allocator_adaptor 50348fb7bfaSmrg template <typename _OutA1, typename _OutA2, typename... _InA> 50448fb7bfaSmrg inline bool 50548fb7bfaSmrg operator==(const scoped_allocator_adaptor<_OutA1, _InA...>& __a, 50648fb7bfaSmrg const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept 50748fb7bfaSmrg { 50848fb7bfaSmrg return __a.outer_allocator() == __b.outer_allocator() 50948fb7bfaSmrg && __a._M_inner == __b._M_inner; 51048fb7bfaSmrg } 51148fb7bfaSmrg 512fb8a8121Smrg#if __cpp_impl_three_way_comparison < 201907L 513fb8a8121Smrg /// @related std::scoped_allocator_adaptor 51448fb7bfaSmrg template <typename _OutA1, typename _OutA2, typename... _InA> 51548fb7bfaSmrg inline bool 51648fb7bfaSmrg operator!=(const scoped_allocator_adaptor<_OutA1, _InA...>& __a, 51748fb7bfaSmrg const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept 51848fb7bfaSmrg { return !(__a == __b); } 519fb8a8121Smrg#endif 52048fb7bfaSmrg 52148fb7bfaSmrg /// @} 52248fb7bfaSmrg 52348fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION 52448fb7bfaSmrg} // namespace 52548fb7bfaSmrg 52648fb7bfaSmrg#endif // C++11 52748fb7bfaSmrg 52848fb7bfaSmrg#endif // _SCOPED_ALLOCATOR 529