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 // We test the cartesian product, so we somethimes compare differently signed types 22 // ADDITIONAL_COMPILE_FLAGS: -Wno-sign-compare 23 24 #include <algorithm> 25 #include <cassert> 26 #include <functional> 27 28 #include "test_iterators.h" 29 #include "test_macros.h" 30 #include "type_algorithms.h" 31 32 template <class UnderlyingType, class Iter1> 33 struct Test { 34 template <class Iter2> 35 TEST_CONSTEXPR_CXX20 void operator()() { 36 UnderlyingType a[] = {0, 1, 2, 3, 4, 5}; 37 const unsigned s = sizeof(a) / sizeof(a[0]); 38 UnderlyingType b[s] = {0, 1, 2, 5, 4, 5}; 39 40 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a))); 41 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b))); 42 43 #if TEST_STD_VER >= 14 44 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), std::equal_to<>())); 45 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), std::equal_to<>())); 46 47 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s))); 48 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s - 1))); 49 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), Iter2(b + s))); 50 51 assert(std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s), std::equal_to<>())); 52 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(a), Iter2(a + s - 1), std::equal_to<>())); 53 assert(!std::equal(Iter1(a), Iter1(a + s), Iter2(b), Iter2(b + s), std::equal_to<>())); 54 #endif 55 } 56 }; 57 58 struct TestNarrowingEqualTo { 59 template <class UnderlyingType> 60 TEST_CONSTEXPR_CXX20 void operator()() { 61 UnderlyingType a[] = { 62 UnderlyingType(0x1000), 63 UnderlyingType(0x1001), 64 UnderlyingType(0x1002), 65 UnderlyingType(0x1003), 66 UnderlyingType(0x1004)}; 67 UnderlyingType b[] = { 68 UnderlyingType(0x1600), 69 UnderlyingType(0x1601), 70 UnderlyingType(0x1602), 71 UnderlyingType(0x1603), 72 UnderlyingType(0x1604)}; 73 74 assert(std::equal(a, a + 5, b, std::equal_to<char>())); 75 #if TEST_STD_VER >= 14 76 assert(std::equal(a, a + 5, b, b + 5, std::equal_to<char>())); 77 #endif 78 } 79 }; 80 81 template <class UnderlyingType, class TypeList> 82 struct TestIter2 { 83 template <class Iter1> 84 TEST_CONSTEXPR_CXX20 void operator()() { 85 types::for_each(TypeList(), Test<UnderlyingType, Iter1>()); 86 } 87 }; 88 89 struct AddressCompare { 90 int i = 0; 91 TEST_CONSTEXPR_CXX20 AddressCompare(int) {} 92 93 operator char() { return static_cast<char>(i); } 94 95 friend TEST_CONSTEXPR_CXX20 bool operator==(const AddressCompare& lhs, const AddressCompare& rhs) { 96 return &lhs == &rhs; 97 } 98 99 friend TEST_CONSTEXPR_CXX20 bool operator!=(const AddressCompare& lhs, const AddressCompare& rhs) { 100 return &lhs != &rhs; 101 } 102 }; 103 104 #if TEST_STD_VER >= 20 105 class trivially_equality_comparable { 106 public: 107 constexpr trivially_equality_comparable(int i) : i_(i) {} 108 bool operator==(const trivially_equality_comparable&) const = default; 109 110 private: 111 int i_; 112 }; 113 114 #endif 115 116 TEST_CONSTEXPR_CXX20 bool test() { 117 types::for_each(types::cpp17_input_iterator_list<int*>(), TestIter2<int, types::cpp17_input_iterator_list<int*> >()); 118 types::for_each( 119 types::cpp17_input_iterator_list<char*>(), TestIter2<char, types::cpp17_input_iterator_list<char*> >()); 120 types::for_each(types::cpp17_input_iterator_list<AddressCompare*>(), 121 TestIter2<AddressCompare, types::cpp17_input_iterator_list<AddressCompare*> >()); 122 123 types::for_each(types::integral_types(), TestNarrowingEqualTo()); 124 125 #if TEST_STD_VER >= 20 126 types::for_each( 127 types::cpp17_input_iterator_list<trivially_equality_comparable*>{}, 128 TestIter2<trivially_equality_comparable, types::cpp17_input_iterator_list<trivially_equality_comparable*>>{}); 129 #endif 130 131 return true; 132 } 133 134 struct Base {}; 135 struct Derived : virtual Base {}; 136 137 struct TestTypes { 138 template <class T> 139 struct Test { 140 template <class U> 141 void operator()() { 142 T a[] = {1, 2, 3, 4, 5, 6}; 143 U b[] = {1, 2, 3, 4, 5, 6}; 144 assert(std::equal(a, a + 6, b)); 145 } 146 }; 147 148 template <class T> 149 void operator()() { 150 types::for_each(types::integer_types(), Test<T>()); 151 } 152 }; 153 154 int main(int, char**) { 155 test(); 156 #if TEST_STD_VER >= 20 157 static_assert(test()); 158 #endif 159 160 types::for_each(types::integer_types(), TestTypes()); 161 types::for_each(types::as_pointers<types::cv_qualified_versions<int> >(), 162 TestIter2<int, types::as_pointers<types::cv_qualified_versions<int> > >()); 163 types::for_each(types::as_pointers<types::cv_qualified_versions<char> >(), 164 TestIter2<char, types::as_pointers<types::cv_qualified_versions<char> > >()); 165 166 { 167 Derived d; 168 Derived* a[] = {&d, nullptr}; 169 Base* b[] = {&d, nullptr}; 170 171 assert(std::equal(a, a + 2, b)); 172 #if TEST_STD_VER >= 14 173 assert(std::equal(a, a + 2, b, b + 2)); 174 #endif 175 } 176 177 return 0; 178 } 179