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.
---
The exception_ptr change need to be handled seprately, due it being
defined in libsup++.
Testing on x86_64-linux. All *inplace_vector* test already passed.
OK for trunk if all test finishes?
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(-)
delete mode 100644
libstdc++-v3/testsuite/23_containers/inplace_vector/debug/invalidation/try_append_range.cc
diff --git a/libstdc++-v3/include/bits/version.def
b/libstdc++-v3/include/bits/version.def
index ada8da88bc5..998223306e2 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 0490e79dd41..cb3b9b0997e 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 750b0a7343c..e579e8636f9 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 c22a9e1f9b4..5ad92332a02 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 ae4ac418f50..00000000000
---
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 f7c8c7a9ba2..606d478a0dc 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 04fc010e500..96af2b65b72 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 454163892ad..e5a482cdc65 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 92bd765982e..245af928800 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 a5bbdb8464b..493e86dc6dd 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
--
2.53.0