• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- C++ -*-
2 //===------------------------------ span ---------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===---------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
11 
12 // <span>
13 
14 // template<ptrdiff_t Count>
15 //  constexpr span<element_type, Count> last() const;
16 //
17 // constexpr span<element_type, dynamic_extent> last(index_type count) const;
18 //
19 //  Requires: 0 <= Count && Count <= size().
20 
21 
22 #include <span>
23 #include <cassert>
24 #include <algorithm>
25 #include <string>
26 
27 #include "test_macros.h"
28 
29 template <typename Span, ptrdiff_t Count>
testConstexprSpan(Span sp)30 constexpr bool testConstexprSpan(Span sp)
31 {
32     LIBCPP_ASSERT((noexcept(sp.template last<Count>())));
33     LIBCPP_ASSERT((noexcept(sp.last(Count))));
34     auto s1 = sp.template last<Count>();
35     auto s2 = sp.last(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 == 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.end() - Count);
46 }
47 
48 
49 template <typename Span, ptrdiff_t Count>
testRuntimeSpan(Span sp)50 void testRuntimeSpan(Span sp)
51 {
52     LIBCPP_ASSERT((noexcept(sp.template last<Count>())));
53     LIBCPP_ASSERT((noexcept(sp.last(Count))));
54     auto s1 = sp.template last<Count>();
55     auto s2 = sp.last(Count);
56     using S1 = decltype(s1);
57     using S2 = decltype(s2);
58     ASSERT_SAME_TYPE(typename Span::value_type, typename S1::value_type);
59     ASSERT_SAME_TYPE(typename Span::value_type, typename S2::value_type);
60     static_assert(S1::extent == Count, "");
61     static_assert(S2::extent == std::dynamic_extent, "");
62     assert(s1.data() == s2.data());
63     assert(s1.size() == s2.size());
64     assert(std::equal(s1.begin(), s1.end(), sp.end() - Count));
65 }
66 
67 
68 constexpr int carr1[] = {1,2,3,4};
69           int   arr[] = {5,6,7};
70 std::string   sarr [] = { "ABC", "DEF", "GHI", "JKL", "MNO"};
71 
main()72 int main ()
73 {
74     {
75     using Sp = std::span<const int>;
76     static_assert(testConstexprSpan<Sp, 0>(Sp{}), "");
77 
78     static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
79     static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
80     static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
81     static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
82     static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
83     }
84 
85     {
86     using Sp = std::span<const int, 4>;
87 
88     static_assert(testConstexprSpan<Sp, 0>(Sp{carr1}), "");
89     static_assert(testConstexprSpan<Sp, 1>(Sp{carr1}), "");
90     static_assert(testConstexprSpan<Sp, 2>(Sp{carr1}), "");
91     static_assert(testConstexprSpan<Sp, 3>(Sp{carr1}), "");
92     static_assert(testConstexprSpan<Sp, 4>(Sp{carr1}), "");
93     }
94 
95     {
96     using Sp = std::span<int>;
97     testRuntimeSpan<Sp, 0>(Sp{});
98 
99     testRuntimeSpan<Sp, 0>(Sp{arr});
100     testRuntimeSpan<Sp, 1>(Sp{arr});
101     testRuntimeSpan<Sp, 2>(Sp{arr});
102     testRuntimeSpan<Sp, 3>(Sp{arr});
103     }
104 
105     {
106     using Sp = std::span<int, 3>;
107 
108     testRuntimeSpan<Sp, 0>(Sp{arr});
109     testRuntimeSpan<Sp, 1>(Sp{arr});
110     testRuntimeSpan<Sp, 2>(Sp{arr});
111     testRuntimeSpan<Sp, 3>(Sp{arr});
112     }
113 
114     {
115     using Sp = std::span<std::string>;
116     testConstexprSpan<Sp, 0>(Sp{});
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     {
127     using Sp = std::span<std::string, 5>;
128 
129     testRuntimeSpan<Sp, 0>(Sp{sarr});
130     testRuntimeSpan<Sp, 1>(Sp{sarr});
131     testRuntimeSpan<Sp, 2>(Sp{sarr});
132     testRuntimeSpan<Sp, 3>(Sp{sarr});
133     testRuntimeSpan<Sp, 4>(Sp{sarr});
134     testRuntimeSpan<Sp, 5>(Sp{sarr});
135     }
136 }
137