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 // ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-sign-compare 10 // MSVC warning C4389: '==': signed/unsigned mismatch 11 // ADDITIONAL_COMPILE_FLAGS(cl-style-warnings): /wd4389 12 13 // <algorithm> 14 15 // template<InputIterator Iter, class T> 16 // requires HasEqualTo<Iter::value_type, T> 17 // constexpr Iter // constexpr after C++17 18 // find(Iter first, Iter last, const T& value); 19 20 #include <algorithm> 21 #include <cassert> 22 #include <vector> 23 #include <type_traits> 24 25 #include "test_macros.h" 26 #include "test_iterators.h" 27 #include "type_algorithms.h" 28 29 static std::vector<int> comparable_data; 30 31 template <class ArrayT, class CompareT> 32 struct Test { 33 template <class Iter> 34 TEST_CONSTEXPR_CXX20 void operator()() { 35 ArrayT arr[] = { 36 ArrayT(1), ArrayT(2), ArrayT(3), ArrayT(4), ArrayT(5), ArrayT(6), ArrayT(7), ArrayT(8), ArrayT(9), ArrayT(10)}; 37 38 static_assert(std::is_same<decltype(std::find(Iter(arr), Iter(arr), 0)), Iter>::value, ""); 39 40 { // first element matches 41 Iter iter = std::find(Iter(arr), Iter(arr + 10), CompareT(1)); 42 assert(*iter == ArrayT(1)); 43 assert(base(iter) == arr); 44 } 45 46 { // range is empty; return last 47 Iter iter = std::find(Iter(arr), Iter(arr), CompareT(1)); 48 assert(base(iter) == arr); 49 } 50 51 { // if multiple elements match, return the first match 52 ArrayT data[] = { 53 ArrayT(1), ArrayT(2), ArrayT(3), ArrayT(4), ArrayT(5), ArrayT(6), ArrayT(7), ArrayT(5), ArrayT(4)}; 54 Iter iter = std::find(Iter(std::begin(data)), Iter(std::end(data)), CompareT(5)); 55 assert(*iter == ArrayT(5)); 56 assert(base(iter) == data + 4); 57 } 58 59 { // some element matches 60 Iter iter = std::find(Iter(arr), Iter(arr + 10), CompareT(6)); 61 assert(*iter == ArrayT(6)); 62 assert(base(iter) == arr + 5); 63 } 64 65 { // last element matches 66 Iter iter = std::find(Iter(arr), Iter(arr + 10), CompareT(10)); 67 assert(*iter == ArrayT(10)); 68 assert(base(iter) == arr + 9); 69 } 70 71 { // if no element matches, last is returned 72 Iter iter = std::find(Iter(arr), Iter(arr + 10), CompareT(20)); 73 assert(base(iter) == arr + 10); 74 } 75 76 if (!TEST_IS_CONSTANT_EVALUATED) 77 comparable_data.clear(); 78 } 79 }; 80 81 template <class IndexT> 82 class Comparable { 83 IndexT index_; 84 85 static IndexT init_index(IndexT i) { 86 IndexT size = static_cast<IndexT>(comparable_data.size()); 87 comparable_data.push_back(i); 88 return size; 89 } 90 91 public: 92 Comparable(IndexT i) : index_(init_index(i)) {} 93 94 friend bool operator==(const Comparable& lhs, const Comparable& rhs) { 95 return comparable_data[lhs.index_] == comparable_data[rhs.index_]; 96 } 97 }; 98 99 #if TEST_STD_VER >= 20 100 template <class ElementT> 101 class TriviallyComparable { 102 ElementT el_; 103 104 public: 105 explicit constexpr TriviallyComparable(ElementT el) : el_(el) {} 106 bool operator==(const TriviallyComparable&) const = default; 107 }; 108 #endif 109 110 template <class CompareT> 111 struct TestTypes { 112 template <class T> 113 TEST_CONSTEXPR_CXX20 void operator()() { 114 types::for_each(types::cpp17_input_iterator_list<T*>(), Test<T, CompareT>()); 115 } 116 }; 117 118 TEST_CONSTEXPR_CXX20 bool test() { 119 types::for_each(types::integer_types(), TestTypes<char>()); 120 types::for_each(types::integer_types(), TestTypes<int>()); 121 types::for_each(types::integer_types(), TestTypes<long long>()); 122 #if TEST_STD_VER >= 20 123 Test<TriviallyComparable<char>, TriviallyComparable<char>>().operator()<TriviallyComparable<char>*>(); 124 Test<TriviallyComparable<wchar_t>, TriviallyComparable<wchar_t>>().operator()<TriviallyComparable<wchar_t>*>(); 125 #endif 126 127 return true; 128 } 129 130 int main(int, char**) { 131 test(); 132 #if TEST_STD_VER >= 20 133 static_assert(test()); 134 #endif 135 136 Test<Comparable<char>, Comparable<char> >().operator()<Comparable<char>*>(); 137 Test<Comparable<wchar_t>, Comparable<wchar_t> >().operator()<Comparable<wchar_t>*>(); 138 139 return 0; 140 } 141