diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h
index 7fa43d1965a..1ca2c5ce2bb 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)
@@ -1056,8 +1057,13 @@ namespace ranges
     using borrowed_iterator_t = __conditional_t<borrowed_range<_Range>,
 						iterator_t<_Range>,
 						dangling>;
-
 } // namespace ranges
+
+#if __glibcxx_ranges_to_container // C++ >= 23
+  struct from_range_t { explicit from_range_t() = default; };
+  inline constexpr from_range_t from_range{};
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 #endif // library concepts
diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 605708dfee7..140777832ed 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1439,19 +1439,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;
   };
 };
 
@@ -1683,6 +1685,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 cacd9375cab..1fb1d148459 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1740,29 +1740,18 @@
 #endif /* !defined(__cpp_lib_reference_from_temporary) && defined(__glibcxx_want_reference_from_temporary) */
 #undef __glibcxx_want_reference_from_temporary
 
-// from version.def line 1443
-#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 1452
+#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 1451
-#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 1459
+// from version.def line 1461
 #if !defined(__cpp_lib_ranges_zip)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_ranges_zip 202110L
@@ -2059,7 +2048,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 1687
+// from version.def line 1689
+#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 1697
+#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 1705
 #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..63bea862c05 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,366 @@ namespace views::__adaptor
 
   namespace views = ranges::views;
 
+#if __cpp_lib_ranges_to_container // C++ >= 23
+namespace ranges
+{
+/// @cond undocumented
+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) {
+	typename _Container::value_type;
+	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 std::back_inserter(__c);
+      else
+	return std::inserter(__c, __c.end());
+    }
+
+  template<typename _Cont, typename _Range>
+    constexpr bool __toable = requires {
+      requires (!input_range<_Range>
+		  || convertible_to<range_reference_t<_Range>,
+				    range_value_t<_Cont>>);
+    };
+} // namespace __detail
+/// @endcond
+
+  /// Convert a range to a container.
+  /**
+   * @tparam _Cont A container type.
+   * @param __r A range that models the `input_range` concept.
+   * @param __args... Arguments to pass to the container constructor.
+   * @since C++23
+   *
+   * This function converts a range to the `_Cont` type.
+   *
+   * For example, `std::ranges::to<std::vector<int>>(some_view)`
+   * will convert the view to `std::vector<int>`.
+   *
+   * Additional constructor arguments for the container can be supplied after
+   * the input range argument, e.g.
+   * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
+   */
+  template<typename _Cont, input_range _Rg, typename... _Args>
+    requires (!view<_Cont>)
+    constexpr _Cont
+    to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
+    {
+      static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
+      static_assert(is_class_v<_Cont>);
+
+      if constexpr (__detail::__toable<_Cont, _Rg>)
+	{
+	  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 (requires { common_range<_Rg>;
+		typename __iter_category_t<iterator_t<_Rg>>;
+		requires derived_from<__iter_category_t<iterator_t<_Rg>>,
+				      input_iterator_tag>;
+		requires 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>>);
+	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+	  // 3984. ranges::to's recursion branch may be ill-formed
+	  return ranges::to<_Cont>(ref_view(__r) | views::transform(
+		[]<typename _Elt>(_Elt&& __elem) {
+		  using _ValT = range_value_t<_Cont>;
+		  return ranges::to<_ValT>(std::forward<_Elt>(__elem));
+		}), std::forward<_Args>(__args)...);
+	}
+    }
+
+/// @cond undocumented
+namespace __detail
+{
+  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;
+    };
+
+#if 0
+  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>()...);
+    };
+#endif
+
+  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
+/// @endcond
+
+  template<template<typename...> typename _Cont, input_range _Rg,
+	   typename... _Args>
+    constexpr auto
+    to [[nodiscard]] (_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.
+    }
+
+/// @cond undocumented
+namespace __detail
+{
+  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));
+	}
+    };
+} // namespace __detail
+/// @endcond
+
+  /// ranges::to adaptor for converting a range to a container type
+  /**
+   * @tparam _Cont A container type.
+   * @param __args... Arguments to pass to the container constructor.
+   * @since C++23
+   *
+   * This range adaptor returns a range adaptor closure object that converts
+   * a range to the `_Cont` type.
+   *
+   * For example, `some_view | std::ranges::to<std::vector<int>>()`
+   * will convert the view to `std::vector<int>`.
+   *
+   * Additional constructor arguments for the container can be supplied, e.g.
+   * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
+   */
+  template<typename _Cont, typename... _Args>
+    requires (!view<_Cont>)
+    constexpr __detail::_ToClosure<_Cont, _Args...>
+    to [[nodiscard]] (_Args&&... __args)
+    { return {std::forward<_Args>(__args)...}; }
+
+/// @cond undocumented
+namespace __detail
+{
+  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));
+	}
+    };
+} // namespace __detail
+/// @endcond
+
+  /// ranges::to adaptor for converting a range to a deduced container type.
+  /**
+   * @tparam _Cont A container template.
+   * @param __args... Arguments to pass to the container constructor.
+   * @since C++23
+   *
+   * This range adaptor returns a range adaptor closure object that converts
+   * a range to a specialization of the `_Cont` class template. The specific
+   * specialization of `_Cont` to be used is deduced automatically.
+   *
+   * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
+   * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
+   * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
+   *
+   * Additional constructor arguments for the container can be supplied, e.g.
+   * `r | std::ranges::to<std::vector>(an_allocator)`.
+   */
+  template<template<typename...> typename _Cont, typename... _Args>
+    constexpr __detail::_ToClosure2<_Cont, _Args...>
+    to [[nodiscard]] (_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 */
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/1.cc b/libstdc++-v3/testsuite/std/ranges/conv/1.cc
new file mode 100644
index 00000000000..0032cf32688
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/1.cc
@@ -0,0 +1,369 @@
+// { dg-do run { target c++23 } }
+
+// C++23 26.5.7 Range conversions [range.utility.conv]
+
+#include <ranges>
+#include <vector>
+#include <string>
+#include <deque>
+#include <list>
+#include <forward_list>
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+#include <testsuite_iterators.h>
+
+void
+test_p1206r7_examples()
+{
+  using Alloc = __gnu_test::uneq_allocator<int>;
+  const Alloc alloc(303);
+  const std::map<int, const char*> m{{1, "one"}, {2, "two"}, {3, "three"}};
+  namespace ranges = std::ranges;
+
+  auto l = std::views::iota(1, 10);
+  // create a vector with the elements of l
+  auto vec = ranges::to<std::vector<int>>(l); // or vector{std::from_range, l};
+  //Specify an allocator
+  auto b = ranges::to<std::vector<int, Alloc>>(l, alloc); // or vector{std::from_range, l, alloc};
+  //deducing value_type
+  auto c = ranges::to<std::vector>(l);
+  // explicit conversion int -> long
+  auto d = ranges::to<std::vector<long>>(l);
+  //Supports converting associative container to sequence containers
+  auto f = ranges::to<std::vector>(m);
+  //Supports converting sequence containers to associative ones
+  auto g = ranges::to<std::map>(f);
+  //Pipe syntax
+  auto g2 = l | ranges::views::take(42) | ranges::to<std::vector>();
+  //Pipe syntax with allocator
+  auto h = l | ranges::views::take(42) | ranges::to<std::vector>(alloc);
+  //The pipe syntax also support specifying the type and conversions
+  auto i = l | ranges::views::take(42) | ranges::to<std::vector<long>>();
+  // Nested ranges
+  std::list<std::forward_list<int>> lst = {{0, 1, 2, 3}, {4, 5, 6, 7}};
+  auto vec1 = ranges::to<std::vector<std::vector<int>>>(lst);
+  auto vec2 = ranges::to<std::vector<std::deque<double>>>(lst);
+
+  VERIFY( vec == std::vector<int>(std::ranges::begin(l), std::ranges::end(l)) );
+  static_assert(std::is_same_v<decltype(b), std::vector<int, Alloc>>);
+  VERIFY( b == (std::vector<int, Alloc>(vec.begin(), vec.end())) );
+  VERIFY( b.get_allocator() == alloc );
+  static_assert(std::is_same_v<decltype(c), std::vector<int>>);
+  VERIFY( c == vec );
+  static_assert(std::is_same_v<decltype(d), std::vector<long>>);
+  VERIFY( d == std::vector<long>(vec.begin(), vec.end()) );
+  VERIFY( g == m );
+  static_assert(std::is_same_v<decltype(g2), std::vector<int>>);
+  VERIFY( g2 == vec );
+  static_assert(std::is_same_v<decltype(h), std::vector<int, Alloc>>);
+  VERIFY( h == b );
+  VERIFY( h.get_allocator() == alloc );
+  VERIFY( i == d );
+  static_assert(std::is_same_v<decltype(vec1), std::vector<std::vector<int>>>);
+  VERIFY( vec1[1][1] == 5 );
+  static_assert(std::is_same_v<decltype(vec2), std::vector<std::deque<double>>>);
+  VERIFY( vec2[1][2] == 6.0 );
+}
+
+void
+test_example_1()
+{
+  using namespace std;
+  using ranges::to;
+
+  // Example 1 from C++23 [range.utility.conv.general]
+  string_view str = "the quick brown fox";
+  auto words = views::split(str, ' ') | to<vector<string>>();
+
+  VERIFY( (is_same_v<decltype(words), vector<string>>) );
+  VERIFY( words == vector<string>({"the", "quick", "brown", "fox"}) );
+}
+
+template<typename C>
+struct Cont1
+{
+  template<typename R, typename... Args>
+    requires std::constructible_from<C, R&, Args&...>
+    Cont1(R&& r, Args&&... args)
+    : c(r, args...)
+    { }
+
+  typename C::iterator begin();
+  typename C::iterator end();
+
+  C c;
+};
+
+void
+test_2_1_1()
+{
+  // (2.1.1) constructible_from<C, R, Args...>
+
+  std::vector<int> v{1, 2, 3, 4};
+  auto v2 = std::ranges::to<std::vector<int>>(v);
+  static_assert(std::is_same_v<decltype(v2), decltype(v)>);
+  VERIFY( v2 == v );
+
+  std::initializer_list<int> il{5, 6, 7, 8};
+  v2 = std::ranges::to<std::vector<int>>(il);
+  VERIFY( v2 == std::vector<int>(il) );
+
+  v2 = std::ranges::to<std::vector<int>>(il, std::allocator<int>{});
+  VERIFY( v2 == std::vector<int>(il) );
+
+  using Alloc = __gnu_test::uneq_allocator<int>;
+  using V = std::vector<int, Alloc>;
+
+  V v3({10, 11, 12, 13}, Alloc(14));
+  auto v4 = std::ranges::to<V>(v3);
+  static_assert(std::is_same_v<decltype(v4), V>);
+  VERIFY( v4 == v3 );
+  VERIFY( v4.get_allocator() == v3.get_allocator() );
+
+  auto v5 = std::ranges::to<V>(v3, Alloc(33));
+  VERIFY( v5 == v3 );
+  VERIFY( v5.get_allocator() == Alloc(33) );
+
+  auto v6 = std::ranges::to<V>(il, Alloc(44));
+  VERIFY( v6 == V(il) );
+  VERIFY( v6.get_allocator() == Alloc(44) );
+
+  auto c = std::ranges::to<Cont1<V>>(V{1, 2, 3});
+  static_assert(std::is_same_v<decltype(c), Cont1<V>>);
+  VERIFY( c.c == V({1, 2, 3}) );
+
+  auto c2 = std::ranges::to<Cont1<V>>(V{4, 5, 6}, Alloc(55));
+  static_assert(std::is_same_v<decltype(c2), Cont1<V>>);
+  VERIFY( c2.c == V({4, 5, 6}) );
+  VERIFY( c2.c.get_allocator() == Alloc(55) );
+
+  auto c3 = std::ranges::to<Cont1<V>>(il, Alloc(66));
+  static_assert(std::is_same_v<decltype(c2), Cont1<V>>);
+  VERIFY( c3.c == V(v2.begin(), v2.end()) );
+  VERIFY( c3.c.get_allocator() == Alloc(66) );
+}
+
+template<typename C>
+struct Cont2
+{
+  template<typename R, typename... Args>
+    requires std::constructible_from<C, R&, Args&...>
+    Cont2(std::from_range_t, R&& r, Args&&... args)
+    : c(r, args...)
+    { }
+
+  typename C::iterator begin();
+  typename C::iterator end();
+
+  C c;
+};
+
+void
+test_2_1_2()
+{
+  // (2.1.2) constructible_from<C, from_range_t, R, Args...>
+
+  using Alloc = __gnu_test::uneq_allocator<int>;
+  using V = std::vector<int, Alloc>;
+  auto c = std::ranges::to<Cont2<V>>(V{1, 2, 3});
+  static_assert(std::is_same_v<decltype(c), Cont2<V>>);
+  VERIFY( c.c == V({1, 2, 3}) );
+
+  auto c2 = std::ranges::to<Cont2<V>>(V{4, 5, 6}, Alloc(7));
+  static_assert(std::is_same_v<decltype(c2), Cont2<V>>);
+  VERIFY( c2.c == V({4, 5, 6}) );
+  VERIFY( c2.c.get_allocator() == Alloc(7) );
+}
+
+template<typename C>
+struct Cont3
+{
+  template<typename It, typename Sent, typename... Args>
+    requires std::same_as<It, Sent>
+    && std::constructible_from<C, It&, Sent&, Args&...>
+    Cont3(It first, Sent last, Args&&... args)
+    : c(first, last, args...)
+    { }
+
+  typename C::iterator begin();
+  typename C::iterator end();
+
+  C c;
+};
+
+void
+test_2_1_3()
+{
+  // (2.1.3) constructible_from<C, iterator_t<R>, sentinel_t<R<, Args...>
+
+  using Alloc = __gnu_test::uneq_allocator<int>;
+  using V = std::vector<int, Alloc>;
+
+  std::list<unsigned> l{1u, 2u, 3u};
+  auto c = std::ranges::to<Cont3<V>>(l);
+  static_assert(std::is_same_v<decltype(c), Cont3<V>>);
+  VERIFY( c.c == V(l.begin(), l.end()) );
+
+  std::list<long> l2{4l, 5l, 6l};
+  auto c2 = std::ranges::to<Cont3<V>>(l2, Alloc(78));
+  static_assert(std::is_same_v<decltype(c2), Cont3<V>>);
+  VERIFY( c2.c == V(l2.begin(), l2.end()) );
+  VERIFY( c2.c.get_allocator() == Alloc(78) );
+}
+
+template<typename C, bool UsePushBack = true>
+struct Cont4
+{
+  using value_type = typename C::value_type;
+
+  // Only support construction with no args or an allocator.
+  // This forces the use of either push_back or insert to fill the container.
+  Cont4() { }
+  Cont4(typename C::allocator_type a) : c(a) { }
+
+  // Required to satisfy range
+  typename C::iterator begin() { return c.begin(); }
+  typename C::iterator end() { return c.end(); }
+
+  // Satisfying container-insertable requires either this ...
+  template<typename T>
+    requires UsePushBack
+    && requires(C& c, T&& t) { c.push_back(std::forward<T>(t)); }
+    void
+    push_back(T&& t)
+    {
+      c.push_back(std::forward<T>(t));
+      used_push_back = true;
+    }
+
+  // ... or this:
+  template<typename T>
+    typename C::iterator
+    insert(typename C::iterator, T&& t)
+    {
+      used_push_back = false;
+      return c.insert(c.end(), std::forward<T>(t));
+    }
+
+  // Required to satisfy reservable-container
+  void
+  reserve(typename C::size_type n) requires requires(C& c) { c.reserve(n); }
+  {
+    c.reserve(n);
+    used_reserve = true;
+  }
+
+  // Required to satisfy reservable-container
+  auto size() const { return c.size(); }
+
+  // Required to satisfy reservable-container
+  auto capacity() const requires requires(C& c) { c.capacity(); }
+  { return c.capacity(); }
+
+  // Required to satisfy reservable-container
+  auto max_size() const { return c.max_size(); }
+
+  C c;
+  bool used_push_back = false;
+  bool used_reserve = false;
+};
+
+void
+test_2_1_4()
+{
+  // (2.1.4) constructible_from<C, Args...> and
+  // container-insertable<C, range_reference_t<R>>
+
+  using Alloc = __gnu_test::uneq_allocator<int>;
+  using V = std::vector<int, Alloc>;
+
+  std::list<unsigned> l{1u, 2u, 3u};
+  auto c = std::ranges::to<Cont4<V>>(l);
+  static_assert(std::is_same_v<decltype(c), Cont4<V>>);
+  VERIFY( c.c == V(l.begin(), l.end()) );
+  VERIFY( c.used_push_back );
+  VERIFY( c.used_reserve );
+
+  std::list<long> l2{4l, 5l, 6l};
+  auto c2 = std::ranges::to<Cont4<V>>(l2, Alloc(78));
+  static_assert(std::is_same_v<decltype(c2), Cont4<V>>);
+  VERIFY( c2.c == V(l2.begin(), l2.end()) );
+  VERIFY( c2.c.get_allocator() == Alloc(78) );
+  VERIFY( c2.used_push_back );
+  VERIFY( c2.used_reserve );
+
+  using Alloc2 = __gnu_test::uneq_allocator<short>;
+  using List = std::list<short, Alloc2>;
+  auto c3 = std::ranges::to<Cont4<List>>(c.c, Alloc2(99));
+  static_assert(std::is_same_v<decltype(c3), Cont4<List>>);
+  VERIFY( c3.c == List(l.begin(), l.end()) );
+  VERIFY( c3.c.get_allocator() == Alloc(99) );
+  VERIFY( c3.used_push_back );
+  VERIFY( ! c3.used_reserve );
+
+  auto c4 = std::ranges::to<Cont4<List, false>>(c.c, Alloc2(111));
+  static_assert(std::is_same_v<decltype(c4), Cont4<List, false>>);
+  VERIFY( c4.c == List(l.begin(), l.end()) );
+  VERIFY( c4.c.get_allocator() == Alloc(111) );
+  VERIFY( ! c4.used_push_back );
+  VERIFY( ! c4.used_reserve );
+}
+
+void
+test_2_2()
+{
+  // (2.2) input_range<range_reference_t<R>>
+
+  std::string s1[]{ "one", "two", "three", "four" };
+  std::string s2[]{ "V", "VI", "VII", "VIII" };
+  std::string s3[]{ "0x09", "0x0a", "0x0b", "0x0c" };
+  using R = __gnu_test::test_input_range<std::string>;
+  R input_ranges[]{R(s1), R(s2), R(s3)};
+  __gnu_test::test_input_range<R> rr(input_ranges);
+  namespace pmr = std::pmr;
+  __gnu_test::memory_resource res;
+#if _GLIBCXX_USE_CXX11_ABI
+  auto vvs = std::ranges::to<pmr::vector<pmr::vector<pmr::string>>>(rr, &res);
+  auto str_alloc = pmr::polymorphic_allocator<char>(&res);
+#else
+  auto vvs = std::ranges::to<pmr::vector<pmr::vector<std::string>>>(rr, &res);
+  auto str_alloc = std::allocator<char>();
+#endif
+  VERIFY( vvs[1][1] == "VI" );
+  VERIFY( vvs[2][2] == "0x0b" );
+  VERIFY( vvs[0].get_allocator().resource() == &res );
+  VERIFY( vvs[2][2].get_allocator() == str_alloc );
+}
+
+void
+test_lwg3984()
+{
+  std::vector<std::vector<int>> v;
+  auto r = std::views::all(std::move(v));
+  auto l = std::ranges::to<std::list<std::list<int>>>(r);
+  VERIFY(l.empty());
+}
+
+void
+test_nodiscard()
+{
+  std::vector<int> v;
+  std::ranges::to<std::vector<long>>(v); // { dg-warning "ignoring return" }
+  std::ranges::to<std::vector>(v);       // { dg-warning "ignoring return" }
+  std::ranges::to<std::vector<long>>();  // { dg-warning "ignoring return" }
+  std::ranges::to<std::vector>();        // { dg-warning "ignoring return" }
+}
+
+int main()
+{
+  test_p1206r7_examples();
+  test_example_1();
+  test_2_1_1();
+  test_2_1_2();
+  test_2_1_3();
+  test_2_1_4();
+  test_2_2();
+  test_lwg3984();
+  test_nodiscard();
+}
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc b/libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc
new file mode 100644
index 00000000000..1e5f6f18408
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/2_neg.cc
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++23 } }
+
+// C++23 26.5.7 Range conversions [range.utility.conv]
+
+#include <ranges>
+#include <vector>
+#include <testsuite_allocator.h>
+
+void
+test_2_1_5()
+{
+  // (2.1.5) Otherwise, the program is ill-formed.
+
+  using Alloc = __gnu_test::uneq_allocator<int>;
+  using Vec = std::vector<int, Alloc>;
+
+  std::vector<int> v;
+  (void) std::ranges::to<Vec>(v, v.get_allocator()); // { dg-error "here" }
+
+  (void) std::ranges::to<Vec>(Vec{}, 1, 2, 3, 4, 5, 6); // { dg-error "here" }
+}
+
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
+// { dg-prune-output "no matching function" }
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/version.cc b/libstdc++-v3/testsuite/std/ranges/conv/version.cc
new file mode 100644
index 00000000000..33736807eb4
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/version.cc
@@ -0,0 +1,19 @@
+// { dg-do preprocess { target c++23 } }
+// { dg-add-options no_pch }
+
+#include <ranges>
+
+#ifndef __cpp_lib_ranges_to_container
+# error "Feature test macro for ranges_to_container is missing in <ranges>"
+#elif __cpp_lib_ranges_to_container < 202202L
+# error "Feature test macro for ranges_to_container has wrong value in <ranges>"
+#endif
+
+#undef __cpp_lib_ranges_to_container
+#include <version>
+
+#ifndef __cpp_lib_ranges_to_container
+# error "Feature test macro for ranges_to_container is missing in <version>"
+#elif __cpp_lib_ranges_to_container < 202202L
+# error "Feature test macro for ranges_to_container has wrong value in <version>"
+#endif
