File indexing completed on 2026-05-03 08:13:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___RANGES_TO_H
0011 #define _LIBCPP___CXX03___RANGES_TO_H
0012
0013 #include <__cxx03/__algorithm/ranges_copy.h>
0014 #include <__cxx03/__concepts/constructible.h>
0015 #include <__cxx03/__concepts/convertible_to.h>
0016 #include <__cxx03/__concepts/derived_from.h>
0017 #include <__cxx03/__concepts/same_as.h>
0018 #include <__cxx03/__config>
0019 #include <__cxx03/__functional/bind_back.h>
0020 #include <__cxx03/__iterator/back_insert_iterator.h>
0021 #include <__cxx03/__iterator/insert_iterator.h>
0022 #include <__cxx03/__iterator/iterator_traits.h>
0023 #include <__cxx03/__ranges/access.h>
0024 #include <__cxx03/__ranges/concepts.h>
0025 #include <__cxx03/__ranges/from_range.h>
0026 #include <__cxx03/__ranges/range_adaptor.h>
0027 #include <__cxx03/__ranges/ref_view.h>
0028 #include <__cxx03/__ranges/size.h>
0029 #include <__cxx03/__ranges/transform_view.h>
0030 #include <__cxx03/__type_traits/add_pointer.h>
0031 #include <__cxx03/__type_traits/is_const.h>
0032 #include <__cxx03/__type_traits/is_volatile.h>
0033 #include <__cxx03/__type_traits/type_identity.h>
0034 #include <__cxx03/__utility/declval.h>
0035 #include <__cxx03/__utility/forward.h>
0036 #include <__cxx03/cstddef>
0037
0038 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0039 # pragma GCC system_header
0040 #endif
0041
0042 _LIBCPP_BEGIN_NAMESPACE_STD
0043
0044 #if _LIBCPP_STD_VER >= 23
0045
0046 namespace ranges {
0047
0048 template <class _Container>
0049 constexpr bool __reservable_container =
0050 sized_range<_Container> && requires(_Container& __c, range_size_t<_Container> __n) {
0051 __c.reserve(__n);
0052 { __c.capacity() } -> same_as<decltype(__n)>;
0053 { __c.max_size() } -> same_as<decltype(__n)>;
0054 };
0055
0056 template <class _Container, class _Ref>
0057 constexpr bool __container_insertable = requires(_Container& __c, _Ref&& __ref) {
0058 requires(
0059 requires { __c.push_back(std::forward<_Ref>(__ref)); } ||
0060 requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); });
0061 };
0062
0063 template <class _Ref, class _Container>
0064 _LIBCPP_HIDE_FROM_ABI constexpr auto __container_inserter(_Container& __c) {
0065 if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) {
0066 return std::back_inserter(__c);
0067 } else {
0068 return std::inserter(__c, __c.end());
0069 }
0070 }
0071
0072
0073 template <class _Container, class _Range>
0074 concept __try_non_recursive_conversion =
0075 !input_range<_Container> || convertible_to<range_reference_t<_Range>, range_value_t<_Container>>;
0076
0077 template <class _Container, class _Range, class... _Args>
0078 concept __constructible_from_iter_pair =
0079 common_range<_Range> && requires { typename iterator_traits<iterator_t<_Range>>::iterator_category; } &&
0080 derived_from<typename iterator_traits<iterator_t<_Range>>::iterator_category, input_iterator_tag> &&
0081 constructible_from<_Container, iterator_t<_Range>, sentinel_t<_Range>, _Args...>;
0082
0083 template <class>
0084 concept __always_false = false;
0085
0086
0087 template <class _Container, input_range _Range, class... _Args>
0088 requires(!view<_Container>)
0089 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) {
0090
0091 static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
0092 static_assert(
0093 !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
0094
0095
0096
0097
0098 if constexpr (__try_non_recursive_conversion<_Container, _Range>) {
0099
0100 if constexpr (constructible_from<_Container, _Range, _Args...>) {
0101 return _Container(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
0102 }
0103
0104
0105 else if constexpr (constructible_from<_Container, from_range_t, _Range, _Args...>) {
0106 return _Container(from_range, std::forward<_Range>(__range), std::forward<_Args>(__args)...);
0107 }
0108
0109
0110 else if constexpr (__constructible_from_iter_pair<_Container, _Range, _Args...>) {
0111 return _Container(ranges::begin(__range), ranges::end(__range), std::forward<_Args>(__args)...);
0112 }
0113
0114
0115 else if constexpr (constructible_from<_Container, _Args...> &&
0116 __container_insertable<_Container, range_reference_t<_Range>>) {
0117 _Container __result(std::forward<_Args>(__args)...);
0118 if constexpr (sized_range<_Range> && __reservable_container<_Container>) {
0119 __result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range)));
0120 }
0121
0122 ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result));
0123
0124 return __result;
0125
0126 } else {
0127 static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
0128 }
0129
0130
0131 } else if constexpr (input_range<range_reference_t<_Range>>) {
0132 return ranges::to<_Container>(
0133 ref_view(__range) | views::transform([](auto&& __elem) {
0134 return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
0135 }),
0136 std::forward<_Args>(__args)...);
0137
0138 } else {
0139 static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
0140 }
0141 }
0142
0143 template <class _Range>
0144 struct __minimal_input_iterator {
0145 using iterator_category = input_iterator_tag;
0146 using value_type = range_value_t<_Range>;
0147 using difference_type = ptrdiff_t;
0148 using pointer = add_pointer_t<range_reference_t<_Range>>;
0149 using reference = range_reference_t<_Range>;
0150
0151 reference operator*() const;
0152 pointer operator->() const;
0153 __minimal_input_iterator& operator++();
0154 __minimal_input_iterator operator++(int);
0155 bool operator==(const __minimal_input_iterator&) const;
0156 };
0157
0158
0159 template <template <class...> class _Container, input_range _Range, class... _Args>
0160 struct _Deducer {
0161 _LIBCPP_HIDE_FROM_ABI static constexpr auto __deduce_func() {
0162 using _InputIter = __minimal_input_iterator<_Range>;
0163
0164
0165 if constexpr (requires { _Container(std::declval<_Range>(), std::declval<_Args>()...); }) {
0166 using _Result = decltype(
0167 _Container(std::declval<_Range>(), std::declval<_Args>()...));
0168 return type_identity<_Result>{};
0169
0170
0171 } else if constexpr (
0172 requires { _Container(from_range, std::declval<_Range>(), std::declval<_Args>()...); }) {
0173 using _Result =
0174 decltype(_Container(from_range, std::declval<_Range>(), std::declval<_Args>()...));
0175 return type_identity<_Result>{};
0176
0177
0178 } else if constexpr (
0179 requires { _Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...); }) {
0180 using _Result =
0181 decltype(_Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...));
0182 return type_identity<_Result>{};
0183
0184 } else {
0185 static_assert(__always_false<_Range>,
0186 "ranges::to: unable to deduce the container type from the template template argument.");
0187 }
0188 }
0189
0190 using type = typename decltype(__deduce_func())::type;
0191 };
0192
0193
0194
0195 template <template <class...> class _Container, input_range _Range, class... _Args>
0196 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Range&& __range, _Args&&... __args) {
0197 using _DeduceExpr = typename _Deducer<_Container, _Range, _Args...>::type;
0198 return ranges::to<_DeduceExpr>(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
0199 }
0200
0201
0202
0203 template <class _Container, class... _Args>
0204 requires(!view<_Container>)
0205 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
0206
0207 static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
0208 static_assert(
0209 !is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
0210
0211 auto __to_func = []<input_range _Range, class... _Tail>(_Range&& __range, _Tail&&... __tail) static
0212 requires requires {
0213 ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
0214 }
0215 { return ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...); };
0216
0217 return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
0218 }
0219
0220
0221
0222 template <template <class...> class _Container, class... _Args>
0223 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
0224
0225 auto __to_func = []<input_range _Range, class... _Tail,
0226 class _DeducedExpr = typename _Deducer<_Container, _Range, _Tail...>::type>
0227 (_Range&& __range, _Tail&& ... __tail) static
0228 requires requires {
0229 ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
0230 }
0231 {
0232 return ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
0233 };
0234
0235
0236 return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
0237 }
0238
0239 }
0240
0241 #endif
0242
0243 _LIBCPP_END_NAMESPACE_STD
0244
0245 #endif