brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.7 KiB · 6733f5c Raw
235 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H10#define _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H11 12#include <__config>13#include <__memory/construct_at.h>14#include <__memory/uses_allocator.h>15#include <__tuple/tuple_like_no_subrange.h>16#include <__type_traits/enable_if.h>17#include <__type_traits/remove_cv.h>18#include <__utility/declval.h>19#include <__utility/pair.h>20#include <__utility/piecewise_construct.h>21#include <tuple>22 23#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)24#  pragma GCC system_header25#endif26 27_LIBCPP_PUSH_MACROS28#include <__undef_macros>29 30_LIBCPP_BEGIN_NAMESPACE_STD31 32#if _LIBCPP_STD_VER >= 1733 34template <class _Tp>35inline constexpr bool __is_cv_std_pair = __is_pair_v<remove_cv_t<_Tp>>;36 37template <class _Tp, class = void>38struct __uses_allocator_construction_args;39 40namespace __uses_allocator_detail {41 42template <class _Ap, class _Bp>43void __fun(const pair<_Ap, _Bp>&);44 45template <class _Tp>46decltype(__uses_allocator_detail::__fun(std::declval<_Tp>()), true_type()) __convertible_to_const_pair_ref_impl(int);47 48template <class>49false_type __convertible_to_const_pair_ref_impl(...);50 51template <class _Tp>52inline constexpr bool __convertible_to_const_pair_ref =53    decltype(__uses_allocator_detail::__convertible_to_const_pair_ref_impl<_Tp>(0))::value;54 55#  if _LIBCPP_STD_VER >= 2356template <class _Tp, class _Up>57inline constexpr bool __uses_allocator_constraints =58    __is_cv_std_pair<_Tp> && !__pair_like_no_subrange<_Up> && !__convertible_to_const_pair_ref<_Up>;59#  else60template <class _Tp, class _Up>61inline constexpr bool __uses_allocator_constraints = __is_cv_std_pair<_Tp> && !__convertible_to_const_pair_ref<_Up>;62#  endif63 64} // namespace __uses_allocator_detail65 66template <class _Type, class _Alloc, class... _Args>67_LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args);68 69template <class _Pair>70struct __uses_allocator_construction_args<_Pair, __enable_if_t<__is_cv_std_pair<_Pair>>> {71  template <class _Alloc, class _Tuple1, class _Tuple2>72  static _LIBCPP_HIDE_FROM_ABI constexpr auto73  __apply(const _Alloc& __alloc, piecewise_construct_t, _Tuple1&& __x, _Tuple2&& __y) noexcept {74    return std::make_tuple(75        piecewise_construct,76        std::apply(77            [&__alloc](auto&&... __args1) {78              return __uses_allocator_construction_args<typename _Pair::first_type>::__apply(79                  __alloc, std::forward<decltype(__args1)>(__args1)...);80            },81            std::forward<_Tuple1>(__x)),82        std::apply(83            [&__alloc](auto&&... __args2) {84              return __uses_allocator_construction_args<typename _Pair::second_type>::__apply(85                  __alloc, std::forward<decltype(__args2)>(__args2)...);86            },87            std::forward<_Tuple2>(__y)));88  }89 90  template <class _Alloc>91  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc) noexcept {92    return __uses_allocator_construction_args<_Pair>::__apply(__alloc, piecewise_construct, tuple<>{}, tuple<>{});93  }94 95  template <class _Alloc, class _Up, class _Vp>96  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _Up&& __u, _Vp&& __v) noexcept {97    return __uses_allocator_construction_args<_Pair>::__apply(98        __alloc,99        piecewise_construct,100        std::forward_as_tuple(std::forward<_Up>(__u)),101        std::forward_as_tuple(std::forward<_Vp>(__v)));102  }103 104#  if _LIBCPP_STD_VER >= 23105  template <class _Alloc, class _Up, class _Vp>106  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, pair<_Up, _Vp>& __pair) noexcept {107    return __uses_allocator_construction_args<_Pair>::__apply(108        __alloc, piecewise_construct, std::forward_as_tuple(__pair.first), std::forward_as_tuple(__pair.second));109  }110#  endif111 112  template <class _Alloc, class _Up, class _Vp>113  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, const pair<_Up, _Vp>& __pair) noexcept {114    return __uses_allocator_construction_args<_Pair>::__apply(115        __alloc, piecewise_construct, std::forward_as_tuple(__pair.first), std::forward_as_tuple(__pair.second));116  }117 118  template <class _Alloc, class _Up, class _Vp>119  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, pair<_Up, _Vp>&& __pair) noexcept {120    return __uses_allocator_construction_args<_Pair>::__apply(121        __alloc,122        piecewise_construct,123        std::forward_as_tuple(std::get<0>(std::move(__pair))),124        std::forward_as_tuple(std::get<1>(std::move(__pair))));125  }126 127#  if _LIBCPP_STD_VER >= 23128  template <class _Alloc, class _Up, class _Vp>129  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, const pair<_Up, _Vp>&& __pair) noexcept {130    return __uses_allocator_construction_args<_Pair>::__apply(131        __alloc,132        piecewise_construct,133        std::forward_as_tuple(std::get<0>(std::move(__pair))),134        std::forward_as_tuple(std::get<1>(std::move(__pair))));135  }136 137  template < class _Alloc, __pair_like_no_subrange _PairLike>138  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _PairLike&& __p) noexcept {139    return __uses_allocator_construction_args<_Pair>::__apply(140        __alloc,141        piecewise_construct,142        std::forward_as_tuple(std::get<0>(std::forward<_PairLike>(__p))),143        std::forward_as_tuple(std::get<1>(std::forward<_PairLike>(__p))));144  }145#  endif146 147  template <class _Alloc,148            class _Type,149            __enable_if_t<__uses_allocator_detail::__uses_allocator_constraints<_Pair, _Type>, int> = 0>150  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _Type&& __value) noexcept {151    struct __pair_constructor {152      using _PairMutable = remove_cv_t<_Pair>;153 154      _LIBCPP_HIDDEN constexpr auto __do_construct(const _PairMutable& __pair) const {155        return std::__make_obj_using_allocator<_PairMutable>(__alloc_, __pair);156      }157 158      _LIBCPP_HIDDEN constexpr auto __do_construct(_PairMutable&& __pair) const {159        return std::__make_obj_using_allocator<_PairMutable>(__alloc_, std::move(__pair));160      }161 162      const _Alloc& __alloc_;163      _Type& __value_;164 165      _LIBCPP_HIDDEN constexpr operator _PairMutable() const { return __do_construct(std::forward<_Type>(__value_)); }166    };167 168    return std::make_tuple(__pair_constructor{__alloc, __value});169  }170};171 172template <class _Type>173struct __uses_allocator_construction_args<_Type, __enable_if_t<!__is_cv_std_pair<_Type>>> {174  template <class _Alloc, class... _Args>175  static _LIBCPP_HIDE_FROM_ABI constexpr auto __apply(const _Alloc& __alloc, _Args&&... __args) noexcept {176    if constexpr (!uses_allocator_v<remove_cv_t<_Type>, _Alloc> && is_constructible_v<_Type, _Args...>) {177      return std::forward_as_tuple(std::forward<_Args>(__args)...);178    } else if constexpr (uses_allocator_v<remove_cv_t<_Type>, _Alloc> &&179                         is_constructible_v<_Type, allocator_arg_t, const _Alloc&, _Args...>) {180      return tuple<allocator_arg_t, const _Alloc&, _Args&&...>(allocator_arg, __alloc, std::forward<_Args>(__args)...);181    } else if constexpr (uses_allocator_v<remove_cv_t<_Type>, _Alloc> &&182                         is_constructible_v<_Type, _Args..., const _Alloc&>) {183      return std::forward_as_tuple(std::forward<_Args>(__args)..., __alloc);184    } else {185      static_assert(186          sizeof(_Type) + 1 == 0, "If uses_allocator_v<Type> is true, the type has to be allocator-constructible");187    }188  }189};190 191template <class _Type, class _Alloc, class... _Args>192_LIBCPP_HIDE_FROM_ABI constexpr _Type __make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args) {193  return std::make_from_tuple<_Type>(194      __uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...));195}196 197template <class _Type, class _Alloc, class... _Args>198_LIBCPP_HIDE_FROM_ABI constexpr _Type*199__uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Args&&... __args) {200  return std::apply(201      [&__ptr](auto&&... __xs) { return std::__construct_at(__ptr, std::forward<decltype(__xs)>(__xs)...); },202      __uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...));203}204 205#endif // _LIBCPP_STD_VER >= 17206 207#if _LIBCPP_STD_VER >= 20208 209template <class _Type, class _Alloc, class... _Args>210_LIBCPP_HIDE_FROM_ABI constexpr auto uses_allocator_construction_args(const _Alloc& __alloc, _Args&&... __args) noexcept211    -> decltype(__uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...)) {212  return /*--*/ __uses_allocator_construction_args<_Type>::__apply(__alloc, std::forward<_Args>(__args)...);213}214 215template <class _Type, class _Alloc, class... _Args>216_LIBCPP_HIDE_FROM_ABI constexpr auto make_obj_using_allocator(const _Alloc& __alloc, _Args&&... __args)217    -> decltype(std::__make_obj_using_allocator<_Type>(__alloc, std::forward<_Args>(__args)...)) {218  return /*--*/ std::__make_obj_using_allocator<_Type>(__alloc, std::forward<_Args>(__args)...);219}220 221template <class _Type, class _Alloc, class... _Args>222_LIBCPP_HIDE_FROM_ABI constexpr auto223uninitialized_construct_using_allocator(_Type* __ptr, const _Alloc& __alloc, _Args&&... __args)224    -> decltype(std::__uninitialized_construct_using_allocator(__ptr, __alloc, std::forward<_Args>(__args)...)) {225  return /*--*/ std::__uninitialized_construct_using_allocator(__ptr, __alloc, std::forward<_Args>(__args)...);226}227 228#endif // _LIBCPP_STD_VER >= 20229 230_LIBCPP_END_NAMESPACE_STD231 232_LIBCPP_POP_MACROS233 234#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H235