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 9 // <algorithm> 10 11 // template<InputIterator Iter1, InputIterator Iter2> 12 // requires HasEqualTo<Iter1::value_type, Iter2::value_type> 13 // constexpr bool // constexpr after c++17 14 // equal(Iter1 first1, Iter1 last1, Iter2 first2); 15 // 16 // Introduced in C++14: 17 // template<InputIterator Iter1, InputIterator Iter2> 18 // constexpr bool // constexpr after c++17 19 // equal(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2); 20 21 #include <algorithm> 22 #include <cassert> 23 #include <functional> 24 25 #include "test_iterators.h" 26 #include "test_macros.h" 27 #include "type_algorithms.h" 28 29 template <class UnderlyingType, class Iter1> 30 struct Test { 31 template <class Iter2> 32 TEST_CONSTEXPR_CXX20 void operator()() { 33 UnderlyingType a[] = {0, 1, 2, 3, 4, 5}; 34 const unsigned s = sizeof(a) / sizeof(a[0]); 35 UnderlyingType b[s] = {0, 1, 2, 5, 4, 5}; 36 37 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a))); 38 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b))); 39 40 #if TEST_STD_VER >= 14 41 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), std::equal_to<>())); 42 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), std::equal_to<>())); 43 44 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s))); 45 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s - 1))); 46 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), Iter2(b + s))); 47 48 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s), std::equal_to<>())); 49 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s - 1), std::equal_to<>())); 50 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), Iter2(b + s), std::equal_to<>())); 51 #endif 52 } 53 }; 54 55 struct TestNarrowingEqualTo { 56 template <class UnderlyingType> 57 TEST_CONSTEXPR_CXX20 void operator()() { 58 UnderlyingType a[] = { 59 UnderlyingType(0x1000), 60 UnderlyingType(0x1001), 61 UnderlyingType(0x1002), 62 UnderlyingType(0x1003), 63 UnderlyingType(0x1004)}; 64 UnderlyingType b[] = { 65 UnderlyingType(0x1600), 66 UnderlyingType(0x1601), 67 UnderlyingType(0x1602), 68 UnderlyingType(0x1603), 69 UnderlyingType(0x1604)}; 70 71 assert(std::equal(a, a + 5, b, std::equal_to<char>())); 72 #if TEST_STD_VER >= 14 73 assert(std::equal(a, a + 5, b, b + 5, std::equal_to<char>())); 74 #endif 75 } 76 }; 77 78 template <class UnderlyingType, class TypeList> 79 struct TestIter2 { 80 template <class Iter1> 81 TEST_CONSTEXPR_CXX20 void operator()() { 82 meta::for_each(TypeList(), Test<UnderlyingType, Iter1>()); 83 } 84 }; 85 86 struct AddressCompare { 87 int i = 0; 88 TEST_CONSTEXPR_CXX20 AddressCompare(int) {} 89 90 operator char() { return static_cast<char>(i); } 91 92 friend TEST_CONSTEXPR_CXX20 bool operator==(const AddressCompare& lhs, const AddressCompare& rhs) { 93 return &lhs == &rhs; 94 } 95 96 friend TEST_CONSTEXPR_CXX20 bool operator!=(const AddressCompare& lhs, const AddressCompare& rhs) { 97 return &lhs != &rhs; 98 } 99 }; 100 101 TEST_CONSTEXPR_CXX20 bool test() { 102 meta::for_each(meta::cpp17_input_iterator_list<int*>(), TestIter2<int, meta::cpp17_input_iterator_list<int*> >()); 103 meta::for_each(meta::cpp17_input_iterator_list<char*>(), TestIter2<char, meta::cpp17_input_iterator_list<char*> >()); 104 meta::for_each(meta::cpp17_input_iterator_list<AddressCompare*>(), 105 TestIter2<AddressCompare, meta::cpp17_input_iterator_list<AddressCompare*> >()); 106 107 meta::for_each(meta::integral_types(), TestNarrowingEqualTo()); 108 109 return true; 110 } 111 112 struct Base {}; 113 struct Derived : virtual Base {}; 114 115 int main(int, char**) { 116 test(); 117 #if TEST_STD_VER >= 20 118 static_assert(test()); 119 #endif 120 121 meta::for_each(meta::as_pointers<meta::cv_qualified_versions<int> >(), 122 TestIter2<int, meta::as_pointers<meta::cv_qualified_versions<int> > >()); 123 meta::for_each(meta::as_pointers<meta::cv_qualified_versions<char> >(), 124 TestIter2<char, meta::as_pointers<meta::cv_qualified_versions<char> > >()); 125 126 { 127 Derived d; 128 Derived* a[] = {&d, nullptr}; 129 Base* b[] = {&d, nullptr}; 130 131 assert(std::equal(a, a + 2, b)); 132 #if TEST_STD_VER >= 14 133 assert(std::equal(a, a + 2, b, b + 2)); 134 #endif 135 } 136 137 return 0; 138 } 139