128 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// UNSUPPORTED: c++03, c++11, c++14, c++179 10// <span>11 12// template<size_t Count>13// constexpr span<element_type, Count> first() const;14//15// constexpr span<element_type, dynamic_extent> first(size_type count) const;16//17// Mandates: Count <= Extent is true.18 19#include <span>20#include <cassert>21#include <algorithm>22#include <string>23 24#include "test_macros.h"25 26template <typename Span, std::size_t Count>27constexpr bool testConstexprSpan(Span sp) {28 LIBCPP_ASSERT((noexcept(sp.template first<Count>())));29 LIBCPP_ASSERT((noexcept(sp.first(Count))));30 auto s1 = sp.template first<Count>();31 auto s2 = sp.first(Count);32 using S1 = decltype(s1);33 using S2 = decltype(s2);34 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);35 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);36 static_assert(S1::extent == Count, "");37 static_assert(S2::extent == std::dynamic_extent, "");38 return s1.data() == s2.data() && s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), sp.begin());39}40 41template <typename Span, std::size_t Count>42void testRuntimeSpan(Span sp) {43 LIBCPP_ASSERT((noexcept(sp.template first<Count>())));44 LIBCPP_ASSERT((noexcept(sp.first(Count))));45 auto s1 = sp.template first<Count>();46 auto s2 = sp.first(Count);47 using S1 = decltype(s1);48 using S2 = decltype(s2);49 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);50 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);51 static_assert(S1::extent == Count, "");52 static_assert(S2::extent == std::dynamic_extent, "");53 assert(s1.data() == s2.data());54 assert(s1.size() == s2.size());55 assert(std::equal(s1.begin(), s1.end(), sp.begin()));56}57 58constexpr int carr1[] = {1, 2, 3, 4};59int arr[] = {5, 6, 7};60std::string sarr[] = {"ABC", "DEF", "GHI", "JKL", "MNO"};61 62int main(int, char**) {63 {64 using Sp = std::span<const int>;65 static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");66 67 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");68 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");69 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");70 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");71 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");72 }73 74 {75 using Sp = std::span<const int, 4>;76 77 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");78 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");79 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");80 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");81 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");82 }83 84 {85 using Sp = std::span<int>;86 testRuntimeSpan<Sp, 0>(Sp{});87 88 testRuntimeSpan<Sp, 0>(Sp{arr});89 testRuntimeSpan<Sp, 1>(Sp{arr});90 testRuntimeSpan<Sp, 2>(Sp{arr});91 testRuntimeSpan<Sp, 3>(Sp{arr});92 }93 94 {95 using Sp = std::span<int, 3>;96 97 testRuntimeSpan<Sp, 0>(Sp{arr});98 testRuntimeSpan<Sp, 1>(Sp{arr});99 testRuntimeSpan<Sp, 2>(Sp{arr});100 testRuntimeSpan<Sp, 3>(Sp{arr});101 }102 103 {104 using Sp = std::span<std::string>;105 testConstexprSpan<Sp, 0>(Sp{});106 107 testRuntimeSpan<Sp, 0>(Sp{sarr});108 testRuntimeSpan<Sp, 1>(Sp{sarr});109 testRuntimeSpan<Sp, 2>(Sp{sarr});110 testRuntimeSpan<Sp, 3>(Sp{sarr});111 testRuntimeSpan<Sp, 4>(Sp{sarr});112 testRuntimeSpan<Sp, 5>(Sp{sarr});113 }114 115 {116 using Sp = std::span<std::string, 5>;117 118 testRuntimeSpan<Sp, 0>(Sp{sarr});119 testRuntimeSpan<Sp, 1>(Sp{sarr});120 testRuntimeSpan<Sp, 2>(Sp{sarr});121 testRuntimeSpan<Sp, 3>(Sp{sarr});122 testRuntimeSpan<Sp, 4>(Sp{sarr});123 testRuntimeSpan<Sp, 5>(Sp{sarr});124 }125 126 return 0;127}128