blob: e0b30c8e898d872ee2d33b487acad45542c77956 [file] [log] [blame]
// { dg-do run { target c++26 } }
#include <optional>
#include <functional>
#include <testsuite_hooks.h>
#include <type_traits>
template<typename T, typename H = std::hash<T>>
constexpr bool has_disabled_hash
= !std::is_default_constructible_v<H>
&& !std::is_copy_constructible_v<H>
&& !std::is_move_constructible_v<H>
&& !std::is_copy_assignable_v<H>
&& !std::is_move_assignable_v<H>;
static_assert(has_disabled_hash<std::optional<int&>>);
static_assert(has_disabled_hash<std::optional<const int&>>);
template<typename T, typename V>
constexpr void
test_compare_val(V& l, V& h)
{
std::optional<T> t;
VERIFY( !(t == l) );
VERIFY( (t != l) );
VERIFY( (t < l) );
VERIFY( (t <= l) );
VERIFY( !(t > l) );
VERIFY( !(t >= l) );
VERIFY( (t <=> l) < 0 );
VERIFY( !(l == t) );
VERIFY( (l != t) );
VERIFY( !(l < t) );
VERIFY( !(l <= t) );
VERIFY( (l > t) );
VERIFY( (l >= t) );
VERIFY( (l <=> t) > 0 );
t.emplace(l);
VERIFY( (t == l) );
VERIFY( !(t != l) );
VERIFY( !(t < l) );
VERIFY( (t <= l) );
VERIFY( !(t > l) );
VERIFY( (t >= l) );
VERIFY( (t <=> l) == 0 );
VERIFY( (l == t) );
VERIFY( !(l != t) );
VERIFY( !(l < t) );
VERIFY( (l <= t) );
VERIFY( !(l > t) );
VERIFY( (l >= t) );
VERIFY( (t <=> l) == 0 );
t.emplace(h);
VERIFY( !(t == l) );
VERIFY( (t != l) );
VERIFY( !(t < l) );
VERIFY( !(t <= l) );
VERIFY( (t > l) );
VERIFY( (t >= l) );
VERIFY( (t <=> l) > 0 );
VERIFY( !(l == t) );
VERIFY( (l != t) );
VERIFY( (l < t) );
VERIFY( (l <= t) );
VERIFY( !(l > t) );
VERIFY( !(l >= t) );
VERIFY( (l <=> t) < 0 );
}
template<typename T, typename U, typename V>
constexpr void
test_compare_opts(V& l, V& h)
{
std::optional<T> t;
std::optional<U> u;
VERIFY( (t == u) );
VERIFY( !(t != u) );
VERIFY( !(t < u) );
VERIFY( (t <= u) );
VERIFY( !(t > u) );
VERIFY( (t >= u) );
VERIFY( (t <=> u) == 0 );
t.emplace(l);
VERIFY( !(t == u) );
VERIFY( (t != u) );
VERIFY( !(t < u) );
VERIFY( !(t <= u) );
VERIFY( (t > u) );
VERIFY( (t >= u) );
VERIFY( (t <=> u) > 0 );
u.emplace(l);
VERIFY( (t == u) );
VERIFY( !(t != u) );
VERIFY( !(t < u) );
VERIFY( (t <= u) );
VERIFY( !(t > u) );
VERIFY( (t <= u) );
VERIFY( (t <=> u) == 0 );
u.emplace(h);
VERIFY( !(t == u) );
VERIFY( (t != u) );
VERIFY( (t < u) );
VERIFY( (t <= u) );
VERIFY( !(t > u) );
VERIFY( !(t >= u) );
VERIFY( (t <=> u) < 0 );
t.reset();
u.emplace(l);
VERIFY( !(t == u) );
VERIFY( (t != u) );
VERIFY( (t < u) );
VERIFY( (t <= u) );
VERIFY( !(t > u) );
VERIFY( !(t >= u) );
VERIFY( (t <=> u) < 0 );
t.emplace(h);
VERIFY( !(t == u) );
VERIFY( (t != u) );
VERIFY( !(t < u) );
VERIFY( !(t <= u) );
VERIFY( (t > u) );
VERIFY( (t >= u) );
VERIFY( (t <=> u) > 0 );
}
template<typename V>
constexpr void
test_compare(V l, V h)
{
test_compare_val<V&>(l, h);
test_compare_val<const V&>(l, h);
test_compare_opts<V&, V&>(l, h);
test_compare_opts<V, V&>(l, h);
test_compare_opts<V&, V>(l, h);
test_compare_opts<const V&, const V&>(l, h);
test_compare_opts<V, const V&>(l, h);
test_compare_opts<const V&, V>(l, h);
test_compare_opts<V&, const V&>(l, h);
test_compare_opts<const V&, V&>(l, h);
}
struct TreeWay
{
int v;
friend auto operator<=>(TreeWay, TreeWay) = default;
};
struct Other
{
int v;
constexpr Other(int p) : v(p) {}
constexpr Other(TreeWay p) : v(p.v) {}
friend bool operator==(Other, Other) = default;
friend auto operator<=>(Other, Other) = default;
friend constexpr bool
operator==(const Other& lhs, const TreeWay& rhs)
{ return lhs.v == rhs.v; }
friend constexpr std::strong_ordering
operator<=>(const Other& lhs, const TreeWay& rhs)
{ return lhs.v <=> rhs.v; }
};
constexpr void
test_heterogeneus_cmp()
{
TreeWay l{10};
Other h{20};
std::optional<TreeWay&> t;
std::optional<const Other&> u;
VERIFY( (t == u) );
VERIFY( !(t != u) );
VERIFY( !(t < u) );
VERIFY( (t <= u) );
VERIFY( !(t > u) );
VERIFY( (t >= u) );
VERIFY( (t <=> u) == 0 );
t.emplace(l);
VERIFY( !(t == u) );
VERIFY( (t != u) );
VERIFY( !(t < u) );
VERIFY( !(t <= u) );
VERIFY( (t > u) );
VERIFY( (t >= u) );
VERIFY( (t <=> u) > 0 );
u.emplace(h);
VERIFY( !(t == u) );
VERIFY( (t != u) );
VERIFY( (t < u) );
VERIFY( (t <= u) );
VERIFY( !(t > u) );
VERIFY( !(t >= u) );
VERIFY( (t <=> u) < 0 );
}
int main()
{
auto test_all = [] {
test_compare(2, 5);
test_compare(TreeWay{11}, TreeWay{12});
test_heterogeneus_cmp();
return true;
};
test_all();
static_assert(test_all());
}