blob: f2dbe8408dd43f928b4a52f81dddecdf58e79a92 [file] [log] [blame]
Marshall Clow8a0794b2018-07-24 03:01:02 +00001// -*- C++ -*-
2//===------------------------------ span ---------------------------------===//
3//
Chandler Carruth57b08b02019-01-19 10:56:40 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Marshall Clow8a0794b2018-07-24 03:01:02 +00007//
8//===---------------------------------------------------------------------===//
Stephan T. Lavavejdec89052018-11-14 03:06:06 +00009// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
Marshall Clow8a0794b2018-07-24 03:01:02 +000010
11// <span>
12
Marshall Clow8eda3ad2019-03-06 03:59:44 +000013// template<size_t Offset, size_t Count = dynamic_extent>
Marshall Clow8a0794b2018-07-24 03:01:02 +000014// constexpr span<element_type, see below> subspan() const;
15//
16// constexpr span<element_type, dynamic_extent> subspan(
17// index_type offset, index_type count = dynamic_extent) const;
18//
19// Requires: (0 <= Offset && Offset <= size())
20// && (Count == dynamic_extent || Count >= 0 && Offset + Count <= size())
21
22#include <span>
23#include <cassert>
24#include <algorithm>
25#include <string>
26
27#include "test_macros.h"
28
Marshall Clow8eda3ad2019-03-06 03:59:44 +000029template <typename Span, size_t Offset, size_t Count>
Marshall Clow8a0794b2018-07-24 03:01:02 +000030constexpr bool testConstexprSpan(Span sp)
31{
32 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
33 LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
34 auto s1 = sp.template subspan<Offset, Count>();
35 auto s2 = sp.subspan(Offset, Count);
36 using S1 = decltype(s1);
37 using S2 = decltype(s2);
38 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
39 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
40 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
41 static_assert(S2::extent == std::dynamic_extent, "");
42 return
43 s1.data() == s2.data()
44 && s1.size() == s2.size()
45 && std::equal(s1.begin(), s1.end(), sp.begin() + Offset);
46}
47
Marshall Clow8eda3ad2019-03-06 03:59:44 +000048template <typename Span, size_t Offset>
Marshall Clow8a0794b2018-07-24 03:01:02 +000049constexpr bool testConstexprSpan(Span sp)
50{
51 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
52 LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
53 auto s1 = sp.template subspan<Offset>();
54 auto s2 = sp.subspan(Offset);
55 using S1 = decltype(s1);
56 using S2 = decltype(s2);
57 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
58 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
59 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
60 static_assert(S2::extent == std::dynamic_extent, "");
61 return
62 s1.data() == s2.data()
63 && s1.size() == s2.size()
64 && std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end());
65}
66
67
Marshall Clow8eda3ad2019-03-06 03:59:44 +000068template <typename Span, size_t Offset, size_t Count>
Marshall Clow8a0794b2018-07-24 03:01:02 +000069void testRuntimeSpan(Span sp)
70{
71 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset, Count>())));
72 LIBCPP_ASSERT((noexcept(sp.subspan(Offset, Count))));
73 auto s1 = sp.template subspan<Offset, Count>();
74 auto s2 = sp.subspan(Offset, Count);
75 using S1 = decltype(s1);
76 using S2 = decltype(s2);
77 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
78 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
79 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Count), "");
80 static_assert(S2::extent == std::dynamic_extent, "");
81 assert(s1.data() == s2.data());
82 assert(s1.size() == s2.size());
83 assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset));
84}
85
86
Marshall Clow8eda3ad2019-03-06 03:59:44 +000087template <typename Span, size_t Offset>
Marshall Clow8a0794b2018-07-24 03:01:02 +000088void testRuntimeSpan(Span sp)
89{
90 LIBCPP_ASSERT((noexcept(sp.template subspan<Offset>())));
91 LIBCPP_ASSERT((noexcept(sp.subspan(Offset))));
92 auto s1 = sp.template subspan<Offset>();
93 auto s2 = sp.subspan(Offset);
94 using S1 = decltype(s1);
95 using S2 = decltype(s2);
96 ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
97 ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
98 static_assert(S1::extent == (Span::extent == std::dynamic_extent ? std::dynamic_extent : Span::extent - Offset), "");
99 static_assert(S2::extent == std::dynamic_extent, "");
100 assert(s1.data() == s2.data());
101 assert(s1.size() == s2.size());
102 assert(std::equal(s1.begin(), s1.end(), sp.begin() + Offset, sp.end()));
103}
104
105
106constexpr int carr1[] = {1,2,3,4};
107 int arr1[] = {5,6,7};
108
JF Bastien2df59c52019-02-04 20:31:13 +0000109int main(int, char**)
Marshall Clow8a0794b2018-07-24 03:01:02 +0000110{
111 {
112 using Sp = std::span<const int>;
113 static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
114
115 static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
116 static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
117 static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
118 static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
119 static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
120
121 static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
122 static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
123 static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
124 static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
125 }
126
127 {
128 using Sp = std::span<const int, 4>;
129
130 static_assert(testConstexprSpan<Sp, 0, 4>(Sp{carr1}), "");
131 static_assert(testConstexprSpan<Sp, 0, 3>(Sp{carr1}), "");
132 static_assert(testConstexprSpan<Sp, 0, 2>(Sp{carr1}), "");
133 static_assert(testConstexprSpan<Sp, 0, 1>(Sp{carr1}), "");
134 static_assert(testConstexprSpan<Sp, 0, 0>(Sp{carr1}), "");
135
136 static_assert(testConstexprSpan<Sp, 1, 3>(Sp{carr1}), "");
137 static_assert(testConstexprSpan<Sp, 2, 2>(Sp{carr1}), "");
138 static_assert(testConstexprSpan<Sp, 3, 1>(Sp{carr1}), "");
139 static_assert(testConstexprSpan<Sp, 4, 0>(Sp{carr1}), "");
140 }
141
142 {
143 using Sp = std::span<const int>;
144 static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
145
146 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
147 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
148 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
149 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
150 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
151 }
152
153 {
154 using Sp = std::span<const int, 4>;
155
156 static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
157
158 static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
159 static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
160 static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
161 static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
162 }
163
164 {
165 using Sp = std::span<int>;
166 testRuntimeSpan<Sp, 0>(Sp{});
167
168 testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
169 testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
170 testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
171 testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
172
173 testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
174 testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
175 testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
176 }
177
178 {
179 using Sp = std::span<int, 3>;
180
181 testRuntimeSpan<Sp, 0, 3>(Sp{arr1});
182 testRuntimeSpan<Sp, 0, 2>(Sp{arr1});
183 testRuntimeSpan<Sp, 0, 1>(Sp{arr1});
184 testRuntimeSpan<Sp, 0, 0>(Sp{arr1});
185
186 testRuntimeSpan<Sp, 1, 2>(Sp{arr1});
187 testRuntimeSpan<Sp, 2, 1>(Sp{arr1});
188 testRuntimeSpan<Sp, 3, 0>(Sp{arr1});
189 }
190
191 {
192 using Sp = std::span<int>;
193 testRuntimeSpan<Sp, 0>(Sp{});
194
195 testRuntimeSpan<Sp, 0>(Sp{arr1});
196 testRuntimeSpan<Sp, 1>(Sp{arr1});
197 testRuntimeSpan<Sp, 2>(Sp{arr1});
198 testRuntimeSpan<Sp, 3>(Sp{arr1});
199 }
200
201 {
202 using Sp = std::span<int, 3>;
203
204 testRuntimeSpan<Sp, 0>(Sp{arr1});
205 testRuntimeSpan<Sp, 1>(Sp{arr1});
206 testRuntimeSpan<Sp, 2>(Sp{arr1});
207 testRuntimeSpan<Sp, 3>(Sp{arr1});
208 }
JF Bastien2df59c52019-02-04 20:31:13 +0000209
210 return 0;
Marshall Clow8a0794b2018-07-24 03:01:02 +0000211}