299 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// <tuple>10 11// template <class... Types> class tuple;12 13// template<class... TTypes, class... UTypes>14// bool15// operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);16// template<tuple-like UTuple>17// friend constexpr bool operator==(const tuple& t, const UTuple& u); // since C++2318 19// UNSUPPORTED: c++0320 21#include <array>22#include <cassert>23#include <tuple>24 25#include "test_comparisons.h"26#include "test_macros.h"27 28#if TEST_STD_VER >= 2329# include <ranges>30#endif31#if TEST_STD_VER >= 2632# include <complex>33#endif34 35#if TEST_STD_VER >= 2636 37// Test SFINAE.38 39static_assert(std::equality_comparable<std::tuple<EqualityComparable>>);40static_assert(std::equality_comparable<std::tuple<EqualityComparable, EqualityComparable>>);41 42static_assert(!std::equality_comparable<std::tuple<NonComparable>>);43static_assert(!std::equality_comparable<std::tuple<EqualityComparable, NonComparable>>);44static_assert(!std::equality_comparable<std::tuple<NonComparable, EqualityComparable>>);45static_assert(!std::equality_comparable_with<std::tuple<EqualityComparable>, std::tuple<NonComparable>>);46static_assert(!std::equality_comparable_with<std::tuple<NonComparable>, std::tuple<EqualityComparable>>);47// Size mismatch.48static_assert(49 !std::equality_comparable_with<std::tuple<EqualityComparable>, std::tuple<EqualityComparable, EqualityComparable>>);50static_assert(51 !std::equality_comparable_with<std::tuple<EqualityComparable, EqualityComparable>, std::tuple<EqualityComparable>>);52 53// Heterogeneous comparisons.54// TODO: Use equality_comparable_with once other changes of tuple introduced in P2165R4 are implemented.55template <class T, class U>56concept can_eq_compare = requires(const T& t, const U& u) { t == u; };57 58static_assert(can_eq_compare<std::tuple<EqualityComparable>, std::array<EqualityComparable, 1>>);59static_assert(!can_eq_compare<std::tuple<EqualityComparable>, std::array<NonComparable, 1>>);60 61static_assert(can_eq_compare<std::tuple<EqualityComparable, EqualityComparable>,62 std::pair<EqualityComparable, EqualityComparable>>);63static_assert(64 !can_eq_compare<std::tuple<EqualityComparable, EqualityComparable>, std::pair<EqualityComparable, NonComparable>>);65 66static_assert(can_eq_compare<std::tuple<int*, int*>, std::ranges::subrange<const int*>>);67static_assert(!can_eq_compare<std::tuple<int (*)[1], int (*)[1]>, std::ranges::subrange<const int*>>);68static_assert(can_eq_compare<std::tuple<double, double>, std::complex<float>>);69static_assert(!can_eq_compare<std::tuple<int*, int*>, std::complex<float>>);70 71// Size mismatch in heterogeneous comparisons.72static_assert(!can_eq_compare<std::tuple<>, std::array<EqualityComparable, 2>>);73static_assert(!can_eq_compare<std::tuple<EqualityComparable>, std::array<EqualityComparable, 2>>);74static_assert(!can_eq_compare<std::tuple<>, std::pair<EqualityComparable, EqualityComparable>>);75static_assert(!can_eq_compare<std::tuple<EqualityComparable>, std::pair<EqualityComparable, EqualityComparable>>);76static_assert(!can_eq_compare<std::tuple<int*>, std::ranges::subrange<int*>>);77static_assert(!can_eq_compare<std::tuple<double>, std::complex<double>>);78 79#endif80 81TEST_CONSTEXPR_CXX14 bool test() {82 {83 typedef std::tuple<> T1;84 typedef std::tuple<> T2;85 const T1 t1;86 const T2 t2;87 assert(t1 == t2);88 assert(!(t1 != t2));89 }90 {91 typedef std::tuple<int> T1;92 typedef std::tuple<double> T2;93 const T1 t1(1);94 const T2 t2(1.1);95 assert(!(t1 == t2));96 assert(t1 != t2);97 }98 {99 typedef std::tuple<int> T1;100 typedef std::tuple<double> T2;101 const T1 t1(1);102 const T2 t2(1);103 assert(t1 == t2);104 assert(!(t1 != t2));105 }106 {107 typedef std::tuple<int, double> T1;108 typedef std::tuple<double, long> T2;109 const T1 t1(1, 2);110 const T2 t2(1, 2);111 assert(t1 == t2);112 assert(!(t1 != t2));113 }114 {115 typedef std::tuple<int, double> T1;116 typedef std::tuple<double, long> T2;117 const T1 t1(1, 2);118 const T2 t2(1, 3);119 assert(!(t1 == t2));120 assert(t1 != t2);121 }122 {123 typedef std::tuple<int, double> T1;124 typedef std::tuple<double, long> T2;125 const T1 t1(1, 2);126 const T2 t2(1.1, 2);127 assert(!(t1 == t2));128 assert(t1 != t2);129 }130 {131 typedef std::tuple<int, double> T1;132 typedef std::tuple<double, long> T2;133 const T1 t1(1, 2);134 const T2 t2(1.1, 3);135 assert(!(t1 == t2));136 assert(t1 != t2);137 }138 {139 typedef std::tuple<long, int, double> T1;140 typedef std::tuple<double, long, int> T2;141 const T1 t1(1, 2, 3);142 const T2 t2(1, 2, 3);143 assert(t1 == t2);144 assert(!(t1 != t2));145 }146 {147 typedef std::tuple<long, int, double> T1;148 typedef std::tuple<double, long, int> T2;149 const T1 t1(1, 2, 3);150 const T2 t2(1.1, 2, 3);151 assert(!(t1 == t2));152 assert(t1 != t2);153 }154 {155 typedef std::tuple<long, int, double> T1;156 typedef std::tuple<double, long, int> T2;157 const T1 t1(1, 2, 3);158 const T2 t2(1, 3, 3);159 assert(!(t1 == t2));160 assert(t1 != t2);161 }162 {163 typedef std::tuple<long, int, double> T1;164 typedef std::tuple<double, long, int> T2;165 const T1 t1(1, 2, 3);166 const T2 t2(1, 2, 4);167 assert(!(t1 == t2));168 assert(t1 != t2);169 }170 {171 typedef std::tuple<long, int, double> T1;172 typedef std::tuple<double, long, int> T2;173 const T1 t1(1, 2, 3);174 const T2 t2(1, 3, 2);175 assert(!(t1 == t2));176 assert(t1 != t2);177 }178 {179 typedef std::tuple<long, int, double> T1;180 typedef std::tuple<double, long, int> T2;181 const T1 t1(1, 2, 3);182 const T2 t2(1.1, 2, 2);183 assert(!(t1 == t2));184 assert(t1 != t2);185 }186 {187 typedef std::tuple<long, int, double> T1;188 typedef std::tuple<double, long, int> T2;189 const T1 t1(1, 2, 3);190 const T2 t2(1.1, 3, 3);191 assert(!(t1 == t2));192 assert(t1 != t2);193 }194 {195 typedef std::tuple<long, int, double> T1;196 typedef std::tuple<double, long, int> T2;197 const T1 t1(1, 2, 3);198 const T2 t2(1.1, 3, 2);199 assert(!(t1 == t2));200 assert(t1 != t2);201 }202#if TEST_STD_VER >= 14203 {204 using T1 = std::tuple<long, int, double>;205 using T2 = std::tuple<double, long, int>;206 constexpr T1 t1(1, 2, 3);207 constexpr T2 t2(1.1, 3, 2);208 assert(!(t1 == t2));209 assert(t1 != t2);210 }211#endif212#if TEST_STD_VER >= 23213 {214 using T1 = std::tuple<long, int>;215 using T2 = std::pair<double, long>;216 constexpr T1 t1{1, 2};217 constexpr T2 t2{1.0, 2};218 assert(t1 == t2);219 assert(!(t1 != t2));220 }221 {222 using T1 = std::tuple<long, int>;223 using T2 = std::pair<double, long>;224 constexpr T1 t1{1, 2};225 constexpr T2 t2{1.1, 3};226 assert(!(t1 == t2));227 assert(t1 != t2);228 }229 {230 using T1 = std::tuple<long, int>;231 using T2 = std::array<double, 2>;232 constexpr T1 t1{1, 2};233 constexpr T2 t2{1.0, 2.0};234 assert(t1 == t2);235 assert(!(t1 != t2));236 }237 {238 using T1 = std::tuple<long, int>;239 using T2 = std::array<double, 2>;240 constexpr T1 t1{1, 2};241 constexpr T2 t2{1.1, 3.0};242 assert(!(t1 == t2));243 assert(t1 != t2);244 }245 {246 using T1 = std::tuple<const int*, const int*>;247 using T2 = std::ranges::subrange<const int*>;248 249 int arr[1]{};250 T1 t1{arr, arr + 1};251 T2 t2{arr};252 assert(t1 == t2);253 assert(!(t1 != t2));254 }255 {256 using T1 = std::tuple<const int*, const int*>;257 using T2 = std::ranges::subrange<const int*>;258 259 int arr[1]{};260 T1 t1{arr, arr};261 T2 t2{arr};262 assert(!(t1 == t2));263 assert(t1 != t2);264 }265 {266 assert((std::tuple<>{} == std::array<int*, 0>{}));267 assert((std::tuple<>{} == std::array<double, 0>{}));268 }269#endif270#if TEST_STD_VER >= 26271 {272 using T1 = std::tuple<long, int>;273 using T2 = std::complex<double>;274 constexpr T1 t1{1, 2};275 constexpr T2 t2{1.0, 2.0};276 assert(t1 == t2);277 assert(!(t1 != t2));278 }279 {280 using T1 = std::tuple<long, int>;281 using T2 = std::complex<double>;282 constexpr T1 t1{1, 2};283 constexpr T2 t2{1.1, 3.0};284 assert(!(t1 == t2));285 assert(t1 != t2);286 }287#endif288 289 return true;290}291 292int main(int, char**) {293 test();294#if TEST_STD_VER >= 14295 static_assert(test(), "");296#endif297 return 0;298}299