ugmisc 0.2-86
Miscellaneous C++ header library
Loading...
Searching...
No Matches
sfinae_helpers.hpp
Go to the documentation of this file.
1/*
2 * SPDX-Licence-Identifier: MIT
3 *
4 * Copyright 2025 Larry Chips
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the “Software”), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#pragma once
25
41
42#include <limits>
43#include <type_traits>
44#include <utility>
45
46#include "ugmisc/features.hpp"
47
48
49
50
51namespace ugmisc {
52
53
54
55
56template<class T>
57using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
58
59
60
61
62template<class T>
63using plain_ref_t = std::remove_cv_t<T>&;
64
65
66
67
68template<class T> plain_ref_t<T> decl_plain_ref();
69
70
71
72
73template<class T, class=void>
74struct get_is_bitwise : std::false_type {};
75
76
77
78
79template<class T>
80struct get_is_bitwise<
81 T,
82 std::void_t<
83 decltype(decl_plain_ref<T>() = std::declval<T>() | std::declval<T>()),
84 decltype(decl_plain_ref<T>() = std::declval<T>() & std::declval<T>()),
85 decltype(decl_plain_ref<T>() = std::declval<T>() ^ std::declval<T>()),
86 decltype(decl_plain_ref<T>() = ~ std::declval<T>())
87 >
88 >
89 : public std::true_type {};
90
91
92
93
102template<class T>
103static constexpr bool is_bitwise = get_is_bitwise<T>::value;
104#ifdef UGMISC_USE_CONCEPT_DECLS
109template<class T>
110concept Bitwise = is_bitwise<T>;
111#endif
112
113
114
115
119template<class T, class R=T> using uint_only = std::enable_if_t<
120 std::numeric_limits<T>::is_integer
121 && ( ! std::numeric_limits<T>::is_signed ),
122
123 R
124 >;
125#ifdef UGMISC_USE_CONCEPT_DECLS
131template<class T>
132concept Uint =
133 std::numeric_limits<T>::is_integer
134 && ! std::numeric_limits<T>::is_signed
135 ;
136#endif
137
138
139
140
144template<class T, class R=T> using modulo_uint_only = std::enable_if_t<
145 std::numeric_limits<T>::is_integer
146 && ( ! std::numeric_limits<T>::is_signed )
147 && std::numeric_limits<T>::is_modulo
148 && std::is_arithmetic_v<T>,
149
150 R
151 >;
152#ifdef UGMISC_USE_CONCEPT_DECLS
158template<class T>
159concept ModuloUint =
160 Uint<T> && std::numeric_limits<T>::is_modulo
161 && std::is_arithmetic_v<T>
162 ;
163#endif
164
165
166
167
168/*
169 * See below.
170 */
171template<class T> static constexpr bool is_bitwise_uint =
172 std::numeric_limits<T>::is_integer
173 && ( ! std::numeric_limits<T>::is_signed )
174 && ( std::numeric_limits<T>::radix == 2 )
175 && std::numeric_limits<T>::is_modulo
176 && std::is_arithmetic_v<T>
177 && is_bitwise<T>
178 ;
179
194template<class T, class R=T> using bitwise_uint_only = std::enable_if_t<
195 is_bitwise_uint<T>,
196 R
197 >;
198#ifdef UGMISC_USE_CONCEPT_DECLS
205template<class T> concept BitwiseUint = Bitwise<T> && ModuloUint<T>;
206#endif
207
208
209
210
214template<class T, class R=T> using int_only = std::enable_if_t<
215 std::numeric_limits<T>::is_integer,
216
217 R
218 >;
219#ifdef UGMISC_USE_CONCEPT_DECLS
226template<class T> concept Int = std::numeric_limits<T>::is_integer;
227#endif
228} /* ugmisc */
Definition sfinae_helpers.hpp:110
Definition sfinae_helpers.hpp:205
Definition sfinae_helpers.hpp:226
Definition sfinae_helpers.hpp:159
Definition sfinae_helpers.hpp:132
Feature detection.
std::enable_if_t< std::numeric_limits< T >::is_integer, R > int_only
Definition sfinae_helpers.hpp:214
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:119
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:144
std::enable_if_t< is_bitwise_uint< T >, R > bitwise_uint_only
Definition sfinae_helpers.hpp:194