[comparisons] # 22 General utilities library [[utilities]](./#utilities) ## 22.10 Function objects [[function.objects]](function.objects#comparisons) ### 22.10.8 Comparisons [comparisons] #### [22.10.8.1](#general) General [[comparisons.general]](comparisons.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12260) The library provides basic function object classes for all of the comparison operators in the language ([[expr.rel]](expr.rel "7.6.9 Relational operators"), [[expr.eq]](expr.eq "7.6.10 Equality operators"))[.](#general-1.sentence-1) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12264) For templates less, greater, less_equal, andgreater_equal, the specializations for any pointer type yield a result consistent with the implementation-defined strict total order over pointers ([[defns.order.ptr]](defns.order.ptr "3.28 implementation-defined strict total order over pointers"))[.](#general-2.sentence-1) [*Note [1](#general-note-1)*: If a < b is well-defined for pointers a and b of type P, then (a < b) == less

()(a, b),(a > b) == greater

()(a, b), and so forth[.](#general-2.sentence-2) — *end note*] For template specializations less, greater,less_equal, and greater_equal, if the call operator calls a built-in operator comparing pointers, the call operator yields a result consistent with the implementation-defined strict total order over pointers[.](#general-2.sentence-3) #### [22.10.8.2](#equal.to) Class template equal_to [[comparisons.equal.to]](comparisons.equal.to) [🔗](#lib:equal_to) `template struct equal_to { constexpr bool operator()(const T& x, const T& y) const; }; ` [🔗](#lib:operator(),equal_to) `constexpr bool operator()(const T& x, const T& y) const; ` [1](#equal.to-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12296) *Returns*: x == y[.](#equal.to-1.sentence-1) [🔗](#lib:equal_to%3c%3e) `template<> struct equal_to { template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) == std::forward(u)); using is_transparent = unspecified; }; ` [🔗](#lib:operator(),equal_to%3c%3e) `template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) == std::forward(u)); ` [2](#equal.to-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12318) *Returns*: std​::​forward(t) == std​::​forward(u)[.](#equal.to-2.sentence-1) #### [22.10.8.3](#not.equal.to) Class template not_equal_to [[comparisons.not.equal.to]](comparisons.not.equal.to) [🔗](#lib:not_equal_to) `template struct not_equal_to { constexpr bool operator()(const T& x, const T& y) const; }; ` [🔗](#lib:operator(),not_equal_to) `constexpr bool operator()(const T& x, const T& y) const; ` [1](#not.equal.to-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12338) *Returns*: x != y[.](#not.equal.to-1.sentence-1) [🔗](#lib:not_equal_to%3c%3e) `template<> struct not_equal_to { template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) != std::forward(u)); using is_transparent = unspecified; }; ` [🔗](#lib:operator(),not_equal_to%3c%3e) `template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) != std::forward(u)); ` [2](#not.equal.to-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12360) *Returns*: std​::​forward(t) != std​::​forward(u)[.](#not.equal.to-2.sentence-1) #### [22.10.8.4](#greater) Class template greater [[comparisons.greater]](comparisons.greater) [🔗](#lib:greater) `template struct greater { constexpr bool operator()(const T& x, const T& y) const; }; ` [🔗](#lib:operator(),greater) `constexpr bool operator()(const T& x, const T& y) const; ` [1](#greater-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12380) *Returns*: x > y[.](#greater-1.sentence-1) [🔗](#lib:greater%3c%3e) `template<> struct greater { template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) > std::forward(u)); using is_transparent = unspecified; }; ` [🔗](#lib:operator(),greater%3c%3e) `template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) > std::forward(u)); ` [2](#greater-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12402) *Returns*: std​::​forward(t) > std​::​forward(u)[.](#greater-2.sentence-1) #### [22.10.8.5](#less) Class template less [[comparisons.less]](comparisons.less) [🔗](#lib:less) `template struct less { constexpr bool operator()(const T& x, const T& y) const; }; ` [🔗](#lib:operator(),less) `constexpr bool operator()(const T& x, const T& y) const; ` [1](#less-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12422) *Returns*: x < y[.](#less-1.sentence-1) [🔗](#lib:less%3c%3e) `template<> struct less { template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) < std::forward(u)); using is_transparent = unspecified; }; ` [🔗](#lib:operator(),less%3c%3e) `template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) < std::forward(u)); ` [2](#less-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12444) *Returns*: std​::​forward(t) < std​::​forward(u)[.](#less-2.sentence-1) #### [22.10.8.6](#greater.equal) Class template greater_equal [[comparisons.greater.equal]](comparisons.greater.equal) [🔗](#lib:greater_equal) `template struct greater_equal { constexpr bool operator()(const T& x, const T& y) const; }; ` [🔗](#lib:operator(),greater_equal) `constexpr bool operator()(const T& x, const T& y) const; ` [1](#greater.equal-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12464) *Returns*: x >= y[.](#greater.equal-1.sentence-1) [🔗](#lib:greater_equal%3c%3e) `template<> struct greater_equal { template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) >= std::forward(u)); using is_transparent = unspecified; }; ` [🔗](#lib:operator(),greater_equal%3c%3e) `template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) >= std::forward(u)); ` [2](#greater.equal-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12486) *Returns*: std​::​forward(t) >= std​::​forward(u)[.](#greater.equal-2.sentence-1) #### [22.10.8.7](#less.equal) Class template less_equal [[comparisons.less.equal]](comparisons.less.equal) [🔗](#lib:less_equal) `template struct less_equal { constexpr bool operator()(const T& x, const T& y) const; }; ` [🔗](#lib:operator(),less_equal) `constexpr bool operator()(const T& x, const T& y) const; ` [1](#less.equal-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12506) *Returns*: x <= y[.](#less.equal-1.sentence-1) [🔗](#lib:less_equal%3c%3e) `template<> struct less_equal { template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) <= std::forward(u)); using is_transparent = unspecified; }; ` [🔗](#lib:operator(),less_equal%3c%3e) `template constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward(t) <= std::forward(u)); ` [2](#less.equal-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12528) *Returns*: std​::​forward(t) <= std​::​forward(u)[.](#less.equal-2.sentence-1) #### [22.10.8.8](#three.way) Class compare_three_way [[comparisons.three.way]](comparisons.three.way) [🔗](#lib:compare_three_way) namespace std {struct compare_three_way {templateconstexpr auto operator()(T&& t, U&& u) const; using is_transparent = *unspecified*; };} [🔗](#three.way-itemdecl:1) `template constexpr auto operator()(T&& t, U&& u) const; ` [1](#three.way-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12553) *Constraints*: T and U satisfy [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_­way_­comparable [cmp.concept]")[.](#three.way-1.sentence-1) [2](#three.way-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12557) *Preconditions*: If the expression std​::​forward(t) <=> std​::​forward(u) results in a call to a built-in operator <=> comparing pointers of type P, the conversion sequences from both T and U to P are equality-preserving ([[concepts.equality]](concepts.equality "18.2 Equality preservation")); otherwise, T and U model [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_­way_­comparable [cmp.concept]")[.](#three.way-2.sentence-1) [3](#three.way-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L12565) *Effects*: - [(3.1)](#three.way-3.1) If the expression std​::​forward(t) <=> std​::​forward(u) results in a call to a built-in operator <=> comparing pointers of type P, returns strong_ordering​::​less if (the converted value of) t precedes u in the implementation-defined strict total order over pointers ([[defns.order.ptr]](defns.order.ptr "3.28 implementation-defined strict total order over pointers")), strong_ordering​::​greater if u precedes t, and otherwise strong_ordering​::​equal. - [(3.2)](#three.way-3.2) Otherwise, equivalent to: return std​::​forward(t) <=> std​::​forward(u);