{"id":2226179,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2226179/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhub4k2xwo.gcc.gcc-TEST.redi.11.1.1@forge-stage.sourceware.org/","project":{"id":17,"url":"http://patchwork.ozlabs.org/api/1.1/projects/17/?format=json","name":"GNU Compiler Collection","link_name":"gcc","list_id":"gcc-patches.gcc.gnu.org","list_email":"gcc-patches@gcc.gnu.org","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<bmm.hhub4k2xwo.gcc.gcc-TEST.redi.11.1.1@forge-stage.sourceware.org>","date":"2026-04-22T10:21:15","name":"[v1,1/1] libstdc++: Add P1206R7 from_range members to std::list and std::forward_list [PR111055]","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"8f50af2e97a5bf89bee36af098fa2afd7c2f9442","submitter":{"id":93210,"url":"http://patchwork.ozlabs.org/api/1.1/people/93210/?format=json","name":"Jonathan Wakely via Sourceware Forge","email":"forge-bot+redi@forge-stage.sourceware.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/gcc/patch/bmm.hhub4k2xwo.gcc.gcc-TEST.redi.11.1.1@forge-stage.sourceware.org/mbox/","series":[{"id":500963,"url":"http://patchwork.ozlabs.org/api/1.1/series/500963/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/list/?series=500963","date":"2026-04-22T10:21:14","name":"libstdc++: Add P1206R7 from_range members to std::list and std::forward_list [PR111055]","version":1,"mbox":"http://patchwork.ozlabs.org/series/500963/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2226179/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2226179/checks/","tags":{},"headers":{"Return-Path":"<gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":["incoming@patchwork.ozlabs.org","gcc-patches@gcc.gnu.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","gcc-patches@gcc.gnu.org"],"Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org;\n receiver=patchwork.ozlabs.org)","sourceware.org; dmarc=none (p=none dis=none)\n header.from=forge-stage.sourceware.org","sourceware.org;\n spf=pass smtp.mailfrom=forge-stage.sourceware.org","server2.sourceware.org;\n arc=none smtp.remote-ip=38.145.34.39"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0wWn0rW0z1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 20:32:05 +1000 (AEST)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 135B04BB592A\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 10:32:02 +0000 (GMT)","from forge-stage.sourceware.org (vm08.sourceware.org [38.145.34.39])\n by sourceware.org (Postfix) with ESMTPS id DFE614BB3BEF\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 10:22:06 +0000 (GMT)","from forge-stage.sourceware.org (localhost [IPv6:::1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256)\n (No client certificate requested)\n by forge-stage.sourceware.org (Postfix) with ESMTPS id BB68640568\n for <gcc-patches@gcc.gnu.org>; Wed, 22 Apr 2026 10:22:06 +0000 (UTC)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 135B04BB592A","OpenDKIM Filter v2.11.0 sourceware.org DFE614BB3BEF"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org DFE614BB3BEF","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org DFE614BB3BEF","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776853327; cv=none;\n b=FRwz4PtfwJdCTYekf/rmkgUpSuYpvOhRoUiDbLPkntkY4i2DFaT+jnkn+4Cad5bfui7puuYnNNNo7E5RbwsUW1oLiGptdAyc5jA36/3w5KYK8MMfRpBKh1jXmdowh0ONIZLaQSl+QGkJJQbhqGH5qSf5od6UUEMvwRCfLGQzMXQ=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1776853327; c=relaxed/simple;\n bh=eQVIvF5hTTWUx+7i7w3NIcq1WxkosXP20KK9UDoRdKY=;\n h=From:Date:Subject:To:Message-ID;\n b=Eck50Xgru5hmembEvo7N0dt9lvNVBuRjoROBjS3DzIWyCvvPujG8GANRh5qQnlQ+F33bjOLfw7q4b/E7hdM3HeB8gBOKWwOivNQqvPmGO1Nwxd2aRVavZJuqLvtxTh70kXPZIFZuQv0VCQ16lxBF6QP3GlWseqsIl6IXPsWJewU=","ARC-Authentication-Results":"i=1; server2.sourceware.org","From":"Jonathan Wakely via Sourceware Forge\n <forge-bot+redi@forge-stage.sourceware.org>","Date":"Wed, 22 Apr 2026 10:21:15 +0000","Subject":"[PATCH v1 1/1] libstdc++: Add P1206R7 from_range members to std::list\n and std::forward_list [PR111055]","To":"gcc-patches mailing list <gcc-patches@gcc.gnu.org>","Message-ID":"\n <bmm.hhub4k2xwo.gcc.gcc-TEST.redi.11.1.1@forge-stage.sourceware.org>","X-Mailer":"batrachomyomachia","X-Requested-Reviewer":"ppalka","X-Pull-Request-Organization":"gcc","X-Pull-Request-Repository":"gcc-TEST","X-Pull-Request":"https://forge.sourceware.org/gcc/gcc-TEST/pulls/11","References":"\n <bmm.hhub4k2xwo.gcc.gcc-TEST.redi.11.1.0@forge-stage.sourceware.org>","In-Reply-To":"\n <bmm.hhub4k2xwo.gcc.gcc-TEST.redi.11.1.0@forge-stage.sourceware.org>","X-Patch-URL":"\n https://forge.sourceware.org/redi/gcc/commit/f2d7cfa0e4f5b5095c7f30d3910d971cdc3848eb","X-BeenThere":"gcc-patches@gcc.gnu.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Gcc-patches mailing list <gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<https://gcc.gnu.org/mailman/options/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe>","List-Archive":"<https://gcc.gnu.org/pipermail/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-request@gcc.gnu.org?subject=help>","List-Subscribe":"<https://gcc.gnu.org/mailman/listinfo/gcc-patches>,\n <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe>","Reply-To":"gcc-patches mailing list <gcc-patches@gcc.gnu.org>, redi@gcc.gnu.org","Errors-To":"gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org"},"content":"From: Jonathan Wakely <jwakely@redhat.com>\n\nThis is another piece of P1206R7, adding new members to std::list and\nstd::forward_list.\n\nlibstdc++-v3/ChangeLog:\n\n\tPR libstdc++/111055\n\t* include/bits/forward_list.h\n\t(forward_list(from_range, R&&, const Alloc&), assign_range)\n\t(prepend_range, insert_range_after): Define.\n\t* include/bits/stl_list.h: (list(from_range, R&&, const Alloc&))\n\t(assign_range, prepend_range, append_range, insert_range):\n\tDefine.\n\t* testsuite/23_containers/forward_list/cons/from_range.cc: New\n\ttest.\n\t* testsuite/23_containers/forward_list/modifiers/assign_range.cc:\n\tNew test.\n\t* testsuite/23_containers/forward_list/modifiers/insert_range_after.cc:\n\tNew test.\n\t* testsuite/23_containers/forward_list/modifiers/prepend_range.cc:\n\tNew test.\n\t* testsuite/23_containers/list/cons/from_range.cc: New test.\n\t* testsuite/23_containers/list/modifiers/append_range.cc: New\n\ttest.\n\t* testsuite/23_containers/list/modifiers/assign/assign_range.cc:\n\tNew test.\n\t* testsuite/23_containers/list/modifiers/insert/insert_range.cc:\n\tNew test.\n\t* testsuite/23_containers/list/modifiers/prepend_range.cc: New\n\ttest.\n---\n libstdc++-v3/include/bits/forward_list.h      | 121 +++++++++++++++++\n libstdc++-v3/include/bits/stl_list.h          | 126 ++++++++++++++++++\n .../forward_list/cons/from_range.cc           | 100 ++++++++++++++\n .../forward_list/modifiers/assign_range.cc    |  97 ++++++++++++++\n .../modifiers/insert_range_after.cc           |  93 +++++++++++++\n .../forward_list/modifiers/prepend_range.cc   |  86 ++++++++++++\n .../23_containers/list/cons/from_range.cc     | 100 ++++++++++++++\n .../list/modifiers/append_range.cc            |  86 ++++++++++++\n .../list/modifiers/assign/assign_range.cc     |  99 ++++++++++++++\n .../list/modifiers/insert/insert_range.cc     |  98 ++++++++++++++\n .../list/modifiers/prepend_range.cc           |  86 ++++++++++++\n 11 files changed, 1092 insertions(+)\n create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/cons/from_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/modifiers/assign_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/modifiers/insert_range_after.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/forward_list/modifiers/prepend_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/cons/from_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/modifiers/append_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/modifiers/assign/assign_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/modifiers/insert/insert_range.cc\n create mode 100644 libstdc++-v3/testsuite/23_containers/list/modifiers/prepend_range.cc","diff":"diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h\nindex eee773c02121..6ccf2eb2bffb 100644\n--- a/libstdc++-v3/include/bits/forward_list.h\n+++ b/libstdc++-v3/include/bits/forward_list.h\n@@ -42,6 +42,10 @@\n #include <bits/allocator.h>\n #include <ext/alloc_traits.h>\n #include <ext/aligned_buffer.h>\n+#if __glibcxx_ranges_to_container // C++ >= 23\n+# include <bits/ranges_base.h> // ranges::begin, ranges::distance etc.\n+# include <bits/ranges_util.h> // ranges::subrange\n+#endif\n \n namespace std _GLIBCXX_VISIBILITY(default)\n {\n@@ -564,6 +568,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t: _Base(_Node_alloc_type(__al))\n \t{ _M_range_initialize(__first, __last); }\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Construct a forward_list from a range.\n+       * @param __rg An input range with elements that are convertible to\n+       *             the forward_list's value_type.\n+       * @param __a An allocator.\n+       *\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tforward_list(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())\n+\t: _Base(_Node_alloc_type(__a))\n+\t{\n+\t  _Node_base* __to = &this->_M_impl._M_head;\n+\t  auto __first = ranges::begin(__rg);\n+\t  const auto __last = ranges::end(__rg);\n+\t  for (; __first != __last; ++__first)\n+\t    {\n+\t      __to->_M_next = this->_M_create_node(*__first);\n+\t      __to = __to->_M_next;\n+\t    }\n+\t}\n+#endif // ranges_to_container\n+\n       /**\n        *  @brief  The %forward_list copy constructor.\n        *  @param  __list  A %forward_list of identical element and allocator\n@@ -675,6 +703,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t  _M_assign(__first, __last, __assignable());\n \t}\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Assign a range to a forward_list.\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tvoid\n+\tassign_range(_Rg&& __rg)\n+\t{\n+\t  static_assert(assignable_from<_Tp&, ranges::range_reference_t<_Rg>>);\n+\n+\t  auto __first = ranges::begin(__rg);\n+\t  const auto __last = ranges::end(__rg);\n+\t  iterator __prev = before_begin();\n+\t  iterator __curr = begin();\n+\t  const iterator __end = end();\n+\n+\t  while (__curr != __end && __first != __last)\n+\t    {\n+\t      *__curr = *__first;\n+\t      __prev = __curr;\n+\t      ++__first;\n+\t      ++__curr;\n+\t    }\n+\n+\t  if (__curr != __end)\n+\t    erase_after(__prev, __end);\n+\t  else\n+\t    insert_range_after(__prev,\n+\t\t\t       ranges::subrange(std::move(__first), __last));\n+\t}\n+#endif // ranges_to_container\n+\n       /**\n        *  @brief  Assigns a given value to a %forward_list.\n        *  @param  __n  Number of elements to be assigned.\n@@ -888,6 +949,33 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n       push_front(_Tp&& __val)\n       { this->_M_insert_after(cbefore_begin(), std::move(__val)); }\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Insert a range at the beginning of a forward_list.\n+       * @param __rg An input range with elements that are convertible to\n+       *             the forward_list's value_type.\n+       *\n+       * The inserted elements will be in the same order as in the range,\n+       * so they are not reversed as would happen with a simple loop calling\n+       * emplace_front for each element of the range.\n+       *\n+       * No iterators to existing elements are invalidated by this function.\n+       * If the insertion fails due to an exception, no elements will be added\n+       * and so the list will be unchanged.\n+       *\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tvoid\n+\tprepend_range(_Rg&& __rg)\n+\t{\n+\t  forward_list __tmp(from_range, std::forward<_Rg>(__rg),\n+\t\t\t     get_allocator());\n+\t  if (!__tmp.empty())\n+\t    splice_after(before_begin(), __tmp);\n+\t}\n+#endif // ranges_to_container\n+\n       /**\n        *  @brief  Removes first element.\n        *\n@@ -985,6 +1073,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \tinsert_after(const_iterator __pos,\n \t\t     _InputIterator __first, _InputIterator __last);\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Insert a rangeinto a forward_list.\n+       * @param  __position An iterator.\n+       * @param  __rg An input range of elements that can be converted to\n+       *              the forward_list's value type.\n+       * @return An iterator pointing to the last element inserted,\n+       *         or `__position` if the range is empty.\n+       *\n+       * Inserts the elements of `__rg` after `__position`.\n+       * No iterators to existing elements are invalidated by this function.\n+       * If the insertion fails due to an exception, no elements will be added\n+       * and so the list will be unchanged.\n+       *\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\titerator\n+\tinsert_range_after(const_iterator __position, _Rg&& __rg)\n+\t{\n+\t  forward_list __tmp(from_range, std::forward<_Rg>(__rg),\n+\t\t\t     get_allocator());\n+\t  return _M_splice_after(__position, __tmp.before_begin(), __tmp.end());\n+\t}\n+#endif // ranges_to_container\n+\n       /**\n        *  @brief  Inserts the contents of an initializer_list into\n        *          %forward_list after the specified iterator.\n@@ -1438,6 +1552,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER\n \t   typename = _RequireAllocator<_Allocator>>\n     forward_list(_InputIterator, _InputIterator, _Allocator = _Allocator())\n       -> forward_list<_ValT, _Allocator>;\n+\n+#if __glibcxx_ranges_to_container // C++ >= 23\n+  template<ranges::input_range _Rg,\n+\t   typename _Alloc = allocator<ranges::range_value_t<_Rg>>>\n+    forward_list(from_range_t, _Rg&&, _Alloc = _Alloc())\n+      -> forward_list<ranges::range_value_t<_Rg>, _Alloc>;\n+#endif\n #endif\n \n   /**\ndiff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h\nindex 8b2521960a8f..2da753853ec4 100644\n--- a/libstdc++-v3/include/bits/stl_list.h\n+++ b/libstdc++-v3/include/bits/stl_list.h\n@@ -64,6 +64,10 @@\n #include <bits/allocated_ptr.h>\n #include <ext/aligned_buffer.h>\n #endif\n+#if __glibcxx_ranges_to_container // C++ >= 23\n+# include <bits/ranges_base.h> // ranges::begin, ranges::distance etc.\n+# include <bits/ranges_util.h> // ranges::subrange\n+#endif\n \n namespace std _GLIBCXX_VISIBILITY(default)\n {\n@@ -892,6 +896,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n \t}\n #endif\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Construct a list from a range.\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tlist(from_range_t, _Rg&& __rg, const _Alloc& __a = _Alloc())\n+\t: _Base(_Node_alloc_type(__a))\n+\t{\n+\t  auto __first = ranges::begin(__rg);\n+\t  const auto __last = ranges::end(__rg);\n+\t  for (; __first != __last; ++__first)\n+\t    emplace_back(*__first);\n+\t}\n+#endif\n+\n #if __cplusplus >= 201103L\n       /**\n        *  No explicit dtor needed as the _Base dtor takes care of\n@@ -951,6 +971,30 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n       }\n #endif\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Assign a range to a list.\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tvoid\n+\tassign_range(_Rg&& __rg)\n+\t{\n+\t  iterator __first1 = begin();\n+\t  const iterator __last1 = end();\n+\t  auto __first2 = ranges::begin(__rg);\n+\t  const auto __last2 = ranges::end(__rg);\n+\t  for (; __first1 != __last1 && __first2 != __last2;\n+\t       ++__first1, (void)++__first2)\n+\t    *__first1 = *__first2;\n+\t  if (__first2 == __last2)\n+\t    erase(__first1, __last1);\n+\t  else\n+\t    insert_range(__last1,\n+\t\t\t ranges::subrange(std::move(__first2), __last2));\n+\t}\n+#endif\n+\n       /**\n        *  @brief  Assigns a given value to a %list.\n        *  @param  __n  Number of elements to be assigned.\n@@ -1275,6 +1319,50 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n \t}\n #endif\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Insert a range at the beginning of a list.\n+       * @param  __rg An input range of elements that can be converted to\n+       *              the list's value type.\n+       *\n+       * Inserts the elements of `__rg` at the beginning of the list.\n+       * No iterators to existing elements are invalidated by this function.\n+       * If the insertion fails due to an exception, no elements will be added\n+       * and so the list will be unchanged.\n+       *\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tvoid\n+\tprepend_range(_Rg&& __rg)\n+\t{\n+\t  list __tmp(from_range, std::forward<_Rg>(__rg), get_allocator());\n+\t  if (!__tmp.empty())\n+\t    splice(begin(), __tmp);\n+\t}\n+\n+      /**\n+       * @brief Insert a range at the end of a list.\n+       * @param  __rg An input range of elements that can be converted to\n+       *              the list's value type.\n+       *\n+       * Inserts the elements of `__rg` at the end of the list.\n+       * No iterators to existing elements are invalidated by this function.\n+       * If the insertion fails due to an exception, no elements will be added\n+       * and so the list will be unchanged.\n+       *\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\tvoid\n+\tappend_range(_Rg&& __rg)\n+\t{\n+\t  list __tmp(from_range, std::forward<_Rg>(__rg), get_allocator());\n+\t  if (!__tmp.empty())\n+\t    splice(end(), __tmp);\n+\t}\n+#endif\n+\n       /**\n        *  @brief  Removes first element.\n        *\n@@ -1505,6 +1593,37 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n \t}\n #endif\n \n+#if __glibcxx_ranges_to_container // C++ >= 23\n+      /**\n+       * @brief Insert a range into a list.\n+       * @param  __position An iterator.\n+       * @param  __rg An input range of elements that can be converted to\n+       *              the list's value type.\n+       * @return An iterator pointing to the first element inserted,\n+       *         or `__position` if the range is empty.\n+       *\n+       * Inserts the elements of `__rg` before `__position`.\n+       * No iterators to existing elements are invalidated by this function.\n+       * If the insertion fails due to an exception, no elements will be added\n+       * and so the list will be unchanged.\n+       *\n+       * @since C++23\n+       */\n+      template<__detail::__container_compatible_range<_Tp> _Rg>\n+\titerator\n+\tinsert_range(const_iterator __position, _Rg&& __rg)\n+\t{\n+\t  list __tmp(from_range, std::forward<_Rg>(__rg), get_allocator());\n+\t  if (!__tmp.empty())\n+\t    {\n+\t      auto __it = __tmp.begin();\n+\t      splice(__position, __tmp);\n+\t      return __it;\n+\t    }\n+\t  return __position._M_const_cast();\n+\t}\n+#endif\n+\n       /**\n        *  @brief  Remove element at given position.\n        *  @param  __position  Iterator pointing to element to be erased.\n@@ -2102,6 +2221,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11\n \t   typename = _RequireAllocator<_Allocator>>\n     list(_InputIterator, _InputIterator, _Allocator = _Allocator())\n       -> list<_ValT, _Allocator>;\n+\n+#if __glibcxx_ranges_to_container // C++ >= 23\n+  template<ranges::input_range _Rg,\n+\t   typename _Alloc = allocator<ranges::range_value_t<_Rg>>>\n+    list(from_range_t, _Rg&&, _Alloc = _Alloc())\n+      -> list<ranges::range_value_t<_Rg>, _Alloc>;\n+#endif\n #endif\n \n _GLIBCXX_END_NAMESPACE_CXX11\ndiff --git a/libstdc++-v3/testsuite/23_containers/forward_list/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/forward_list/cons/from_range.cc\nnew file mode 100644\nindex 000000000000..65b378e69773\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/forward_list/cons/from_range.cc\n@@ -0,0 +1,100 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <forward_list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+void\n+test_deduction_guide(long* p)\n+{\n+  __gnu_test::test_input_range<long> r(p, p);\n+  std::forward_list v(std::from_range, r);\n+  static_assert(std::is_same_v<decltype(v), std::forward_list<long>>);\n+\n+  using Alloc = __gnu_test::SimpleAllocator<long>;\n+  Alloc alloc;\n+  std::forward_list v2(std::from_range, r, alloc);\n+  static_assert(std::is_same_v<decltype(v2), std::forward_list<long, Alloc>>);\n+}\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test(Alloc alloc)\n+{\n+  // The forward_list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::forward_list<V, Alloc>& l, std::span<T> r) {\n+    if (std::distance(l.begin(), l.end()) != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::forward_list<V, Alloc> v0(std::from_range, Range(a, a+0));\n+  VERIFY( v0.empty() );\n+  VERIFY( v0.get_allocator() == Alloc() );\n+\n+  std::forward_list<V, Alloc> v4(std::from_range, Range(a, a+4));\n+  VERIFY( eq(v4, {a, 4}) );\n+  VERIFY( v4.get_allocator() == Alloc() );\n+\n+  std::forward_list<V, Alloc> v9(std::from_range, Range(a, a+9), alloc);\n+  VERIFY( eq(v9, {a, 9}) );\n+  VERIFY( v9.get_allocator() == alloc );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range>(std::allocator<int>());\n+  do_test<Range>(__gnu_test::uneq_allocator<int>(42));\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to bool\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range>(std::allocator<int>());\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/assign_range.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/assign_range.cc\nnew file mode 100644\nindex 000000000000..d8352539724b\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/assign_range.cc\n@@ -0,0 +1,97 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <forward_list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The forward_list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::forward_list<V, Alloc>& l, std::span<T> r) {\n+    if (std::distance(l.begin(), l.end()) != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  // assign to empty forward_list\n+  std::forward_list<V, Alloc> v;\n+  v.assign_range(Range(a, a));\n+  VERIFY( v.empty() );\n+  v.assign_range(Range(a, a+4));\n+  VERIFY( eq(v, {a, 4}) );\n+  v.clear();\n+  v.assign_range(Range(a));\n+  VERIFY( eq(v, a) );\n+\n+  // assign to non-empty forward_list\n+  v.assign_range(Range(a, a+4));\n+  VERIFY( eq(v, {a, 4}) );\n+  v.assign_range(Range(a)); // larger than size()\n+  VERIFY( eq(v, a) );\n+  v.assign_range(Range(a, a+4)); // smaller than size()\n+  VERIFY( eq(v, {a, 4}) );\n+  v.assign_range(Range(a+2, a+6)); // equal to size()\n+  VERIFY( eq(v, {a+2, 4}) );\n+  v.assign_range(Range(a, a));\n+  VERIFY( v.empty() );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/insert_range_after.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/insert_range_after.cc\nnew file mode 100644\nindex 000000000000..32580a6ed1e2\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/insert_range_after.cc\n@@ -0,0 +1,93 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <forward_list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The forward_list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::forward_list<V, Alloc>& l, std::span<T> r) {\n+    if (std::distance(l.begin(), l.end()) != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::forward_list<V, Alloc> v;\n+  v.insert_range_after(v.before_begin(), Range(a, a));\n+  VERIFY( v.empty() );\n+  v.insert_range_after(v.before_begin(), Range(a, a+4));\n+  VERIFY( eq(v, {a, a+4}) );\n+  v.clear();\n+  v.insert_range_after(v.before_begin(), Range(a+4, a+9));\n+  VERIFY( eq(v, {a+4, a+9}) );\n+  v.insert_range_after(v.before_begin(), Range(a, a+4));\n+  VERIFY( eq(v, a) );\n+  v.clear();\n+  v.insert_range_after(v.before_begin(), Range(a, a+3));\n+  v.insert_range_after(std::next(v.before_begin(), 3), Range(a+6, a+9));\n+  v.insert_range_after(std::next(v.before_begin(), 3), Range(a+3, a+6));\n+  VERIFY( eq(v, a) );\n+  v.insert_range_after(std::next(v.before_begin(), 2), Range(a, a));\n+  VERIFY( eq(v, a) );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/prepend_range.cc b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/prepend_range.cc\nnew file mode 100644\nindex 000000000000..ae38fb7e791f\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/forward_list/modifiers/prepend_range.cc\n@@ -0,0 +1,86 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <forward_list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The forward_list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::forward_list<V, Alloc>& l, std::span<T> r) {\n+    if (std::distance(l.begin(), l.end()) != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::forward_list<V, Alloc> v;\n+  v.prepend_range(Range(a+4, a+9));\n+  VERIFY( eq(v, {a+4, 5}) );\n+  v.prepend_range(Range(a, a+4));\n+  VERIFY( eq(v, a) );\n+  v.prepend_range(Range(a, a));\n+  VERIFY( eq(v, a) );\n+  v.clear();\n+  v.prepend_range(Range(a, a));\n+  VERIFY( v.empty() );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/cons/from_range.cc b/libstdc++-v3/testsuite/23_containers/list/cons/from_range.cc\nnew file mode 100644\nindex 000000000000..31448b9122b4\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/cons/from_range.cc\n@@ -0,0 +1,100 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+void\n+test_deduction_guide(long* p)\n+{\n+  __gnu_test::test_input_range<long> r(p, p);\n+  std::list v(std::from_range, r);\n+  static_assert(std::is_same_v<decltype(v), std::list<long>>);\n+\n+  using Alloc = __gnu_test::SimpleAllocator<long>;\n+  Alloc alloc;\n+  std::list v2(std::from_range, r, alloc);\n+  static_assert(std::is_same_v<decltype(v2), std::list<long, Alloc>>);\n+}\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test(Alloc alloc)\n+{\n+  // The list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::list<V, Alloc>& l, std::span<T> r) {\n+    if (l.size() != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::list<V, Alloc> v0(std::from_range, Range(a, a+0));\n+  VERIFY( v0.empty() );\n+  VERIFY( v0.get_allocator() == Alloc() );\n+\n+  std::list<V, Alloc> v4(std::from_range, Range(a, a+4));\n+  VERIFY( eq(v4, {a, 4}) );\n+  VERIFY( v4.get_allocator() == Alloc() );\n+\n+  std::list<V, Alloc> v9(std::from_range, Range(a, a+9), alloc);\n+  VERIFY( eq(v9, {a, 9}) );\n+  VERIFY( v9.get_allocator() == alloc );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range>(std::allocator<int>());\n+  do_test<Range>(__gnu_test::uneq_allocator<int>(42));\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to bool\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range>(std::allocator<int>());\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/append_range.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/append_range.cc\nnew file mode 100644\nindex 000000000000..9ddfc7dbea38\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/append_range.cc\n@@ -0,0 +1,86 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::list<V, Alloc>& l, std::span<T> r) {\n+    if (l.size() != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::list<V, Alloc> v;\n+  v.append_range(Range(a, a+4));\n+  VERIFY( eq(v, {a, 4}) );\n+  v.append_range(Range(a+4, a+9));\n+  VERIFY( eq(v, a) );\n+  v.append_range(Range(a, a));\n+  VERIFY( eq(v, a) );\n+  v.clear();\n+  v.append_range(Range(a, a));\n+  VERIFY( v.empty() );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/assign/assign_range.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/assign/assign_range.cc\nnew file mode 100644\nindex 000000000000..84b9f07a8eb3\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/assign/assign_range.cc\n@@ -0,0 +1,99 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::list<V, Alloc>& l, std::span<T> r) {\n+    if (l.size() != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  // assign to empty list\n+  std::list<V, Alloc> v;\n+  v.assign_range(Range(a, a));\n+  VERIFY( v.empty() );\n+  v.assign_range(Range(a, a+4));\n+  VERIFY( eq(v, {a, 4}) );\n+  v.clear();\n+  v.assign_range(Range(a));\n+  VERIFY( eq(v, a) );\n+\n+  // assign to non-empty list\n+  v.assign_range(Range(a, a+4));\n+  VERIFY( eq(v, {a, 4}) );\n+  v.assign_range(Range(a)); // larger than size()\n+  VERIFY( eq(v, a) );\n+  v.assign_range(Range(a, a+4)); // smaller than size()\n+  VERIFY( eq(v, {a, 4}) );\n+  v.clear();\n+  v.resize(4);\n+  v.assign_range(Range(a, a+4)); // equal to size()\n+  VERIFY( eq(v, {a, 4}) );\n+  v.assign_range(Range(a, a));\n+  VERIFY( v.empty() );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/insert_range.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/insert_range.cc\nnew file mode 100644\nindex 000000000000..a15d51d74668\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/insert_range.cc\n@@ -0,0 +1,98 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::list<V, Alloc>& l, std::span<T> r) {\n+    if (l.size() != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::list<V, Alloc> v;\n+  v.insert_range(v.begin(), Range(a, a));\n+  VERIFY( v.empty() );\n+  v.insert_range(v.begin(), Range(a, a+4));\n+  VERIFY( eq(v, {a, a+4}) );\n+  v.clear();\n+  v.insert_range(v.begin(), Range(a+4, a+9));\n+  VERIFY( eq(v, {a+4, a+9}) );\n+  v.insert_range(v.begin(), Range(a, a+4));\n+  VERIFY( eq(v, a) );\n+  v.clear();\n+  v.insert_range(v.begin(), Range(a, a+3));\n+  v.insert_range(v.end(), Range(a+6, a+9));\n+  v.insert_range(std::next(v.begin(), 3), Range(a+3, a+6));\n+  VERIFY( eq(v, a) );\n+  v.resize(3);\n+  v.insert_range(std::next(v.begin()), Range(a+4, a+9));\n+  v.insert_range(std::next(v.begin()), Range(a+1, a+4));\n+  v.resize(9);\n+  VERIFY( eq(v, a) );\n+  v.insert_range(std::next(v.begin(), 6), Range(a, a));\n+  VERIFY( eq(v, a) );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\ndiff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/prepend_range.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/prepend_range.cc\nnew file mode 100644\nindex 000000000000..fe217e195731\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/prepend_range.cc\n@@ -0,0 +1,86 @@\n+// { dg-do run { target c++23 } }\n+\n+#include <list>\n+#include <span>\n+#include <testsuite_hooks.h>\n+#include <testsuite_iterators.h>\n+#include <testsuite_allocator.h>\n+\n+template<typename Range, typename Alloc>\n+constexpr void\n+do_test()\n+{\n+  // The list's value_type.\n+  using V = typename std::allocator_traits<Alloc>::value_type;\n+\n+  // The range's value_type.\n+  using T = std::ranges::range_value_t<Range>;\n+  T a[]{1,2,3,4,5,6,7,8,9};\n+\n+  auto eq = [](const std::list<V, Alloc>& l, std::span<T> r) {\n+    if (l.size() != r.size())\n+      return false;\n+    unsigned i = 0;\n+    for (auto& e : l)\n+      if (e != r[i++])\n+\treturn false;\n+    return true;\n+  };\n+\n+  std::list<V, Alloc> v;\n+  v.prepend_range(Range(a+4, a+9));\n+  VERIFY( eq(v, {a+4, 5}) );\n+  v.prepend_range(Range(a, a+4));\n+  VERIFY( eq(v, a) );\n+  v.prepend_range(Range(a, a));\n+  VERIFY( eq(v, a) );\n+  v.clear();\n+  v.prepend_range(Range(a, a));\n+  VERIFY( v.empty() );\n+}\n+\n+template<typename Range>\n+void\n+do_test_a()\n+{\n+  do_test<Range, std::allocator<int>>();\n+  do_test<Range, __gnu_test::SimpleAllocator<int>>();\n+}\n+\n+bool\n+test_ranges()\n+{\n+  using namespace __gnu_test;\n+\n+  do_test_a<test_forward_range<int>>();\n+  do_test_a<test_forward_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, forward_iterator_wrapper>>();\n+\n+  do_test_a<test_input_range<int>>();\n+  do_test_a<test_input_sized_range<int>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper>>();\n+\n+  do_test_a<test_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range<int, input_iterator_wrapper_nocopy>>();\n+  do_test_a<test_sized_range_sized_sent<int, input_iterator_wrapper_nocopy>>();\n+\n+  do_test_a<test_forward_range<short>>();\n+  do_test_a<test_input_range<short>>();\n+\n+  // Not lvalue-convertible to int\n+  struct C {\n+    C(int v) : val(v) { }\n+    operator int() && { return val; }\n+    bool operator==(int b) const { return b == val; }\n+    int val;\n+  };\n+  using rvalue_input_range = test_range<C, input_iterator_wrapper_rval>;\n+  do_test<rvalue_input_range, std::allocator<int>>();\n+\n+  return true;\n+}\n+\n+int main()\n+{\n+  test_ranges();\n+}\n","prefixes":["v1","1/1"]}