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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
9 | |
10 | // <span> |
11 | |
12 | // template<class ElementType, size_t Extent = dynamic_extent> |
13 | // class span { |
14 | // public: |
15 | // // constants and types |
16 | // using element_type = ElementType; |
17 | // using value_type = remove_cv_t<ElementType>; |
18 | // using size_type = size_t; |
19 | // using difference_type = ptrdiff_t; |
20 | // using pointer = element_type *; |
21 | // using reference = element_type &; |
22 | // using const_pointer = const element_type *; |
23 | // using const_reference = const element_type &; |
24 | // using iterator = implementation-defined; |
25 | // using const_iterator = implementation-defined; |
26 | // using reverse_iterator = std::reverse_iterator<iterator>; |
27 | // using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
28 | // |
29 | // static constexpr size_type extent = Extent; |
30 | // |
31 | |
32 | #include <span> |
33 | #include <cassert> |
34 | #include <iterator> |
35 | #include <string> |
36 | |
37 | #include "test_macros.h" |
38 | |
39 | template <typename S, typename Iter> |
40 | void testIterator() |
41 | { |
42 | typedef std::iterator_traits<Iter> ItT; |
43 | |
44 | ASSERT_SAME_TYPE(typename ItT::iterator_category, std::random_access_iterator_tag); |
45 | ASSERT_SAME_TYPE(typename ItT::value_type, typename S::value_type); |
46 | ASSERT_SAME_TYPE(typename ItT::reference, typename S::reference); |
47 | ASSERT_SAME_TYPE(typename ItT::pointer, typename S::pointer); |
48 | ASSERT_SAME_TYPE(typename ItT::difference_type, typename S::difference_type); |
49 | } |
50 | |
51 | template <typename S, typename ElementType, std::size_t Size> |
52 | void testSpan() |
53 | { |
54 | ASSERT_SAME_TYPE(typename S::element_type, ElementType); |
55 | ASSERT_SAME_TYPE(typename S::value_type, std::remove_cv_t<ElementType>); |
56 | ASSERT_SAME_TYPE(typename S::size_type, std::size_t); |
57 | ASSERT_SAME_TYPE(typename S::difference_type, std::ptrdiff_t); |
58 | ASSERT_SAME_TYPE(typename S::pointer, ElementType *); |
59 | ASSERT_SAME_TYPE(typename S::const_pointer, const ElementType *); |
60 | ASSERT_SAME_TYPE(typename S::reference, ElementType &); |
61 | ASSERT_SAME_TYPE(typename S::const_reference, const ElementType &); |
62 | |
63 | static_assert(S::extent == Size); // check that it exists |
64 | |
65 | testIterator<S, typename S::iterator>(); |
66 | testIterator<S, typename S::reverse_iterator>(); |
67 | } |
68 | |
69 | |
70 | template <typename T> |
71 | void test() |
72 | { |
73 | testSpan<std::span< T>, T, std::dynamic_extent>(); |
74 | testSpan<std::span<const T>, const T, std::dynamic_extent>(); |
75 | testSpan<std::span< volatile T>, volatile T, std::dynamic_extent>(); |
76 | testSpan<std::span<const volatile T>, const volatile T, std::dynamic_extent>(); |
77 | |
78 | testSpan<std::span< T, 5>, T, 5>(); |
79 | testSpan<std::span<const T, 5>, const T, 5>(); |
80 | testSpan<std::span< volatile T, 5>, volatile T, 5>(); |
81 | testSpan<std::span<const volatile T, 5>, const volatile T, 5>(); |
82 | } |
83 | |
84 | struct A{}; |
85 | |
86 | int main(int, char**) |
87 | { |
88 | test<int>(); |
89 | test<long>(); |
90 | test<double>(); |
91 | test<std::string>(); |
92 | test<A>(); |
93 | |
94 | return 0; |
95 | } |
96 | |