FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
types_traits.h
Go to the documentation of this file.
1// Copyright 2016-2023 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
16
23#ifndef TYPES_TRAITS_HH
24#define TYPES_TRAITS_HH
25
26#include <stddef.h>
27#include <stdint.h>
28#include "defines.h"
29
36namespace types_traits
37{
46 template<typename T> struct Type_trait
47 {
49 static constexpr bool IS_INT = false;
51 static constexpr bool IS_SIGNED = false;
53 static constexpr size_t SIZE = 0;
54 };
55
57 template<typename T_, bool IS_SIGNED_> struct Type_trait_int
58 {
59 static constexpr bool IS_INT = true;
60 static constexpr bool IS_SIGNED = IS_SIGNED_;
61 static constexpr size_t SIZE = sizeof(T_);
62 };
63
64 template<> struct Type_trait<uint8_t> : Type_trait_int<uint8_t, false> {};
65 template<> struct Type_trait<uint16_t> : Type_trait_int<uint16_t, false> {};
66 template<> struct Type_trait<uint32_t> : Type_trait_int<uint32_t, false> {};
67 template<> struct Type_trait<uint64_t> : Type_trait_int<uint64_t, false> {};
68 template<> struct Type_trait<int8_t> : Type_trait_int<int8_t, true> {};
69 template<> struct Type_trait<int16_t> : Type_trait_int<int16_t, true> {};
70 template<> struct Type_trait<int32_t> : Type_trait_int<int32_t, true> {};
71 template<> struct Type_trait<int64_t> : Type_trait_int<int64_t, true> {};
73
79 template<typename T> static constexpr bool is_uint8_or_uint16()
80 {
81 using TRAIT = Type_trait<T>;
82 return TRAIT::IS_INT && (TRAIT::SIZE <= sizeof(uint16_t)) && (!TRAIT::IS_SIGNED);
83 }
84
92 template<class T, class B> struct derives_from
93 {
95 static void constraints(T* p)
96 {
97 UNUSED B* pb = p;
98 }
99 constexpr derives_from()
100 {
101 UNUSED void (*p)(T*) = constraints;
102 }
104 };
105
111 template<typename T> struct remove_reference
112 {
114 using type = T;
115 };
117 template<typename T> struct remove_reference<T&>
118 {
119 using type = T;
120 };
121 template<typename T> struct remove_reference<T&&>
122 {
123 using type = T;
124 };
126
128 // Find min number of bytes (as power of 2) needed to store value
129 constexpr uint8_t uint_size_in_val(uint64_t value)
130 {
131 return (value & 0xFFFF'FFFF'0000'0000ULL ? 8 :
132 value & 0x0000'0000'FFFF'0000ULL ? 4 :
133 value & 0x0000'0000'0000'FF00ULL ? 2 : 1);
134 }
135 template<uint8_t bytes> struct UnsignedInt
136 {
137 using UTYPE = void;
138 using STYPE = void;
139 };
140 template<> struct UnsignedInt<8>
141 {
142 using UTYPE = uint64_t;
143 using STYPE = int64_t;
144 };
145 template<> struct UnsignedInt<4>
146 {
147 using UTYPE = uint32_t;
148 using STYPE = int32_t;
149 };
150 template<> struct UnsignedInt<2>
151 {
152 using UTYPE = uint16_t;
153 using STYPE = int16_t;
154 };
155 template<> struct UnsignedInt<1>
156 {
157 using UTYPE = uint8_t;
158 using STYPE = int8_t;
159 };
161
167 template<uint64_t VAL> struct SmallestInt
168 {
170 using UNSIGNED_TYPE = typename UnsignedInt<uint_size_in_val(VAL)>::UTYPE;
172 using SIGNED_TYPE = typename UnsignedInt<uint_size_in_val(VAL)>::STYPE;
173 };
174}
175
176#endif /* TYPES_TRAITS_HH */
Useful defines GCC specific attributes.
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Definition: defines.h:45
Defines traits and utility methods for standard types, like uint16_t.
Definition: types_traits.h:37
static constexpr bool is_uint8_or_uint16()
Check if a given type is uint8_t or uint16_t.
Definition: types_traits.h:79
Find the smallest integral types, signed and unsigned, tha can hold a given value.
Definition: types_traits.h:168
typename UnsignedInt< uint_size_in_val(VAL)>::UTYPE UNSIGNED_TYPE
The smallest unsigned integral type that can hold VAL.
Definition: types_traits.h:170
typename UnsignedInt< uint_size_in_val(VAL)>::STYPE SIGNED_TYPE
The smallest signed integral type that can hold VAL.
Definition: types_traits.h:172
This trait allows static checks (at compile-time) of properties of various types.
Definition: types_traits.h:47
static constexpr bool IS_INT
Indicates if T is an integer type.
Definition: types_traits.h:49
static constexpr bool IS_SIGNED
Indicates if T is a signed integer type.
Definition: types_traits.h:51
static constexpr size_t SIZE
Indicates the size in bytes of T.
Definition: types_traits.h:53
Utility class that checks, at compile-time, that type T is a subtype of type B.
Definition: types_traits.h:93
Remove a reference from the given type.
Definition: types_traits.h:112
T type
The type T without reference.
Definition: types_traits.h:114