types.pass.cpp (3956B)
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<class ElementType, ptrdiff_t Extent = dynamic_extent> 15 // class span { 16 // public: 17 // // constants and types 18 // using element_type = ElementType; 19 // using value_type = remove_cv_t<ElementType>; 20 // using index_type = ptrdiff_t; 21 // using difference_type = ptrdiff_t; 22 // using pointer = element_type *; 23 // using reference = 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 index_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 Iter> 52 void testConstIterator() 53 { 54 typedef std::iterator_traits<Iter> ItT; 55 56 ASSERT_SAME_TYPE(typename ItT::iterator_category, std::random_access_iterator_tag); 57 ASSERT_SAME_TYPE(typename ItT::value_type, typename S::value_type); 58 // I'd like to say 'const typename S::pointer' here, but that gives me 59 // a const pointer to a non-const value, which is not what I want. 60 ASSERT_SAME_TYPE(typename ItT::reference, typename S::element_type const &); 61 ASSERT_SAME_TYPE(typename ItT::pointer, typename S::element_type const *); 62 ASSERT_SAME_TYPE(typename ItT::difference_type, typename S::difference_type); 63 } 64 65 template <typename S, typename ElementType, std::ptrdiff_t Size> 66 void testSpan() 67 { 68 ASSERT_SAME_TYPE(typename S::element_type, ElementType); 69 ASSERT_SAME_TYPE(typename S::value_type, std::remove_cv_t<ElementType>); 70 ASSERT_SAME_TYPE(typename S::index_type, std::ptrdiff_t); 71 ASSERT_SAME_TYPE(typename S::difference_type, std::ptrdiff_t); 72 ASSERT_SAME_TYPE(typename S::pointer, ElementType *); 73 ASSERT_SAME_TYPE(typename S::reference, ElementType &); 74 75 static_assert(S::extent == Size); // check that it exists 76 77 testIterator<S, typename S::iterator>(); 78 testIterator<S, typename S::reverse_iterator>(); 79 testConstIterator<S, typename S::const_iterator>(); 80 testConstIterator<S, typename S::const_reverse_iterator>(); 81 } 82 83 84 template <typename T> 85 void test() 86 { 87 testSpan<std::span< T>, T, -1>(); 88 testSpan<std::span<const T>, const T, -1>(); 89 testSpan<std::span< volatile T>, volatile T, -1>(); 90 testSpan<std::span<const volatile T>, const volatile T, -1>(); 91 92 testSpan<std::span< T, 5>, T, 5>(); 93 testSpan<std::span<const T, 5>, const T, 5>(); 94 testSpan<std::span< volatile T, 5>, volatile T, 5>(); 95 testSpan<std::span<const volatile T, 5>, const volatile T, 5>(); 96 } 97 98 struct A{}; 99 100 int main () 101 { 102 test<int>(); 103 test<long>(); 104 test<double>(); 105 test<std::string>(); 106 test<A>(); 107 }