https://gcc.gnu.org/g:8b95d5f5b22621da6a5f0d6e07e7d9bf8d270a6d

commit r16-8429-g8b95d5f5b22621da6a5f0d6e07e7d9bf8d270a6d
Author: Tomasz Kamiński <[email protected]>
Date:   Thu Apr 2 12:00:01 2026 +0200

    libstdc++: Updated inplace_vector::try_ functions per P3981R2 and P4022R0.
    
    This paper removes the try_append_range from inplace_vector and changes the
    return type of try_emplace_back and try_push_back to optional<_Tp&> per:
    P4022R0: Remove try_append_range from inplace_vector for now.
    P3981R2: Better return types in std::inplace_vector and 
std::exception_ptr_cast.
    
    The test are also expanded to cover type Y, that is convertible to 
optional<Y&>,
    and require return type to be constructed using in_place.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/version.def (inplace_vector): Bump to 202603.
            * include/bits/version.h: Regenerate.
            * include/std/inplace_vector (inplace_vector::try_emplace_back)
            (inplace_vector::try_push_back): Change return type to 
optional<_Tp&>
            and adjust implementation accordingly.
            (inplace_vector::try_append_range): Remove.
            * include/debug/inplace_vector (inplace_vector::try_emplace_back)
            (inplace_vector::try_push_back, inplace_vector::try_append_range):
            Likewise.
            * testsuite/23_containers/inplace_vector/modifiers/single_insert.cc:
            Updated check for the optional<T&> return. Added test for type
            convertible to optional<T&>
            * 
testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc:
            Use has_value() to check if engaged optional is returned.
            * 
testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc:
            Likewise.
            * testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
            Remove try_append_range tests.
            * 
testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc:
            Removed.
            * testsuite/23_containers/inplace_vector/version.cc: Updated 
expected
            feature test macro value.
    
    Reviewed-by: Jonathan Wakely <[email protected]>
    Signed-off-by: Tomasz Kamiński <[email protected]>

Diff:
---
 libstdc++-v3/include/bits/version.def              |  5 +-
 libstdc++-v3/include/bits/version.h                |  4 +-
 libstdc++-v3/include/debug/inplace_vector          | 26 +++-----
 libstdc++-v3/include/std/inplace_vector            | 70 ++++++----------------
 .../debug/invalidation/try_append_range.cc         | 45 --------------
 .../debug/invalidation/try_emplace_back.cc         |  2 +-
 .../debug/invalidation/try_push_back.cc            |  4 +-
 .../inplace_vector/modifiers/multi_insert.cc       | 46 --------------
 .../inplace_vector/modifiers/single_insert.cc      | 41 +++++++++----
 .../23_containers/inplace_vector/version.cc        |  4 +-
 10 files changed, 66 insertions(+), 181 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index ada8da88bc52..998223306e25 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -2223,9 +2223,12 @@ ftms = {
 };
 
 ftms = {
+  // 202406 P0843R14 inplace_vector 
+  // 202603 P3981R2 Better return types in std::inplace_vector and 
std::exception_ptr_cast
+  //        P4022R0 Remove try_append_range from inplace_vector for now
   name = inplace_vector;
   values = {
-    v = 202406;
+    v = 202603;
     cxxmin = 26;
   };
 };
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 0490e79dd416..cb3b9b0997e8 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2488,9 +2488,9 @@
 
 #if !defined(__cpp_lib_inplace_vector)
 # if (__cplusplus >  202302L)
-#  define __glibcxx_inplace_vector 202406L
+#  define __glibcxx_inplace_vector 202603L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_inplace_vector)
-#   define __cpp_lib_inplace_vector 202406L
+#   define __cpp_lib_inplace_vector 202603L
 #  endif
 # endif
 #endif /* !defined(__cpp_lib_inplace_vector) */
diff --git a/libstdc++-v3/include/debug/inplace_vector 
b/libstdc++-v3/include/debug/inplace_vector
index 750b0a7343ca..e579e8636f98 100644
--- a/libstdc++-v3/include/debug/inplace_vector
+++ b/libstdc++-v3/include/debug/inplace_vector
@@ -338,11 +338,12 @@ namespace __debug
       }
 
       template<typename... _Args>
-       constexpr _Tp*
+       constexpr optional<_Tp&>
        try_emplace_back(_Args&&... __args)
        {
          auto __end = _Base::cend();
-         _Tp* __res = _Base::try_emplace_back(std::forward<_Args>(__args)...);
+         optional<_Tp&> __res
+           = _Base::try_emplace_back(std::forward<_Args>(__args)...);
 
          if (__res)
            this->_M_invalidate_if(_Equal(__end));
@@ -350,11 +351,11 @@ namespace __debug
          return __res;
        }
 
-      constexpr _Tp*
+      constexpr optional<_Tp&>
       try_push_back(const _Tp& __x)
       {
        const auto __end = _Base::cend();
-       _Tp* __res = _Base::try_push_back(__x);
+       optional<_Tp&> __res = _Base::try_push_back(__x);
 
        if (__res)
          this->_M_invalidate_if(_Equal(__end));
@@ -362,11 +363,11 @@ namespace __debug
        return __res;
       }
 
-      constexpr _Tp*
+      constexpr optional<_Tp&>
       try_push_back(_Tp&& __x)
       {
        const auto __end = _Base::cend();
-       _Tp* __res = _Base::try_push_back(std::move(__x));
+       optional<_Tp&> __res = _Base::try_push_back(std::move(__x));
 
        if (__res)
          this->_M_invalidate_if(_Equal(__end));
@@ -374,19 +375,6 @@ namespace __debug
        return __res;
       }
 
-      template<__detail::__container_compatible_range<_Tp> _Rg>
-       constexpr ranges::borrowed_iterator_t<_Rg>
-       try_append_range(_Rg&& __rg)
-       {
-         const auto __size = size();
-         const auto __end = _Base::cend();
-         auto __res = _Base::try_append_range(__rg);
-         if (size() != __size)
-           this->_M_invalidate_if(_Equal(__end));
-
-         return __res;
-       }
-
       template<typename... _Args>
        constexpr _Tp&
        unchecked_emplace_back(_Args&&... __args)
diff --git a/libstdc++-v3/include/std/inplace_vector 
b/libstdc++-v3/include/std/inplace_vector
index c22a9e1f9b40..5ad92332a02c 100644
--- a/libstdc++-v3/include/std/inplace_vector
+++ b/libstdc++-v3/include/std/inplace_vector
@@ -38,6 +38,7 @@
 #ifdef __glibcxx_inplace_vector // C++ >= 26
 #include <compare>
 #include <initializer_list>
+#include <optional>
 #include <bits/stdexcept_throw.h>
 #include <bits/range_access.h>
 #include <bits/ranges_base.h> // borrowed_iterator_t, 
__detail::__container_compatible_range
@@ -550,63 +551,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       }
 
       template<typename... _Args>
-       constexpr _Tp*
+       constexpr optional<_Tp&>
        try_emplace_back(_Args&&... __args)
        {
          if (_M_size >= _Nm) [[unlikely]]
-           return nullptr;
-         auto& __r = unchecked_emplace_back(std::forward<_Args>(__args)...);
-         return __builtin_addressof(__r);
+           return nullopt;
+         return optional<_Tp&>(in_place,
+                  unchecked_emplace_back(std::forward<_Args>(__args)...));
        }
 
-      constexpr _Tp*
+      constexpr optional<_Tp&>
       try_push_back(const _Tp& __x)
       {
        if (_M_size >= _Nm) [[unlikely]]
-         return nullptr;
-       return __builtin_addressof(unchecked_emplace_back(__x));
+         return nullopt;
+       return optional<_Tp&>(in_place, unchecked_emplace_back(__x));
       }
 
-      constexpr _Tp*
+      constexpr optional<_Tp&>
       try_push_back(_Tp&& __x)
       {
        if (_M_size >= _Nm) [[unlikely]]
-         return nullptr;
-       return __builtin_addressof(unchecked_emplace_back(std::move(__x)));
+         return nullopt;
+       return optional<_Tp&>(in_place, unchecked_emplace_back(std::move(__x)));
       }
 
-      template<__detail::__container_compatible_range<_Tp> _Rg>
-       constexpr ranges::borrowed_iterator_t<_Rg>
-       try_append_range(_Rg&& __rg)
-       {
-         if constexpr (ranges::sized_range<_Rg>)
-           {
-             auto __n = ranges::distance(__rg);
-             if (__n == 0) [[unlikely]]
-               return ranges::begin(__rg);
-
-             const auto __end = data() + _M_size;
-             const size_t __avail = _Nm - size();
-             if (__n <= __avail)
-               _M_size += size_type(__n);
-             else
-               {
-                 __n = __avail;
-                 _M_size = _Nm;
-               }
-             return ranges::uninitialized_copy_n(
-                      ranges::begin(__rg), __n,
-                      __end, unreachable_sentinel).in;
-           }
-         else
-           {
-             ranges::subrange<pointer> __tail(data() + _M_size, data() + _Nm);
-             auto [__in, __out] = ranges::uninitialized_copy(__rg, __tail);
-             _M_size = __out - data();
-             return std::move(__in);
-           }
-       }
-
       template<typename... _Args>
        constexpr _Tp&
        unchecked_emplace_back(_Args&&... __args)
@@ -1208,22 +1177,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
       { __builtin_trap(); }
 
       template<typename... _Args>
-       constexpr _Tp*
+        constexpr optional<_Tp&>
        try_emplace_back(_Args&&...)
-       { return nullptr; }
+       { return nullopt; }
 
-      constexpr _Tp*
+      constexpr optional<_Tp&>
       try_push_back(const _Tp&)
-      { return nullptr; }
+      { return nullopt; }
 
-      constexpr _Tp*
+      constexpr optional<_Tp&>
       try_push_back(_Tp&&)
-      { return nullptr; }
-
-      template<__detail::__container_compatible_range<_Tp> _Rg>
-       constexpr ranges::borrowed_iterator_t<_Rg>
-       try_append_range(_Rg&& __rg)
-       { return ranges::begin(__rg); }
+      { return nullopt; }
 
       template<typename... _Args>
        [[noreturn]]
diff --git 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc
 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc
deleted file mode 100644
index ae4ac418f501..000000000000
--- 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// { dg-do run { target c++26 } }
-
-#include <debug/inplace_vector>
-#include <testsuite_hooks.h>
-
-using __gnu_debug::inplace_vector;
-
-void test01()
-{
-  inplace_vector<int, 100> v(10, 17);
-  inplace_vector<int, 10> v1(10, 19);
-
-  auto before = v.begin() + 6;
-  auto last = v.end();
-  auto end = last--;
-
-  v.try_append_range(v1);
-
-  VERIFY(before._M_dereferenceable());
-  VERIFY(last._M_dereferenceable());
-  VERIFY(end._M_singular());
-}
-
-void test02()
-{
-  inplace_vector<int, 100> v(10, 17);
-  inplace_vector<int, 0> v1;
-
-  auto before = v.begin() + 6;
-  auto last = v.end();
-  auto end = last--;
-
-  v.try_append_range(v1);
-
-  VERIFY(before._M_dereferenceable());
-  VERIFY(last._M_dereferenceable());
-  VERIFY(!end._M_singular());
-}
-
-int main()
-{
-  test01();
-  test02();
-  return 0;
-}
diff --git 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc
 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc
index f7c8c7a9ba20..606d478a0dce 100644
--- 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_emplace_back.cc
@@ -13,7 +13,7 @@ void test01()
   auto last = v.end();
   auto end = last--;
 
-  VERIFY( v.try_emplace_back(42) != nullptr );
+  VERIFY( v.try_emplace_back(42).has_value() );
 
   VERIFY(before._M_dereferenceable());
   VERIFY(last._M_dereferenceable());
diff --git 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc
 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc
index 04fc010e5003..96af2b65b725 100644
--- 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_push_back.cc
@@ -14,7 +14,7 @@ void test01()
   auto last = v.end();
   auto end = last--;
 
-  VERIFY( v.try_push_back(42) != nullptr );
+  VERIFY( v.try_push_back(42).has_value() );
 
   VERIFY(before._M_dereferenceable());
   VERIFY(last._M_dereferenceable());
@@ -30,7 +30,7 @@ void test02()
   auto last = v.end();
   auto end = last--;
 
-  VERIFY( v.try_push_back(std::move(vv)) != nullptr );
+  VERIFY( v.try_push_back(std::move(vv)).has_value() );
 
   VERIFY(before._M_dereferenceable());
   VERIFY(last._M_dereferenceable());
diff --git 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc
index 454163892add..e5a482cdc65d 100644
--- 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc
@@ -54,16 +54,6 @@ test_add_to_full_it()
 
   std::inplace_vector<T, N> v(std::from_range, std::span(a, a+N));
 
-  Range r1(a, a);
-  auto rit1 = v.try_append_range(r1);
-  VERIFY( eq<T>(v, {a, N}) );
-  VERIFY( rit1.base() == a );
-
-  SizedRange r2(a, a);
-  auto rit2 = v.try_append_range(r2);
-  VERIFY( eq<T>(v, {a, N}) );
-  VERIFY( rit2.base() == a );
-
   v.append_range(Range(a, a));
   VERIFY( eq<T>(v, {a, N}) );
   v.append_range(SizedRange(a, a));
@@ -93,17 +83,6 @@ test_add_to_full_it()
   VERIFY( eq<T>(v, {a, N}) );
   VERIFY( it == v.begin() );
 
-  // Inserting non-empty range
-  Range r3(a+3, a+5);
-  auto rit3 = v.try_append_range(r3);
-  VERIFY( eq<T>(v, {a, N}) );
-  VERIFY( rit3.base() == a+3 );
-
-  SizedRange r4(a+2, a+5);
-  auto rit4 = v.try_append_range(r4);
-  VERIFY( eq<T>(v, {a, N}) );
-  VERIFY( rit4.base() == a+2 );
-
 #ifdef __cpp_exceptions
 #ifndef __cpp_lib_constexpr_exceptions
   if consteval {
@@ -265,30 +244,6 @@ test_append_range()
 #endif
 }
 
-template<typename Range>
-constexpr void
-test_try_append_range()
-{
-  using T = std::ranges::range_value_t<Range>;
-  T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
-
-  std::inplace_vector<T, 20> v;
-  Range r1 = Range(a, a+10);
-  auto it1 = v.try_append_range(r1);
-  VERIFY( eq<T>(v, {a, 10}) );
-  VERIFY( it1.base() == a+10 );
-
-  Range r2 = Range(a+10, a+15);
-  auto it2 = v.try_append_range(r2);
-  VERIFY( eq<T>(v, {a, 15}) );
-  VERIFY( it2.base() == a+15 );
-
-  Range r3 = Range(a+15, a+25);
-  auto it3 = v.try_append_range(r3);
-  VERIFY( eq<T>(v, {a, 20}) );
-  VERIFY( it3.base() == a+20 );
-}
-
 template<typename Range>
 constexpr void
 test_insert_range()
@@ -357,7 +312,6 @@ constexpr void
 do_test_ranges()
 {
   test_append_range<Range>();
-  test_try_append_range<Range>();
   test_insert_range<Range>();
 }
 
diff --git 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc
 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc
index 92bd765982e2..245af9288009 100644
--- 
a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert.cc
@@ -3,6 +3,7 @@
 #include <inplace_vector>
 
 #include <span>
+#include <optional>
 #include <testsuite_hooks.h>
 
 struct X
@@ -18,6 +19,20 @@ struct X
   friend auto operator<=>(const X&, const X&) = default;
 };
 
+// Type that is convertible to optional<Y&>
+struct Y
+{
+  Y() = default;
+  constexpr Y(int p) : v(p) {}
+      
+  constexpr operator std::optional<Y&>()
+  { return std::nullopt; }
+
+  int v;
+
+  friend auto operator<=>(const Y&, const Y&) = default;
+};
+
 template<typename T, typename V, size_t N>
 constexpr bool
 eq(const std::inplace_vector<V, N>& l, std::span<const T> r) {
@@ -40,11 +55,11 @@ test_add_to_full()
 
   std::inplace_vector<T, N> v(std::from_range, std::span(a, a+N));
 
-  VERIFY( v.try_emplace_back(1) == nullptr );
+  VERIFY( !v.try_emplace_back(1).has_value() );
   VERIFY( eq<T>(v, {a, N}) );
-  VERIFY( v.try_push_back(T(1)) == nullptr );
+  VERIFY( !v.try_push_back(T(1)).has_value() );
   VERIFY( eq<T>(v, {a, N}) );
-  VERIFY( v.try_push_back(c) == nullptr );
+  VERIFY( !v.try_push_back(c).has_value() );
   VERIFY( eq<T>(v, {a, N}) );
 
 #ifdef __cpp_exceptions
@@ -149,15 +164,18 @@ test_inserts()
   v.unchecked_push_back(c);
   VERIFY( eq<T>(v, {a+3, 6}) );
 
-  T* ptr = v.try_emplace_back(7);
+  std::optional<T&> opt = v.try_emplace_back(7);
   VERIFY( eq<T>(v, {a+3, 7}) );
-  VERIFY( ptr = &v.back() );
-  ptr = v.try_push_back(T(8));
+  VERIFY( opt.has_value() );
+  VERIFY( &*opt == &v.back() );
+  opt = v.try_push_back(T(8));
   VERIFY( eq<T>(v, {a+3, 8}) );
-  VERIFY( ptr = &v.back() );
-  ptr = v.try_push_back(c);
+  VERIFY( opt.has_value() );
+  VERIFY( &*opt == &v.back() );
+  opt = v.try_push_back(c);
   VERIFY( eq<T>(v, {a+3, 9}) );
-  VERIFY( ptr = &v.back() );
+  VERIFY( opt.has_value() );
+  VERIFY( &*opt == &v.back() );
 
   auto it = v.emplace(v.end(), 10);
   VERIFY( eq<T>(v, {a+3, 10}) );
@@ -195,12 +213,15 @@ int main()
   auto test_all = [] {
     test_add_to_full<0, int>();
     test_add_to_full<0, X>();
+    test_add_to_full<0, Y>();
 
     test_add_to_full<4, int>();
+    test_add_to_full<4, Y>();
 
     test_inserts<int>();
+    test_inserts<Y>();
 #ifdef __cpp_lib_constexpr_inplace_vector
-#error uncomemnt test_inserts<X>()
+#error enable tests bellow
 #endif
     if ! consteval {
       test_add_to_full<4, X>();
diff --git a/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc 
b/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc
index a5bbdb8464be..493e86dc6dd2 100644
--- a/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc
+++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/version.cc
@@ -5,7 +5,7 @@
 
 #ifndef __cpp_lib_inplace_vector
 # error "Feature-test macro for inplace_vector missing in <inplace_vector>"
-#elif __cpp_lib_inplace_vector != 202406L
+#elif __cpp_lib_inplace_vector != 202603L
 # error "Feature-test macro for inplace_vector has wrong value in 
<inplace_vector>"
 #endif
 
@@ -15,6 +15,6 @@
 
 #ifndef __cpp_lib_inplace_vector
 # error "Feature-test macro for inplace_vector missing in <version>"
-#elif __cpp_lib_inplace_vector != 202406L
+#elif __cpp_lib_inplace_vector != 202603L
 # error "Feature-test macro for inplace_vector has wrong value in <version>"
 #endif

Reply via email to