From a772b52c9dec6cf165e962d0d1e15aa2c563b04c Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 6 Jan 2025 16:30:53 -0500 Subject: [PATCH 1/2] Mark vector::at() as constexpr --- libcxx/include/__vector/vector_bool.h | 9 ++-- .../vector.bool/at.constexpr.pass.cpp | 42 +++++++++++++++++++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index 8658745b8a8f9..4c334176a037e 100644 --- a/libcxx/include/__vector/vector_bool.h +++ b/libcxx/include/__vector/vector_bool.h @@ -279,8 +279,8 @@ class _LIBCPP_TEMPLATE_VIS vector { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference operator[](size_type __n) const { return __make_ref(__n); } - _LIBCPP_HIDE_FROM_ABI reference at(size_type __n); - _LIBCPP_HIDE_FROM_ABI const_reference at(size_type __n) const; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference at(size_type __n); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference at(size_type __n) const; _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference front() { return __make_ref(0); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 const_reference front() const { return __make_ref(0); } @@ -853,14 +853,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 void vector::shrink_to_fit() _NO } template -typename vector::reference vector::at(size_type __n) { +_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector::reference vector::at(size_type __n) { if (__n >= size()) this->__throw_out_of_range(); return (*this)[__n]; } template -typename vector::const_reference vector::at(size_type __n) const { +_LIBCPP_CONSTEXPR_SINCE_CXX20 typename vector::const_reference +vector::at(size_type __n) const { if (__n >= size()) this->__throw_out_of_range(); return (*this)[__n]; diff --git a/libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp new file mode 100644 index 0000000000000..cc9ce99f9488b --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// constexpr const_reference at(size_type n) const; +// constexpr reference at(size_type n); + +#include +#include +#include + +#include "min_allocator.h" +#include "test_allocator.h" + +template +constexpr void test() { + std::vector v{1, 0, 1}; + assert(v.at(0) == 1); + assert(v.at(1) == 0); + assert(v.at(2) == 1); +} + +constexpr bool tests() { + test>(); + test>(); + test>(); + + return true; +} + +int main(int, char**) { + tests(); + static_assert(tests()); + + return 0; +} From c7ab1a28fa7270a3cbc715f59300dea57a82fa97 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Mon, 6 Jan 2025 23:30:09 -0500 Subject: [PATCH 2/2] Add tests for at() function in all modes --- .../vector.bool/at.constexpr.pass.cpp | 42 ------ .../sequences/vector.bool/at.pass.cpp | 125 ++++++++++++++++++ .../sequences/vector.bool/at_const.pass.cpp | 121 +++++++++++++++++ 3 files changed, 246 insertions(+), 42 deletions(-) delete mode 100644 libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp create mode 100644 libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp diff --git a/libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp deleted file mode 100644 index cc9ce99f9488b..0000000000000 --- a/libcxx/test/std/containers/sequences/vector.bool/at.constexpr.pass.cpp +++ /dev/null @@ -1,42 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03, c++11, c++14, c++17 - -// constexpr const_reference at(size_type n) const; -// constexpr reference at(size_type n); - -#include -#include -#include - -#include "min_allocator.h" -#include "test_allocator.h" - -template -constexpr void test() { - std::vector v{1, 0, 1}; - assert(v.at(0) == 1); - assert(v.at(1) == 0); - assert(v.at(2) == 1); -} - -constexpr bool tests() { - test>(); - test>(); - test>(); - - return true; -} - -int main(int, char**) { - tests(); - static_assert(tests()); - - return 0; -} diff --git a/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp new file mode 100644 index 0000000000000..16832dd831e61 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/at.pass.cpp @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// reference at(size_type n); // constexpr since C++20 + +#include +#include +#include + +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" + +#ifndef TEST_HAS_NO_EXCEPTIONS +# include +#endif + +template +TEST_CONSTEXPR_CXX20 void test() { + using C = std::vector; + using reference = typename C::reference; + bool a[] = {1, 0, 1, 0, 1}; + C v(a, a + sizeof(a) / sizeof(a[0])); + ASSERT_SAME_TYPE(reference, decltype(v.at(0))); + assert(v.at(0) == true); + assert(v.at(1) == false); + assert(v.at(2) == true); + assert(v.at(3) == false); + assert(v.at(4) == true); + v.at(1) = 1; + assert(v.at(1) == true); + v.at(3) = 1; + assert(v.at(3) == true); +} + +template +void test_exception() { +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool a[] = {1, 0, 1, 1}; + using C = std::vector; + C v(a, a + sizeof(a) / sizeof(a[0])); + + try { + TEST_IGNORE_NODISCARD v.at(4); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(5); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(6); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + using size_type = typename C::size_type; + TEST_IGNORE_NODISCARD v.at(static_cast(-1)); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } + + { + std::vector v; + try { + TEST_IGNORE_NODISCARD v.at(0); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } +#endif +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test >(); + test >(); + test >(); + return true; +} + +void test_exceptions() { + test_exception >(); + test_exception >(); + test_exception >(); +} + +int main(int, char**) { + tests(); + test_exceptions(); + +#if TEST_STD_VER >= 20 + static_assert(tests()); +#endif + + return 0; +} diff --git a/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp new file mode 100644 index 0000000000000..5ed794d13f193 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/at_const.pass.cpp @@ -0,0 +1,121 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +// const_reference at(size_type n) const; // constexpr since C++20 + +#include +#include +#include + +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" + +#ifndef TEST_HAS_NO_EXCEPTIONS +# include +#endif + +template +TEST_CONSTEXPR_CXX20 void test() { + using C = const std::vector; + using const_reference = typename C::const_reference; + bool a[] = {1, 0, 1, 0, 1}; + C v(a, a + sizeof(a) / sizeof(a[0])); + ASSERT_SAME_TYPE(const_reference, decltype(v.at(0))); + assert(v.at(0) == true); + assert(v.at(1) == false); + assert(v.at(2) == true); + assert(v.at(3) == false); + assert(v.at(4) == true); +} + +template +void test_exception() { +#ifndef TEST_HAS_NO_EXCEPTIONS + { + bool a[] = {1, 0, 1, 1}; + using C = const std::vector; + C v(a, a + sizeof(a) / sizeof(a[0])); + + try { + TEST_IGNORE_NODISCARD v.at(4); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(5); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + TEST_IGNORE_NODISCARD v.at(6); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + + try { + using size_type = typename C::size_type; + TEST_IGNORE_NODISCARD v.at(static_cast(-1)); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } + + { + std::vector v; + try { + TEST_IGNORE_NODISCARD v.at(0); + assert(false); + } catch (std::out_of_range const&) { + // pass + } catch (...) { + assert(false); + } + } +#endif +} + +TEST_CONSTEXPR_CXX20 bool tests() { + test >(); + test >(); + test >(); + return true; +} + +void test_exceptions() { + test_exception >(); + test_exception >(); + test_exception >(); +} + +int main(int, char**) { + tests(); + test_exceptions(); + +#if TEST_STD_VER >= 20 + static_assert(tests()); +#endif + + return 0; +}