Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/header/compare"

From natekohl.net
< cpp‎ | header
m (correct)
m (- reason: miss constexpr & noexcept)
Line 12: Line 12:
 
{{dsc inc | cpp/utility/compare/dsc strong_ordering}}
 
{{dsc inc | cpp/utility/compare/dsc strong_ordering}}
 
{{dsc end}}
 
{{dsc end}}
 
===Synopsis===
 
{{source|1=
 
namespace std {
 
enum class eq { equal = 0, equivalent = 0, nonequal = 1, nonequivalent = 1 };
 
enum class ord { less = -1, greater = 1 };
 
enum class ncmp { unordered = 255 };
 
 
class weak_equality {
 
int value;
 
public:
 
explicit weak_equality(eq v) : value{ (int)v } { }
 
static const weak_equality equivalent, nonequivalent;
 
explicit operator int() const { return value; }
 
friend bool operator==(weak_equality v, nullptr_t) { return v.value == 0; }
 
friend bool operator!=(weak_equality v, nullptr_t) { return v.value != 0; }
 
friend bool operator==(nullptr_t i, weak_equality v) { return 0 == v.value; }
 
friend bool operator!=(nullptr_t i, weak_equality v) { return 0 != v.value; }
 
friend bool operator==(weak_equality v, weak_equality v2) { return v.value == v2.value; }
 
friend bool operator!=(weak_equality v, weak_equality v2) { return v.value == v2.value; }
 
};
 
 
const weak_equality weak_equality::equivalent{ eq::equivalent };
 
const weak_equality weak_equality::nonequivalent{ eq::nonequivalent };
 
 
class strong_equality {
 
int value;
 
public:
 
explicit strong_equality(eq v) : value{ (int)v } { }
 
static const strong_equality equal, equivalent, nonequal, nonequivalent;
 
explicit operator int() const { return value; }
 
operator weak_equality() const { return *this == equal ? weak_equality::equivalent : weak_equality::nonequivalent; }
 
friend bool operator==(strong_equality v, nullptr_t) { return v.value == 0; }
 
friend bool operator!=(strong_equality v, nullptr_t) { return v.value != 0; }
 
friend bool operator==(nullptr_t, strong_equality v) { return 0 == v.value; }
 
friend bool operator!=(nullptr_t, strong_equality v) { return 0 != v.value; }
 
friend bool operator==(strong_equality v, strong_equality v2) { return v.value == v2.value; }
 
friend bool operator!=(strong_equality v, strong_equality v2) { return v.value == v2.value; }
 
};
 
const strong_equality strong_equality::equal{ eq::equal };
 
const strong_equality strong_equality::equivalent{ eq::equivalent }; // for convenient substitutability in generic code
 
const strong_equality strong_equality::nonequal{ eq::nonequal };
 
const strong_equality strong_equality::nonequivalent{ eq::nonequivalent }; // for convenient substitutability in generic code
 
 
class partial_ordering {
 
public:
 
struct result {
 
int cmp : 7;
 
bool unordered : 1;
 
};
 
private:
 
result value;
 
public:
 
explicit partial_ordering(eq v) : value{ (int)v, false } { }
 
explicit partial_ordering(ord v) : value{ (int)v, false } { }
 
explicit partial_ordering(ncmp ) : value{ -255, true } { }
 
static const partial_ordering less, equivalent, greater, unordered;
 
operator result() const { return value; }
 
operator weak_equality() const { return *this == equivalent ? weak_equality::equivalent : weak_equality::nonequivalent; }
 
friend bool operator==(partial_ordering v, nullptr_t) { return !v.value.unordered && v.value.cmp == 0; }
 
friend bool operator!=(partial_ordering v, nullptr_t) { return v.value.unordered || v.value.cmp != 0; }
 
friend bool operator< (partial_ordering v, nullptr_t) { return !v.value.unordered && v.value.cmp < 0; }
 
friend bool operator<=(partial_ordering v, nullptr_t) { return !v.value.unordered && v.value.cmp <= 0; }
 
friend bool operator> (partial_ordering v, nullptr_t) { return !v.value.unordered && v.value.cmp > 0; }
 
friend bool operator>=(partial_ordering v, nullptr_t) { return !v.value.unordered && v.value.cmp >= 0; }
 
friend bool operator==(nullptr_t, partial_ordering v) { return !v.value.unordered && 0 == v.value.cmp; }
 
friend bool operator!=(nullptr_t, partial_ordering v) { return v.value.unordered || 0 != v.value.cmp; }
 
friend bool operator< (nullptr_t, partial_ordering v) { return !v.value.unordered && 0 < v.value.cmp; }
 
friend bool operator<=(nullptr_t, partial_ordering v) { return !v.value.unordered && 0 <= v.value.cmp; }
 
friend bool operator> (nullptr_t, partial_ordering v) { return !v.value.unordered && 0 > v.value.cmp; }
 
friend bool operator>=(nullptr_t, partial_ordering v) { return !v.value.unordered && 0 >= v.value.cmp; }
 
friend bool operator==(partial_ordering v, partial_ordering v2) { return v.value.unordered == v2.value.unordered && v.value.cmp == v2.value.cmp; }
 
friend bool operator!=(partial_ordering v, partial_ordering v2) { return v.value.unordered != v2.value.unordered || v.value.cmp != v2.value.cmp; }
 
};
 
const partial_ordering partial_ordering::less{ ord::less };
 
const partial_ordering partial_ordering::equivalent{ eq::equivalent };
 
const partial_ordering partial_ordering::greater{ ord::greater };
 
const partial_ordering partial_ordering::unordered{ ncmp::unordered };
 
 
class weak_ordering {
 
int value;
 
public:
 
explicit weak_ordering(eq v) : value{ (int)v } { }
 
explicit weak_ordering(ord v) : value{ (int)v } { }
 
static const weak_ordering less, equivalent, greater;
 
explicit operator int() const { return value; }
 
operator weak_equality() const { return *this == equivalent ? weak_equality::equivalent : weak_equality::nonequivalent; }
 
operator partial_ordering() const { return *this == equivalent ? partial_ordering::equivalent
 
: *this == less ? partial_ordering::less : partial_ordering::greater; }
 
friend bool operator==(weak_ordering v, nullptr_t) { return v.value == 0; }
 
friend bool operator!=(weak_ordering v, nullptr_t) { return v.value != 0; }
 
friend bool operator< (weak_ordering v, nullptr_t) { return v.value < 0; }
 
friend bool operator<=(weak_ordering v, nullptr_t) { return v.value <= 0; }
 
friend bool operator> (weak_ordering v, nullptr_t) { return v.value > 0; }
 
friend bool operator>=(weak_ordering v, nullptr_t) { return v.value >= 0; }
 
friend bool operator==(nullptr_t, weak_ordering v) { return 0 == v.value; }
 
friend bool operator!=(nullptr_t, weak_ordering v) { return 0 != v.value; }
 
friend bool operator< (nullptr_t, weak_ordering v) { return 0 < v.value; }
 
friend bool operator<=(nullptr_t, weak_ordering v) { return 0 <= v.value; }
 
friend bool operator> (nullptr_t, weak_ordering v) { return 0 > v.value; }
 
friend bool operator>=(nullptr_t, weak_ordering v) { return 0 >= v.value; }
 
friend bool operator==(weak_ordering v, weak_ordering v2) { return v.value == v2.value; }
 
friend bool operator!=(weak_ordering v, weak_ordering v2) { return v.value != v2.value; }
 
};
 
const weak_ordering weak_ordering::less{ ord::less };
 
const weak_ordering weak_ordering::equivalent{ eq::equivalent };
 
const weak_ordering weak_ordering::greater{ ord::greater };
 
 
class strong_ordering {
 
int value;
 
public:
 
explicit strong_ordering(eq v) : value{ (int)v } { }
 
explicit strong_ordering(ord v) : value{ (int)v } { }
 
static const strong_ordering less, equal, equivalent, greater;
 
xplicit operator int() const { return value; }
 
operator weak_equality() const { return *this == equal ? weak_equality::equivalent : weak_equality::nonequivalent; }
 
operator strong_equality() const { return *this == equal ? strong_equality::equal : strong_equality::nonequivalent; }
 
operator partial_ordering() const { return *this == equal ? partial_ordering::equivalent
 
: *this == less ? partial_ordering::less : partial_ordering::greater; }
 
operator weak_ordering() const { return *this == equal ? weak_ordering::equivalent
 
: *this == less ? weak_ordering::less : weak_ordering::greater; }
 
friend bool operator!=(strong_ordering v, nullptr_t) { return v.value != 0; }
 
friend bool operator< (strong_ordering v, nullptr_t) { return v.value < 0; }
 
friend bool operator==(strong_ordering v, nullptr_t) { return v.value == 0; }
 
friend bool operator<=(strong_ordering v, nullptr_t) { return v.value <= 0; }
 
friend bool operator> (strong_ordering v, nullptr_t) { return v.value > 0; }
 
friend bool operator>=(strong_ordering v, nullptr_t) { return v.value >= 0; }
 
friend bool operator==(nullptr_t, strong_ordering v) { return 0 == v.value; }
 
friend bool operator!=(nullptr_t, strong_ordering v) { return 0 != v.value; }
 
friend bool operator< (nullptr_t, strong_ordering v) { return 0 < v.value; }
 
friend bool operator<=(nullptr_t, strong_ordering v) { return 0 <= v.value; }
 
friend bool operator> (nullptr_t, strong_ordering v) { return 0 > v.value; }
 
friend bool operator>=(nullptr_t, strong_ordering v) { return 0 >= v.value; }
 
friend bool operator==(strong_ordering v, strong_ordering v2) { return v.value == v2.value; }
 
friend bool operator!=(strong_ordering v, strong_ordering v2) { return v.value != v2.value; }
 
};
 
const strong_ordering strong_ordering::less{ ord::less };
 
const strong_ordering strong_ordering::equal{ eq::equal };
 
const strong_ordering strong_ordering::equivalent{ eq::equivalent }; // for convenient substitutability in generic code
 
const strong_ordering strong_ordering::greater{ ord::greater };
 
}
 
 
}}
 

Revision as of 03:56, 25 November 2017

 
 
 

This header is part of the general utility library.

Classes

the result type of 3-way comparison that supports only equality/inequality and is not substitutable
(class) [edit]
the result type of 3-way comparison that supports only equality/inequality and is substitutable
(class) [edit]
the result type of 3-way comparison that supports all 6 operators, is not substitutable, and allows incomparable values
(class) [edit]
the result type of 3-way comparison that supports all 6 operators and is not substitutable
(class) [edit]
the result type of 3-way comparison that supports all 6 operators and is substitutable
(class) [edit]