@@ -37,6 +37,7 @@
#include <bits/stl_iterator.h>
#include <ext/numeric_traits.h>
#include <bits/max_size_type.h>
+#include <bits/version.h>
#ifdef __cpp_lib_concepts
namespace std _GLIBCXX_VISIBILITY(default)
@@ -1057,6 +1058,11 @@ namespace ranges
iterator_t<_Range>,
dangling>;
+#if __glibcxx_ranges_to_container // C++ >= 23
+ struct from_range_t { explicit from_range_t() = default; };
+ inline constexpr from_range_t from_range{};
+#endif
+
} // namespace ranges
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
@@ -1370,19 +1370,21 @@ ftms = {
};
};
-ftms = {
- name = to_underlying;
- values = {
- v = 202102;
- cxxmin = 23;
- };
-};
+//ftms = {
+// name = container_ranges;
+// values = {
+// v = 202202;
+// cxxmin = 23;
+// hosted = yes;
+// };
+//};
ftms = {
- name = unreachable;
+ name = ranges_to_container;
values = {
v = 202202;
cxxmin = 23;
+ hosted = yes;
};
};
@@ -1614,6 +1616,22 @@ ftms = {
};
};
+ftms = {
+ name = to_underlying;
+ values = {
+ v = 202102;
+ cxxmin = 23;
+ };
+};
+
+ftms = {
+ name = unreachable;
+ values = {
+ v = 202202;
+ cxxmin = 23;
+ };
+};
+
ftms = {
name = fstream_native_handle;
values = {
@@ -1658,29 +1658,18 @@
#endif /* !defined(__cpp_lib_reference_from_temporary) && defined(__glibcxx_want_reference_from_temporary) */
#undef __glibcxx_want_reference_from_temporary
-// from version.def line 1374
-#if !defined(__cpp_lib_to_underlying)
-# if (__cplusplus >= 202100L)
-# define __glibcxx_to_underlying 202102L
-# if defined(__glibcxx_want_all) || defined(__glibcxx_want_to_underlying)
-# define __cpp_lib_to_underlying 202102L
+// from version.def line 1383
+#if !defined(__cpp_lib_ranges_to_container)
+# if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
+# define __glibcxx_ranges_to_container 202202L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_to_container)
+# define __cpp_lib_ranges_to_container 202202L
# endif
# endif
-#endif /* !defined(__cpp_lib_to_underlying) && defined(__glibcxx_want_to_underlying) */
-#undef __glibcxx_want_to_underlying
+#endif /* !defined(__cpp_lib_ranges_to_container) && defined(__glibcxx_want_ranges_to_container) */
+#undef __glibcxx_want_ranges_to_container
-// from version.def line 1382
-#if !defined(__cpp_lib_unreachable)
-# if (__cplusplus >= 202100L)
-# define __glibcxx_unreachable 202202L
-# if defined(__glibcxx_want_all) || defined(__glibcxx_want_unreachable)
-# define __cpp_lib_unreachable 202202L
-# endif
-# endif
-#endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */
-#undef __glibcxx_want_unreachable
-
-// from version.def line 1390
+// from version.def line 1392
#if !defined(__cpp_lib_ranges_zip)
# if (__cplusplus >= 202100L)
# define __glibcxx_ranges_zip 202110L
@@ -1977,7 +1966,29 @@
#endif /* !defined(__cpp_lib_string_resize_and_overwrite) && defined(__glibcxx_want_string_resize_and_overwrite) */
#undef __glibcxx_want_string_resize_and_overwrite
-// from version.def line 1618
+// from version.def line 1620
+#if !defined(__cpp_lib_to_underlying)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_to_underlying 202102L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_to_underlying)
+# define __cpp_lib_to_underlying 202102L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_to_underlying) && defined(__glibcxx_want_to_underlying) */
+#undef __glibcxx_want_to_underlying
+
+// from version.def line 1628
+#if !defined(__cpp_lib_unreachable)
+# if (__cplusplus >= 202100L)
+# define __glibcxx_unreachable 202202L
+# if defined(__glibcxx_want_all) || defined(__glibcxx_want_unreachable)
+# define __cpp_lib_unreachable 202202L
+# endif
+# endif
+#endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */
+#undef __glibcxx_want_unreachable
+
+// from version.def line 1636
#if !defined(__cpp_lib_fstream_native_handle)
# if (__cplusplus > 202302L) && _GLIBCXX_HOSTED
# define __glibcxx_fstream_native_handle 202306L
@@ -64,6 +64,7 @@
#define __glibcxx_want_ranges_repeat
#define __glibcxx_want_ranges_slide
#define __glibcxx_want_ranges_stride
+#define __glibcxx_want_ranges_to_container
#define __glibcxx_want_ranges_zip
#include <bits/version.h>
@@ -9213,8 +9214,284 @@ namespace views::__adaptor
namespace views = ranges::views;
+#if __cpp_lib_ranges_to_container // C++ >= 23
+namespace ranges
+{
+namespace __detail
+{
+ template<typename _Container>
+ constexpr bool __reservable_container
+ = sized_range<_Container>
+ && requires(_Container& __c, range_size_t<_Container> __n) {
+ __c.reserve(__n);
+ { __c.capacity() } -> same_as<decltype(__n)>;
+ { __c.max_size() } -> same_as<decltype(__n)>;
+ };
+
+ template<typename _Container, typename _Ref>
+ constexpr bool __container_insertable
+ = requires(_Container& __c, _Ref&& __ref) {
+ requires (requires { __c.push_back(std::forward<_Ref>(__ref)); }
+ || requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); });
+ };
+
+ template<typename _Ref, typename _Container>
+ constexpr auto
+ __container_inserter(_Container& __c)
+ {
+ if constexpr (requires { __c.push_back(std::declval<_Ref>()); })
+ return back_inserter(__c);
+ else
+ return inserter(__c, __c.end());
+ }
+
+ template<typename _Rg>
+ struct _InputIter
+ {
+ using iterator_category = input_iterator_tag;
+ using value_type = range_value_t<_Rg>;
+ using difference_type = ptrdiff_t;
+ using pointer = add_pointer_t<range_reference_t<_Rg>>;
+ using reference = range_reference_t<_Rg>;
+ reference operator*() const;
+ pointer operator->() const;
+ _InputIter& operator++();
+ _InputIter operator++(int);
+ bool operator==(const _InputIter&) const;
+ };
+
+ template<template<typename...> typename _Cont, typename _Rg,
+ typename... _Args>
+ concept __deduce_expr_1 = requires {
+ _Cont(std::declval<_Rg>(), std::declval<_Args>()...);
+ };
+
+ template<template<typename...> typename _Cont, typename _Rg,
+ typename... _Args>
+ concept __deduce_expr_2 = requires {
+ _Cont(from_range, std::declval<_Rg>(), std::declval<_Args>()...);
+ };
+
+ template<template<typename...> typename _Cont, typename _Rg,
+ typename... _Args>
+ concept __deduce_expr_3 = requires(_InputIter<_Rg> __i) {
+ _Cont(std::move(__i), std::move(__i), std::declval<_Args>()...);
+ };
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ using _DeduceExpr1
+ = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ using _DeduceExpr2
+ = decltype(_Cont(from_range, std::declval<_Rg>(),
+ std::declval<_Args>()...));
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ using _DeduceExpr3
+ = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
+ std::declval<_InputIter<_Rg>>(),
+ std::declval<_Args>()...));
+
+} // namespace __detail
+
+ template<typename _Cont, input_range _Rg, typename... _Args>
+ requires (!view<_Cont>)
+ constexpr _Cont
+ to(_Rg&& __r, _Args&&... __args)
+ {
+ static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
+ static_assert(is_class_v<_Cont>);
+ if constexpr (!input_range<_Cont>
+ || convertible_to<range_reference_t<_Rg>, range_value_t<_Cont>>)
+ {
+ if constexpr (constructible_from<_Cont, _Rg, _Args...>)
+ return _Cont(std::forward<_Rg>(__r),
+ std::forward<_Args>(__args)...);
+ else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
+ return _Cont(from_range, std::forward<_Rg>(__r),
+ std::forward<_Args>(__args)...);
+ else if constexpr (common_range<_Rg>
+ && derived_from<__iter_category_t<iterator_t<_Rg>>,
+ input_iterator_tag>
+ && constructible_from<_Cont, iterator_t<_Rg>, sentinel_t<_Rg>,
+ _Args...>)
+ return _Cont(ranges::begin(__r), ranges::end(__r),
+ std::forward<_Args>(__args)...);
+ else
+ {
+ using __detail::__container_insertable;
+ using __detail::__reservable_container;
+ using _RefT = range_reference_t<_Rg>;
+ static_assert(constructible_from<_Cont, _Args...>);
+ static_assert(__container_insertable<_Cont, _RefT>);
+ _Cont __c(std::forward<_Args>(__args)...);
+ if constexpr (sized_range<_Rg> && __reservable_container<_Cont>)
+ __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
+ auto __ins = __detail::__container_inserter<_RefT>(__c);
+ for (auto&& __e : __r)
+ *__ins++ = std::forward<decltype(__e)>(__e);
+ return __c;
+ }
+ }
+ else
+ {
+ static_assert(input_range<range_reference_t<_Rg>>);
+ return ranges::to<_Cont>(__r | views::transform( // XXX not in scope
+ []<typename _Elt>(_Elt&& __elem) {
+ using _ValT = range_value_t<_Cont>;
+ return ranges::to<_ValT>(std::forward<_Elt>(__elem));
+ }), std::forward<_Args>(__args)...);
+ }
+ }
+
+ template<template<typename...> typename _Cont, input_range _Rg,
+ typename... _Args>
+ constexpr auto
+ to(_Rg&& __r, _Args&&... __args)
+ {
+ using __detail::_DeduceExpr1;
+ using __detail::_DeduceExpr2;
+ using __detail::_DeduceExpr3;
+ if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
+ return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
+ std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
+ else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
+ return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
+ std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
+ else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
+ return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
+ std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
+ else
+ static_assert(false); // Cannot deduce container specialization.
+ }
+
+ template<typename _Cont, typename... _Args>
+ class _ToClosure
+ : public views::__adaptor::_RangeAdaptorClosure<_ToClosure<_Cont, _Args...>>
+ {
+ tuple<decay_t<_Args>...> _M_bound_args;
+
+ public:
+ _ToClosure(_Args&&... __args)
+ : _M_bound_args(std::forward<_Args>(__args)...)
+ { }
+
+ // TODO: use explicit object functions ("deducing this").
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+ };
+
+ template<typename _Cont, typename... _Args>
+ requires (!view<_Cont>)
+ constexpr _ToClosure<_Cont, _Args...>
+ to(_Args&&... __args)
+ { return {std::forward<_Args>(__args)...}; }
+
+ template<template<typename...> typename _Cont, typename... _Args>
+ class _ToClosure2
+ : public views::__adaptor::_RangeAdaptorClosure<_ToClosure2<_Cont, _Args...>>
+ {
+ tuple<decay_t<_Args>...> _M_bound_args;
+
+ public:
+ _ToClosure2(_Args&&... __args)
+ : _M_bound_args(std::forward<_Args>(__args)...)
+ { }
+
+ // TODO: use explicit object functions ("deducing this").
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, _M_bound_args);
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+
+ template<typename _Rg>
+ constexpr auto
+ operator()(_Rg&& __r) const &&
+ {
+ return std::apply([&__r]<typename... _Tp>(_Tp&&... __args) {
+ return ranges::to<_Cont>(std::forward<_Rg>(__r),
+ std::forward<_Tp>(__args)...);
+ }, std::move(_M_bound_args));
+ }
+ };
+
+ template<template<typename...> typename _Cont, typename... _Args>
+ constexpr _ToClosure2<_Cont, _Args...>
+ to(_Args&&... __args)
+ { return {std::forward<_Args>(__args)...}; }
+} // namespace ranges
+#endif // __cpp_lib_ranges_to_container
+
_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace std
#endif // library concepts
#endif // C++2a
#endif /* _GLIBCXX_RANGES */