table of contents
std::cmp_equal,cmp_not_equal,cmp_less,cmp_greater,cmp_less_equal,cmp_greater_equal(3) | C++ Standard Libary | std::cmp_equal,cmp_not_equal,cmp_less,cmp_greater,cmp_less_equal,cmp_greater_equal(3) |
NAME¶
std::cmp_equal,cmp_not_equal,cmp_less,cmp_greater,cmp_less_equal,cmp_greater_equal - std::cmp_equal,cmp_not_equal,cmp_less,cmp_greater,cmp_less_equal,cmp_greater_equal
Synopsis¶
Defined in header <utility>
template< class T, class U > (1) (since C++20)
constexpr bool cmp_equal( T t, U u ) noexcept;
template< class T, class U > (2) (since C++20)
constexpr bool cmp_not_equal( T t, U u ) noexcept;
template< class T, class U > (3) (since C++20)
constexpr bool cmp_less( T t, U u ) noexcept;
template< class T, class U > (4) (since C++20)
constexpr bool cmp_greater( T t, U u ) noexcept;
template< class T, class U > (5) (since C++20)
constexpr bool cmp_less_equal( T t, U u ) noexcept;
template< class T, class U > (6) (since C++20)
constexpr bool cmp_greater_equal( T t, U u ) noexcept;
Compare the values of two integers t and u. Unlike builtin comparison
operators,
negative signed integers always compare less than (and not equal to) unsigned
integers: the comparison is safe against lossy integer conversion.
-1 > 0u; // true
std::cmp_greater(-1, 0u); // false
It is a compile-time error if either T or U is not a signed or unsigned
integer type
(including standard integer type and extended integer type).
Parameters¶
t - left-hand argument
u - right-hand argument
Return value¶
1) true if t is equal to u.
2) true if t is not equal to u.
3) true if t is less than u.
4) true if t is greater than u.
5) true if t is less or equal to u.
6) true if t is greater or equal to u.
Possible implementation¶
template< class T, class U >
constexpr bool cmp_equal( T t, U u ) noexcept
{
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t == u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? false : UT(t) == u;
else
return u < 0 ? false : t == UU(u);
}
template< class T, class U >
constexpr bool cmp_not_equal( T t, U u ) noexcept
{
return !cmp_equal(t, u);
}
template< class T, class U >
constexpr bool cmp_less( T t, U u ) noexcept
{
using UT = std::make_unsigned_t<T>;
using UU = std::make_unsigned_t<U>;
if constexpr (std::is_signed_v<T> == std::is_signed_v<U>)
return t < u;
else if constexpr (std::is_signed_v<T>)
return t < 0 ? true : UT(t) < u;
else
return u < 0 ? false : t < UU(u);
}
template< class T, class U >
constexpr bool cmp_greater( T t, U u ) noexcept
{
return cmp_less(u, t);
}
template< class T, class U >
constexpr bool cmp_less_equal( T t, U u ) noexcept
{
return !cmp_greater(t, u);
}
template< class T, class U >
constexpr bool cmp_greater_equal( T t, U u ) noexcept
{
return !cmp_less(t, u);
}
Notes¶
These functions cannot be used to compare enums (including
std::byte), char,
char8_t, char16_t, char32_t, wchar_t and bool.
Feature-test macro: __cpp_lib_integer_comparison_functions
Example¶
The example below might produce different signedness comparison
warning if compiled
without an appropriate warning suppression flag, e.g. -Wno-sign-compare
(gcc/clang
with -Wall -Wextra, see also SO: disabling a specific warning).
// Run this code
#include <utility>
// Uncommenting the next line will disable "signed/unsigned
comparison" warnings:
// #pragma GCC diagnostic ignored "-Wsign-compare"
int main()
{
static_assert( sizeof(int) == 4 ); // precondition
// Quite surprisingly
static_assert( -1 > 1U ); //< warning: sign-unsign comparison
// because after implicit conversion of -1 to the RHS type (`unsigned int`)
// the expression is equivalent to:
static_assert( 0xFFFFFFFFU > 1U );
static_assert( 0xFFFFFFFFU == static_cast<unsigned>(-1) );
// In contrast, the cmp_* family compares integers as most expected -
// negative signed integers always compare less than unsigned integers:
static_assert( std::cmp_less( -1, 1U ) );
static_assert( std::cmp_less_equal( -1, 1U ) );
static_assert( ! std::cmp_greater( -1, 1U ) );
static_assert( ! std::cmp_greater_equal( -1, 1U ) );
static_assert( -1 == 0xFFFFFFFFU ); //< warning: sign-unsign comparison
static_assert( std::cmp_not_equal( -1, 0xFFFFFFFFU ) );
}
See also¶
equal_to function object implementing x == y
(class template)
not_equal_to function object implementing x != y
(class template)
less function object implementing x < y
(class template)
greater function object implementing x > y
(class template)
less_equal function object implementing x <= y
(class template)
greater_equal function object implementing x >= y
(class template)
ranges::equal_to function object implementing x == y
(C++20) (class)
ranges::not_equal_to function object implementing x != y
(C++20) (class)
ranges::less function object implementing x < y
(C++20) (class)
ranges::greater function object implementing x > y
(C++20) (class)
ranges::less_equal function object implementing x <= y
(C++20) (class)
ranges::greater_equal function object implementing x >= y
(C++20) (class)
compare_three_way function object implementing x <=> y
(C++20) (class)
in_range checks if an integer value is in the range of a given integer
(C++20) type
(function template)
provides an interface to query properties of all fundamental
numeric_limits numeric types.
(class template)
2022.07.31 | http://cppreference.com |