//===----------------------------------------------------------------------===// // // 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, c++20, c++23 // // constexpr reference at(size_type idx) const; // since C++26 #include #include #include #include #include #include #include #include #include #include #include "test_macros.h" template constexpr void testSpanAt(auto&& anySpan, int index, int expectedValue) { // non-const { std::same_as decltype(auto) elem = anySpan.at(index); assert(elem == expectedValue); } // const { std::same_as decltype(auto) elem = std::as_const(anySpan).at(index); assert(elem == expectedValue); } } constexpr bool test() { // With static extent { std::array arr{0, 1, 2, 3, 4, 5, 9084}; std::span arrSpan{arr}; assert(std::dynamic_extent != arrSpan.extent); using ReferenceT = typename decltype(arrSpan)::reference; testSpanAt(arrSpan, 0, 0); testSpanAt(arrSpan, 1, 1); testSpanAt(arrSpan, 6, 9084); } // With dynamic extent { std::vector vec{0, 1, 2, 3, 4, 5, 9084}; std::span vecSpan{vec}; assert(std::dynamic_extent == vecSpan.extent); using ReferenceT = typename decltype(vecSpan)::reference; testSpanAt(vecSpan, 0, 0); testSpanAt(vecSpan, 1, 1); testSpanAt(vecSpan, 6, 9084); } return true; } void test_exceptions() { #ifndef TEST_HAS_NO_EXCEPTIONS using namespace std::string_literals; // With static extent { std::array arr{0, 1, 2, 3, 4, 5, 9084, std::numeric_limits::max()}; const std::span arrSpan{arr}; try { using SizeT = typename decltype(arrSpan)::size_type; std::ignore = arrSpan.at(std::numeric_limits::max()); assert(false); } catch ([[maybe_unused]] const std::out_of_range& e) { // pass LIBCPP_ASSERT(e.what() == "span"s); } catch (...) { assert(false); } try { std::ignore = arrSpan.at(arr.size()); assert(false); } catch ([[maybe_unused]] const std::out_of_range& e) { // pass LIBCPP_ASSERT(e.what() == "span"s); } catch (...) { assert(false); } try { std::ignore = arrSpan.at(arr.size() - 1); // pass assert(arrSpan.at(arr.size() - 1) == std::numeric_limits::max()); } catch (...) { assert(false); } } { std::array arr{}; const std::span arrSpan{arr}; try { std::ignore = arrSpan.at(0); assert(false); } catch ([[maybe_unused]] const std::out_of_range& e) { // pass LIBCPP_ASSERT(e.what() == "span"s); } catch (...) { assert(false); } } // With dynamic extent { std::vector vec{0, 1, 2, 3, 4, 5, 9084, std::numeric_limits::max()}; const std::span vecSpan{vec}; try { using SizeT = typename decltype(vecSpan)::size_type; std::ignore = vecSpan.at(std::numeric_limits::max()); assert(false); } catch ([[maybe_unused]] const std::out_of_range& e) { // pass LIBCPP_ASSERT(e.what() == "span"s); } catch (...) { assert(false); } try { std::ignore = vecSpan.at(vec.size()); assert(false); } catch (const std::out_of_range& e) { // pass LIBCPP_ASSERT(e.what() == "span"s); } catch (...) { assert(false); } try { std::ignore = vecSpan.at(vec.size() - 1); assert(vecSpan.at(vec.size() - 1) == std::numeric_limits::max()); } catch (...) { assert(false); } } { std::vector vec{}; const std::span vecSpan{vec}; try { std::ignore = vecSpan.at(0); assert(false); } catch ([[maybe_unused]] const std::out_of_range& e) { // pass LIBCPP_ASSERT(e.what() == "span"s); } catch (...) { assert(false); } } #endif // TEST_HAS_NO_EXCEPTIONS } int main(int, char**) { test(); static_assert(test()); test_exceptions(); return 0; }