Difference between revisions of "cpp/header/compare"
From natekohl.net
m (+) |
m (+) |
||
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:50, 25 November 2017
This header is part of the general utility library.
Classes
(C++20) |
the result type of 3-way comparison that supports only equality/inequality and is not substitutable (class) |
(C++20) |
the result type of 3-way comparison that supports only equality/inequality and is substitutable (class) |
(C++20) |
the result type of 3-way comparison that supports all 6 operators, is not substitutable, and allows incomparable values (class) |
(C++20) |
the result type of 3-way comparison that supports all 6 operators and is not substitutable (class) |
(C++20) |
the result type of 3-way comparison that supports all 6 operators and is substitutable (class) |