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 types::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 #if TEST_STD_VER >= 20 102 class trivially_equality_comparable { 103 public: 104 constexpr trivially_equality_comparable(int i) : i_(i) {} 105 bool operator==(const trivially_equality_comparable&) const = default; 106 107 private: 108 int i_; 109 }; 110 111 #endif 112 113 TEST_CONSTEXPR_CXX20 bool test() { 114 types::for_each(types::cpp17_input_iterator_list<int*>(), TestIter2<int, types::cpp17_input_iterator_list<int*> >()); 115 types::for_each( 116 types::cpp17_input_iterator_list<char*>(), TestIter2<char, types::cpp17_input_iterator_list<char*> >()); 117 types::for_each(types::cpp17_input_iterator_list<AddressCompare*>(), 118 TestIter2<AddressCompare, types::cpp17_input_iterator_list<AddressCompare*> >()); 119 120 types::for_each(types::integral_types(), TestNarrowingEqualTo()); 121 122 #if TEST_STD_VER >= 20 123 types::for_each( 124 types::cpp17_input_iterator_list<trivially_equality_comparable*>{}, 125 TestIter2<trivially_equality_comparable, types::cpp17_input_iterator_list<trivially_equality_comparable*>>{}); 126 #endif 127 128 return true; 129 } 130 131 struct Base {}; 132 struct Derived : virtual Base {}; 133 134 int main(int, char**) { 135 test(); 136 #if TEST_STD_VER >= 20 137 static_assert(test()); 138 #endif 139 140 types::for_each(types::as_pointers<types::cv_qualified_versions<int> >(), 141 TestIter2<int, types::as_pointers<types::cv_qualified_versions<int> > >()); 142 types::for_each(types::as_pointers<types::cv_qualified_versions<char> >(), 143 TestIter2<char, types::as_pointers<types::cv_qualified_versions<char> > >()); 144 145 { 146 Derived d; 147 Derived* a[] = {&d, nullptr}; 148 Base* b[] = {&d, nullptr}; 149 150 assert(std::equal(a, a + 2, b)); 151 #if TEST_STD_VER >= 14 152 assert(std::equal(a, a + 2, b, b + 2)); 153 #endif 154 } 155 156 return 0; 157 } 158