Commit 82facf68 authored by Matthias Vallentin's avatar Matthias Vallentin

Add operator< for variant

parent 640a55e7
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#pragma once #pragma once
#include <functional>
#include <type_traits> #include <type_traits>
#include "caf/config.hpp" #include "caf/config.hpp"
...@@ -417,7 +418,7 @@ bool holds_alternative(const variant<Ts...>& data) { ...@@ -417,7 +418,7 @@ bool holds_alternative(const variant<Ts...>& data) {
} }
/// @relates variant /// @relates variant
template <class T> template <class T, template <class> class Predicate>
struct variant_compare_helper { struct variant_compare_helper {
using result_type = bool; using result_type = bool;
const T& lhs; const T& lhs;
...@@ -427,21 +428,21 @@ struct variant_compare_helper { ...@@ -427,21 +428,21 @@ struct variant_compare_helper {
template <class U> template <class U>
bool operator()(const U& rhs) const { bool operator()(const U& rhs) const {
auto ptr = get_if<U>(&lhs); auto ptr = get_if<U>(&lhs);
return ptr ? *ptr == rhs : false; return ptr && Predicate<U>{}(*ptr, rhs);
} }
}; };
/// @relates variant /// @relates variant
template <class... Ts> template <class... Ts>
bool operator==(const variant<Ts...>& x, const variant<Ts...>& y) { bool operator==(const variant<Ts...>& x, const variant<Ts...>& y) {
variant_compare_helper<variant<Ts...>> f{x}; variant_compare_helper<variant<Ts...>, std::equal_to> f{x};
return visit(f, y); return visit(f, y);
} }
/// @relates variant /// @relates variant
template <class T, class... Ts> template <class T, class... Ts>
bool operator==(const T& x, const variant<Ts...>& y) { bool operator==(const T& x, const variant<Ts...>& y) {
variant_compare_helper<variant<Ts...>> f{y}; variant_compare_helper<variant<Ts...>, std::equal_to> f{y};
return f(x); return f(x);
} }
...@@ -451,6 +452,58 @@ bool operator==(const variant<Ts...>& x, const T& y) { ...@@ -451,6 +452,58 @@ bool operator==(const variant<Ts...>& x, const T& y) {
return y == x; return y == x;
} }
/// @relates variant
template <class... Ts>
bool operator<(const variant<Ts...>& x, const variant<Ts...>& y) {
if (y.valueless_by_exception())
return false;
if (x.valueless_by_exception())
return true;
if (x.index() != y.index())
return x.index() < y.index();
variant_compare_helper<variant<Ts...>, std::less> f{x};
return visit(f, y);
}
/// @relates variant
template <class... Ts>
bool operator>(const variant<Ts...>& x, const variant<Ts...>& y) {
if (x.valueless_by_exception())
return false;
if (y.valueless_by_exception())
return true;
if (x.index() != y.index())
return x.index() > y.index();
variant_compare_helper<variant<Ts...>, std::greater> f{x};
return visit(f, y);
}
/// @relates variant
template <class... Ts>
bool operator<=(const variant<Ts...>& x, const variant<Ts...>& y) {
if (x.valueless_by_exception())
return true;
if (y.valueless_by_exception())
return false;
if (x.index() != y.index())
return x.index() < y.index();
variant_compare_helper<variant<Ts...>, std::less_equal> f{x};
return visit(f, y);
}
/// @relates variant
template <class... Ts>
bool operator>=(const variant<Ts...>& x, const variant<Ts...>& y) {
if (y.valueless_by_exception())
return true;
if (x.valueless_by_exception())
return false;
if (x.index() != y.index())
return x.index() >= y.index();
variant_compare_helper<variant<Ts...>, std::greater_equal> f{x};
return visit(f, y);
}
/// @relates variant /// @relates variant
template <class T> template <class T>
struct variant_reader { struct variant_reader {
......
...@@ -149,3 +149,23 @@ CAF_TEST(n_ary_visit) { ...@@ -149,3 +149,23 @@ CAF_TEST(n_ary_visit) {
CAF_CHECK_EQUAL(visit(f, a, b, c, d), "(42, 'foo', \"bar\", 123)"); CAF_CHECK_EQUAL(visit(f, a, b, c, d), "(42, 'foo', \"bar\", 123)");
} }
CAF_TEST(less_than) {
using variant_type = variant<char, int>;
auto a = variant_type{'x'};
auto b = variant_type{'y'};
CAF_CHECK(a < b);
CAF_CHECK(!(a > b));
CAF_CHECK(a <= b);
CAF_CHECK(!(a >= b));
b = 42;
CAF_CHECK(a < b);
CAF_CHECK(!(a > b));
CAF_CHECK(a <= b);
CAF_CHECK(!(a >= b));
a = 42;
CAF_CHECK(!(a < b));
CAF_CHECK(!(a > b));
CAF_CHECK(a <= b);
CAF_CHECK(a >= b);
b = 'x';
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment