//===----------------------------------------------------------------------===// // // 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 // // template // constexpr span subspan() const; // // constexpr span subspan( // size_type offset, size_type count = dynamic_extent) const; // // Mandates: Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset) is true. #include #include #include #include #include "test_macros.h" template constexpr bool testConstexprSpan(Span sp) { LIBCPP_ASSERT((noexcept(sp.template subspan()))); LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count)))); auto s1 = sp.template subspan(); auto s2 = sp.subspan(Offset, Count); using S1 = decltype(s1); using S2 = decltype(s2); ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); static_assert(S1::extent == Count); static_assert(S2::extent == std::dynamic_extent, ""); return s1.data() == s2.data() && s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), sp.begin() + Offset); } template constexpr bool testConstexprSpan(Span sp) { LIBCPP_ASSERT((noexcept(sp.template subspan()))); LIBCPP_ASSERT((noexcept(sp.subspan(Offset)))); auto s1 = sp.template subspan(); auto s2 = sp.subspan(Offset); using S1 = decltype(s1); using S2 = decltype(s2); ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), ""); static_assert(S2::extent == std::dynamic_extent, ""); return s1.data() == s2.data() && s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end()); } template void testRuntimeSpan(Span sp) { LIBCPP_ASSERT((noexcept(sp.template subspan()))); LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count)))); auto s1 = sp.template subspan(); auto s2 = sp.subspan(Offset, Count); using S1 = decltype(s1); using S2 = decltype(s2); ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); static_assert(S1::extent == Count); static_assert(S2::extent == std::dynamic_extent, ""); assert(s1.data() == s2.data()); assert(s1.size() == s2.size()); assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset)); } template void testRuntimeSpan(Span sp) { LIBCPP_ASSERT((noexcept(sp.template subspan()))); LIBCPP_ASSERT((noexcept(sp.subspan(Offset)))); auto s1 = sp.template subspan(); auto s2 = sp.subspan(Offset); using S1 = decltype(s1); using S2 = decltype(s2); ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type); ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type); static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), ""); static_assert(S2::extent == std::dynamic_extent, ""); assert(s1.data() == s2.data()); assert(s1.size() == s2.size()); assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end())); } constexpr int carr1[] = {1,2,3,4}; int arr1[] = {5,6,7}; int main(int, char**) { { using Sp = std::span; static_assert(testConstexprSpan(Sp{}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); } { using Sp = std::span; static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); } { using Sp = std::span; static_assert(testConstexprSpan(Sp{}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); } { using Sp = std::span; static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); static_assert(testConstexprSpan(Sp{carr1}), ""); } { using Sp = std::span; testRuntimeSpan(Sp{}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); } { using Sp = std::span; testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); } { using Sp = std::span; testRuntimeSpan(Sp{}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); } { using Sp = std::span; testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); testRuntimeSpan(Sp{arr1}); } return 0; }