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
> 
> 

Reply via email to