17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===-------------------------- scoped_allocator --------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_SCOPED_ALLOCATOR 127a984708SDavid Chisnall#define _LIBCPP_SCOPED_ALLOCATOR 137a984708SDavid Chisnall 147a984708SDavid Chisnall/* 157a984708SDavid Chisnall scoped_allocator synopsis 167a984708SDavid Chisnall 177a984708SDavid Chisnallnamespace std 187a984708SDavid Chisnall{ 197a984708SDavid Chisnall 207a984708SDavid Chisnalltemplate <class OuterAlloc, class... InnerAllocs> 217a984708SDavid Chisnallclass scoped_allocator_adaptor : public OuterAlloc 227a984708SDavid Chisnall{ 237a984708SDavid Chisnall typedef allocator_traits<OuterAlloc> OuterTraits; // exposition only 247a984708SDavid Chisnall scoped_allocator_adaptor<InnerAllocs...> inner; // exposition only 257a984708SDavid Chisnallpublic: 267a984708SDavid Chisnall 277a984708SDavid Chisnall typedef OuterAlloc outer_allocator_type; 287a984708SDavid Chisnall typedef see below inner_allocator_type; 297a984708SDavid Chisnall 307a984708SDavid Chisnall typedef typename OuterTraits::value_type value_type; 317a984708SDavid Chisnall typedef typename OuterTraits::size_type size_type; 327a984708SDavid Chisnall typedef typename OuterTraits::difference_type difference_type; 337a984708SDavid Chisnall typedef typename OuterTraits::pointer pointer; 347a984708SDavid Chisnall typedef typename OuterTraits::const_pointer const_pointer; 357a984708SDavid Chisnall typedef typename OuterTraits::void_pointer void_pointer; 367a984708SDavid Chisnall typedef typename OuterTraits::const_void_pointer const_void_pointer; 377a984708SDavid Chisnall 387a984708SDavid Chisnall typedef see below propagate_on_container_copy_assignment; 397a984708SDavid Chisnall typedef see below propagate_on_container_move_assignment; 407a984708SDavid Chisnall typedef see below propagate_on_container_swap; 41854fa44bSDimitry Andric typedef see below is_always_equal; 427a984708SDavid Chisnall 437a984708SDavid Chisnall template <class Tp> 447a984708SDavid Chisnall struct rebind 457a984708SDavid Chisnall { 467a984708SDavid Chisnall typedef scoped_allocator_adaptor< 477a984708SDavid Chisnall OuterTraits::template rebind_alloc<Tp>, InnerAllocs...> other; 487a984708SDavid Chisnall }; 497a984708SDavid Chisnall 507a984708SDavid Chisnall scoped_allocator_adaptor(); 517a984708SDavid Chisnall template <class OuterA2> 527a984708SDavid Chisnall scoped_allocator_adaptor(OuterA2&& outerAlloc, 537a984708SDavid Chisnall const InnerAllocs&... innerAllocs) noexcept; 547a984708SDavid Chisnall scoped_allocator_adaptor(const scoped_allocator_adaptor& other) noexcept; 557a984708SDavid Chisnall scoped_allocator_adaptor(scoped_allocator_adaptor&& other) noexcept; 567a984708SDavid Chisnall template <class OuterA2> 577a984708SDavid Chisnall scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& other) noexcept; 587a984708SDavid Chisnall template <class OuterA2> 597a984708SDavid Chisnall scoped_allocator_adaptor(const scoped_allocator_adaptor<OuterA2, InnerAllocs...>&& other) noexcept; 607a984708SDavid Chisnall 619729cf09SDimitry Andric scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; 629729cf09SDimitry Andric scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; 637a984708SDavid Chisnall ~scoped_allocator_adaptor(); 647a984708SDavid Chisnall 657a984708SDavid Chisnall inner_allocator_type& inner_allocator() noexcept; 667a984708SDavid Chisnall const inner_allocator_type& inner_allocator() const noexcept; 677a984708SDavid Chisnall 687a984708SDavid Chisnall outer_allocator_type& outer_allocator() noexcept; 697a984708SDavid Chisnall const outer_allocator_type& outer_allocator() const noexcept; 707a984708SDavid Chisnall 71b2c7081bSDimitry Andric pointer allocate(size_type n); // [[nodiscard]] in C++20 72b2c7081bSDimitry Andric pointer allocate(size_type n, const_void_pointer hint); // [[nodiscard]] in C++20 737a984708SDavid Chisnall void deallocate(pointer p, size_type n) noexcept; 747a984708SDavid Chisnall 757a984708SDavid Chisnall size_type max_size() const; 767a984708SDavid Chisnall template <class T, class... Args> void construct(T* p, Args&& args); 777a984708SDavid Chisnall template <class T1, class T2, class... Args1, class... Args2> 787a984708SDavid Chisnall void construct(pair<T1, T2>* p, piecewise_construct t, tuple<Args1...> x, 797a984708SDavid Chisnall tuple<Args2...> y); 807a984708SDavid Chisnall template <class T1, class T2> 817a984708SDavid Chisnall void construct(pair<T1, T2>* p); 827a984708SDavid Chisnall template <class T1, class T2, class U, class V> 837a984708SDavid Chisnall void construct(pair<T1, T2>* p, U&& x, V&& y); 847a984708SDavid Chisnall template <class T1, class T2, class U, class V> 857a984708SDavid Chisnall void construct(pair<T1, T2>* p, const pair<U, V>& x); 867a984708SDavid Chisnall template <class T1, class T2, class U, class V> 877a984708SDavid Chisnall void construct(pair<T1, T2>* p, pair<U, V>&& x); 887a984708SDavid Chisnall template <class T> void destroy(T* p); 897a984708SDavid Chisnall 907a984708SDavid Chisnall template <class T> void destroy(T* p) noexcept; 917a984708SDavid Chisnall 927a984708SDavid Chisnall scoped_allocator_adaptor select_on_container_copy_construction() const noexcept; 937a984708SDavid Chisnall}; 947a984708SDavid Chisnall 957a984708SDavid Chisnalltemplate <class OuterA1, class OuterA2, class... InnerAllocs> 967a984708SDavid Chisnall bool 977a984708SDavid Chisnall operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 987a984708SDavid Chisnall const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 997a984708SDavid Chisnall 1007a984708SDavid Chisnalltemplate <class OuterA1, class OuterA2, class... InnerAllocs> 1017a984708SDavid Chisnall bool 1027a984708SDavid Chisnall operator!=(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a, 1037a984708SDavid Chisnall const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept; 1047a984708SDavid Chisnall 1057a984708SDavid Chisnall} // std 1067a984708SDavid Chisnall 1077a984708SDavid Chisnall*/ 1087a984708SDavid Chisnall 1097a984708SDavid Chisnall#include <__config> 1107a984708SDavid Chisnall#include <memory> 111*b5893f02SDimitry Andric#include <version> 1127a984708SDavid Chisnall 1137a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1147a984708SDavid Chisnall#pragma GCC system_header 1157a984708SDavid Chisnall#endif 1167a984708SDavid Chisnall 1177a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 1187a984708SDavid Chisnall 119aed8d94eSDimitry Andric#if !defined(_LIBCPP_CXX03_LANG) 1207a984708SDavid Chisnall 1217a984708SDavid Chisnall// scoped_allocator_adaptor 1227a984708SDavid Chisnall 1237a984708SDavid Chisnalltemplate <class ..._Allocs> 1247a984708SDavid Chisnallclass scoped_allocator_adaptor; 1257a984708SDavid Chisnall 1267a984708SDavid Chisnalltemplate <class ..._Allocs> struct __get_poc_copy_assignment; 1277a984708SDavid Chisnall 1287a984708SDavid Chisnalltemplate <class _A0> 1297a984708SDavid Chisnallstruct __get_poc_copy_assignment<_A0> 1307a984708SDavid Chisnall{ 1317a984708SDavid Chisnall static const bool value = allocator_traits<_A0>:: 1327a984708SDavid Chisnall propagate_on_container_copy_assignment::value; 1337a984708SDavid Chisnall}; 1347a984708SDavid Chisnall 1357a984708SDavid Chisnalltemplate <class _A0, class ..._Allocs> 1367a984708SDavid Chisnallstruct __get_poc_copy_assignment<_A0, _Allocs...> 1377a984708SDavid Chisnall{ 1387a984708SDavid Chisnall static const bool value = 1397a984708SDavid Chisnall allocator_traits<_A0>::propagate_on_container_copy_assignment::value || 1407a984708SDavid Chisnall __get_poc_copy_assignment<_Allocs...>::value; 1417a984708SDavid Chisnall}; 1427a984708SDavid Chisnall 1437a984708SDavid Chisnalltemplate <class ..._Allocs> struct __get_poc_move_assignment; 1447a984708SDavid Chisnall 1457a984708SDavid Chisnalltemplate <class _A0> 1467a984708SDavid Chisnallstruct __get_poc_move_assignment<_A0> 1477a984708SDavid Chisnall{ 1487a984708SDavid Chisnall static const bool value = allocator_traits<_A0>:: 1497a984708SDavid Chisnall propagate_on_container_move_assignment::value; 1507a984708SDavid Chisnall}; 1517a984708SDavid Chisnall 1527a984708SDavid Chisnalltemplate <class _A0, class ..._Allocs> 1537a984708SDavid Chisnallstruct __get_poc_move_assignment<_A0, _Allocs...> 1547a984708SDavid Chisnall{ 1557a984708SDavid Chisnall static const bool value = 1567a984708SDavid Chisnall allocator_traits<_A0>::propagate_on_container_move_assignment::value || 1577a984708SDavid Chisnall __get_poc_move_assignment<_Allocs...>::value; 1587a984708SDavid Chisnall}; 1597a984708SDavid Chisnall 1607a984708SDavid Chisnalltemplate <class ..._Allocs> struct __get_poc_swap; 1617a984708SDavid Chisnall 1627a984708SDavid Chisnalltemplate <class _A0> 1637a984708SDavid Chisnallstruct __get_poc_swap<_A0> 1647a984708SDavid Chisnall{ 1657a984708SDavid Chisnall static const bool value = allocator_traits<_A0>:: 1667a984708SDavid Chisnall propagate_on_container_swap::value; 1677a984708SDavid Chisnall}; 1687a984708SDavid Chisnall 1697a984708SDavid Chisnalltemplate <class _A0, class ..._Allocs> 1707a984708SDavid Chisnallstruct __get_poc_swap<_A0, _Allocs...> 1717a984708SDavid Chisnall{ 1727a984708SDavid Chisnall static const bool value = 1737a984708SDavid Chisnall allocator_traits<_A0>::propagate_on_container_swap::value || 1747a984708SDavid Chisnall __get_poc_swap<_Allocs...>::value; 1757a984708SDavid Chisnall}; 1767a984708SDavid Chisnall 177854fa44bSDimitry Andrictemplate <class ..._Allocs> struct __get_is_always_equal; 178854fa44bSDimitry Andric 179854fa44bSDimitry Andrictemplate <class _A0> 180854fa44bSDimitry Andricstruct __get_is_always_equal<_A0> 181854fa44bSDimitry Andric{ 182854fa44bSDimitry Andric static const bool value = allocator_traits<_A0>::is_always_equal::value; 183854fa44bSDimitry Andric}; 184854fa44bSDimitry Andric 185854fa44bSDimitry Andrictemplate <class _A0, class ..._Allocs> 186854fa44bSDimitry Andricstruct __get_is_always_equal<_A0, _Allocs...> 187854fa44bSDimitry Andric{ 188854fa44bSDimitry Andric static const bool value = 189854fa44bSDimitry Andric allocator_traits<_A0>::is_always_equal::value && 190854fa44bSDimitry Andric __get_is_always_equal<_Allocs...>::value; 191854fa44bSDimitry Andric}; 192854fa44bSDimitry Andric 1937a984708SDavid Chisnalltemplate <class ..._Allocs> 1947a984708SDavid Chisnallclass __scoped_allocator_storage; 1957a984708SDavid Chisnall 1967a984708SDavid Chisnalltemplate <class _OuterAlloc, class... _InnerAllocs> 1977a984708SDavid Chisnallclass __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> 1987a984708SDavid Chisnall : public _OuterAlloc 1997a984708SDavid Chisnall{ 2007a984708SDavid Chisnall typedef _OuterAlloc outer_allocator_type; 2017a984708SDavid Chisnallprotected: 2027a984708SDavid Chisnall typedef scoped_allocator_adaptor<_InnerAllocs...> inner_allocator_type; 2037a984708SDavid Chisnall 2047a984708SDavid Chisnallprivate: 2057a984708SDavid Chisnall inner_allocator_type __inner_; 2067a984708SDavid Chisnall 2077a984708SDavid Chisnallprotected: 2087a984708SDavid Chisnall 2097a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2107a984708SDavid Chisnall __scoped_allocator_storage() _NOEXCEPT {} 2117a984708SDavid Chisnall 2127a984708SDavid Chisnall template <class _OuterA2, 2137a984708SDavid Chisnall class = typename enable_if< 2147a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 2157a984708SDavid Chisnall >::type> 2167a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2177a984708SDavid Chisnall __scoped_allocator_storage(_OuterA2&& __outerAlloc, 2187a984708SDavid Chisnall const _InnerAllocs& ...__innerAllocs) _NOEXCEPT 2197a984708SDavid Chisnall : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)), 2207a984708SDavid Chisnall __inner_(__innerAllocs...) {} 2217a984708SDavid Chisnall 2227a984708SDavid Chisnall template <class _OuterA2, 2237a984708SDavid Chisnall class = typename enable_if< 2247a984708SDavid Chisnall is_constructible<outer_allocator_type, const _OuterA2&>::value 2257a984708SDavid Chisnall >::type> 2267a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2277a984708SDavid Chisnall __scoped_allocator_storage( 2287a984708SDavid Chisnall const __scoped_allocator_storage<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT 2297a984708SDavid Chisnall : outer_allocator_type(__other.outer_allocator()), 2307a984708SDavid Chisnall __inner_(__other.inner_allocator()) {} 2317a984708SDavid Chisnall 2327a984708SDavid Chisnall template <class _OuterA2, 2337a984708SDavid Chisnall class = typename enable_if< 2347a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 2357a984708SDavid Chisnall >::type> 2367a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2377a984708SDavid Chisnall __scoped_allocator_storage( 2387a984708SDavid Chisnall __scoped_allocator_storage<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT 2397a984708SDavid Chisnall : outer_allocator_type(_VSTD::move(__other.outer_allocator())), 2407a984708SDavid Chisnall __inner_(_VSTD::move(__other.inner_allocator())) {} 2417a984708SDavid Chisnall 2427a984708SDavid Chisnall template <class _OuterA2, 2437a984708SDavid Chisnall class = typename enable_if< 2447a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 2457a984708SDavid Chisnall >::type> 2467a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2477a984708SDavid Chisnall __scoped_allocator_storage(_OuterA2&& __o, 2487a984708SDavid Chisnall const inner_allocator_type& __i) _NOEXCEPT 2497a984708SDavid Chisnall : outer_allocator_type(_VSTD::forward<_OuterA2>(__o)), 2507a984708SDavid Chisnall __inner_(__i) 2517a984708SDavid Chisnall { 2527a984708SDavid Chisnall } 2537a984708SDavid Chisnall 2547a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2557a984708SDavid Chisnall inner_allocator_type& inner_allocator() _NOEXCEPT {return __inner_;} 2567a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2577a984708SDavid Chisnall const inner_allocator_type& inner_allocator() const _NOEXCEPT {return __inner_;} 2587a984708SDavid Chisnall 2597a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2607a984708SDavid Chisnall outer_allocator_type& outer_allocator() _NOEXCEPT 2617a984708SDavid Chisnall {return static_cast<outer_allocator_type&>(*this);} 2627a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2637a984708SDavid Chisnall const outer_allocator_type& outer_allocator() const _NOEXCEPT 2647a984708SDavid Chisnall {return static_cast<const outer_allocator_type&>(*this);} 2657a984708SDavid Chisnall 2667a984708SDavid Chisnall scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> 2677a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2687a984708SDavid Chisnall select_on_container_copy_construction() const _NOEXCEPT 2697a984708SDavid Chisnall { 2707a984708SDavid Chisnall return scoped_allocator_adaptor<outer_allocator_type, _InnerAllocs...> 2717a984708SDavid Chisnall ( 2727a984708SDavid Chisnall allocator_traits<outer_allocator_type>:: 2737a984708SDavid Chisnall select_on_container_copy_construction(outer_allocator()), 2747a984708SDavid Chisnall allocator_traits<inner_allocator_type>:: 2757a984708SDavid Chisnall select_on_container_copy_construction(inner_allocator()) 2767a984708SDavid Chisnall ); 2777a984708SDavid Chisnall } 2787a984708SDavid Chisnall 2797a984708SDavid Chisnall template <class...> friend class __scoped_allocator_storage; 2807a984708SDavid Chisnall}; 2817a984708SDavid Chisnall 2827a984708SDavid Chisnalltemplate <class _OuterAlloc> 2837a984708SDavid Chisnallclass __scoped_allocator_storage<_OuterAlloc> 2847a984708SDavid Chisnall : public _OuterAlloc 2857a984708SDavid Chisnall{ 2867a984708SDavid Chisnall typedef _OuterAlloc outer_allocator_type; 2877a984708SDavid Chisnallprotected: 2887a984708SDavid Chisnall typedef scoped_allocator_adaptor<_OuterAlloc> inner_allocator_type; 2897a984708SDavid Chisnall 2907a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2917a984708SDavid Chisnall __scoped_allocator_storage() _NOEXCEPT {} 2927a984708SDavid Chisnall 2937a984708SDavid Chisnall template <class _OuterA2, 2947a984708SDavid Chisnall class = typename enable_if< 2957a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 2967a984708SDavid Chisnall >::type> 2977a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 2987a984708SDavid Chisnall __scoped_allocator_storage(_OuterA2&& __outerAlloc) _NOEXCEPT 2997a984708SDavid Chisnall : outer_allocator_type(_VSTD::forward<_OuterA2>(__outerAlloc)) {} 3007a984708SDavid Chisnall 3017a984708SDavid Chisnall template <class _OuterA2, 3027a984708SDavid Chisnall class = typename enable_if< 3037a984708SDavid Chisnall is_constructible<outer_allocator_type, const _OuterA2&>::value 3047a984708SDavid Chisnall >::type> 3057a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3067a984708SDavid Chisnall __scoped_allocator_storage( 3077a984708SDavid Chisnall const __scoped_allocator_storage<_OuterA2>& __other) _NOEXCEPT 3087a984708SDavid Chisnall : outer_allocator_type(__other.outer_allocator()) {} 3097a984708SDavid Chisnall 3107a984708SDavid Chisnall template <class _OuterA2, 3117a984708SDavid Chisnall class = typename enable_if< 3127a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 3137a984708SDavid Chisnall >::type> 3147a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3157a984708SDavid Chisnall __scoped_allocator_storage( 3167a984708SDavid Chisnall __scoped_allocator_storage<_OuterA2>&& __other) _NOEXCEPT 3177a984708SDavid Chisnall : outer_allocator_type(_VSTD::move(__other.outer_allocator())) {} 3187a984708SDavid Chisnall 3197a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3207a984708SDavid Chisnall inner_allocator_type& inner_allocator() _NOEXCEPT 3217a984708SDavid Chisnall {return static_cast<inner_allocator_type&>(*this);} 3227a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3237a984708SDavid Chisnall const inner_allocator_type& inner_allocator() const _NOEXCEPT 3247a984708SDavid Chisnall {return static_cast<const inner_allocator_type&>(*this);} 3257a984708SDavid Chisnall 3267a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3277a984708SDavid Chisnall outer_allocator_type& outer_allocator() _NOEXCEPT 3287a984708SDavid Chisnall {return static_cast<outer_allocator_type&>(*this);} 3297a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3307a984708SDavid Chisnall const outer_allocator_type& outer_allocator() const _NOEXCEPT 3317a984708SDavid Chisnall {return static_cast<const outer_allocator_type&>(*this);} 3327a984708SDavid Chisnall 3337a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3347a984708SDavid Chisnall scoped_allocator_adaptor<outer_allocator_type> 3357a984708SDavid Chisnall select_on_container_copy_construction() const _NOEXCEPT 3367a984708SDavid Chisnall {return scoped_allocator_adaptor<outer_allocator_type>( 3377a984708SDavid Chisnall allocator_traits<outer_allocator_type>:: 3387a984708SDavid Chisnall select_on_container_copy_construction(outer_allocator()) 3397a984708SDavid Chisnall );} 3407a984708SDavid Chisnall 3417a984708SDavid Chisnall __scoped_allocator_storage(const outer_allocator_type& __o, 3427a984708SDavid Chisnall const inner_allocator_type& __i) _NOEXCEPT; 3437a984708SDavid Chisnall 3447a984708SDavid Chisnall template <class...> friend class __scoped_allocator_storage; 3457a984708SDavid Chisnall}; 3467a984708SDavid Chisnall 3477a984708SDavid Chisnall// __outermost 3487a984708SDavid Chisnall 3497a984708SDavid Chisnalltemplate <class _Alloc> 3507a984708SDavid Chisnalldecltype(declval<_Alloc>().outer_allocator(), true_type()) 3517a984708SDavid Chisnall__has_outer_allocator_test(_Alloc&& __a); 3527a984708SDavid Chisnall 3537a984708SDavid Chisnalltemplate <class _Alloc> 3547a984708SDavid Chisnallfalse_type 3557a984708SDavid Chisnall__has_outer_allocator_test(const volatile _Alloc& __a); 3567a984708SDavid Chisnall 3577a984708SDavid Chisnalltemplate <class _Alloc> 3587a984708SDavid Chisnallstruct __has_outer_allocator 3597a984708SDavid Chisnall : public common_type 3607a984708SDavid Chisnall < 3617a984708SDavid Chisnall decltype(__has_outer_allocator_test(declval<_Alloc&>())) 3627a984708SDavid Chisnall >::type 3637a984708SDavid Chisnall{ 3647a984708SDavid Chisnall}; 3657a984708SDavid Chisnall 3667a984708SDavid Chisnalltemplate <class _Alloc, bool = __has_outer_allocator<_Alloc>::value> 3677a984708SDavid Chisnallstruct __outermost 3687a984708SDavid Chisnall{ 3697a984708SDavid Chisnall typedef _Alloc type; 3707a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3717a984708SDavid Chisnall type& operator()(type& __a) const _NOEXCEPT {return __a;} 3727a984708SDavid Chisnall}; 3737a984708SDavid Chisnall 3747a984708SDavid Chisnalltemplate <class _Alloc> 3757a984708SDavid Chisnallstruct __outermost<_Alloc, true> 3767a984708SDavid Chisnall{ 3777a984708SDavid Chisnall typedef typename remove_reference 3787a984708SDavid Chisnall < 3797a984708SDavid Chisnall decltype(_VSTD::declval<_Alloc>().outer_allocator()) 3807a984708SDavid Chisnall >::type _OuterAlloc; 3817a984708SDavid Chisnall typedef typename __outermost<_OuterAlloc>::type type; 3827a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 3837a984708SDavid Chisnall type& operator()(_Alloc& __a) const _NOEXCEPT 3847a984708SDavid Chisnall {return __outermost<_OuterAlloc>()(__a.outer_allocator());} 3857a984708SDavid Chisnall}; 3867a984708SDavid Chisnall 3877a984708SDavid Chisnalltemplate <class _OuterAlloc, class... _InnerAllocs> 388aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS scoped_allocator_adaptor<_OuterAlloc, _InnerAllocs...> 3897a984708SDavid Chisnall : public __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> 3907a984708SDavid Chisnall{ 3917a984708SDavid Chisnall typedef __scoped_allocator_storage<_OuterAlloc, _InnerAllocs...> base; 3927a984708SDavid Chisnall typedef allocator_traits<_OuterAlloc> _OuterTraits; 3937a984708SDavid Chisnallpublic: 3947a984708SDavid Chisnall typedef _OuterAlloc outer_allocator_type; 3957a984708SDavid Chisnall typedef typename base::inner_allocator_type inner_allocator_type; 3967a984708SDavid Chisnall typedef typename _OuterTraits::size_type size_type; 3977a984708SDavid Chisnall typedef typename _OuterTraits::difference_type difference_type; 3987a984708SDavid Chisnall typedef typename _OuterTraits::pointer pointer; 3997a984708SDavid Chisnall typedef typename _OuterTraits::const_pointer const_pointer; 4007a984708SDavid Chisnall typedef typename _OuterTraits::void_pointer void_pointer; 4017a984708SDavid Chisnall typedef typename _OuterTraits::const_void_pointer const_void_pointer; 4027a984708SDavid Chisnall 4037a984708SDavid Chisnall typedef integral_constant 4047a984708SDavid Chisnall < 4057a984708SDavid Chisnall bool, 4067a984708SDavid Chisnall __get_poc_copy_assignment<outer_allocator_type, 4077a984708SDavid Chisnall _InnerAllocs...>::value 4087a984708SDavid Chisnall > propagate_on_container_copy_assignment; 4097a984708SDavid Chisnall typedef integral_constant 4107a984708SDavid Chisnall < 4117a984708SDavid Chisnall bool, 4127a984708SDavid Chisnall __get_poc_move_assignment<outer_allocator_type, 4137a984708SDavid Chisnall _InnerAllocs...>::value 4147a984708SDavid Chisnall > propagate_on_container_move_assignment; 4157a984708SDavid Chisnall typedef integral_constant 4167a984708SDavid Chisnall < 4177a984708SDavid Chisnall bool, 4187a984708SDavid Chisnall __get_poc_swap<outer_allocator_type, _InnerAllocs...>::value 4197a984708SDavid Chisnall > propagate_on_container_swap; 420854fa44bSDimitry Andric typedef integral_constant 421854fa44bSDimitry Andric < 422854fa44bSDimitry Andric bool, 423854fa44bSDimitry Andric __get_is_always_equal<outer_allocator_type, _InnerAllocs...>::value 424854fa44bSDimitry Andric > is_always_equal; 4257a984708SDavid Chisnall 4267a984708SDavid Chisnall template <class _Tp> 4277a984708SDavid Chisnall struct rebind 4287a984708SDavid Chisnall { 4297a984708SDavid Chisnall typedef scoped_allocator_adaptor 4307a984708SDavid Chisnall < 4317a984708SDavid Chisnall typename _OuterTraits::template rebind_alloc<_Tp>, _InnerAllocs... 4327a984708SDavid Chisnall > other; 4337a984708SDavid Chisnall }; 4347a984708SDavid Chisnall 4357a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4367a984708SDavid Chisnall scoped_allocator_adaptor() _NOEXCEPT {} 4377a984708SDavid Chisnall template <class _OuterA2, 4387a984708SDavid Chisnall class = typename enable_if< 4397a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 4407a984708SDavid Chisnall >::type> 4417a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4427a984708SDavid Chisnall scoped_allocator_adaptor(_OuterA2&& __outerAlloc, 4437a984708SDavid Chisnall const _InnerAllocs& ...__innerAllocs) _NOEXCEPT 4447a984708SDavid Chisnall : base(_VSTD::forward<_OuterA2>(__outerAlloc), __innerAllocs...) {} 4457a984708SDavid Chisnall // scoped_allocator_adaptor(const scoped_allocator_adaptor& __other) = default; 4467a984708SDavid Chisnall template <class _OuterA2, 4477a984708SDavid Chisnall class = typename enable_if< 4487a984708SDavid Chisnall is_constructible<outer_allocator_type, const _OuterA2&>::value 4497a984708SDavid Chisnall >::type> 4507a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4517a984708SDavid Chisnall scoped_allocator_adaptor( 4527a984708SDavid Chisnall const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __other) _NOEXCEPT 4537a984708SDavid Chisnall : base(__other) {} 4547a984708SDavid Chisnall template <class _OuterA2, 4557a984708SDavid Chisnall class = typename enable_if< 4567a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 4577a984708SDavid Chisnall >::type> 4587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4597a984708SDavid Chisnall scoped_allocator_adaptor( 4607a984708SDavid Chisnall scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>&& __other) _NOEXCEPT 4617a984708SDavid Chisnall : base(_VSTD::move(__other)) {} 4627a984708SDavid Chisnall 4639729cf09SDimitry Andric // scoped_allocator_adaptor& operator=(const scoped_allocator_adaptor&) = default; 4649729cf09SDimitry Andric // scoped_allocator_adaptor& operator=(scoped_allocator_adaptor&&) = default; 4657a984708SDavid Chisnall // ~scoped_allocator_adaptor() = default; 4667a984708SDavid Chisnall 4677a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4687a984708SDavid Chisnall inner_allocator_type& inner_allocator() _NOEXCEPT 4697a984708SDavid Chisnall {return base::inner_allocator();} 4707a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4717a984708SDavid Chisnall const inner_allocator_type& inner_allocator() const _NOEXCEPT 4727a984708SDavid Chisnall {return base::inner_allocator();} 4737a984708SDavid Chisnall 4747a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4757a984708SDavid Chisnall outer_allocator_type& outer_allocator() _NOEXCEPT 4767a984708SDavid Chisnall {return base::outer_allocator();} 4777a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4787a984708SDavid Chisnall const outer_allocator_type& outer_allocator() const _NOEXCEPT 4797a984708SDavid Chisnall {return base::outer_allocator();} 4807a984708SDavid Chisnall 481b2c7081bSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 4827a984708SDavid Chisnall pointer allocate(size_type __n) 4837a984708SDavid Chisnall {return allocator_traits<outer_allocator_type>:: 4847a984708SDavid Chisnall allocate(outer_allocator(), __n);} 485b2c7081bSDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 4867a984708SDavid Chisnall pointer allocate(size_type __n, const_void_pointer __hint) 4877a984708SDavid Chisnall {return allocator_traits<outer_allocator_type>:: 4887a984708SDavid Chisnall allocate(outer_allocator(), __n, __hint);} 4897a984708SDavid Chisnall 4907a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4917a984708SDavid Chisnall void deallocate(pointer __p, size_type __n) _NOEXCEPT 4927a984708SDavid Chisnall {allocator_traits<outer_allocator_type>:: 4937a984708SDavid Chisnall deallocate(outer_allocator(), __p, __n);} 4947a984708SDavid Chisnall 4957a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 4967a984708SDavid Chisnall size_type max_size() const 4977a984708SDavid Chisnall {return allocator_traits<outer_allocator_type>::max_size(outer_allocator());} 4987a984708SDavid Chisnall 4997a984708SDavid Chisnall template <class _Tp, class... _Args> 5007a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5017a984708SDavid Chisnall void construct(_Tp* __p, _Args&& ...__args) 502aed8d94eSDimitry Andric {__construct(__uses_alloc_ctor<_Tp, inner_allocator_type&, _Args...>(), 5037a984708SDavid Chisnall __p, _VSTD::forward<_Args>(__args)...);} 504aed8d94eSDimitry Andric 505aed8d94eSDimitry Andric template <class _T1, class _T2, class... _Args1, class... _Args2> 506aed8d94eSDimitry Andric void construct(pair<_T1, _T2>* __p, piecewise_construct_t, 507aed8d94eSDimitry Andric tuple<_Args1...> __x, tuple<_Args2...> __y) 508aed8d94eSDimitry Andric { 509aed8d94eSDimitry Andric typedef __outermost<outer_allocator_type> _OM; 510aed8d94eSDimitry Andric allocator_traits<typename _OM::type>::construct( 511aed8d94eSDimitry Andric _OM()(outer_allocator()), __p, piecewise_construct 512aed8d94eSDimitry Andric , __transform_tuple( 513aed8d94eSDimitry Andric typename __uses_alloc_ctor< 514aed8d94eSDimitry Andric _T1, inner_allocator_type&, _Args1... 515aed8d94eSDimitry Andric >::type() 516aed8d94eSDimitry Andric , _VSTD::move(__x) 517aed8d94eSDimitry Andric , typename __make_tuple_indices<sizeof...(_Args1)>::type{} 518aed8d94eSDimitry Andric ) 519aed8d94eSDimitry Andric , __transform_tuple( 520aed8d94eSDimitry Andric typename __uses_alloc_ctor< 521aed8d94eSDimitry Andric _T2, inner_allocator_type&, _Args2... 522aed8d94eSDimitry Andric >::type() 523aed8d94eSDimitry Andric , _VSTD::move(__y) 524aed8d94eSDimitry Andric , typename __make_tuple_indices<sizeof...(_Args2)>::type{} 525aed8d94eSDimitry Andric ) 526aed8d94eSDimitry Andric ); 527aed8d94eSDimitry Andric } 528aed8d94eSDimitry Andric 529aed8d94eSDimitry Andric template <class _T1, class _T2> 530aed8d94eSDimitry Andric void construct(pair<_T1, _T2>* __p) 531aed8d94eSDimitry Andric { construct(__p, piecewise_construct, tuple<>{}, tuple<>{}); } 532aed8d94eSDimitry Andric 533aed8d94eSDimitry Andric template <class _T1, class _T2, class _Up, class _Vp> 534aed8d94eSDimitry Andric void construct(pair<_T1, _T2>* __p, _Up&& __x, _Vp&& __y) { 535aed8d94eSDimitry Andric construct(__p, piecewise_construct, 536aed8d94eSDimitry Andric _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x)), 537aed8d94eSDimitry Andric _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__y))); 538aed8d94eSDimitry Andric } 539aed8d94eSDimitry Andric 540aed8d94eSDimitry Andric template <class _T1, class _T2, class _Up, class _Vp> 541aed8d94eSDimitry Andric void construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x) { 542aed8d94eSDimitry Andric construct(__p, piecewise_construct, 543aed8d94eSDimitry Andric _VSTD::forward_as_tuple(__x.first), 544aed8d94eSDimitry Andric _VSTD::forward_as_tuple(__x.second)); 545aed8d94eSDimitry Andric } 546aed8d94eSDimitry Andric 547aed8d94eSDimitry Andric template <class _T1, class _T2, class _Up, class _Vp> 548aed8d94eSDimitry Andric void construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x) { 549aed8d94eSDimitry Andric construct(__p, piecewise_construct, 550aed8d94eSDimitry Andric _VSTD::forward_as_tuple(_VSTD::forward<_Up>(__x.first)), 551aed8d94eSDimitry Andric _VSTD::forward_as_tuple(_VSTD::forward<_Vp>(__x.second))); 552aed8d94eSDimitry Andric } 553aed8d94eSDimitry Andric 5547a984708SDavid Chisnall template <class _Tp> 5557a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5567a984708SDavid Chisnall void destroy(_Tp* __p) 5577a984708SDavid Chisnall { 5587a984708SDavid Chisnall typedef __outermost<outer_allocator_type> _OM; 5597a984708SDavid Chisnall allocator_traits<typename _OM::type>:: 5607a984708SDavid Chisnall destroy(_OM()(outer_allocator()), __p); 5617a984708SDavid Chisnall } 5627a984708SDavid Chisnall 5637a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5647a984708SDavid Chisnall scoped_allocator_adaptor select_on_container_copy_construction() const _NOEXCEPT 5657a984708SDavid Chisnall {return base::select_on_container_copy_construction();} 5667a984708SDavid Chisnall 5677a984708SDavid Chisnallprivate: 5687a984708SDavid Chisnall 569aed8d94eSDimitry Andric 5707a984708SDavid Chisnall template <class _OuterA2, 5717a984708SDavid Chisnall class = typename enable_if< 5727a984708SDavid Chisnall is_constructible<outer_allocator_type, _OuterA2>::value 5737a984708SDavid Chisnall >::type> 5747a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5757a984708SDavid Chisnall scoped_allocator_adaptor(_OuterA2&& __o, 5767a984708SDavid Chisnall const inner_allocator_type& __i) _NOEXCEPT 5777a984708SDavid Chisnall : base(_VSTD::forward<_OuterA2>(__o), __i) {} 5787a984708SDavid Chisnall 5797a984708SDavid Chisnall template <class _Tp, class... _Args> 5807a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5817a984708SDavid Chisnall void __construct(integral_constant<int, 0>, _Tp* __p, _Args&& ...__args) 5827a984708SDavid Chisnall { 5837a984708SDavid Chisnall typedef __outermost<outer_allocator_type> _OM; 5847a984708SDavid Chisnall allocator_traits<typename _OM::type>::construct 5857a984708SDavid Chisnall ( 5867a984708SDavid Chisnall _OM()(outer_allocator()), 5877a984708SDavid Chisnall __p, 5887a984708SDavid Chisnall _VSTD::forward<_Args>(__args)... 5897a984708SDavid Chisnall ); 5907a984708SDavid Chisnall } 5917a984708SDavid Chisnall 5927a984708SDavid Chisnall template <class _Tp, class... _Args> 5937a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 5947a984708SDavid Chisnall void __construct(integral_constant<int, 1>, _Tp* __p, _Args&& ...__args) 5957a984708SDavid Chisnall { 5967a984708SDavid Chisnall typedef __outermost<outer_allocator_type> _OM; 5977a984708SDavid Chisnall allocator_traits<typename _OM::type>::construct 5987a984708SDavid Chisnall ( 5997a984708SDavid Chisnall _OM()(outer_allocator()), 600aed8d94eSDimitry Andric __p, allocator_arg, inner_allocator(), 6017a984708SDavid Chisnall _VSTD::forward<_Args>(__args)... 6027a984708SDavid Chisnall ); 6037a984708SDavid Chisnall } 6047a984708SDavid Chisnall 6057a984708SDavid Chisnall template <class _Tp, class... _Args> 6067a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 6077a984708SDavid Chisnall void __construct(integral_constant<int, 2>, _Tp* __p, _Args&& ...__args) 6087a984708SDavid Chisnall { 6097a984708SDavid Chisnall typedef __outermost<outer_allocator_type> _OM; 6107a984708SDavid Chisnall allocator_traits<typename _OM::type>::construct 6117a984708SDavid Chisnall ( 6127a984708SDavid Chisnall _OM()(outer_allocator()), 6137a984708SDavid Chisnall __p, 6147a984708SDavid Chisnall _VSTD::forward<_Args>(__args)..., 6157a984708SDavid Chisnall inner_allocator() 6167a984708SDavid Chisnall ); 6177a984708SDavid Chisnall } 6187a984708SDavid Chisnall 619aed8d94eSDimitry Andric template <class ..._Args, size_t ..._Idx> 620aed8d94eSDimitry Andric _LIBCPP_INLINE_VISIBILITY 621aed8d94eSDimitry Andric tuple<_Args&&...> 622aed8d94eSDimitry Andric __transform_tuple(integral_constant<int, 0>, tuple<_Args...>&& __t, 623aed8d94eSDimitry Andric __tuple_indices<_Idx...>) 624aed8d94eSDimitry Andric { 625aed8d94eSDimitry Andric return _VSTD::forward_as_tuple(_VSTD::get<_Idx>(_VSTD::move(__t))...); 626aed8d94eSDimitry Andric } 627aed8d94eSDimitry Andric 628aed8d94eSDimitry Andric template <class ..._Args, size_t ..._Idx> 629aed8d94eSDimitry Andric _LIBCPP_INLINE_VISIBILITY 630aed8d94eSDimitry Andric tuple<allocator_arg_t, inner_allocator_type&, _Args&&...> 631aed8d94eSDimitry Andric __transform_tuple(integral_constant<int, 1>, tuple<_Args...> && __t, 632aed8d94eSDimitry Andric __tuple_indices<_Idx...>) 633aed8d94eSDimitry Andric { 634aed8d94eSDimitry Andric using _Tup = tuple<allocator_arg_t, inner_allocator_type&, _Args&&...>; 635aed8d94eSDimitry Andric return _Tup(allocator_arg, inner_allocator(), 636aed8d94eSDimitry Andric _VSTD::get<_Idx>(_VSTD::move(__t))...); 637aed8d94eSDimitry Andric } 638aed8d94eSDimitry Andric 639aed8d94eSDimitry Andric template <class ..._Args, size_t ..._Idx> 640aed8d94eSDimitry Andric _LIBCPP_INLINE_VISIBILITY 641aed8d94eSDimitry Andric tuple<_Args&&..., inner_allocator_type&> 642aed8d94eSDimitry Andric __transform_tuple(integral_constant<int, 2>, tuple<_Args...> && __t, 643aed8d94eSDimitry Andric __tuple_indices<_Idx...>) 644aed8d94eSDimitry Andric { 645aed8d94eSDimitry Andric using _Tup = tuple<_Args&&..., inner_allocator_type&>; 646aed8d94eSDimitry Andric return _Tup(_VSTD::get<_Idx>(_VSTD::move(__t))..., inner_allocator()); 647aed8d94eSDimitry Andric } 648aed8d94eSDimitry Andric 6497a984708SDavid Chisnall template <class...> friend class __scoped_allocator_storage; 6507a984708SDavid Chisnall}; 6517a984708SDavid Chisnall 6527a984708SDavid Chisnalltemplate <class _OuterA1, class _OuterA2> 6537a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 6547a984708SDavid Chisnallbool 6557a984708SDavid Chisnalloperator==(const scoped_allocator_adaptor<_OuterA1>& __a, 6567a984708SDavid Chisnall const scoped_allocator_adaptor<_OuterA2>& __b) _NOEXCEPT 6577a984708SDavid Chisnall{ 6587a984708SDavid Chisnall return __a.outer_allocator() == __b.outer_allocator(); 6597a984708SDavid Chisnall} 6607a984708SDavid Chisnall 6617a984708SDavid Chisnalltemplate <class _OuterA1, class _OuterA2, class _InnerA0, class... _InnerAllocs> 6627a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 6637a984708SDavid Chisnallbool 6647a984708SDavid Chisnalloperator==(const scoped_allocator_adaptor<_OuterA1, _InnerA0, _InnerAllocs...>& __a, 6657a984708SDavid Chisnall const scoped_allocator_adaptor<_OuterA2, _InnerA0, _InnerAllocs...>& __b) _NOEXCEPT 6667a984708SDavid Chisnall{ 6677a984708SDavid Chisnall return __a.outer_allocator() == __b.outer_allocator() && 6687a984708SDavid Chisnall __a.inner_allocator() == __b.inner_allocator(); 6697a984708SDavid Chisnall} 6707a984708SDavid Chisnall 6717a984708SDavid Chisnalltemplate <class _OuterA1, class _OuterA2, class... _InnerAllocs> 6727a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 6737a984708SDavid Chisnallbool 6747a984708SDavid Chisnalloperator!=(const scoped_allocator_adaptor<_OuterA1, _InnerAllocs...>& __a, 6757a984708SDavid Chisnall const scoped_allocator_adaptor<_OuterA2, _InnerAllocs...>& __b) _NOEXCEPT 6767a984708SDavid Chisnall{ 6777a984708SDavid Chisnall return !(__a == __b); 6787a984708SDavid Chisnall} 6797a984708SDavid Chisnall 680aed8d94eSDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG) 6817a984708SDavid Chisnall 6827a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 6837a984708SDavid Chisnall 6847a984708SDavid Chisnall#endif // _LIBCPP_SCOPED_ALLOCATOR 685