OSCR
Open Source Cartridge Reader
Loading...
Searching...
No Matches
specializations.h
1/********************************************************************
2 * Open Source Cartridge Reader *
3 ********************************************************************/
4#pragma once
5#ifndef OSCR_SPECIALIZATIONS_H_
6# define OSCR_SPECIALIZATIONS_H_
7
8# include <stdint.h>
9# include <limits.h>
10# include "macros.h"
11# include "common/Types.h"
12
13#define __spec_def(NAME, ...) template<__VA_ARGS__> struct NAME
14#define __spec_cond(NAME, ...) template<> struct NAME<__VA_ARGS__>
15#define __spec_template(...) template<__VA_ARGS__> struct
16#define __spec_enabled public enable_spec {}
17#define __spec_disabled public disable_spec {}
18
19#define __spec_v(NAME) template <class T> inline constexpr bool NAME ## _v = NAME ## <T>::value;
20
21namespace OSCR
22{
24 // Note: We don't include template specializations in docs
25 //
26
27 namespace Util
28 {
29
30 template <bool B,
31 class T = void>
32 struct enable_if {};
33
34 template <class T>
35 struct enable_if<true, T>
36 {
37 typedef T type;
38 };
39
40 template <bool B, class T = void >
41 using enable_if_t = typename enable_if<B, T>::type;
42
43 template <typename T>
44 T && declval();
45
46 /******************************************************************
47 * Helpers
48 */
49
50 template <class T, T v>
51 struct __spec_result
52 {
53 static const T value = v;
54 };
55
56 typedef __spec_result<bool, true> enable_spec;
57 typedef __spec_result<bool, false> disable_spec;
58
59 template <bool v>
60 using spec_result = __spec_result<bool, v>;
61 typedef spec_result<true> enable_spec;
62 typedef spec_result<false> disable_spec;
63
64 template<class T, T v>
65 struct integral_constant
66 {
67 static constexpr T value = v;
68 using value_type = T;
69 using type = integral_constant; // using injected-class-name
70 constexpr operator value_type() const noexcept { return value; }
71 constexpr value_type operator()() const noexcept { return value; } // since c++14
72 };
73
74 using true_type = integral_constant<bool, true>;
75 using false_type = integral_constant<bool, false>;
76
77 namespace detail
78 {
79 template<class T>
80 true_type test(int T::*);
81
82 template<class>
83 false_type test(...);
84 }
85
86 template<class T>
87 struct is_class : decltype(detail::test<T>(nullptr)) {};
88
89 namespace details
90 {
91 template<typename B>
92 true_type test_ptr_conv(const volatile B*);
93
94 template<typename>
95 false_type test_ptr_conv(const volatile void*);
96
97 template<typename, typename>
98 auto test_is_base_of(...) -> true_type; // private or ambiguous base
99
100 template<typename B, typename D>
101 auto test_is_base_of(int) -> decltype(test_ptr_conv<B>(static_cast<D *>(nullptr)));
102 }
103
104 template <typename Base, typename Derived>
105 struct is_base_of : integral_constant<
106 bool,
107 is_class<Base>::value &&
108 is_class<Derived>::value &&
109 decltype(details::test_is_base_of<Base, Derived>(0))::value
110 > {};
111
112 template <class Base, class Derived>
113 inline constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
114
115
116
117 template <template <typename...> class base, typename derived>
118 struct is_base_of_template_impl
119 {
120 template<typename... Ts>
121 static constexpr true_type test(const base<Ts...> *);
122 static constexpr false_type test(...);
123 using type = decltype(test(declval<derived*>()));
124 };
125
126 template < template <typename...> class base, typename derived>
127 using is_base_of_template = typename is_base_of_template_impl<base, derived>::type;
128
129 /******************************************************************
130 * is_same<T, U> / is_same_v<T, U>
131 */
132
133 template<class T, class U>
134 struct is_same: __spec_disabled;
135
136 template<class T>
137 struct is_same<T, T>: __spec_enabled;
138
139 template <class T, class U>
140 inline constexpr bool is_same_v = is_same<T, U>::value;
141
142 /******************************************************************
143 * is_int32<T> / is_int32_v<T>
144 */
145
146 TRAIT_DEF(is_int32, typename T);
147 TRAIT_COND(is_int32, int32_t);
148 TRAIT_HELPERS(is_int32);
149
150 /******************************************************************
151 * is_integer<T>
152 */
153
154 TRAIT_DEF(is_integer, typename T);
155 TRAIT_COND(is_integer, int8_t);
156 TRAIT_COND(is_integer, uint8_t);
157 TRAIT_COND(is_integer, int16_t);
158 TRAIT_COND(is_integer, uint16_t);
159 TRAIT_COND(is_integer, int32_t);
160 TRAIT_COND(is_integer, uint32_t);
161 TRAIT_HELPERS(is_integer);
162
163 /******************************************************************
164 * is_signed<T>
165 */
166
167 // is_signed
168 TRAIT_DEF(is_signed, typename T);
169 TRAIT_COND(is_signed, int8_t);
170 TRAIT_COND(is_signed, int16_t);
171 TRAIT_COND(is_signed, int32_t);
172 TRAIT_HELPERS(is_signed);
173
174 // is_unsigned
175 TRAIT_DEF(is_unsigned, typename T);
176 TRAIT_COND(is_unsigned, uint8_t);
177 TRAIT_COND(is_unsigned, uint16_t);
178 TRAIT_COND(is_unsigned, uint32_t);
179 TRAIT_HELPERS(is_unsigned);
180
181 // is_number
182 TRAIT_DEF(is_number, typename T);
183 TRAIT_COND(is_number, int8_t);
184 TRAIT_COND(is_number, uint8_t);
185 TRAIT_COND(is_number, int16_t);
186 TRAIT_COND(is_number, uint16_t);
187 TRAIT_COND(is_number, int32_t);
188 TRAIT_COND(is_number, uint32_t);
189 TRAIT_COND(is_number, double);
190 TRAIT_HELPERS(is_number);
191
192 // is_any_number
193 TRAIT_DEF(is_any_number, typename T);
194 TRAIT_COND(is_any_number, int8_t);
195 TRAIT_COND(is_any_number, uint8_t);
196 TRAIT_COND(is_any_number, int16_t);
197 TRAIT_COND(is_any_number, uint16_t);
198 TRAIT_COND(is_any_number, int32_t);
199 TRAIT_COND(is_any_number, uint32_t);
200 TRAIT_COND(is_any_number, int64_t);
201 TRAIT_COND(is_any_number, uint64_t);
202 TRAIT_COND(is_any_number, double);
203 TRAIT_HELPERS(is_any_number);
204
205 // is_signed
206 TRAIT_DEF(is_any_signed, typename T);
207 TRAIT_COND(is_any_signed, int8_t);
208 TRAIT_COND(is_any_signed, int16_t);
209 TRAIT_COND(is_any_signed, int32_t);
210 TRAIT_COND(is_any_signed, int64_t);
211 TRAIT_HELPERS(is_any_signed);
212
213 // is_unsigned
214 TRAIT_DEF(is_any_unsigned, typename T);
215 TRAIT_COND(is_any_unsigned, uint8_t);
216 TRAIT_COND(is_any_unsigned, uint16_t);
217 TRAIT_COND(is_any_unsigned, uint32_t);
218 TRAIT_COND(is_any_unsigned, uint64_t);
219 TRAIT_HELPERS(is_any_unsigned);
220
221 // make_signed
222 CONV_DEF(make_signed, if_is_any_number_t<T> Enable = true);
223 CONV_TYPE(make_signed, int8_t, uint8_t, true);
224 CONV_TYPE(make_signed, int16_t, uint16_t, true);
225 CONV_TYPE(make_signed, int32_t, uint32_t, true);
226 CONV_TYPE(make_signed, int64_t, uint64_t, true);
227 CONV_HELPER(make_signed);
228
229 // make_unsigned
230 CONV_DEF(make_unsigned, if_is_any_number_t<T> Enable = true);
231 CONV_TYPE(make_unsigned, uint8_t, int8_t, true);
232 CONV_TYPE(make_unsigned, uint16_t, int16_t, true);
233 CONV_TYPE(make_unsigned, uint32_t, int32_t, true);
234 CONV_TYPE(make_unsigned, uint64_t, int64_t, true);
235 CONV_HELPER(make_unsigned);
236
237 template<typename T>
238 struct is_format
239 {
240 static bool const value = false;
241 };
242
243 template<>
244 struct is_format<OSCR::Serial::Style>
245 {
246 static bool const value = true;
247 };
248
249 template<>
250 struct is_format<OSCR::Serial::Foreground>
251 {
252 static bool const value = true;
253 };
254
255 template<>
256 struct is_format<OSCR::Serial::Background>
257 {
258 static bool const value = true;
259 };
260
261 template<typename T>
262 struct is_printable
263 {
264 static bool const value = false;
265 };
266 }
267
268 //
269 // End of template specializations
271}
272
273#endif /* OSCR_SPECIALIZATIONS_H_ */
Utility methods.
Definition Util.h:18
Main program.
Definition Storage.h:13