1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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);
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);
21 // We test the cartesian product, so we sometimes compare differently signed types
22 // ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-sign-compare
23 // MSVC warning C4242: 'argument': conversion from 'int' to 'const _Ty', possible loss of data
24 // MSVC warning C4244: 'argument': conversion from 'wchar_t' to 'const _Ty', possible loss of data
25 // MSVC warning C4389: '==': signed/unsigned mismatch
26 // ADDITIONAL_COMPILE_FLAGS(cl-style-warnings): /wd4242 /wd4244 /wd4389
32 #include "test_iterators.h"
33 #include "test_macros.h"
34 #include "type_algorithms.h"
36 template <class UnderlyingType
, class Iter1
>
38 template <class Iter2
>
39 TEST_CONSTEXPR_CXX20
void operator()() {
40 UnderlyingType a
[] = {0, 1, 2, 3, 4, 5};
41 const unsigned s
= sizeof(a
) / sizeof(a
[0]);
42 UnderlyingType b
[s
] = {0, 1, 2, 5, 4, 5};
44 assert(std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(a
)));
45 assert(!std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(b
)));
47 #if TEST_STD_VER >= 14
48 assert(std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(a
), std::equal_to
<>()));
49 assert(!std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(b
), std::equal_to
<>()));
51 assert(std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(a
), Iter2(a
+ s
)));
52 assert(!std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(a
), Iter2(a
+ s
- 1)));
53 assert(!std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(b
), Iter2(b
+ s
)));
55 assert(std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(a
), Iter2(a
+ s
), std::equal_to
<>()));
56 assert(!std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(a
), Iter2(a
+ s
- 1), std::equal_to
<>()));
57 assert(!std::equal(Iter1(a
), Iter1(a
+ s
), Iter2(b
), Iter2(b
+ s
), std::equal_to
<>()));
62 struct TestNarrowingEqualTo
{
63 template <class UnderlyingType
>
64 TEST_CONSTEXPR_CXX20
void operator()() {
66 // MSVC warning C4310: cast truncates constant value
67 TEST_MSVC_DIAGNOSTIC_IGNORED(4310)
69 UnderlyingType a
[] = {
70 UnderlyingType(0x1000),
71 UnderlyingType(0x1001),
72 UnderlyingType(0x1002),
73 UnderlyingType(0x1003),
74 UnderlyingType(0x1004)};
75 UnderlyingType b
[] = {
76 UnderlyingType(0x1600),
77 UnderlyingType(0x1601),
78 UnderlyingType(0x1602),
79 UnderlyingType(0x1603),
80 UnderlyingType(0x1604)};
84 assert(std::equal(a
, a
+ 5, b
, std::equal_to
<char>()));
85 #if TEST_STD_VER >= 14
86 assert(std::equal(a
, a
+ 5, b
, b
+ 5, std::equal_to
<char>()));
91 template <class UnderlyingType
, class TypeList
>
93 template <class Iter1
>
94 TEST_CONSTEXPR_CXX20
void operator()() {
95 types::for_each(TypeList(), Test
<UnderlyingType
, Iter1
>());
99 struct AddressCompare
{
101 TEST_CONSTEXPR_CXX20
AddressCompare(int) {}
103 operator char() { return static_cast<char>(i
); }
105 friend TEST_CONSTEXPR_CXX20
bool operator==(const AddressCompare
& lhs
, const AddressCompare
& rhs
) {
109 friend TEST_CONSTEXPR_CXX20
bool operator!=(const AddressCompare
& lhs
, const AddressCompare
& rhs
) {
114 #if TEST_STD_VER >= 20
115 class trivially_equality_comparable
{
117 constexpr trivially_equality_comparable(int i
) : i_(i
) {}
118 bool operator==(const trivially_equality_comparable
&) const = default;
126 TEST_CONSTEXPR_CXX20
bool test() {
127 types::for_each(types::cpp17_input_iterator_list
<int*>(), TestIter2
<int, types::cpp17_input_iterator_list
<int*> >());
129 types::cpp17_input_iterator_list
<char*>(), TestIter2
<char, types::cpp17_input_iterator_list
<char*> >());
130 types::for_each(types::cpp17_input_iterator_list
<AddressCompare
*>(),
131 TestIter2
<AddressCompare
, types::cpp17_input_iterator_list
<AddressCompare
*> >());
133 types::for_each(types::integral_types(), TestNarrowingEqualTo());
135 #if TEST_STD_VER >= 20
137 types::cpp17_input_iterator_list
<trivially_equality_comparable
*>{},
138 TestIter2
<trivially_equality_comparable
, types::cpp17_input_iterator_list
<trivially_equality_comparable
*>>{});
145 struct Derived
: virtual Base
{};
152 T a
[] = {1, 2, 3, 4, 5, 6};
153 U b
[] = {1, 2, 3, 4, 5, 6};
154 assert(std::equal(a
, a
+ 6, b
));
160 types::for_each(types::integer_types(), Test
<T
>());
164 int main(int, char**) {
166 #if TEST_STD_VER >= 20
167 static_assert(test());
170 types::for_each(types::integer_types(), TestTypes());
171 types::for_each(types::as_pointers
<types::cv_qualified_versions
<int> >(),
172 TestIter2
<int, types::as_pointers
<types::cv_qualified_versions
<int> > >());
173 types::for_each(types::as_pointers
<types::cv_qualified_versions
<char> >(),
174 TestIter2
<char, types::as_pointers
<types::cv_qualified_versions
<char> > >());
178 Derived
* a
[] = {&d
, nullptr};
179 Base
* b
[] = {&d
, nullptr};
181 assert(std::equal(a
, a
+ 2, b
));
182 #if TEST_STD_VER >= 14
183 assert(std::equal(a
, a
+ 2, b
, b
+ 2));