UgMisc 0.2-128
Miscellaneous C++ header library
Loading...
Searching...
No Matches
sfinae_helpers.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: © 2025 Larry Chips <larry@larrychips.net>
3 * SPDX-Licence-Identifier: MIT
4 */
5#ifndef UGMISC_SFINAE_HELPERS_HPP
6#define UGMISC_SFINAE_HELPERS_HPP
7
23
24#include <limits>
25#include <type_traits>
26#include <utility>
27
28#include "ugmisc/features.hpp"
29
30
31
32
33namespace ugmisc {
34
35
36
37
38template<class T>
39using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
40
41
42
43
44template<class T>
45using plain_ref_t = std::remove_cv_t<T>&;
46
47
48
49
50template<class T> plain_ref_t<T> decl_plain_ref();
51
52
53
54
55namespace _sfinae {
56
57template<class T, class=void>
58struct get_is_bitwise : std::false_type {};
59
60
61
62
63template<class T>
64struct get_is_bitwise<
65 T,
66 std::void_t<
67 decltype(decl_plain_ref<T>() = std::declval<T>() | std::declval<T>()),
68 decltype(decl_plain_ref<T>() = std::declval<T>() & std::declval<T>()),
69 decltype(decl_plain_ref<T>() = std::declval<T>() ^ std::declval<T>()),
70 decltype(decl_plain_ref<T>() = ~ std::declval<T>())
71 >
72 >
73 : public std::true_type {};
74
75} /* _sfinae (::ugmisc::_sfinae) */
76
77
78
79
90template<class T>
91static constexpr bool is_bitwise = _sfinae::get_is_bitwise<T>::value;
92#ifdef UGMISC_USE_CONCEPT_DECLS
97template<class T>
98concept Bitwise = is_bitwise<T>;
99#endif
100
101
102
103
107template<class T, class R=T> using uint_only = std::enable_if_t<
108 std::numeric_limits<T>::is_integer
109 && ( ! std::numeric_limits<T>::is_signed ),
110
111 R
112 >;
113#ifdef UGMISC_USE_CONCEPT_DECLS
119template<class T>
120concept Uint =
121 std::numeric_limits<T>::is_integer
122 && ! std::numeric_limits<T>::is_signed
123 ;
124
128# define UGMISC_UINT_RETURN(T, R) R requires ::ugmisc::Uint<T>
129#else
130# define UGMISC_UINT_RETURN(T, R) ::ugmisc::uint_only<T, R>
131#endif
132
133
134
135
139template<class T, class R=T> using modulo_uint_only = std::enable_if_t<
140 std::numeric_limits<T>::is_integer
141 && ( ! std::numeric_limits<T>::is_signed )
142 && std::numeric_limits<T>::is_modulo,
143
144 R
145 >;
146#ifdef UGMISC_USE_CONCEPT_DECLS
152template<class T>
153concept ModuloUint =
154 Uint<T> && std::numeric_limits<T>::is_modulo;
155#endif
156
157
158
159
160/*
161 * See below.
162 */
163template<class T> static constexpr bool is_bitwise_uint =
164 std::numeric_limits<T>::is_integer
165 && ( ! std::numeric_limits<T>::is_signed )
166 && ( std::numeric_limits<T>::radix == 2 )
167 && std::numeric_limits<T>::is_modulo
168 && is_bitwise<T>
169 ;
170
185template<class T, class R=T> using bitwise_uint_only = std::enable_if_t<
186 is_bitwise_uint<T>,
187 R
188 >;
189#ifdef UGMISC_USE_CONCEPT_DECLS
196template<class T> concept BitwiseUint = Bitwise<T> && ModuloUint<T>;
197
201# define UGMISC_BITWISE_UINT_RETURN(T, R) R requires ::ugmisc::BitwiseUint<T>
202#else
203# define UGMISC_BITWISE_UINT_RETURN(T, R) ::ugmisc::bitwise_uint_only<T, R>
204#endif
205
206
207
208
212template<class T, class R=T> using int_only = std::enable_if_t<
213 std::numeric_limits<T>::is_integer,
214
215 R
216 >;
217#ifdef UGMISC_USE_CONCEPT_DECLS
224template<class T> concept Int = std::numeric_limits<T>::is_integer;
225#endif
226} /* ugmisc */
227
228#endif /* UGMISC_SFINAE_HELPERS_HPP */
Definition sfinae_helpers.hpp:98
Definition sfinae_helpers.hpp:196
Definition sfinae_helpers.hpp:224
Definition sfinae_helpers.hpp:153
Definition sfinae_helpers.hpp:120
Feature detection.
std::enable_if_t< std::numeric_limits< T >::is_integer, R > int_only
Definition sfinae_helpers.hpp:212
std::enable_if_t< std::numeric_limits< T >::is_integer &&(! std::numeric_limits< T >::is_signed) &&std::numeric_limits< T >::is_modulo, R > modulo_uint_only
Resolves to R if T is an unsigned integer with modulo arithmetic.
Definition sfinae_helpers.hpp:139
std::enable_if_t< is_bitwise_uint< T >, R > bitwise_uint_only
Definition sfinae_helpers.hpp:185
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:107