Scroll to navigation

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