Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
IntTypes.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2022 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_UTIL_INTTYPES_HPP
18#define TOOLBOX_UTIL_INTTYPES_HPP
19
22
23#include <boost/functional/hash.hpp>
24
25namespace toolbox {
26inline namespace util {
27
28template <typename ValueT>
29struct IntPolicy {
31 static constexpr ValueT min() noexcept { return std::numeric_limits<ValueT>::min(); }
32 static constexpr ValueT max() noexcept { return std::numeric_limits<ValueT>::max(); }
33};
37
38template <typename PolicyT>
40 using ValueType = typename PolicyT::ValueType;
41
42 template <typename RhsT>
43 requires std::convertible_to<RhsT, ValueType>
44 constexpr explicit IntWrapper(RhsT rhs) noexcept
45 : value_{static_cast<ValueType>(rhs)}
46 {
47 }
48
49 constexpr IntWrapper() noexcept = default;
50 ~IntWrapper() = default;
51
52 // Copy.
53 constexpr IntWrapper(const IntWrapper&) noexcept = default;
54 constexpr IntWrapper& operator=(const IntWrapper&) noexcept = default;
55
56 // Move.
57 constexpr IntWrapper(IntWrapper&&) noexcept = default;
58 constexpr IntWrapper& operator=(IntWrapper&&) noexcept = default;
59
60 constexpr ValueType count() const noexcept { return value_; }
61
62 static constexpr IntWrapper min() noexcept { return PolicyT::min(); }
63 static constexpr IntWrapper max() noexcept { return PolicyT::max(); }
64 static constexpr IntWrapper zero() noexcept { return IntWrapper{0}; }
65
66 // Assignment.
67
69 constexpr IntWrapper& operator+=(IntWrapper rhs) noexcept
70 {
71 value_ += rhs.value_;
72 return *this;
73 }
74
76 constexpr IntWrapper& operator-=(IntWrapper rhs) noexcept
77 {
78 value_ -= rhs.value_;
79 return *this;
80 }
81
83 constexpr IntWrapper& operator*=(IntWrapper rhs) noexcept
84 {
85 value_ *= rhs.value_;
86 return *this;
87 }
88
90 constexpr IntWrapper& operator/=(IntWrapper rhs) noexcept
91 {
92 value_ /= rhs.value_;
93 return *this;
94 }
95
97 constexpr IntWrapper& operator%=(IntWrapper rhs) noexcept
98 {
99 value_ %= rhs.value_;
100 return *this;
101 }
102
104 constexpr IntWrapper& operator&=(IntWrapper rhs) noexcept
105 {
106 value_ &= rhs.value_;
107 return *this;
108 }
109
111 constexpr IntWrapper& operator|=(IntWrapper rhs) noexcept
112 {
113 value_ |= rhs.value_;
114 return *this;
115 }
116
118 constexpr IntWrapper& operator^=(IntWrapper rhs) noexcept
119 {
120 value_ ^= rhs.value_;
121 return *this;
122 }
123
125 constexpr IntWrapper& operator<<=(IntWrapper rhs) noexcept
126 {
127 value_ <<= rhs.value_;
128 return *this;
129 }
130
132 constexpr IntWrapper& operator>>=(IntWrapper rhs) noexcept
133 {
134 value_ >>= rhs.value_;
135 return *this;
136 }
137
138 // Increment/Decrement.
139
141 constexpr IntWrapper& operator++() noexcept
142 {
143 ++value_;
144 return *this;
145 }
146
148 constexpr IntWrapper& operator--() noexcept
149 {
150 --value_;
151 return *this;
152 }
153
155 constexpr IntWrapper operator++(int) noexcept { return IntWrapper{value_++}; }
156
158 constexpr IntWrapper operator--(int) noexcept { return IntWrapper{value_--}; }
159
160 // Arithmetic.
161
163 constexpr IntWrapper operator+() const noexcept { return IntWrapper{+value_}; }
164
166 constexpr IntWrapper operator-() const noexcept { return IntWrapper{-value_}; }
167
169 friend constexpr IntWrapper operator+(IntWrapper lhs, IntWrapper rhs) noexcept
170 {
171 return IntWrapper{lhs.value_ + rhs.value_};
172 }
173
175 friend constexpr IntWrapper operator-(IntWrapper lhs, IntWrapper rhs) noexcept
176 {
177 return IntWrapper{lhs.value_ - rhs.value_};
178 }
179
181 friend constexpr IntWrapper operator*(IntWrapper lhs, IntWrapper rhs) noexcept
182 {
183 return IntWrapper{lhs.value_ * rhs.value_};
184 }
185
187 friend constexpr IntWrapper operator/(IntWrapper lhs, IntWrapper rhs) noexcept
188 {
189 return IntWrapper{lhs.value_ / rhs.value_};
190 }
191
193 friend constexpr IntWrapper operator%(IntWrapper lhs, IntWrapper rhs) noexcept
194 {
195 return IntWrapper{lhs.value_ % rhs.value_};
196 }
197
198 // Bitwise.
199
201 constexpr IntWrapper operator~() const noexcept { return IntWrapper{~value_}; }
202
204 friend constexpr IntWrapper operator&(IntWrapper lhs, IntWrapper rhs) noexcept
205 {
206 return IntWrapper{lhs.value_ & rhs.value_};
207 }
208
210 friend constexpr IntWrapper operator|(IntWrapper lhs, IntWrapper rhs) noexcept
211 {
212 return IntWrapper{lhs.value_ | rhs.value_};
213 }
214
216 friend constexpr IntWrapper operator^(IntWrapper lhs, IntWrapper rhs) noexcept
217 {
218 return IntWrapper{lhs.value_ ^ rhs.value_};
219 }
220
222 friend constexpr IntWrapper operator<<(IntWrapper lhs, IntWrapper rhs) noexcept
223 {
224 return IntWrapper{lhs.value_ << rhs.value_};
225 }
226
228 friend constexpr IntWrapper operator>>(IntWrapper lhs, IntWrapper rhs) noexcept
229 {
230 return IntWrapper{lhs.value_ >> rhs.value_};
231 }
232
233 // Comparison.
234 friend constexpr auto operator<=>(const IntWrapper&, const IntWrapper&) noexcept = default;
235 friend constexpr bool operator==(const IntWrapper&, const IntWrapper&) noexcept = default;
236
237 // Stream.
238
240 template <typename StreamT>
241 requires Streamable<StreamT>
242 friend constexpr StreamT& operator<<(StreamT& os, IntWrapper rhs)
243 {
244 os << rhs.value_;
245 return os;
246 }
247
248 private:
249 ValueType value_;
250};
251
254static_assert(std::is_standard_layout_v<IntWrapper<Int32Policy>>
255 && std::is_trivial_v<IntWrapper<Int32Policy>>);
256static_assert(sizeof(IntWrapper<Int16Policy>) == 2, "must be specific size");
257static_assert(sizeof(IntWrapper<Int32Policy>) == 4, "must be specific size");
258static_assert(sizeof(IntWrapper<Int64Policy>) == 8, "must be specific size");
259
260template <typename ValueT>
261concept IsIntWrapper = is_instantiation_of<ValueT, IntWrapper>::value;
262
263template <typename PolicyT>
265{
266 boost::hash<typename PolicyT::ValueType> hasher;
267 return hasher(wrapper.count());
268}
269
270template <typename ValueT>
271 requires IsIntWrapper<ValueT>
273 static constexpr auto from_string(std::string_view sv) noexcept
274 {
276 return ValueT{UnderlyingTraits::from_string(sv)};
277 }
278};
279
283
286
287constexpr Id16 operator""_id16(unsigned long long val) noexcept
288{
289 return Id16{val};
290}
291
294
295constexpr Id32 operator""_id32(unsigned long long val) noexcept
296{
297 return Id32{val};
298}
299
302
303constexpr Id64 operator""_id64(unsigned long long val) noexcept
304{
305 return Id64{val};
306}
307
308} // namespace util
309} // namespace toolbox
310
311namespace std {
312template <typename PolicyT>
313struct hash<toolbox::IntWrapper<PolicyT>> {
314 inline std::size_t operator()(toolbox::IntWrapper<PolicyT> wrapper) const
315 {
316 return wrapper.count();
317 }
318};
319} // namespace std
320
321#endif // TOOLBOX_UTIL_INTTYPES_HPP
#define TOOLBOX_PACKED
Definition Config.h:29
STL namespace.
std::size_t hash_value(IntWrapper< PolicyT > wrapper)
Definition IntTypes.hpp:264
std::string_view sv
Definition Tokeniser.hpp:26
constexpr auto bind() noexcept
Definition Slot.hpp:92
std::size_t operator()(toolbox::IntWrapper< PolicyT > wrapper) const
Definition IntTypes.hpp:314
static constexpr ValueT max() noexcept
Definition IntTypes.hpp:32
static constexpr ValueT min() noexcept
Definition IntTypes.hpp:31
friend constexpr bool operator==(const IntWrapper &, const IntWrapper &) noexcept=default
friend constexpr IntWrapper operator-(IntWrapper lhs, IntWrapper rhs) noexcept
Subtraction.
Definition IntTypes.hpp:175
friend constexpr IntWrapper operator+(IntWrapper lhs, IntWrapper rhs) noexcept
Addition.
Definition IntTypes.hpp:169
friend constexpr StreamT & operator<<(StreamT &os, IntWrapper rhs)
Insertion.
Definition IntTypes.hpp:242
constexpr IntWrapper() noexcept=default
constexpr IntWrapper & operator|=(IntWrapper rhs) noexcept
Bitwise OR assignment.
Definition IntTypes.hpp:111
friend constexpr IntWrapper operator^(IntWrapper lhs, IntWrapper rhs) noexcept
Bitwise XOR.
Definition IntTypes.hpp:216
constexpr IntWrapper & operator-=(IntWrapper rhs) noexcept
Subtraction assignment.
Definition IntTypes.hpp:76
constexpr IntWrapper & operator>>=(IntWrapper rhs) noexcept
Bitwise right shift assignment.
Definition IntTypes.hpp:132
constexpr IntWrapper & operator^=(IntWrapper rhs) noexcept
Bitwise XOR assignment.
Definition IntTypes.hpp:118
typename PolicyT::ValueType ValueType
Definition IntTypes.hpp:40
friend constexpr IntWrapper operator*(IntWrapper lhs, IntWrapper rhs) noexcept
Multiplication.
Definition IntTypes.hpp:181
friend constexpr IntWrapper operator|(IntWrapper lhs, IntWrapper rhs) noexcept
Bitwise OR.
Definition IntTypes.hpp:210
constexpr IntWrapper operator-() const noexcept
Unary minus.
Definition IntTypes.hpp:166
friend constexpr IntWrapper operator&(IntWrapper lhs, IntWrapper rhs) noexcept
Bitwise AND.
Definition IntTypes.hpp:204
constexpr IntWrapper & operator*=(IntWrapper rhs) noexcept
Multiplication assignment.
Definition IntTypes.hpp:83
constexpr IntWrapper operator~() const noexcept
Bitwise NOT.
Definition IntTypes.hpp:201
friend constexpr IntWrapper operator<<(IntWrapper lhs, IntWrapper rhs) noexcept
Bitwise left shift.
Definition IntTypes.hpp:222
constexpr IntWrapper operator+() const noexcept
Unary plus.
Definition IntTypes.hpp:163
static constexpr IntWrapper min() noexcept
Definition IntTypes.hpp:62
constexpr IntWrapper operator--(int) noexcept
Post-decrement.
Definition IntTypes.hpp:158
constexpr IntWrapper & operator++() noexcept
Pre-increment.
Definition IntTypes.hpp:141
friend constexpr IntWrapper operator>>(IntWrapper lhs, IntWrapper rhs) noexcept
Bitwise right shift.
Definition IntTypes.hpp:228
constexpr IntWrapper & operator--() noexcept
Pre-decrement.
Definition IntTypes.hpp:148
friend constexpr IntWrapper operator%(IntWrapper lhs, IntWrapper rhs) noexcept
Modulo.
Definition IntTypes.hpp:193
constexpr IntWrapper & operator<<=(IntWrapper rhs) noexcept
Bitwise left shift assignment.
Definition IntTypes.hpp:125
constexpr IntWrapper operator++(int) noexcept
Post-increment.
Definition IntTypes.hpp:155
constexpr IntWrapper & operator%=(IntWrapper rhs) noexcept
Modulo assignment.
Definition IntTypes.hpp:97
constexpr ValueType count() const noexcept
Definition IntTypes.hpp:60
static constexpr IntWrapper zero() noexcept
Definition IntTypes.hpp:64
friend constexpr IntWrapper operator/(IntWrapper lhs, IntWrapper rhs) noexcept
Division.
Definition IntTypes.hpp:187
friend constexpr auto operator<=>(const IntWrapper &, const IntWrapper &) noexcept=default
static constexpr IntWrapper max() noexcept
Definition IntTypes.hpp:63
constexpr IntWrapper & operator+=(IntWrapper rhs) noexcept
Addition assignment.
Definition IntTypes.hpp:69
constexpr IntWrapper & operator&=(IntWrapper rhs) noexcept
Bitwise AND assignment.
Definition IntTypes.hpp:104
constexpr IntWrapper(RhsT rhs) noexcept
Definition IntTypes.hpp:44
constexpr IntWrapper & operator/=(IntWrapper rhs) noexcept
Division assignment.
Definition IntTypes.hpp:90
static constexpr auto from_string(std::string_view sv) noexcept
Definition IntTypes.hpp:273