On Fri, 24 Apr 2026, Tomasz KamiĆski wrote:
> Simply cast size of the input range to size_t, after verifying that
> it fits in remaining capacity, and thus in size_t.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/inplace_vector (inplace_vector::assign_range)
> (inplace_vector::append_range): Cast ranges::distance(__rg)
> to size_t.
> * testsuite/23_containers/inplace_vector/cons/from_range.cc: New
> test for ranges with integer-class size_type.
> * testsuite/23_containers/inplace_vector/modifiers/assign.cc:
> Likewise.
> * testsuite/23_containers/inplace_vector/modifiers/multi_insert.cc:
> Likewise.
LGTM
> ---
> New in v2 seriers, as I encountered this while testing integer-class ranges
> with later patches.
>
> Tested on x86_64-linux. OK for trunk?
>
> libstdc++-v3/include/std/inplace_vector | 12 +-
> .../inplace_vector/cons/from_range.cc | 59 +++++++++-
> .../inplace_vector/modifiers/assign.cc | 55 ++++++++-
> .../inplace_vector/modifiers/multi_insert.cc | 106 +++++++++++++++++-
> 4 files changed, 219 insertions(+), 13 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/inplace_vector
> b/libstdc++-v3/include/std/inplace_vector
> index 5ad92332a02..0096bd83a17 100644
> --- a/libstdc++-v3/include/std/inplace_vector
> +++ b/libstdc++-v3/include/std/inplace_vector
> @@ -248,9 +248,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> {
> if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
> {
> - const auto __sz = ranges::distance(__rg);
> - if (__sz > _Nm)
> + const auto __len = ranges::distance(__rg);
> + if (__len > _Nm)
> __throw_bad_alloc();
> +
> + const size_t __sz = size_t(__len);
> if (__sz <= size())
> {
> ranges::copy_n(ranges::begin(__rg), __sz, data());
> @@ -523,9 +525,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> {
> if constexpr (ranges::forward_range<_Rg> || ranges::sized_range<_Rg>)
> {
> - const auto __sz = ranges::distance(__rg);
> - if (__sz > (_Nm - size()))
> + const auto __len = ranges::distance(__rg);
> + if (__len > (_Nm - size()))
> __throw_bad_alloc();
> +
> + const size_t __sz = size_t(__len);
> // Bounded on output range due PR121143
> ranges::uninitialized_copy(
> ranges::begin(__rg), unreachable_sentinel,
> diff --git
> a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc
> index b79434dd111..b30fc04e4cd 100644
> --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc
> +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/cons/from_range.cc
> @@ -2,6 +2,7 @@
>
> #include <inplace_vector>
>
> +#include <ranges>
> #include <span>
> #include <testsuite_hooks.h>
> #include <testsuite_iterators.h>
> @@ -77,7 +78,7 @@ test_iterators()
> do_test_it<int, input_iterator_wrapper>();
> do_test_it<int, forward_iterator_wrapper>();
> do_test_it<int, random_access_iterator_wrapper>();
> -
> +
> do_test_it<short, forward_iterator_wrapper>();
> return true;
> }
> @@ -108,7 +109,7 @@ do_test_r()
> return;
> }
> #endif
> -
> +
> try
> {
> std::inplace_vector<V, 5> v9(std::from_range, Range(a, a+9));
> @@ -161,11 +162,65 @@ test_ranges()
> return true;
> }
>
> +template<typename T>
> +constexpr void
> +test_iota()
> +{
> + T a[]{1,2,3,4,5,6,7,8,9,10};
> +
> + std::inplace_vector<T, 10> v1(
> + std::from_range, std::views::iota(T(1), T(11)));
> + VERIFY( eq<T>(v1, {a, a+10}) );
> +
> + std::inplace_vector<T, 10> v2(
> + std::from_range,
> + std::views::iota(T(1))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t <= 10; }));
> + VERIFY( eq<T>(v2, {a, a+10}) );
> +
> +#ifdef __cpp_exceptions
> +#ifndef __cpp_lib_constexpr_exceptions
> + if consteval {
> + return;
> + }
> +#endif
> + constexpr T max = std::numeric_limits<T>::max();
> + try
> + {
> + std::inplace_vector<T, 10> v(
> + std::from_range, std::views::iota(T(0), max));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> +
> + try
> + {
> + std::inplace_vector<T, 10> v(
> + std::from_range,
> + std::views::iota(T(0))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t < 15; }));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> +#endif
> +}
> +
> int main()
> {
> auto test_all = [] {
> test_iterators();
> test_ranges();
> +
> + test_iota<long long>();
> +#ifdef __SIZEOF_INT128__
> + test_iota<__int128>();
> +#endif
> return true;
> };
>
> diff --git
> a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc
> index c1d867ee1d4..577c1047708 100644
> --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc
> +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/assign.cc
> @@ -2,6 +2,7 @@
>
> #include <inplace_vector>
>
> +#include <ranges>
> #include <span>
> #include <testsuite_hooks.h>
> #include <testsuite_iterators.h>
> @@ -353,6 +354,53 @@ test_assigns()
> test_resize<T>();
> }
>
> +template<typename T>
> +constexpr void
> +test_iota()
> +{
> + T a[]{1,2,3,4,5,6,7,8,9,10};
> +
> + std::inplace_vector<T, 10> v;
> + v.assign_range(std::views::iota(T(1), T(11)));
> + VERIFY( eq<T>(v, {a, a+10}) );
> +
> + v.assign_range(
> + std::views::iota(T(1))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t <= 10; }));
> + VERIFY( eq<T>(v, {a, a+10}) );
> +
> +#ifdef __cpp_exceptions
> +#ifndef __cpp_lib_constexpr_exceptions
> + if consteval {
> + return;
> + }
> +#endif
> + constexpr T max = std::numeric_limits<T>::max();
> + try
> + {
> + v.assign_range(std::views::iota(T(0), max));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> + VERIFY( eq<T>(v, {a, 10}) );
> +
> + try
> + {
> + v.assign_range(
> + std::views::iota(T(0))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t < 15; }));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> +#endif
> +}
> +
> int main()
> {
> auto test_all = [] {
> @@ -368,10 +416,15 @@ int main()
> test_assign_empty<2, X>();
> test_assigns<X>();
> }
> +
> + test_iota<long long>();
> +#ifdef __SIZEOF_INT128__
> + test_iota<__int128>();
> +#endif
> +
> return true;
> };
>
> -
> test_all();
> static_assert(test_all());
> }
> 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 e5a482cdc65..bde66847a34 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
> @@ -2,6 +2,7 @@
>
> #include <inplace_vector>
>
> +#include <ranges>
> #include <span>
> #include <testsuite_hooks.h>
> #include <testsuite_iterators.h>
> @@ -506,6 +507,8 @@ test_insert_repeated()
> #endif
> }
>
> +
> +
> template<typename T>
> constexpr void
> test_inserts()
> @@ -526,16 +529,102 @@ test_inserts()
> test_insert_iterators<T, forward_iterator_wrapper>();
> test_insert_iterators<T, random_access_iterator_wrapper>();
>
> -test_insert_initializer_list<T>();
> -test_insert_repeated<T>();
> + test_insert_initializer_list<T>();
> + test_insert_repeated<T>();
> +}
> +
> +template<typename T>
> +constexpr void
> +test_iota()
> +{
> + T a[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
> +
> + std::inplace_vector<T, 20> v;
> + auto it = v.insert_range(v.begin(), std::views::iota(T(1), T(11)));
> + VERIFY( eq<T>(v, {a, a+10}) );
> + VERIFY( it == v.begin() );
> +
> + v.append_range(std::views::iota(T(11), T(16)));
> + VERIFY( eq<T>(v, {a, 15}) );
> +
> + v.clear();
> + it = v.insert_range(v.begin(),
> + std::views::iota(T(1))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t <= 10; }));
> + VERIFY( eq<T>(v, {a, a+10}) );
> + VERIFY( it == v.begin() );
> +
> + v.append_range(
> + std::views::iota(T(11))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t <= 15; }));
> + VERIFY( eq<T>(v, {a, 15}) );
> +
> +#ifdef __cpp_exceptions
> +#ifndef __cpp_lib_constexpr_exceptions
> + if consteval {
> + return;
> + }
> +#endif
> + constexpr T max = std::numeric_limits<T>::max();
> + try
> + {
> + v.insert_range(v.end(), std::views::iota(T(0), max));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> + VERIFY( eq<T>(v, {a, 15}) );
> +
> + try
> + {
> + v.append_range(std::views::iota(T(0), max));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> + VERIFY( eq<T>(v, {a, 15}) );
> +
> + auto vc = v;
> + try
> + {
> + vc.insert_range(vc.end(),
> + std::views::iota(T(1))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t <= 20; }));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> + VERIFY( prefix<T>(vc, {a, 15}) );
> +
> + vc = v;
> + try
> + {
> + vc.append_range(
> + std::views::iota(T(1))
> + | std::views::as_input
> + | std::views::take_while([](T t) { return t <= 20; }));
> + VERIFY(false);
> + }
> + catch (std::bad_alloc const&)
> + {
> + }
> + VERIFY( prefix<T>(vc, {a, 15}) );
> +
> +#endif
> }
>
> int main()
> {
> -auto test_all = []{
> - test_add_to_full<0, int>();
> - test_add_to_full<0, X>();
> - test_add_to_full<4, int>();
> + auto test_all = []{
> + test_add_to_full<0, int>();
> + test_add_to_full<0, X>();
> + test_add_to_full<4, int>();
>
> test_inserts<int>();
> #ifdef __cpp_lib_constexpr_inplace_vector
> @@ -545,6 +634,11 @@ auto test_all = []{
> test_add_to_full<4, X>();
> test_inserts<X>();
> }
> +
> + test_iota<long long>();
> +#ifdef __SIZEOF_INT128__
> + test_iota<__int128>();
> +#endif
> return true;
> };
>
> --
> 2.53.0
>
>