diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index 7fa43d1965a..555065b4ed7 100644
--- a/libstdc++-v3/include/bits/ranges_base.h
+++ b/libstdc++-v3/include/bits/ranges_base.h
@@ -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
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 447fdeb9519..15bd502f52c 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -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 = {
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 97c6d8508f4..9563b6cd2f7 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -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
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 26d6c013ad0..fcc0a786091 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -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 */
