10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_SCOPED_ALLOCATOR 110b57cec5SDimitry Andric#define _LIBCPP_SCOPED_ALLOCATOR 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric scoped_allocator synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std 170b57cec5SDimitry Andric{ 180b57cec5SDimitry Andric 190b57cec5SDimitry Andrictemplate <class OuterAlloc, class... InnerAllocs> 200b57cec5SDimitry Andricclass scoped_allocator_adaptor : public OuterAlloc 210b57cec5SDimitry Andric{ 220b57cec5SDimitry Andric typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only 230b57cec5SDimitry Andric scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only 240b57cec5SDimitry Andricpublic: 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric typedef OuterAlloc outer_allocator_type; 270b57cec5SDimitry Andric typedef see below inner_allocator_type; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric typedef typename OuterTraits::value_type value_type; 300b57cec5SDimitry Andric typedef typename OuterTraits::size_type size_type; 310b57cec5SDimitry Andric typedef typename OuterTraits::difference_type difference_type; 320b57cec5SDimitry Andric typedef typename OuterTraits::pointer pointer; 330b57cec5SDimitry Andric typedef typename OuterTraits::const_pointer const_pointer; 340b57cec5SDimitry Andric typedef typename OuterTraits::void_pointer void_pointer; 350b57cec5SDimitry Andric typedef typename OuterTraits::const_void_pointer const_void_pointer; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric typedef see below propagate_on_container_copy_assignment; 380b57cec5SDimitry Andric typedef see below propagate_on_container_move_assignment; 390b57cec5SDimitry Andric typedef see below propagate_on_container_swap; 400b57cec5SDimitry Andric typedef see below is_always_equal; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric template <class Tp> 430b57cec5SDimitry Andric struct rebind 440b57cec5SDimitry Andric { 450b57cec5SDimitry Andric typedef scoped_allocator_adaptor< 460b57cec5SDimitry Andric OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other; 470b57cec5SDimitry Andric }; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric scoped_allocator_adaptor(); 500b57cec5SDimitry Andric template <class OuterA2> 510b57cec5SDimitry Andric scoped_allocator_adaptor(OuterA2&& outerAlloc, 520b57cec5SDimitry Andric const InnerAllocs&... innerAllocs) noexcept; 530b57cec5SDimitry Andric scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; 540b57cec5SDimitry Andric scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; 550b57cec5SDimitry Andric template <class OuterA2> 560b57cec5SDimitry Andric scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept; 570b57cec5SDimitry Andric template <class OuterA2> 580b57cec5SDimitry Andric scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; 610b57cec5SDimitry Andric scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; 620b57cec5SDimitry Andric ~scoped_allocator_adaptor(); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric inner_allocator_type& inner_allocator() noexcept; 650b57cec5SDimitry Andric const inner_allocator_type& inner_allocator() const noexcept; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric outer_allocator_type& outer_allocator() noexcept; 680b57cec5SDimitry Andric const outer_allocator_type& outer_allocator() const noexcept; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric pointer allocate(size_type n); // [[nodiscard]] in C++20 710b57cec5SDimitry Andric pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20 720b57cec5SDimitry Andric void deallocate(pointer p, size_type n) noexcept; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric size_type max_size() const; 750b57cec5SDimitry Andric template <class T, class... Args> void construct(T* p, Args&& args); 760b57cec5SDimitry Andric template <class T1, class T2, class... Args1, class... Args2> 770b57cec5SDimitry Andric void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x, 780b57cec5SDimitry Andric tuple<Args2...> y); 790b57cec5SDimitry Andric template <class T1, class T2> 800b57cec5SDimitry Andric void construct(pair<T1, T2>* p); 810b57cec5SDimitry Andric template <class T1, class T2, class U, class V> 820b57cec5SDimitry Andric void construct(pair<T1, T2>* p, U&& x, V&& y); 830b57cec5SDimitry Andric template <class T1, class T2, class U, class V> 840b57cec5SDimitry Andric void construct(pair<T1, T2>* p, const pair<U, V>& x); 850b57cec5SDimitry Andric template <class T1, class T2, class U, class V> 860b57cec5SDimitry Andric void construct(pair<T1, T2>* p, pair<U, V>&& x); 870b57cec5SDimitry Andric template <class T> void destroy(T* p); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric template <class T> void destroy(T* p) noexcept; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric scoped_allocator_adaptor select_on_container_copy_construction() const noexcept; 920b57cec5SDimitry Andric}; 930b57cec5SDimitry Andric 94349cc55cSDimitry Andrictemplate<class OuterAlloc, class... InnerAllocs> 95349cc55cSDimitry Andric scoped_allocator_adaptor(OuterAlloc, InnerAllocs...) 96349cc55cSDimitry Andric -> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>; 97349cc55cSDimitry Andric 980b57cec5SDimitry Andrictemplate <class OuterA1, class OuterA2, class... InnerAllocs> 990b57cec5SDimitry Andric bool 1000b57cec5SDimitry Andric operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 1010b57cec5SDimitry Andric const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andrictemplate <class OuterA1, class OuterA2, class... InnerAllocs> 1040b57cec5SDimitry Andric bool 1050b57cec5SDimitry Andric operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 10606c3fb27SDimitry Andric const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; // removed in C++20 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric} // std 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric*/ 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric#include <__config> 113bdd1243dSDimitry Andric#include <__memory/allocator_traits.h> 114bdd1243dSDimitry Andric#include <__memory/uses_allocator_construction.h> 115bdd1243dSDimitry Andric#include <__type_traits/common_type.h> 116bdd1243dSDimitry Andric#include <__type_traits/enable_if.h> 117bdd1243dSDimitry Andric#include <__type_traits/integral_constant.h> 118bdd1243dSDimitry Andric#include <__type_traits/is_constructible.h> 119bdd1243dSDimitry Andric#include <__type_traits/remove_reference.h> 120bdd1243dSDimitry Andric#include <__utility/declval.h> 121fe6060f1SDimitry Andric#include <__utility/forward.h> 122bdd1243dSDimitry Andric#include <__utility/move.h> 123bdd1243dSDimitry Andric#include <__utility/pair.h> 124bdd1243dSDimitry Andric#include <__utility/piecewise_construct.h> 125bdd1243dSDimitry Andric#include <tuple> 1260b57cec5SDimitry Andric#include <version> 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1290b57cec5SDimitry Andric# pragma GCC system_header 1300b57cec5SDimitry Andric#endif 1310b57cec5SDimitry Andric 13206c3fb27SDimitry Andric_LIBCPP_PUSH_MACROS 13306c3fb27SDimitry Andric#include <__undef_macros> 13406c3fb27SDimitry Andric 1350b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric#if !defined(_LIBCPP_CXX03_LANG) 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric// scoped_allocator_adaptor 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andrictemplate <class... _Allocs> 1420b57cec5SDimitry Andricclass scoped_allocator_adaptor; 1430b57cec5SDimitry Andric 144cb14a3feSDimitry Andrictemplate <class... _Allocs> 145cb14a3feSDimitry Andricstruct __get_poc_copy_assignment; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andrictemplate <class _A0> 148cb14a3feSDimitry Andricstruct __get_poc_copy_assignment<_A0> { 149cb14a3feSDimitry Andric static const bool value = allocator_traits<_A0>::propagate_on_container_copy_assignment::value; 1500b57cec5SDimitry Andric}; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andrictemplate <class _A0, class... _Allocs> 153cb14a3feSDimitry Andricstruct __get_poc_copy_assignment<_A0, _Allocs...> { 154cb14a3feSDimitry Andric static const bool value = allocator_traits<_A0>::propagate_on_container_copy_assignment::value || 1550b57cec5SDimitry Andric __get_poc_copy_assignment<_Allocs...>::value; 1560b57cec5SDimitry Andric}; 1570b57cec5SDimitry Andric 158cb14a3feSDimitry Andrictemplate <class... _Allocs> 159cb14a3feSDimitry Andricstruct __get_poc_move_assignment; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andrictemplate <class _A0> 162cb14a3feSDimitry Andricstruct __get_poc_move_assignment<_A0> { 163cb14a3feSDimitry Andric static const bool value = allocator_traits<_A0>::propagate_on_container_move_assignment::value; 1640b57cec5SDimitry Andric}; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andrictemplate <class _A0, class... _Allocs> 167cb14a3feSDimitry Andricstruct __get_poc_move_assignment<_A0, _Allocs...> { 168cb14a3feSDimitry Andric static const bool value = allocator_traits<_A0>::propagate_on_container_move_assignment::value || 1690b57cec5SDimitry Andric __get_poc_move_assignment<_Allocs...>::value; 1700b57cec5SDimitry Andric}; 1710b57cec5SDimitry Andric 172cb14a3feSDimitry Andrictemplate <class... _Allocs> 173cb14a3feSDimitry Andricstruct __get_poc_swap; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andrictemplate <class _A0> 176cb14a3feSDimitry Andricstruct __get_poc_swap<_A0> { 177cb14a3feSDimitry Andric static const bool value = allocator_traits<_A0>::propagate_on_container_swap::value; 1780b57cec5SDimitry Andric}; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andrictemplate <class _A0, class... _Allocs> 181cb14a3feSDimitry Andricstruct __get_poc_swap<_A0, _Allocs...> { 1820b57cec5SDimitry Andric static const bool value = 183cb14a3feSDimitry Andric allocator_traits<_A0>::propagate_on_container_swap::value || __get_poc_swap<_Allocs...>::value; 1840b57cec5SDimitry Andric}; 1850b57cec5SDimitry Andric 186cb14a3feSDimitry Andrictemplate <class... _Allocs> 187cb14a3feSDimitry Andricstruct __get_is_always_equal; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andrictemplate <class _A0> 190cb14a3feSDimitry Andricstruct __get_is_always_equal<_A0> { 1910b57cec5SDimitry Andric static const bool value = allocator_traits<_A0>::is_always_equal::value; 1920b57cec5SDimitry Andric}; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andrictemplate <class _A0, class... _Allocs> 195cb14a3feSDimitry Andricstruct __get_is_always_equal<_A0, _Allocs...> { 196cb14a3feSDimitry Andric static const bool value = allocator_traits<_A0>::is_always_equal::value && __get_is_always_equal<_Allocs...>::value; 1970b57cec5SDimitry Andric}; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andrictemplate <class... _Allocs> 2000b57cec5SDimitry Andricclass __scoped_allocator_storage; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andrictemplate <class _OuterAlloc, class... _InnerAllocs> 203cb14a3feSDimitry Andricclass __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> : public _OuterAlloc { 2040b57cec5SDimitry Andric typedef _OuterAlloc outer_allocator_type; 205cb14a3feSDimitry Andric 2060b57cec5SDimitry Andricprotected: 2070b57cec5SDimitry Andric typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andricprivate: 2100b57cec5SDimitry Andric inner_allocator_type __inner_; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andricprotected: 213cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage() _NOEXCEPT {} 2140b57cec5SDimitry Andric 215cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 2165f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 217cb14a3feSDimitry Andric __scoped_allocator_storage(_OuterA2&& __outer_alloc, const _InnerAllocs&... __inner_allocs) _NOEXCEPT 2185f757f3fSDimitry Andric : outer_allocator_type(std::forward<_OuterA2>(__outer_alloc)), 219753f127fSDimitry Andric __inner_(__inner_allocs...) {} 2200b57cec5SDimitry Andric 221cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0> 2225f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 223cb14a3feSDimitry Andric __scoped_allocator_storage(const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT 2240b57cec5SDimitry Andric : outer_allocator_type(__other.outer_allocator()), 2250b57cec5SDimitry Andric __inner_(__other.inner_allocator()) {} 2260b57cec5SDimitry Andric 227cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 2285f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 229cb14a3feSDimitry Andric __scoped_allocator_storage(__scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT 2305f757f3fSDimitry Andric : outer_allocator_type(std::move(__other.outer_allocator())), 2315f757f3fSDimitry Andric __inner_(std::move(__other.inner_allocator())) {} 2320b57cec5SDimitry Andric 233cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 234cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(_OuterA2&& __o, const inner_allocator_type& __i) _NOEXCEPT 2355f757f3fSDimitry Andric : outer_allocator_type(std::forward<_OuterA2>(__o)), 236cb14a3feSDimitry Andric __inner_(__i) {} 237cb14a3feSDimitry Andric 238cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return __inner_; } 239cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT { return __inner_; } 240cb14a3feSDimitry Andric 241cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { 242cb14a3feSDimitry Andric return static_cast<outer_allocator_type&>(*this); 243cb14a3feSDimitry Andric } 244cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT { 245cb14a3feSDimitry Andric return static_cast<const outer_allocator_type&>(*this); 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric 248cb14a3feSDimitry Andric scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> _LIBCPP_HIDE_FROM_ABI 249cb14a3feSDimitry Andric select_on_container_copy_construction() const _NOEXCEPT { 250cb14a3feSDimitry Andric return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...>( 251cb14a3feSDimitry Andric allocator_traits<outer_allocator_type>::select_on_container_copy_construction(outer_allocator()), 252cb14a3feSDimitry Andric allocator_traits<inner_allocator_type>::select_on_container_copy_construction(inner_allocator())); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 255cb14a3feSDimitry Andric template <class...> 256cb14a3feSDimitry Andric friend class __scoped_allocator_storage; 2570b57cec5SDimitry Andric}; 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andrictemplate <class _OuterAlloc> 260cb14a3feSDimitry Andricclass __scoped_allocator_storage<_OuterAlloc> : public _OuterAlloc { 2610b57cec5SDimitry Andric typedef _OuterAlloc outer_allocator_type; 262cb14a3feSDimitry Andric 2630b57cec5SDimitry Andricprotected: 2640b57cec5SDimitry Andric typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type; 2650b57cec5SDimitry Andric 266cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage() _NOEXCEPT {} 2670b57cec5SDimitry Andric 268cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 269cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(_OuterA2&& __outer_alloc) _NOEXCEPT 2705f757f3fSDimitry Andric : outer_allocator_type(std::forward<_OuterA2>(__outer_alloc)) {} 2710b57cec5SDimitry Andric 272cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0> 273cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT 2740b57cec5SDimitry Andric : outer_allocator_type(__other.outer_allocator()) {} 2750b57cec5SDimitry Andric 276cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 277cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI __scoped_allocator_storage(__scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT 2785f757f3fSDimitry Andric : outer_allocator_type(std::move(__other.outer_allocator())) {} 2790b57cec5SDimitry Andric 280cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { 281cb14a3feSDimitry Andric return static_cast<inner_allocator_type&>(*this); 282cb14a3feSDimitry Andric } 283cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT { 284cb14a3feSDimitry Andric return static_cast<const inner_allocator_type&>(*this); 285cb14a3feSDimitry Andric } 2860b57cec5SDimitry Andric 287cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { 288cb14a3feSDimitry Andric return static_cast<outer_allocator_type&>(*this); 289cb14a3feSDimitry Andric } 290cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT { 291cb14a3feSDimitry Andric return static_cast<const outer_allocator_type&>(*this); 292cb14a3feSDimitry Andric } 2930b57cec5SDimitry Andric 294cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor<outer_allocator_type> 295cb14a3feSDimitry Andric select_on_container_copy_construction() const _NOEXCEPT { 296cb14a3feSDimitry Andric return scoped_allocator_adaptor<outer_allocator_type>( 297cb14a3feSDimitry Andric allocator_traits<outer_allocator_type>::select_on_container_copy_construction(outer_allocator())); 298cb14a3feSDimitry Andric } 2990b57cec5SDimitry Andric 300cb14a3feSDimitry Andric __scoped_allocator_storage(const outer_allocator_type& __o, const inner_allocator_type& __i) _NOEXCEPT; 3010b57cec5SDimitry Andric 302cb14a3feSDimitry Andric template <class...> 303cb14a3feSDimitry Andric friend class __scoped_allocator_storage; 3040b57cec5SDimitry Andric}; 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric// __outermost 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andrictemplate <class _Alloc> 309cb14a3feSDimitry Andricdecltype(std::declval<_Alloc>().outer_allocator(), true_type()) __has_outer_allocator_test(_Alloc&& __a); 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andrictemplate <class _Alloc> 312cb14a3feSDimitry Andricfalse_type __has_outer_allocator_test(const volatile _Alloc& __a); 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andrictemplate <class _Alloc> 3150b57cec5SDimitry Andricstruct __has_outer_allocator 316cb14a3feSDimitry Andric : public common_type< decltype(std::__has_outer_allocator_test(std::declval<_Alloc&>()))>::type {}; 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andrictemplate <class _Alloc, bool = __has_outer_allocator<_Alloc>::value> 319cb14a3feSDimitry Andricstruct __outermost { 3200b57cec5SDimitry Andric typedef _Alloc type; 321cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI type& operator()(type& __a) const _NOEXCEPT { return __a; } 3220b57cec5SDimitry Andric}; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andrictemplate <class _Alloc> 325cb14a3feSDimitry Andricstruct __outermost<_Alloc, true> { 326cb14a3feSDimitry Andric typedef __libcpp_remove_reference_t< decltype(std::declval<_Alloc>().outer_allocator()) > _OuterAlloc; 3270b57cec5SDimitry Andric typedef typename __outermost<_OuterAlloc>::type type; 328cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI type& operator()(_Alloc& __a) const _NOEXCEPT { 329cb14a3feSDimitry Andric return __outermost<_OuterAlloc>()(__a.outer_allocator()); 330cb14a3feSDimitry Andric } 3310b57cec5SDimitry Andric}; 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andrictemplate <class _OuterAlloc, class... _InnerAllocs> 3340b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...> 335cb14a3feSDimitry Andric : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> { 336*0fca6ea1SDimitry Andric typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> _Base; 3370b57cec5SDimitry Andric typedef allocator_traits<_OuterAlloc> _OuterTraits; 338cb14a3feSDimitry Andric 3390b57cec5SDimitry Andricpublic: 3400b57cec5SDimitry Andric typedef _OuterAlloc outer_allocator_type; 341*0fca6ea1SDimitry Andric typedef typename _Base::inner_allocator_type inner_allocator_type; 3420b57cec5SDimitry Andric typedef typename _OuterTraits::size_type size_type; 3430b57cec5SDimitry Andric typedef typename _OuterTraits::difference_type difference_type; 3440b57cec5SDimitry Andric typedef typename _OuterTraits::pointer pointer; 3450b57cec5SDimitry Andric typedef typename _OuterTraits::const_pointer const_pointer; 3460b57cec5SDimitry Andric typedef typename _OuterTraits::void_pointer void_pointer; 3470b57cec5SDimitry Andric typedef typename _OuterTraits::const_void_pointer const_void_pointer; 3480b57cec5SDimitry Andric 349cb14a3feSDimitry Andric typedef integral_constant< bool, __get_poc_copy_assignment<outer_allocator_type, _InnerAllocs...>::value > 350cb14a3feSDimitry Andric propagate_on_container_copy_assignment; 351cb14a3feSDimitry Andric typedef integral_constant< bool, __get_poc_move_assignment<outer_allocator_type, _InnerAllocs...>::value > 352cb14a3feSDimitry Andric propagate_on_container_move_assignment; 353cb14a3feSDimitry Andric typedef integral_constant< bool, __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value > 354cb14a3feSDimitry Andric propagate_on_container_swap; 355cb14a3feSDimitry Andric typedef integral_constant< bool, __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value > 356cb14a3feSDimitry Andric is_always_equal; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric template <class _Tp> 359cb14a3feSDimitry Andric struct rebind { 360cb14a3feSDimitry Andric typedef scoped_allocator_adaptor< typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs... > other; 3610b57cec5SDimitry Andric }; 3620b57cec5SDimitry Andric 363cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor() _NOEXCEPT {} 364cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 3655f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 366cb14a3feSDimitry Andric scoped_allocator_adaptor(_OuterA2&& __outer_alloc, const _InnerAllocs&... __inner_allocs) _NOEXCEPT 367*0fca6ea1SDimitry Andric : _Base(std::forward<_OuterA2>(__outer_alloc), __inner_allocs...) {} 3680b57cec5SDimitry Andric // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default; 369cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, const _OuterA2&>::value, int> = 0> 3705f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 371cb14a3feSDimitry Andric scoped_allocator_adaptor(const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT 372*0fca6ea1SDimitry Andric : _Base(__other) {} 373cb14a3feSDimitry Andric template <class _OuterA2, __enable_if_t<is_constructible<outer_allocator_type, _OuterA2>::value, int> = 0> 3745f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI 375cb14a3feSDimitry Andric scoped_allocator_adaptor(scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT 376*0fca6ea1SDimitry Andric : _Base(std::move(__other)) {} 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; 3790b57cec5SDimitry Andric // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; 3800b57cec5SDimitry Andric // ~scoped_allocator_adaptor() = default; 3810b57cec5SDimitry Andric 382*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI inner_allocator_type& inner_allocator() _NOEXCEPT { return _Base::inner_allocator(); } 383cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const inner_allocator_type& inner_allocator() const _NOEXCEPT { 384*0fca6ea1SDimitry Andric return _Base::inner_allocator(); 385cb14a3feSDimitry Andric } 3860b57cec5SDimitry Andric 387*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI outer_allocator_type& outer_allocator() _NOEXCEPT { return _Base::outer_allocator(); } 388cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI const outer_allocator_type& outer_allocator() const _NOEXCEPT { 389*0fca6ea1SDimitry Andric return _Base::outer_allocator(); 390cb14a3feSDimitry Andric } 3910b57cec5SDimitry Andric 392*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI pointer allocate(size_type __n) { 393cb14a3feSDimitry Andric return allocator_traits<outer_allocator_type>::allocate(outer_allocator(), __n); 394cb14a3feSDimitry Andric } 395*0fca6ea1SDimitry Andric _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI pointer allocate(size_type __n, const_void_pointer __hint) { 396cb14a3feSDimitry Andric return allocator_traits<outer_allocator_type>::allocate(outer_allocator(), __n, __hint); 397cb14a3feSDimitry Andric } 3980b57cec5SDimitry Andric 399cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void deallocate(pointer __p, size_type __n) _NOEXCEPT { 400cb14a3feSDimitry Andric allocator_traits<outer_allocator_type>::deallocate(outer_allocator(), __p, __n); 401cb14a3feSDimitry Andric } 4020b57cec5SDimitry Andric 403cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_type max_size() const { 404cb14a3feSDimitry Andric return allocator_traits<outer_allocator_type>::max_size(outer_allocator()); 405cb14a3feSDimitry Andric } 4060b57cec5SDimitry Andric 407bdd1243dSDimitry Andric# if _LIBCPP_STD_VER >= 20 408bdd1243dSDimitry Andric template <class _Type, class... _Args> 409bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI void construct(_Type* __ptr, _Args&&... __args) { 410bdd1243dSDimitry Andric using _OM = __outermost<outer_allocator_type>; 411bdd1243dSDimitry Andric std::apply( 412bdd1243dSDimitry Andric [__ptr, this](auto&&... __newargs) { 413bdd1243dSDimitry Andric allocator_traits<typename _OM::type>::construct( 414bdd1243dSDimitry Andric _OM()(outer_allocator()), __ptr, std::forward<decltype(__newargs)>(__newargs)...); 415bdd1243dSDimitry Andric }, 416bdd1243dSDimitry Andric std::uses_allocator_construction_args<_Type>(inner_allocator(), std::forward<_Args>(__args)...)); 417bdd1243dSDimitry Andric } 418bdd1243dSDimitry Andric# else 4190b57cec5SDimitry Andric template <class _Tp, class... _Args> 420cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void construct(_Tp* __p, _Args&&... __args) { 421cb14a3feSDimitry Andric __construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(), __p, std::forward<_Args>(__args)...); 422cb14a3feSDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric template <class _T1, class _T2, class... _Args1, class... _Args2> 425cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void 426cb14a3feSDimitry Andric construct(pair<_T1, _T2>* __p, piecewise_construct_t, tuple<_Args1...> __x, tuple<_Args2...> __y) { 4270b57cec5SDimitry Andric typedef __outermost<outer_allocator_type> _OM; 4280b57cec5SDimitry Andric allocator_traits<typename _OM::type>::construct( 429cb14a3feSDimitry Andric _OM()(outer_allocator()), 430cb14a3feSDimitry Andric __p, 431cb14a3feSDimitry Andric piecewise_construct, 432cb14a3feSDimitry Andric __transform_tuple(typename __uses_alloc_ctor< _T1, inner_allocator_type&, _Args1... >::type(), 433cb14a3feSDimitry Andric std::move(__x), 434cb14a3feSDimitry Andric typename __make_tuple_indices<sizeof...(_Args1)>::type{}), 435cb14a3feSDimitry Andric __transform_tuple(typename __uses_alloc_ctor< _T2, inner_allocator_type&, _Args2... >::type(), 436cb14a3feSDimitry Andric std::move(__y), 437cb14a3feSDimitry Andric typename __make_tuple_indices<sizeof...(_Args2)>::type{})); 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric template <class _T1, class _T2> 441cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p) { 442cb14a3feSDimitry Andric construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); 443cb14a3feSDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric template <class _T1, class _T2, class _Up, class _Vp> 44606c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { 447cb14a3feSDimitry Andric construct(__p, 448cb14a3feSDimitry Andric piecewise_construct, 4495f757f3fSDimitry Andric std::forward_as_tuple(std::forward<_Up>(__x)), 4505f757f3fSDimitry Andric std::forward_as_tuple(std::forward<_Vp>(__y))); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric template <class _T1, class _T2, class _Up, class _Vp> 45406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { 455cb14a3feSDimitry Andric construct(__p, piecewise_construct, std::forward_as_tuple(__x.first), std::forward_as_tuple(__x.second)); 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric template <class _T1, class _T2, class _Up, class _Vp> 45906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { 460cb14a3feSDimitry Andric construct(__p, 461cb14a3feSDimitry Andric piecewise_construct, 4625f757f3fSDimitry Andric std::forward_as_tuple(std::forward<_Up>(__x.first)), 4635f757f3fSDimitry Andric std::forward_as_tuple(std::forward<_Vp>(__x.second))); 4640b57cec5SDimitry Andric } 465bdd1243dSDimitry Andric# endif 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric template <class _Tp> 468cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void destroy(_Tp* __p) { 4690b57cec5SDimitry Andric typedef __outermost<outer_allocator_type> _OM; 470cb14a3feSDimitry Andric allocator_traits<typename _OM::type>::destroy(_OM()(outer_allocator()), __p); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 473cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT { 474*0fca6ea1SDimitry Andric return _Base::select_on_container_copy_construction(); 475cb14a3feSDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andricprivate: 478*0fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI explicit scoped_allocator_adaptor( 479*0fca6ea1SDimitry Andric outer_allocator_type&& __o, inner_allocator_type&& __i) _NOEXCEPT : _Base(std::move(__o), std::move(__i)) {} 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric template <class _Tp, class... _Args> 482cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 0>, _Tp* __p, _Args&&... __args) { 4830b57cec5SDimitry Andric typedef __outermost<outer_allocator_type> _OM; 484cb14a3feSDimitry Andric allocator_traits<typename _OM::type>::construct(_OM()(outer_allocator()), __p, std::forward<_Args>(__args)...); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric template <class _Tp, class... _Args> 488cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 1>, _Tp* __p, _Args&&... __args) { 4890b57cec5SDimitry Andric typedef __outermost<outer_allocator_type> _OM; 490cb14a3feSDimitry Andric allocator_traits<typename _OM::type>::construct( 491cb14a3feSDimitry Andric _OM()(outer_allocator()), __p, allocator_arg, inner_allocator(), std::forward<_Args>(__args)...); 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric template <class _Tp, class... _Args> 495cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __construct(integral_constant<int, 2>, _Tp* __p, _Args&&... __args) { 4960b57cec5SDimitry Andric typedef __outermost<outer_allocator_type> _OM; 497cb14a3feSDimitry Andric allocator_traits<typename _OM::type>::construct( 498cb14a3feSDimitry Andric _OM()(outer_allocator()), __p, std::forward<_Args>(__args)..., inner_allocator()); 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric template <class... _Args, size_t... _Idx> 502cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI tuple<_Args&&...> 503cb14a3feSDimitry Andric __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) { 5045f757f3fSDimitry Andric return std::forward_as_tuple(std::get<_Idx>(std::move(__t))...); 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric template <class... _Args, size_t... _Idx> 508cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI tuple<allocator_arg_t, inner_allocator_type&, _Args&&...> 509cb14a3feSDimitry Andric __transform_tuple(integral_constant<int, 1>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) { 5100b57cec5SDimitry Andric using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>; 511cb14a3feSDimitry Andric return _Tup(allocator_arg, inner_allocator(), std::get<_Idx>(std::move(__t))...); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric template <class... _Args, size_t... _Idx> 515cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI tuple<_Args&&..., inner_allocator_type&> 516cb14a3feSDimitry Andric __transform_tuple(integral_constant<int, 2>, tuple<_Args...>&& __t, __tuple_indices<_Idx...>) { 5170b57cec5SDimitry Andric using _Tup = tuple<_Args&&..., inner_allocator_type&>; 5185f757f3fSDimitry Andric return _Tup(std::get<_Idx>(std::move(__t))..., inner_allocator()); 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 521cb14a3feSDimitry Andric template <class...> 522cb14a3feSDimitry Andric friend class __scoped_allocator_storage; 5230b57cec5SDimitry Andric}; 5240b57cec5SDimitry Andric 52506c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 17 526349cc55cSDimitry Andrictemplate <class _OuterAlloc, class... _InnerAllocs> 527cb14a3feSDimitry Andricscoped_allocator_adaptor(_OuterAlloc, _InnerAllocs...) -> scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...>; 528349cc55cSDimitry Andric# endif 529349cc55cSDimitry Andric 5300b57cec5SDimitry Andrictemplate <class _OuterA1, class _OuterA2> 531cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 532cb14a3feSDimitry Andricoperator==(const scoped_allocator_adaptor<_OuterA1>& __a, const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT { 5330b57cec5SDimitry Andric return __a.outer_allocator() == __b.outer_allocator(); 5340b57cec5SDimitry Andric} 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andrictemplate <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs> 537cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool 5380b57cec5SDimitry Andricoperator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a, 539cb14a3feSDimitry Andric const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT { 540cb14a3feSDimitry Andric return __a.outer_allocator() == __b.outer_allocator() && __a.inner_allocator() == __b.inner_allocator(); 5410b57cec5SDimitry Andric} 5420b57cec5SDimitry Andric 54306c3fb27SDimitry Andric# if _LIBCPP_STD_VER <= 17 54406c3fb27SDimitry Andric 5450b57cec5SDimitry Andrictemplate <class _OuterA1, class _OuterA2, class... _InnerAllocs> 546cb14a3feSDimitry Andricinline _LIBCPP_HIDE_FROM_ABI bool operator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a, 547cb14a3feSDimitry Andric const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT { 5480b57cec5SDimitry Andric return !(__a == __b); 5490b57cec5SDimitry Andric} 5500b57cec5SDimitry Andric 55106c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER <= 17 55206c3fb27SDimitry Andric 5530b57cec5SDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG) 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5560b57cec5SDimitry Andric 55706c3fb27SDimitry Andric_LIBCPP_POP_MACROS 55806c3fb27SDimitry Andric 559bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 560bdd1243dSDimitry Andric# include <atomic> 561bdd1243dSDimitry Andric# include <climits> 562bdd1243dSDimitry Andric# include <concepts> 563bdd1243dSDimitry Andric# include <cstring> 564bdd1243dSDimitry Andric# include <ctime> 565bdd1243dSDimitry Andric# include <iterator> 566bdd1243dSDimitry Andric# include <memory> 567bdd1243dSDimitry Andric# include <ratio> 568bdd1243dSDimitry Andric# include <stdexcept> 569bdd1243dSDimitry Andric# include <type_traits> 570bdd1243dSDimitry Andric# include <variant> 571bdd1243dSDimitry Andric#endif 572bdd1243dSDimitry Andric 5730b57cec5SDimitry Andric#endif // _LIBCPP_SCOPED_ALLOCATOR 574