1
+ /*
2
+ * Copyright (c) 2022, Thomas Sommer
3
+ *
4
+ * This file is part of the modm project.
5
+ *
6
+ * This Source Code Form is subject to the terms of the Mozilla Public
7
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
8
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
+ */
10
+ // ----------------------------------------------------------------------------
11
+ #pragma once
12
+
13
+ #include < algorithm>
14
+ #include < concepts>
15
+
16
+ #include < modm/math/utils/integer_traits.hpp>
17
+ #include < modm/architecture/interface/assert.hpp>
18
+
19
+ namespace modm {
20
+
21
+ /* *
22
+ * @brief Unsigned integer with arbitrary number of digits.
23
+ * Artihmetic over- and underflows wrap by default, just like builtin integral types.
24
+ *
25
+ * @tparam Bits Resolution of the unsigned integer
26
+ *
27
+ * @author Thomas Sommer
28
+ * @ingroup modm_math
29
+ */
30
+ template <int Bits>
31
+ requires (Bits > 0 )
32
+ class uintn_t {
33
+ public:
34
+ static constexpr int digits = Bits;
35
+
36
+ using T = uint_t <Bits>::least;
37
+ static constexpr T bitmask = ::modm::bitmask<Bits>();
38
+
39
+ static constexpr T min = 0 ;
40
+ static constexpr T max = bitmask;
41
+
42
+ // / constructors
43
+ constexpr uintn_t () = default;
44
+
45
+ constexpr uintn_t (T value) {
46
+ #ifdef MODM_DEBUG_BUILD
47
+ if (not modm_assert_continue_ignore_debug (value <= max, " uintn_t.ctor" , " value exceeded max" , max)) {
48
+ value_ = std::min (max, value);
49
+ return ;
50
+ }
51
+ #endif
52
+
53
+ value_ = value;
54
+ }
55
+
56
+ #if 0
57
+ template <int E>
58
+ requires (Bits <= E)
59
+ constexpr uintn_t(const uintn_t<E>& other)
60
+ : value_(other.value_ >> (E - Bits))
61
+ {}
62
+
63
+ template <int E>
64
+ requires (Bits > E)
65
+ constexpr uintn_t(const uintn_t<E>& other)
66
+ : value_(other.value_ * max / other.max)
67
+ {}
68
+ #endif
69
+
70
+ // / assignment operators
71
+ void operator =(T value) {
72
+ #ifdef MODM_DEBUG_BUILD
73
+ if (not modm_assert_continue_ignore_debug (value <= max, " uintn_t.assign" , " value exceeded max" , max)) {
74
+ value_ = std::min (max, value);
75
+ return ;
76
+ }
77
+ #endif
78
+
79
+ value_ = value;
80
+ }
81
+
82
+ #if 0
83
+ template <int E>
84
+ requires (Bits <= E)
85
+ constexpr void operator=(const uintn_t<E>& other) {
86
+ value_ = other.value_ >> (E - Bits);
87
+ }
88
+
89
+ template <int E>
90
+ requires (Bits > E)
91
+ constexpr void operator=(const uintn_t<E>& other) {
92
+ value_ = other.value_ * max / other.max;
93
+ }
94
+ #endif
95
+
96
+ constexpr T value () const { return value_; }
97
+ constexpr T& value () { return value_; }
98
+
99
+ bool operator <=>(const uintn_t & other) const = default ;
100
+
101
+ // / operator +, -, *, /
102
+ template <std::integral U>
103
+ uintn_t
104
+ operator +(U value)
105
+ {
106
+ return {T (value_ + value) & uintn_t ::max};
107
+ }
108
+
109
+ template <std::integral U>
110
+ uintn_t
111
+ operator -(U value)
112
+ {
113
+ return {T (value_ - value) & uintn_t ::max};
114
+ }
115
+
116
+ template <std::integral U>
117
+ uintn_t
118
+ operator *(U value)
119
+ {
120
+ return {T (value_ * value) & uintn_t ::max};
121
+ }
122
+
123
+ template <std::integral U>
124
+ uintn_t
125
+ operator /(U value)
126
+ {
127
+ return {T (value_ / value) & uintn_t ::max};
128
+ }
129
+
130
+ // / operator +=, -=, *=, /=
131
+ template <std::integral U>
132
+ uintn_t &
133
+ operator +=(U value)
134
+ {
135
+ value_ = T (value_ + value) & uintn_t ::max;
136
+ return *this ;
137
+ }
138
+
139
+ template <std::integral U>
140
+ uintn_t &
141
+ operator -=(U value)
142
+ {
143
+ value_ = T (value_ - value) & uintn_t ::max;
144
+ return *this ;
145
+ }
146
+
147
+ template <std::integral U>
148
+ uintn_t &
149
+ operator *(U value)
150
+ {
151
+ value_ = T (value_ * value) & uintn_t ::max;
152
+ return *this ;
153
+ }
154
+
155
+ template <std::integral U>
156
+ uintn_t &
157
+ operator /(U value)
158
+ {
159
+ value_ = T (value_ / value) & uintn_t ::max;
160
+ return this ;
161
+ }
162
+
163
+ protected:
164
+ T value_{0 };
165
+
166
+ private:
167
+ template <int >
168
+ friend class uintn_t ;
169
+ };
170
+
171
+ }
0 commit comments