On Tue, 22 Jul 2025, Tomasz Kamiński wrote:

> Adds negative tests for preconditions on inserting into a full
> inplace_vector and erasing non-existent elementsi at compile-time.
> This ensures coverage for the inplace_vector<T, 0> specialization.
> 
> Also extends element access tests to cover front() and back()
> methods, and const and mutable overloads for all accesses.
> 
>       PR libstdc++/119137
> 
> libstdc++-v3/ChangeLog:
> 
>       * testsuite/23_containers/inplace_vector/access/elem.cc: Cover
>       front and back methods and const calls.
>       * testsuite/23_containers/inplace_vector/access/elem_neg.cc:
>       Likewise.
>       * testsuite/23_containers/inplace_vector/modifiers/erase_neg.cc:
>       New test.
>       * testsuite/23_containers/inplace_vector/modifiers/single_insert_neg.cc:
>       New test.
> ---
> v2 removes accidentally added access/single_insert.cc file with copy of 
> content
> of modifiers/single_insert.cc.

LGTM

> 
>  .../inplace_vector/access/elem.cc             | 35 ++++++++-------
>  .../inplace_vector/access/elem_neg.cc         | 44 ++++++++++++-------
>  .../inplace_vector/modifiers/erase_neg.cc     | 43 ++++++++++++++++++
>  .../modifiers/single_insert_neg.cc            | 42 ++++++++++++++++++
>  4 files changed, 132 insertions(+), 32 deletions(-)
>  create mode 100644 
> libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase_neg.cc
>  create mode 100644 
> libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert_neg.cc
> 
> diff --git 
> a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc 
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc
> index 8b1f492dd51..bc06aa09425 100644
> --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc
> +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem.cc
> @@ -41,11 +41,17 @@ test_out_of_capacity()
>  #endif
>  }
>  
> -template<typename T>
> +
> +template<bool Const, typename T, size_t N>
> +using InplaceVector = std::conditional_t<Const, 
> +                                      const std::inplace_vector<T, N>,
> +                                      std::inplace_vector<T, N>>;
> +
> +template<bool Const, typename T>
>  constexpr void
>  test_access()
>  {
> -  std::inplace_vector<T, 10> v{1, 2, 3, 4, 5};
> +  InplaceVector<Const, T, 10> v{1, 2, 3, 4, 5};
>  
>    auto& e0a = v[0];
>    auto& e0b = v.at(0);
> @@ -53,23 +59,26 @@ test_access()
>    VERIFY( &e0a == &e0b );
>    VERIFY( &e0a == &e0c );
>    VERIFY( &e0a == &v.begin()[0] );
> +  VERIFY( &e0a == &v.cbegin()[0] );
>    VERIFY( &e0a == v.data() );
>    VERIFY( e0a == T(1) );
>  
>    auto& e3a = v[2];
> -  auto& e3b = std::as_const(v).at(2);
> +  auto& e3b = v.at(2);
>    VERIFY( &e3a == &e3b );
>    VERIFY( &e3a == &v.begin()[2] );
> -  VERIFY( &e3a == std::as_const(v).data() + 2 );
> +  VERIFY( &e3a == &v.cbegin()[2] );
> +  VERIFY( &e3a == v.data() + 2 );
>    VERIFY( e3a == T(3) );
>  
> -  auto& e4a = as_const(v)[4];
> +  auto& e4a = v[4];
>    auto& e4b = v.at(4);
> -  auto& e4c = as_const(v).back();
> +  auto& e4c = v.back();
>    VERIFY( &e4a == &e4b );
>    VERIFY( &e4a == &e4c );
> +  VERIFY( &e4a == &v.begin()[4] );
>    VERIFY( &e4a == &v.cbegin()[4] );
> -  VERIFY( &e4a == as_const(v).data() + 4 );
> +  VERIFY( &e4a == v.data() + 4 );
>    VERIFY( e4a == T(5) );
>  
>  #ifdef __cpp_exceptions
> @@ -88,15 +97,6 @@ test_access()
>    catch (std::out_of_range const&)
>    {
>    }
> -
> -  try
> -  {
> -    (void)as_const(v).at(7);
> -    VERIFY(false);
> -  }
> -  catch (std::out_of_range const&)
> -  {
> -  }
>  #endif
>  }
>  
> @@ -105,7 +105,8 @@ int main()
>    auto test_all = [] {
>      test_out_of_capacity<0, int>();
>      test_out_of_capacity<4, int>();
> -    test_access<int>();
> +    test_access<true, int>();
> +    test_access<false, int>();
>      return true;
>    };
>  
> diff --git 
> a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc 
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc
> index 7e6780163ab..b2bff0d6387 100644
> --- a/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc
> +++ b/libstdc++-v3/testsuite/23_containers/inplace_vector/access/elem_neg.cc
> @@ -2,49 +2,63 @@
>  
>  #include <inplace_vector>
>  
> -template<size_t N, typename T>
> +template<bool Const, typename T, size_t N>
> +using InplaceVector 
> +  = std::conditional_t<Const, 
> +                    const std::inplace_vector<T, N>,
> +                    std::inplace_vector<T, N>>;
> +
> +template<bool Const, size_t N, typename T>
>  constexpr bool
>  test_front_on_empty()
>  {
> -  std::inplace_vector<T, N> v;
> +  InplaceVector<Const, T, N> v;
>    (void)v.front(); // { dg-error "in 'constexpr' expansion of" }
>    return true;
>  }
>  
> -template<size_t N, typename T>
> +template<bool Const, size_t N, typename T>
>  constexpr bool
>  test_back_on_empty()
>  {
> -  std::inplace_vector<T, N> v;
> +  InplaceVector<Const, T, N> v;
>    (void)v.back(); // { dg-error "in 'constexpr' expansion of" }
>    return true;
>  }
>  
> -template<size_t N, typename T>
> +template<bool Const, size_t N, typename T>
>  constexpr bool
>  test_out_of_capacity()
>  {
> -  std::inplace_vector<T, N> v;
> +  InplaceVector<Const, T, N> v;
>    (void)v[N+2]; // { dg-error "in 'constexpr' expansion of" }
>    return true;
>  }
>  
> -template<typename T>
> +template<bool Const, typename T>
>  constexpr bool
>  test_out_of_size()
>  {
> -  std::inplace_vector<T, 10> v{1, 2, 3, 4, 5};
> +  InplaceVector<Const, T, 10> v{1, 2, 3, 4, 5};
>    (void)v[7]; // { dg-error "in 'constexpr' expansion of" }
>    return true;
>  }
>  
> -static_assert(test_front_on_empty<0, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> -static_assert(test_front_on_empty<4, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> -static_assert(test_back_on_empty<0, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> -static_assert(test_back_on_empty<4, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> -static_assert(test_out_of_capacity<0, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> -static_assert(test_out_of_capacity<4, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> -static_assert(test_out_of_size<int>());        // { dg-error "in 'constexpr' 
> expansion of" }
> +static_assert(test_front_on_empty<false, 0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_front_on_empty<false, 4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_back_on_empty<false, 0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_back_on_empty<false, 4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_out_of_capacity<false, 0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_out_of_capacity<false, 4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_out_of_size<false, int>());        // { dg-error "in 
> 'constexpr' expansion of" }
> +
> +static_assert(test_front_on_empty<true, 0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_front_on_empty<true, 4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_back_on_empty<true, 0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_back_on_empty<true, 4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_out_of_capacity<true, 0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_out_of_capacity<true, 4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_out_of_size<true, int>());        // { dg-error "in 
> 'constexpr' expansion of" }
>  
>  // { dg-prune-output "non-constant condition for static assertion" }
>  // { dg-prune-output "is not a constant expression" }
> diff --git 
> a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase_neg.cc 
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase_neg.cc
> new file mode 100644
> index 00000000000..a1f43b3b53b
> --- /dev/null
> +++ 
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/erase_neg.cc
> @@ -0,0 +1,43 @@
> +// { dg-do compile { target c++26 } }
> +
> +#include <inplace_vector>
> +
> +template<size_t N, typename T>
> +constexpr bool
> +test_pop_back_on_empty()
> +{
> +  std::inplace_vector<T, N> v;
> +  v.pop_back(); // { dg-error "in 'constexpr' expansion of" }
> +  return true;
> +}
> +
> +template<size_t N, typename T>
> +constexpr bool
> +test_erase_begin_on_empty()
> +{
> +  std::inplace_vector<T, N> v;
> +  v.erase(v.begin()); // { dg-error "in 'constexpr' expansion of" }
> +  return true;
> +}
> +
> +template<size_t N, typename T>
> +constexpr bool
> +test_erase_end(size_t size = 0)
> +{
> +  std::inplace_vector<T, N> v(size, T());
> +  v.erase(v.end()); // { dg-error "in 'constexpr' expansion of" }
> +  return true;
> +}
> +
> +static_assert(test_pop_back_on_empty<0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_pop_back_on_empty<4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_erase_begin_on_empty<0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_erase_begin_on_empty<4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_erase_end<0, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> +static_assert(test_erase_end<4, int>()); // { dg-error "in 'constexpr' 
> expansion of" }
> +static_assert(test_erase_end<4, int>(2)); // { dg-error "in 'constexpr' 
> expansion of" }
> +static_assert(test_erase_end<4, int>(4)); // { dg-error "in 'constexpr' 
> expansion of" }
> +
> +// { dg-prune-output "non-constant condition for static assertion" }
> +// { dg-prune-output "is not a constant expression" }
> +// { dg-prune-output "call to non-'constexpr' function" }
> diff --git 
> a/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert_neg.cc
>  
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert_neg.cc
> new file mode 100644
> index 00000000000..0552b8c2b7d
> --- /dev/null
> +++ 
> b/libstdc++-v3/testsuite/23_containers/inplace_vector/modifiers/single_insert_neg.cc
> @@ -0,0 +1,42 @@
> +// { dg-do compile { target c++26 } }
> +
> +#include <inplace_vector>
> +
> +template<size_t N, typename T>
> +constexpr bool
> +test_unchecked_emplace_back()
> +{
> +  std::inplace_vector<T, N> v(N, T(1));
> +  v.unchecked_emplace_back(); // { dg-error "in 'constexpr' expansion of" }
> +  return true;
> +}
> +
> +template<size_t N, typename T>
> +constexpr bool
> +test_push_back_lvalue()
> +{
> +  auto val = T();;
> +  std::inplace_vector<T, N> v(N, T(1));
> +  v.unchecked_push_back(val); // { dg-error "in 'constexpr' expansion of" }
> +  return true;
> +}
> +
> +template<size_t N, typename T>
> +constexpr bool
> +test_push_back_rvalue()
> +{
> +  std::inplace_vector<T, N> v(N, T(1));
> +  v.unchecked_push_back(T()); // { dg-error "in 'constexpr' expansion of" }
> +  return true;
> +}
> +
> +static_assert(test_unchecked_emplace_back<0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_unchecked_emplace_back<4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_push_back_lvalue<0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_push_back_lvalue<4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_push_back_rvalue<0, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +static_assert(test_push_back_rvalue<4, int>()); // { dg-error "in 
> 'constexpr' expansion of" }
> +
> +// { dg-prune-output "non-constant condition for static assertion" }
> +// { dg-prune-output "is not a constant expression" }
> +// { dg-prune-output "call to non-'constexpr' function" }
> -- 
> 2.49.0
> 
> 

Reply via email to