UgMisc 0.2-110
Miscellaneous C++ header library
Loading...
Searching...
No Matches
sfinae_helpers.hpp File Reference

Utility required by other ugmisc headers. More...

#include <limits>
#include <type_traits>
#include <utility>
#include "ugmisc/features.hpp"

Go to the source code of this file.

Concepts

concept  ugmisc::Bitwise
concept  ugmisc::Uint
concept  ugmisc::ModuloUint
concept  ugmisc::BitwiseUint
concept  ugmisc::Int

Macros

#define UGMISC_UINT_RETURN(T, R)
#define UGMISC_BITWISE_UINT_RETURN(T, R)

Typedefs

template<class T>
using ugmisc::remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>
template<class T>
using ugmisc::plain_ref_t = std::remove_cv_t<T>&
template<class T, class R = T>
using ugmisc::uint_only
 Resolves to R if T is an unsigned integer.
template<class T, class R = T>
using ugmisc::modulo_uint_only
 Resolves to R if T is an unsigned integer with modulo arithmetic.
template<class T, class R = T>
using ugmisc::bitwise_uint_only
template<class T, class R = T>
using ugmisc::int_only

Functions

template<class T>
plain_ref_t< T > ugmisc::decl_plain_ref ()

Detailed Description

Utility required by other ugmisc headers.

The miscellaneous templates often want to be selected only when a type parameter is an integral type, or some similar condition. Since many of them use the same condition, it makes sense to make a special helper for that condition, which makes the declarations that use it a bit more legible.

If C++20 or later is supported, concepts will be used so compiler error messages will be clearer. Where concepts are not supported, templates which can be used for SFINAE exclusion of a candidate function overload are used instead.

Macro Definition Documentation

◆ UGMISC_BITWISE_UINT_RETURN

#define UGMISC_BITWISE_UINT_RETURN ( T,
R )
Value:
R requires ::ugmisc::BitwiseUint<T>

Macro to place after the return arrow on a function declaration, to enable a function only when type T meets the BitwiseUint criteria. R is the return type.

UGMISC_BITWISE_UINT_RETURN(T, R) expands either to an enable_if_t type-expression or something similar, or to R requires BitwiseUint<T>, depending on whether concepts are supported. For example, if concepts are supported:

template<typename T>
auto foo(T) -> UGMISC_BITWISE_UINT_RETURN(T, R);
#define UGMISC_BITWISE_UINT_RETURN(T, R)
Definition sfinae_helpers.hpp:224

becomes:

template<typename T>
auto foo(T) -> R requires BitwiseUint<T>;

◆ UGMISC_UINT_RETURN

#define UGMISC_UINT_RETURN ( T,
R )
Value:
R requires ::ugmisc::Uint<T>

Macro to place after the return arrow on a function declaration, to enable a function only when type T meets the Uint criteria. R is the return type.

UGMISC_UINT_RETURN(T, R) expands either to an enable_if_t type-expression or something similar, or to R requires Uint<T>, depending on whether concepts are supported. For example, if concepts are supported:

template<typename T>
auto foo(T) -> UGMISC_UINT_RETURN(T, R);
#define UGMISC_UINT_RETURN(T, R)
Definition sfinae_helpers.hpp:147

becomes:

template<typename T>
auto foo(T) -> R requires Uint<T>;

Typedef Documentation

◆ bitwise_uint_only

template<class T, class R = T>
using ugmisc::bitwise_uint_only
Initial value:
std::enable_if_t<
is_bitwise_uint<T>,
R
>

This type alias attempts to be valid only in cases where T supports bitwise operators, and where those operators work in the way you would normally expect.

In practice this could let some odd things slip through the net. If you create a type with a std::numeric_limits specialisation such that it claims to be an unsigned integer with a radix of 2, and it supports the |, &, ^, and ~ operators, but those operators don't do what someone would normally expect, then that could cause a problem.

Warning
I can't remember why I put modulo in here as a requirement. That might be removed later.

◆ int_only

template<class T, class R = T>
using ugmisc::int_only
Initial value:
std::enable_if_t<
std::numeric_limits<T>::is_integer,
R
>

Resolves to R if T is an integer.

◆ modulo_uint_only

template<class T, class R = T>
using ugmisc::modulo_uint_only
Initial value:
std::enable_if_t<
std::numeric_limits<T>::is_integer
&& ( ! std::numeric_limits<T>::is_signed )
&& std::numeric_limits<T>::is_modulo
&& std::is_arithmetic_v<T>,
R
>

Resolves to R if T is an unsigned integer with modulo arithmetic.

◆ uint_only

template<class T, class R = T>
using ugmisc::uint_only
Initial value:
std::enable_if_t<
std::numeric_limits<T>::is_integer
&& ( ! std::numeric_limits<T>::is_signed ),
R
>

Resolves to R if T is an unsigned integer.