24#ifndef UGMISC_SFINAE_HELPERS_HPP
25#define UGMISC_SFINAE_HELPERS_HPP
58using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
64using plain_ref_t = std::remove_cv_t<T>&;
69template<
class T> plain_ref_t<T> decl_plain_ref();
76template<
class T,
class=
void>
77struct get_is_bitwise : std::false_type {};
86 decltype(decl_plain_ref<T>() = std::declval<T>() | std::declval<T>()),
87 decltype(decl_plain_ref<T>() = std::declval<T>() & std::declval<T>()),
88 decltype(decl_plain_ref<T>() = std::declval<T>() ^ std::declval<T>()),
89 decltype(decl_plain_ref<T>() = ~ std::declval<T>())
92 :
public std::true_type {};
110static constexpr bool is_bitwise = _sfinae::get_is_bitwise<T>::value;
111#ifdef UGMISC_USE_CONCEPT_DECLS
126template<
class T,
class R=T>
using uint_only = std::enable_if_t<
127 std::numeric_limits<T>::is_integer
128 && ( ! std::numeric_limits<T>::is_signed ),
132#ifdef UGMISC_USE_CONCEPT_DECLS
140 std::numeric_limits<T>::is_integer
141 && ! std::numeric_limits<T>::is_signed
147# define UGMISC_UINT_RETURN(T, R) R requires ::ugmisc::Uint<T>
149# define UGMISC_UINT_RETURN(T, R) ::ugmisc::uint_only<T, R>
159 std::numeric_limits<T>::is_integer
160 && ( ! std::numeric_limits<T>::is_signed )
161 && std::numeric_limits<T>::is_modulo
162 && std::is_arithmetic_v<T>,
166#ifdef UGMISC_USE_CONCEPT_DECLS
174 Uint<T> && std::numeric_limits<T>::is_modulo
175 && std::is_arithmetic_v<T>
185template<
class T>
static constexpr bool is_bitwise_uint =
186 std::numeric_limits<T>::is_integer
187 && ( ! std::numeric_limits<T>::is_signed )
188 && ( std::numeric_limits<T>::radix == 2 )
189 && std::numeric_limits<T>::is_modulo
190 && std::is_arithmetic_v<T>
212#ifdef UGMISC_USE_CONCEPT_DECLS
224# define UGMISC_BITWISE_UINT_RETURN(T, R) R requires ::ugmisc::BitwiseUint<T>
226# define UGMISC_BITWISE_UINT_RETURN(T, R) ::ugmisc::bitwise_uint_only<T, R>
235template<
class T,
class R=T>
using int_only = std::enable_if_t<
236 std::numeric_limits<T>::is_integer,
240#ifdef UGMISC_USE_CONCEPT_DECLS
247template<
class T>
concept Int = std::numeric_limits<T>::is_integer;
Definition sfinae_helpers.hpp:117
Definition sfinae_helpers.hpp:219
Definition sfinae_helpers.hpp:247
Definition sfinae_helpers.hpp:173
Definition sfinae_helpers.hpp:139
std::enable_if_t< std::numeric_limits< T >::is_integer, R > int_only
Definition sfinae_helpers.hpp:235
std::enable_if_t< is_bitwise_uint< T >, R > bitwise_uint_only
Definition sfinae_helpers.hpp:208
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 > modulo_uint_only
Resolves to R if T is an unsigned integer with modulo arithmetic.
Definition sfinae_helpers.hpp:158
std::enable_if_t< std::numeric_limits< T >::is_integer &&(! std::numeric_limits< T >::is_signed), R > uint_only
Resolves to R if T is an unsigned integer.
Definition sfinae_helpers.hpp:126