// -*- C++ -*- //===------------------------------ span ---------------------------------===// // // The LLVM Compiler Infrastructure // // This file is dual licensed under the MIT and the University of Illinois Open // Source Licenses. See LICENSE.TXT for details. // //===---------------------------------------------------------------------===// // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 // // template // constexpr span subspan() const; // // constexpr span subspan( // index_type offset, index_type count = dynamic_extent) const; // // Requires: (0 <= Offset && Offset <= size()) // && (Count == dynamic_extent || Count >= 0 && Offset + Count <= size()) #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 == (Span::extent == std::dynamic_extent ? std::dynamic_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 == (Span::extent == std::dynamic_extent ? std::dynamic_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 () { { 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}); } }