brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.8 KiB · 2c00703 Raw
326 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// UNSUPPORTED: c++03, c++11, c++1410 11// <variant>12 13// template <class ...Types>14// constexpr bool15// operator==(variant<Types...> const&, variant<Types...> const&) noexcept;16//17// template <class ...Types>18// constexpr bool19// operator!=(variant<Types...> const&, variant<Types...> const&) noexcept;20//21// template <class ...Types>22// constexpr bool23// operator<(variant<Types...> const&, variant<Types...> const&) noexcept;24//25// template <class ...Types>26// constexpr bool27// operator>(variant<Types...> const&, variant<Types...> const&) noexcept;28//29// template <class ...Types>30// constexpr bool31// operator<=(variant<Types...> const&, variant<Types...> const&) noexcept;32//33// template <class ...Types>34// constexpr bool35// operator>=(variant<Types...> const&, variant<Types...> const&) noexcept;36 37#include <cassert>38#include <type_traits>39#include <utility>40#include <variant>41 42#include "test_comparisons.h"43#include "test_macros.h"44 45#if TEST_STD_VER >= 2646 47// Test SFINAE.48 49// ==50static_assert(HasOperatorEqual<std::variant<EqualityComparable>>);51static_assert(HasOperatorEqual<std::variant<EqualityComparable, int, long>>);52 53static_assert(!HasOperatorEqual<std::variant<NonComparable>>);54static_assert(!HasOperatorEqual<std::variant<NonComparable, EqualityComparable>>);55 56// >57static_assert(HasOperatorGreaterThan<std::variant<ThreeWayComparable>>);58static_assert(HasOperatorGreaterThan<std::variant<ThreeWayComparable, int, long>>);59 60static_assert(!HasOperatorGreaterThan<std::variant<NonComparable>>);61static_assert(!HasOperatorGreaterThan<std::variant<NonComparable, ThreeWayComparable>>);62 63// >=64static_assert(HasOperatorGreaterThanEqual<std::variant<ThreeWayComparable>>);65static_assert(HasOperatorGreaterThanEqual<std::variant<ThreeWayComparable, int, long>>);66 67static_assert(!HasOperatorGreaterThanEqual<std::variant<NonComparable>>);68static_assert(!HasOperatorGreaterThanEqual<std::variant<NonComparable, ThreeWayComparable>>);69 70// <71static_assert(HasOperatorLessThan<std::variant<ThreeWayComparable>>);72static_assert(HasOperatorLessThan<std::variant<ThreeWayComparable, int, long>>);73 74static_assert(!HasOperatorLessThan<std::variant<NonComparable>>);75static_assert(!HasOperatorLessThan<std::variant<NonComparable, ThreeWayComparable>>);76 77// <=78static_assert(HasOperatorLessThanEqual<std::variant<ThreeWayComparable>>);79static_assert(HasOperatorLessThanEqual<std::variant<ThreeWayComparable, int, long>>);80 81static_assert(!HasOperatorLessThanEqual<std::variant<NonComparable>>);82static_assert(!HasOperatorLessThanEqual<std::variant<NonComparable, ThreeWayComparable>>);83 84// !=85static_assert(HasOperatorNotEqual<std::variant<EqualityComparable>>);86static_assert(HasOperatorNotEqual<std::variant<EqualityComparable, int, long>>);87 88static_assert(!HasOperatorNotEqual<std::variant<NonComparable>>);89static_assert(!HasOperatorNotEqual<std::variant<NonComparable, EqualityComparable>>);90 91#endif92 93#ifndef TEST_HAS_NO_EXCEPTIONS94struct MakeEmptyT {95  MakeEmptyT() = default;96  MakeEmptyT(MakeEmptyT &&) { throw 42; }97  MakeEmptyT &operator=(MakeEmptyT &&) { throw 42; }98};99inline bool operator==(const MakeEmptyT &, const MakeEmptyT &) {100  assert(false);101  return false;102}103inline bool operator!=(const MakeEmptyT &, const MakeEmptyT &) {104  assert(false);105  return false;106}107inline bool operator<(const MakeEmptyT &, const MakeEmptyT &) {108  assert(false);109  return false;110}111inline bool operator<=(const MakeEmptyT &, const MakeEmptyT &) {112  assert(false);113  return false;114}115inline bool operator>(const MakeEmptyT &, const MakeEmptyT &) {116  assert(false);117  return false;118}119inline bool operator>=(const MakeEmptyT &, const MakeEmptyT &) {120  assert(false);121  return false;122}123 124template <class Variant> void makeEmpty(Variant &v) {125  Variant v2(std::in_place_type<MakeEmptyT>);126  try {127    v = std::move(v2);128    assert(false);129  } catch (...) {130    assert(v.valueless_by_exception());131  }132}133#endif // TEST_HAS_NO_EXCEPTIONS134 135struct MyBool {136  bool value;137  constexpr explicit MyBool(bool v) : value(v) {}138  constexpr operator bool() const noexcept { return value; }139};140 141struct ComparesToMyBool {142  int value = 0;143};144inline constexpr MyBool operator==(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {145  return MyBool(LHS.value == RHS.value);146}147inline constexpr MyBool operator!=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {148  return MyBool(LHS.value != RHS.value);149}150inline constexpr MyBool operator<(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {151  return MyBool(LHS.value < RHS.value);152}153inline constexpr MyBool operator<=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {154  return MyBool(LHS.value <= RHS.value);155}156inline constexpr MyBool operator>(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {157  return MyBool(LHS.value > RHS.value);158}159inline constexpr MyBool operator>=(const ComparesToMyBool& LHS, const ComparesToMyBool& RHS) noexcept {160  return MyBool(LHS.value >= RHS.value);161}162 163template <class T1, class T2>164void test_equality_basic() {165  {166    using V = std::variant<T1, T2>;167    constexpr V v1(std::in_place_index<0>, T1{42});168    constexpr V v2(std::in_place_index<0>, T1{42});169    static_assert(v1 == v2, "");170    static_assert(v2 == v1, "");171    static_assert(!(v1 != v2), "");172    static_assert(!(v2 != v1), "");173  }174  {175    using V = std::variant<T1, T2>;176    constexpr V v1(std::in_place_index<0>, T1{42});177    constexpr V v2(std::in_place_index<0>, T1{43});178    static_assert(!(v1 == v2), "");179    static_assert(!(v2 == v1), "");180    static_assert(v1 != v2, "");181    static_assert(v2 != v1, "");182  }183  {184    using V = std::variant<T1, T2>;185    constexpr V v1(std::in_place_index<0>, T1{42});186    constexpr V v2(std::in_place_index<1>, T2{42});187    static_assert(!(v1 == v2), "");188    static_assert(!(v2 == v1), "");189    static_assert(v1 != v2, "");190    static_assert(v2 != v1, "");191  }192  {193    using V = std::variant<T1, T2>;194    constexpr V v1(std::in_place_index<1>, T2{42});195    constexpr V v2(std::in_place_index<1>, T2{42});196    static_assert(v1 == v2, "");197    static_assert(v2 == v1, "");198    static_assert(!(v1 != v2), "");199    static_assert(!(v2 != v1), "");200  }201}202 203void test_equality() {204  test_equality_basic<int, long>();205  test_equality_basic<ComparesToMyBool, int>();206  test_equality_basic<int, ComparesToMyBool>();207  test_equality_basic<ComparesToMyBool, ComparesToMyBool>();208#ifndef TEST_HAS_NO_EXCEPTIONS209  {210    using V = std::variant<int, MakeEmptyT>;211    V v1;212    V v2;213    makeEmpty(v2);214    assert(!(v1 == v2));215    assert(!(v2 == v1));216    assert(v1 != v2);217    assert(v2 != v1);218  }219  {220    using V = std::variant<int, MakeEmptyT>;221    V v1;222    makeEmpty(v1);223    V v2;224    assert(!(v1 == v2));225    assert(!(v2 == v1));226    assert(v1 != v2);227    assert(v2 != v1);228  }229  {230    using V = std::variant<int, MakeEmptyT>;231    V v1;232    makeEmpty(v1);233    V v2;234    makeEmpty(v2);235    assert(v1 == v2);236    assert(v2 == v1);237    assert(!(v1 != v2));238    assert(!(v2 != v1));239  }240#endif241}242 243template <class Var>244constexpr bool test_less(const Var &l, const Var &r, bool expect_less,245                         bool expect_greater) {246  static_assert(std::is_same_v<decltype(l < r), bool>, "");247  static_assert(std::is_same_v<decltype(l <= r), bool>, "");248  static_assert(std::is_same_v<decltype(l > r), bool>, "");249  static_assert(std::is_same_v<decltype(l >= r), bool>, "");250 251  return ((l < r) == expect_less) && (!(l >= r) == expect_less) &&252         ((l > r) == expect_greater) && (!(l <= r) == expect_greater);253}254 255template <class T1, class T2>256void test_relational_basic() {257  { // same index, same value258    using V = std::variant<T1, T2>;259    constexpr V v1(std::in_place_index<0>, T1{1});260    constexpr V v2(std::in_place_index<0>, T1{1});261    static_assert(test_less(v1, v2, false, false), "");262  }263  { // same index, value < other_value264    using V = std::variant<T1, T2>;265    constexpr V v1(std::in_place_index<0>, T1{0});266    constexpr V v2(std::in_place_index<0>, T1{1});267    static_assert(test_less(v1, v2, true, false), "");268  }269  { // same index, value > other_value270    using V = std::variant<T1, T2>;271    constexpr V v1(std::in_place_index<0>, T1{1});272    constexpr V v2(std::in_place_index<0>, T1{0});273    static_assert(test_less(v1, v2, false, true), "");274  }275  { // LHS.index() < RHS.index()276    using V = std::variant<T1, T2>;277    constexpr V v1(std::in_place_index<0>, T1{0});278    constexpr V v2(std::in_place_index<1>, T2{0});279    static_assert(test_less(v1, v2, true, false), "");280  }281  { // LHS.index() > RHS.index()282    using V = std::variant<T1, T2>;283    constexpr V v1(std::in_place_index<1>, T2{0});284    constexpr V v2(std::in_place_index<0>, T1{0});285    static_assert(test_less(v1, v2, false, true), "");286  }287}288 289void test_relational() {290  test_relational_basic<int, long>();291  test_relational_basic<ComparesToMyBool, int>();292  test_relational_basic<int, ComparesToMyBool>();293  test_relational_basic<ComparesToMyBool, ComparesToMyBool>();294#ifndef TEST_HAS_NO_EXCEPTIONS295  { // LHS.index() < RHS.index(), RHS is empty296    using V = std::variant<int, MakeEmptyT>;297    V v1;298    V v2;299    makeEmpty(v2);300    assert(test_less(v1, v2, false, true));301  }302  { // LHS.index() > RHS.index(), LHS is empty303    using V = std::variant<int, MakeEmptyT>;304    V v1;305    makeEmpty(v1);306    V v2;307    assert(test_less(v1, v2, true, false));308  }309  { // LHS.index() == RHS.index(), LHS and RHS are empty310    using V = std::variant<int, MakeEmptyT>;311    V v1;312    makeEmpty(v1);313    V v2;314    makeEmpty(v2);315    assert(test_less(v1, v2, false, false));316  }317#endif318}319 320int main(int, char**) {321  test_equality();322  test_relational();323 324  return 0;325}326