summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt7
-rw-r--r--src/common/bit_field.h15
-rw-r--r--src/common/bounded_threadsafe_queue.h9
-rw-r--r--src/common/concepts.h24
-rw-r--r--src/common/fixed_point.h187
-rw-r--r--src/common/fs/file.h12
-rw-r--r--src/common/input.h5
7 files changed, 108 insertions, 151 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 46cf75fde..c0555f840 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -156,12 +156,13 @@ if (MSVC)
156 ) 156 )
157 target_compile_options(common PRIVATE 157 target_compile_options(common PRIVATE
158 /W4 158 /W4
159 /WX 159
160 /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
161 /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
162 /we4800 # Implicit conversion from 'type' to bool. Possible information loss
160 ) 163 )
161else() 164else()
162 target_compile_options(common PRIVATE 165 target_compile_options(common PRIVATE
163 -Werror
164
165 $<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation> 166 $<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
166 ) 167 )
167endif() 168endif()
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 7e1df62b1..e4e58ea45 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -141,10 +141,6 @@ public:
141 constexpr BitField(BitField&&) noexcept = default; 141 constexpr BitField(BitField&&) noexcept = default;
142 constexpr BitField& operator=(BitField&&) noexcept = default; 142 constexpr BitField& operator=(BitField&&) noexcept = default;
143 143
144 [[nodiscard]] constexpr operator T() const {
145 return Value();
146 }
147
148 constexpr void Assign(const T& value) { 144 constexpr void Assign(const T& value) {
149#ifdef _MSC_VER 145#ifdef _MSC_VER
150 storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value)); 146 storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value));
@@ -162,6 +158,17 @@ public:
162 return ExtractValue(storage); 158 return ExtractValue(storage);
163 } 159 }
164 160
161 template <typename ConvertedToType>
162 [[nodiscard]] constexpr ConvertedToType As() const {
163 static_assert(!std::is_same_v<T, ConvertedToType>,
164 "Unnecessary cast. Use Value() instead.");
165 return static_cast<ConvertedToType>(Value());
166 }
167
168 [[nodiscard]] constexpr operator T() const {
169 return Value();
170 }
171
165 [[nodiscard]] constexpr explicit operator bool() const { 172 [[nodiscard]] constexpr explicit operator bool() const {
166 return Value() != 0; 173 return Value() != 0;
167 } 174 }
diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h
index 7e465549b..21217801e 100644
--- a/src/common/bounded_threadsafe_queue.h
+++ b/src/common/bounded_threadsafe_queue.h
@@ -21,11 +21,6 @@ constexpr size_t hardware_interference_size = std::hardware_destructive_interfer
21constexpr size_t hardware_interference_size = 64; 21constexpr size_t hardware_interference_size = 64;
22#endif 22#endif
23 23
24#ifdef _MSC_VER
25#pragma warning(push)
26#pragma warning(disable : 4324)
27#endif
28
29template <typename T, size_t capacity = 0x400> 24template <typename T, size_t capacity = 0x400>
30class MPSCQueue { 25class MPSCQueue {
31public: 26public:
@@ -160,8 +155,4 @@ private:
160 static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); 155 static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible");
161}; 156};
162 157
163#ifdef _MSC_VER
164#pragma warning(pop)
165#endif
166
167} // namespace Common 158} // namespace Common
diff --git a/src/common/concepts.h b/src/common/concepts.h
index a97555f6a..a9acff3e7 100644
--- a/src/common/concepts.h
+++ b/src/common/concepts.h
@@ -3,24 +3,14 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <iterator>
6#include <type_traits> 7#include <type_traits>
7 8
8namespace Common { 9namespace Common {
9 10
10// Check if type is like an STL container 11// Check if type satisfies the ContiguousContainer named requirement.
11template <typename T> 12template <typename T>
12concept IsSTLContainer = requires(T t) { 13concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
13 typename T::value_type;
14 typename T::iterator;
15 typename T::const_iterator;
16 // TODO(ogniK): Replace below is std::same_as<void> when MSVC supports it.
17 t.begin();
18 t.end();
19 t.cbegin();
20 t.cend();
21 t.data();
22 t.size();
23};
24 14
25// TODO: Replace with std::derived_from when the <concepts> header 15// TODO: Replace with std::derived_from when the <concepts> header
26// is available on all supported platforms. 16// is available on all supported platforms.
@@ -34,4 +24,12 @@ concept DerivedFrom = requires {
34template <typename From, typename To> 24template <typename From, typename To>
35concept ConvertibleTo = std::is_convertible_v<From, To>; 25concept ConvertibleTo = std::is_convertible_v<From, To>;
36 26
27// No equivalents in the stdlib
28
29template <typename T>
30concept IsArithmetic = std::is_arithmetic_v<T>;
31
32template <typename T>
33concept IsIntegral = std::is_integral_v<T>;
34
37} // namespace Common 35} // namespace Common
diff --git a/src/common/fixed_point.h b/src/common/fixed_point.h
index 6eb6afe2f..f899b0d54 100644
--- a/src/common/fixed_point.h
+++ b/src/common/fixed_point.h
@@ -12,6 +12,8 @@
12#include <ostream> 12#include <ostream>
13#include <type_traits> 13#include <type_traits>
14 14
15#include <common/concepts.h>
16
15namespace Common { 17namespace Common {
16 18
17template <size_t I, size_t F> 19template <size_t I, size_t F>
@@ -50,8 +52,8 @@ struct type_from_size<64> {
50 static constexpr size_t size = 64; 52 static constexpr size_t size = 64;
51 53
52 using value_type = int64_t; 54 using value_type = int64_t;
53 using unsigned_type = std::make_unsigned<value_type>::type; 55 using unsigned_type = std::make_unsigned_t<value_type>;
54 using signed_type = std::make_signed<value_type>::type; 56 using signed_type = std::make_signed_t<value_type>;
55 using next_size = type_from_size<128>; 57 using next_size = type_from_size<128>;
56}; 58};
57 59
@@ -61,8 +63,8 @@ struct type_from_size<32> {
61 static constexpr size_t size = 32; 63 static constexpr size_t size = 32;
62 64
63 using value_type = int32_t; 65 using value_type = int32_t;
64 using unsigned_type = std::make_unsigned<value_type>::type; 66 using unsigned_type = std::make_unsigned_t<value_type>;
65 using signed_type = std::make_signed<value_type>::type; 67 using signed_type = std::make_signed_t<value_type>;
66 using next_size = type_from_size<64>; 68 using next_size = type_from_size<64>;
67}; 69};
68 70
@@ -72,8 +74,8 @@ struct type_from_size<16> {
72 static constexpr size_t size = 16; 74 static constexpr size_t size = 16;
73 75
74 using value_type = int16_t; 76 using value_type = int16_t;
75 using unsigned_type = std::make_unsigned<value_type>::type; 77 using unsigned_type = std::make_unsigned_t<value_type>;
76 using signed_type = std::make_signed<value_type>::type; 78 using signed_type = std::make_signed_t<value_type>;
77 using next_size = type_from_size<32>; 79 using next_size = type_from_size<32>;
78}; 80};
79 81
@@ -83,8 +85,8 @@ struct type_from_size<8> {
83 static constexpr size_t size = 8; 85 static constexpr size_t size = 8;
84 86
85 using value_type = int8_t; 87 using value_type = int8_t;
86 using unsigned_type = std::make_unsigned<value_type>::type; 88 using unsigned_type = std::make_unsigned_t<value_type>;
87 using signed_type = std::make_signed<value_type>::type; 89 using signed_type = std::make_signed_t<value_type>;
88 using next_size = type_from_size<16>; 90 using next_size = type_from_size<16>;
89}; 91};
90 92
@@ -101,7 +103,7 @@ struct divide_by_zero : std::exception {};
101template <size_t I, size_t F> 103template <size_t I, size_t F>
102constexpr FixedPoint<I, F> divide( 104constexpr FixedPoint<I, F> divide(
103 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, 105 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
104 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 106 std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
105 107
106 using next_type = typename FixedPoint<I, F>::next_type; 108 using next_type = typename FixedPoint<I, F>::next_type;
107 using base_type = typename FixedPoint<I, F>::base_type; 109 using base_type = typename FixedPoint<I, F>::base_type;
@@ -121,7 +123,7 @@ constexpr FixedPoint<I, F> divide(
121template <size_t I, size_t F> 123template <size_t I, size_t F>
122constexpr FixedPoint<I, F> divide( 124constexpr FixedPoint<I, F> divide(
123 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, 125 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
124 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 126 std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
125 127
126 using unsigned_type = typename FixedPoint<I, F>::unsigned_type; 128 using unsigned_type = typename FixedPoint<I, F>::unsigned_type;
127 129
@@ -191,7 +193,7 @@ constexpr FixedPoint<I, F> divide(
191template <size_t I, size_t F> 193template <size_t I, size_t F>
192constexpr FixedPoint<I, F> multiply( 194constexpr FixedPoint<I, F> multiply(
193 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, 195 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
194 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 196 std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
195 197
196 using next_type = typename FixedPoint<I, F>::next_type; 198 using next_type = typename FixedPoint<I, F>::next_type;
197 using base_type = typename FixedPoint<I, F>::base_type; 199 using base_type = typename FixedPoint<I, F>::base_type;
@@ -210,7 +212,7 @@ constexpr FixedPoint<I, F> multiply(
210template <size_t I, size_t F> 212template <size_t I, size_t F>
211constexpr FixedPoint<I, F> multiply( 213constexpr FixedPoint<I, F> multiply(
212 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, 214 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
213 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 215 std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
214 216
215 using base_type = typename FixedPoint<I, F>::base_type; 217 using base_type = typename FixedPoint<I, F>::base_type;
216 218
@@ -265,15 +267,16 @@ public:
265 static constexpr base_type one = base_type(1) << fractional_bits; 267 static constexpr base_type one = base_type(1) << fractional_bits;
266 268
267public: // constructors 269public: // constructors
268 FixedPoint() = default; 270 constexpr FixedPoint() = default;
269 FixedPoint(const FixedPoint&) = default; 271
270 FixedPoint(FixedPoint&&) = default; 272 constexpr FixedPoint(const FixedPoint&) = default;
271 FixedPoint& operator=(const FixedPoint&) = default; 273 constexpr FixedPoint& operator=(const FixedPoint&) = default;
272 274
273 template <class Number> 275 constexpr FixedPoint(FixedPoint&&) noexcept = default;
274 constexpr FixedPoint( 276 constexpr FixedPoint& operator=(FixedPoint&&) noexcept = default;
275 Number n, typename std::enable_if<std::is_arithmetic<Number>::value>::type* = nullptr) 277
276 : data_(static_cast<base_type>(n * one)) {} 278 template <IsArithmetic Number>
279 constexpr FixedPoint(Number n) : data_(static_cast<base_type>(n * one)) {}
277 280
278public: // conversion 281public: // conversion
279 template <size_t I2, size_t F2> 282 template <size_t I2, size_t F2>
@@ -301,36 +304,14 @@ public:
301 } 304 }
302 305
303public: // comparison operators 306public: // comparison operators
304 constexpr bool operator==(FixedPoint rhs) const { 307 friend constexpr auto operator<=>(FixedPoint lhs, FixedPoint rhs) = default;
305 return data_ == rhs.data_;
306 }
307
308 constexpr bool operator!=(FixedPoint rhs) const {
309 return data_ != rhs.data_;
310 }
311
312 constexpr bool operator<(FixedPoint rhs) const {
313 return data_ < rhs.data_;
314 }
315
316 constexpr bool operator>(FixedPoint rhs) const {
317 return data_ > rhs.data_;
318 }
319
320 constexpr bool operator<=(FixedPoint rhs) const {
321 return data_ <= rhs.data_;
322 }
323
324 constexpr bool operator>=(FixedPoint rhs) const {
325 return data_ >= rhs.data_;
326 }
327 308
328public: // unary operators 309public: // unary operators
329 constexpr bool operator!() const { 310 [[nodiscard]] constexpr bool operator!() const {
330 return !data_; 311 return !data_;
331 } 312 }
332 313
333 constexpr FixedPoint operator~() const { 314 [[nodiscard]] constexpr FixedPoint operator~() const {
334 // NOTE(eteran): this will often appear to "just negate" the value 315 // NOTE(eteran): this will often appear to "just negate" the value
335 // that is not an error, it is because -x == (~x+1) 316 // that is not an error, it is because -x == (~x+1)
336 // and that "+1" is adding an infinitesimally small fraction to the 317 // and that "+1" is adding an infinitesimally small fraction to the
@@ -338,11 +319,11 @@ public: // unary operators
338 return FixedPoint::from_base(~data_); 319 return FixedPoint::from_base(~data_);
339 } 320 }
340 321
341 constexpr FixedPoint operator-() const { 322 [[nodiscard]] constexpr FixedPoint operator-() const {
342 return FixedPoint::from_base(-data_); 323 return FixedPoint::from_base(-data_);
343 } 324 }
344 325
345 constexpr FixedPoint operator+() const { 326 [[nodiscard]] constexpr FixedPoint operator+() const {
346 return FixedPoint::from_base(+data_); 327 return FixedPoint::from_base(+data_);
347 } 328 }
348 329
@@ -411,15 +392,13 @@ public: // binary math operators, effects underlying bit pattern since these
411 return *this; 392 return *this;
412 } 393 }
413 394
414 template <class Integer, 395 template <IsIntegral Integer>
415 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
416 constexpr FixedPoint& operator>>=(Integer n) { 396 constexpr FixedPoint& operator>>=(Integer n) {
417 data_ >>= n; 397 data_ >>= n;
418 return *this; 398 return *this;
419 } 399 }
420 400
421 template <class Integer, 401 template <IsIntegral Integer>
422 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
423 constexpr FixedPoint& operator<<=(Integer n) { 402 constexpr FixedPoint& operator<<=(Integer n) {
424 data_ <<= n; 403 data_ <<= n;
425 return *this; 404 return *this;
@@ -430,42 +409,42 @@ public: // conversion to basic types
430 data_ += (data_ & fractional_mask) >> 1; 409 data_ += (data_ & fractional_mask) >> 1;
431 } 410 }
432 411
433 constexpr int to_int() { 412 [[nodiscard]] constexpr int to_int() {
434 round_up(); 413 round_up();
435 return static_cast<int>((data_ & integer_mask) >> fractional_bits); 414 return static_cast<int>((data_ & integer_mask) >> fractional_bits);
436 } 415 }
437 416
438 constexpr unsigned int to_uint() const { 417 [[nodiscard]] constexpr unsigned int to_uint() {
439 round_up(); 418 round_up();
440 return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits); 419 return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits);
441 } 420 }
442 421
443 constexpr int64_t to_long() { 422 [[nodiscard]] constexpr int64_t to_long() {
444 round_up(); 423 round_up();
445 return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits); 424 return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits);
446 } 425 }
447 426
448 constexpr int to_int_floor() const { 427 [[nodiscard]] constexpr int to_int_floor() const {
449 return static_cast<int>((data_ & integer_mask) >> fractional_bits); 428 return static_cast<int>((data_ & integer_mask) >> fractional_bits);
450 } 429 }
451 430
452 constexpr int64_t to_long_floor() { 431 [[nodiscard]] constexpr int64_t to_long_floor() const {
453 return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits); 432 return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits);
454 } 433 }
455 434
456 constexpr unsigned int to_uint_floor() const { 435 [[nodiscard]] constexpr unsigned int to_uint_floor() const {
457 return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits); 436 return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits);
458 } 437 }
459 438
460 constexpr float to_float() const { 439 [[nodiscard]] constexpr float to_float() const {
461 return static_cast<float>(data_) / FixedPoint::one; 440 return static_cast<float>(data_) / FixedPoint::one;
462 } 441 }
463 442
464 constexpr double to_double() const { 443 [[nodiscard]] constexpr double to_double() const {
465 return static_cast<double>(data_) / FixedPoint::one; 444 return static_cast<double>(data_) / FixedPoint::one;
466 } 445 }
467 446
468 constexpr base_type to_raw() const { 447 [[nodiscard]] constexpr base_type to_raw() const {
469 return data_; 448 return data_;
470 } 449 }
471 450
@@ -473,27 +452,27 @@ public: // conversion to basic types
473 data_ &= fractional_mask; 452 data_ &= fractional_mask;
474 } 453 }
475 454
476 constexpr base_type get_frac() const { 455 [[nodiscard]] constexpr base_type get_frac() const {
477 return data_ & fractional_mask; 456 return data_ & fractional_mask;
478 } 457 }
479 458
480public: 459public:
481 constexpr void swap(FixedPoint& rhs) { 460 constexpr void swap(FixedPoint& rhs) noexcept {
482 using std::swap; 461 using std::swap;
483 swap(data_, rhs.data_); 462 swap(data_, rhs.data_);
484 } 463 }
485 464
486public: 465public:
487 base_type data_; 466 base_type data_{};
488}; 467};
489 468
490// if we have the same fractional portion, but differing integer portions, we trivially upgrade the 469// if we have the same fractional portion, but differing integer portions, we trivially upgrade the
491// smaller type 470// smaller type
492template <size_t I1, size_t I2, size_t F> 471template <size_t I1, size_t I2, size_t F>
493constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator+( 472constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator+(
494 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 473 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
495 474
496 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 475 using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
497 476
498 const T l = T::from_base(lhs.to_raw()); 477 const T l = T::from_base(lhs.to_raw());
499 const T r = T::from_base(rhs.to_raw()); 478 const T r = T::from_base(rhs.to_raw());
@@ -501,10 +480,10 @@ constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2,
501} 480}
502 481
503template <size_t I1, size_t I2, size_t F> 482template <size_t I1, size_t I2, size_t F>
504constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator-( 483constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator-(
505 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 484 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
506 485
507 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 486 using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
508 487
509 const T l = T::from_base(lhs.to_raw()); 488 const T l = T::from_base(lhs.to_raw());
510 const T r = T::from_base(rhs.to_raw()); 489 const T r = T::from_base(rhs.to_raw());
@@ -512,10 +491,10 @@ constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2,
512} 491}
513 492
514template <size_t I1, size_t I2, size_t F> 493template <size_t I1, size_t I2, size_t F>
515constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator*( 494constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator*(
516 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 495 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
517 496
518 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 497 using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
519 498
520 const T l = T::from_base(lhs.to_raw()); 499 const T l = T::from_base(lhs.to_raw());
521 const T r = T::from_base(rhs.to_raw()); 500 const T r = T::from_base(rhs.to_raw());
@@ -523,10 +502,10 @@ constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2,
523} 502}
524 503
525template <size_t I1, size_t I2, size_t F> 504template <size_t I1, size_t I2, size_t F>
526constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator/( 505constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator/(
527 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 506 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
528 507
529 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 508 using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
530 509
531 const T l = T::from_base(lhs.to_raw()); 510 const T l = T::from_base(lhs.to_raw());
532 const T r = T::from_base(rhs.to_raw()); 511 const T r = T::from_base(rhs.to_raw());
@@ -561,54 +540,46 @@ constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs)
561 return lhs; 540 return lhs;
562} 541}
563 542
564template <size_t I, size_t F, class Number, 543template <size_t I, size_t F, IsArithmetic Number>
565 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
566constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) { 544constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
567 lhs += FixedPoint<I, F>(rhs); 545 lhs += FixedPoint<I, F>(rhs);
568 return lhs; 546 return lhs;
569} 547}
570template <size_t I, size_t F, class Number, 548template <size_t I, size_t F, IsArithmetic Number>
571 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
572constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) { 549constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
573 lhs -= FixedPoint<I, F>(rhs); 550 lhs -= FixedPoint<I, F>(rhs);
574 return lhs; 551 return lhs;
575} 552}
576template <size_t I, size_t F, class Number, 553template <size_t I, size_t F, IsArithmetic Number>
577 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
578constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) { 554constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
579 lhs *= FixedPoint<I, F>(rhs); 555 lhs *= FixedPoint<I, F>(rhs);
580 return lhs; 556 return lhs;
581} 557}
582template <size_t I, size_t F, class Number, 558template <size_t I, size_t F, IsArithmetic Number>
583 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
584constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) { 559constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
585 lhs /= FixedPoint<I, F>(rhs); 560 lhs /= FixedPoint<I, F>(rhs);
586 return lhs; 561 return lhs;
587} 562}
588 563
589template <size_t I, size_t F, class Number, 564template <size_t I, size_t F, IsArithmetic Number>
590 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
591constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) { 565constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
592 FixedPoint<I, F> tmp(lhs); 566 FixedPoint<I, F> tmp(lhs);
593 tmp += rhs; 567 tmp += rhs;
594 return tmp; 568 return tmp;
595} 569}
596template <size_t I, size_t F, class Number, 570template <size_t I, size_t F, IsArithmetic Number>
597 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
598constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) { 571constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
599 FixedPoint<I, F> tmp(lhs); 572 FixedPoint<I, F> tmp(lhs);
600 tmp -= rhs; 573 tmp -= rhs;
601 return tmp; 574 return tmp;
602} 575}
603template <size_t I, size_t F, class Number, 576template <size_t I, size_t F, IsArithmetic Number>
604 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
605constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) { 577constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
606 FixedPoint<I, F> tmp(lhs); 578 FixedPoint<I, F> tmp(lhs);
607 tmp *= rhs; 579 tmp *= rhs;
608 return tmp; 580 return tmp;
609} 581}
610template <size_t I, size_t F, class Number, 582template <size_t I, size_t F, IsArithmetic Number>
611 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
612constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) { 583constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
613 FixedPoint<I, F> tmp(lhs); 584 FixedPoint<I, F> tmp(lhs);
614 tmp /= rhs; 585 tmp /= rhs;
@@ -616,78 +587,64 @@ constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
616} 587}
617 588
618// shift operators 589// shift operators
619template <size_t I, size_t F, class Integer, 590template <size_t I, size_t F, IsIntegral Integer>
620 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
621constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) { 591constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
622 lhs <<= rhs; 592 lhs <<= rhs;
623 return lhs; 593 return lhs;
624} 594}
625template <size_t I, size_t F, class Integer, 595template <size_t I, size_t F, IsIntegral Integer>
626 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
627constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) { 596constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
628 lhs >>= rhs; 597 lhs >>= rhs;
629 return lhs; 598 return lhs;
630} 599}
631 600
632// comparison operators 601// comparison operators
633template <size_t I, size_t F, class Number, 602template <size_t I, size_t F, IsArithmetic Number>
634 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
635constexpr bool operator>(FixedPoint<I, F> lhs, Number rhs) { 603constexpr bool operator>(FixedPoint<I, F> lhs, Number rhs) {
636 return lhs > FixedPoint<I, F>(rhs); 604 return lhs > FixedPoint<I, F>(rhs);
637} 605}
638template <size_t I, size_t F, class Number, 606template <size_t I, size_t F, IsArithmetic Number>
639 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
640constexpr bool operator<(FixedPoint<I, F> lhs, Number rhs) { 607constexpr bool operator<(FixedPoint<I, F> lhs, Number rhs) {
641 return lhs < FixedPoint<I, F>(rhs); 608 return lhs < FixedPoint<I, F>(rhs);
642} 609}
643template <size_t I, size_t F, class Number, 610template <size_t I, size_t F, IsArithmetic Number>
644 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
645constexpr bool operator>=(FixedPoint<I, F> lhs, Number rhs) { 611constexpr bool operator>=(FixedPoint<I, F> lhs, Number rhs) {
646 return lhs >= FixedPoint<I, F>(rhs); 612 return lhs >= FixedPoint<I, F>(rhs);
647} 613}
648template <size_t I, size_t F, class Number, 614template <size_t I, size_t F, IsArithmetic Number>
649 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
650constexpr bool operator<=(FixedPoint<I, F> lhs, Number rhs) { 615constexpr bool operator<=(FixedPoint<I, F> lhs, Number rhs) {
651 return lhs <= FixedPoint<I, F>(rhs); 616 return lhs <= FixedPoint<I, F>(rhs);
652} 617}
653template <size_t I, size_t F, class Number, 618template <size_t I, size_t F, IsArithmetic Number>
654 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
655constexpr bool operator==(FixedPoint<I, F> lhs, Number rhs) { 619constexpr bool operator==(FixedPoint<I, F> lhs, Number rhs) {
656 return lhs == FixedPoint<I, F>(rhs); 620 return lhs == FixedPoint<I, F>(rhs);
657} 621}
658template <size_t I, size_t F, class Number, 622template <size_t I, size_t F, IsArithmetic Number>
659 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
660constexpr bool operator!=(FixedPoint<I, F> lhs, Number rhs) { 623constexpr bool operator!=(FixedPoint<I, F> lhs, Number rhs) {
661 return lhs != FixedPoint<I, F>(rhs); 624 return lhs != FixedPoint<I, F>(rhs);
662} 625}
663 626
664template <size_t I, size_t F, class Number, 627template <size_t I, size_t F, IsArithmetic Number>
665 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
666constexpr bool operator>(Number lhs, FixedPoint<I, F> rhs) { 628constexpr bool operator>(Number lhs, FixedPoint<I, F> rhs) {
667 return FixedPoint<I, F>(lhs) > rhs; 629 return FixedPoint<I, F>(lhs) > rhs;
668} 630}
669template <size_t I, size_t F, class Number, 631template <size_t I, size_t F, IsArithmetic Number>
670 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
671constexpr bool operator<(Number lhs, FixedPoint<I, F> rhs) { 632constexpr bool operator<(Number lhs, FixedPoint<I, F> rhs) {
672 return FixedPoint<I, F>(lhs) < rhs; 633 return FixedPoint<I, F>(lhs) < rhs;
673} 634}
674template <size_t I, size_t F, class Number, 635template <size_t I, size_t F, IsArithmetic Number>
675 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
676constexpr bool operator>=(Number lhs, FixedPoint<I, F> rhs) { 636constexpr bool operator>=(Number lhs, FixedPoint<I, F> rhs) {
677 return FixedPoint<I, F>(lhs) >= rhs; 637 return FixedPoint<I, F>(lhs) >= rhs;
678} 638}
679template <size_t I, size_t F, class Number, 639template <size_t I, size_t F, IsArithmetic Number>
680 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
681constexpr bool operator<=(Number lhs, FixedPoint<I, F> rhs) { 640constexpr bool operator<=(Number lhs, FixedPoint<I, F> rhs) {
682 return FixedPoint<I, F>(lhs) <= rhs; 641 return FixedPoint<I, F>(lhs) <= rhs;
683} 642}
684template <size_t I, size_t F, class Number, 643template <size_t I, size_t F, IsArithmetic Number>
685 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
686constexpr bool operator==(Number lhs, FixedPoint<I, F> rhs) { 644constexpr bool operator==(Number lhs, FixedPoint<I, F> rhs) {
687 return FixedPoint<I, F>(lhs) == rhs; 645 return FixedPoint<I, F>(lhs) == rhs;
688} 646}
689template <size_t I, size_t F, class Number, 647template <size_t I, size_t F, IsArithmetic Number>
690 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
691constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) { 648constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) {
692 return FixedPoint<I, F>(lhs) != rhs; 649 return FixedPoint<I, F>(lhs) != rhs;
693} 650}
diff --git a/src/common/fs/file.h b/src/common/fs/file.h
index 69b53384c..167c4d826 100644
--- a/src/common/fs/file.h
+++ b/src/common/fs/file.h
@@ -209,8 +209,8 @@ public:
209 209
210 /** 210 /**
211 * Helper function which deduces the value type of a contiguous STL container used in ReadSpan. 211 * Helper function which deduces the value type of a contiguous STL container used in ReadSpan.
212 * If T is not a contiguous STL container as defined by the concept IsSTLContainer, this calls 212 * If T is not a contiguous container as defined by the concept IsContiguousContainer, this
213 * ReadObject and T must be a trivially copyable object. 213 * calls ReadObject and T must be a trivially copyable object.
214 * 214 *
215 * See ReadSpan for more details if T is a contiguous container. 215 * See ReadSpan for more details if T is a contiguous container.
216 * See ReadObject for more details if T is a trivially copyable object. 216 * See ReadObject for more details if T is a trivially copyable object.
@@ -223,7 +223,7 @@ public:
223 */ 223 */
224 template <typename T> 224 template <typename T>
225 [[nodiscard]] size_t Read(T& data) const { 225 [[nodiscard]] size_t Read(T& data) const {
226 if constexpr (IsSTLContainer<T>) { 226 if constexpr (IsContiguousContainer<T>) {
227 using ContiguousType = typename T::value_type; 227 using ContiguousType = typename T::value_type;
228 static_assert(std::is_trivially_copyable_v<ContiguousType>, 228 static_assert(std::is_trivially_copyable_v<ContiguousType>,
229 "Data type must be trivially copyable."); 229 "Data type must be trivially copyable.");
@@ -235,8 +235,8 @@ public:
235 235
236 /** 236 /**
237 * Helper function which deduces the value type of a contiguous STL container used in WriteSpan. 237 * Helper function which deduces the value type of a contiguous STL container used in WriteSpan.
238 * If T is not a contiguous STL container as defined by the concept IsSTLContainer, this calls 238 * If T is not a contiguous STL container as defined by the concept IsContiguousContainer, this
239 * WriteObject and T must be a trivially copyable object. 239 * calls WriteObject and T must be a trivially copyable object.
240 * 240 *
241 * See WriteSpan for more details if T is a contiguous container. 241 * See WriteSpan for more details if T is a contiguous container.
242 * See WriteObject for more details if T is a trivially copyable object. 242 * See WriteObject for more details if T is a trivially copyable object.
@@ -249,7 +249,7 @@ public:
249 */ 249 */
250 template <typename T> 250 template <typename T>
251 [[nodiscard]] size_t Write(const T& data) const { 251 [[nodiscard]] size_t Write(const T& data) const {
252 if constexpr (IsSTLContainer<T>) { 252 if constexpr (IsContiguousContainer<T>) {
253 using ContiguousType = typename T::value_type; 253 using ContiguousType = typename T::value_type;
254 static_assert(std::is_trivially_copyable_v<ContiguousType>, 254 static_assert(std::is_trivially_copyable_v<ContiguousType>,
255 "Data type must be trivially copyable."); 255 "Data type must be trivially copyable.");
diff --git a/src/common/input.h b/src/common/input.h
index b533f3844..cb30b7254 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -100,7 +100,6 @@ enum class CameraError {
100enum class VibrationAmplificationType { 100enum class VibrationAmplificationType {
101 Linear, 101 Linear,
102 Exponential, 102 Exponential,
103 Test,
104}; 103};
105 104
106// Analog properties for calibration 105// Analog properties for calibration
@@ -325,6 +324,10 @@ public:
325 return VibrationError::NotSupported; 324 return VibrationError::NotSupported;
326 } 325 }
327 326
327 virtual bool IsVibrationEnabled() {
328 return false;
329 }
330
328 virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { 331 virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
329 return PollingError::NotSupported; 332 return PollingError::NotSupported;
330 } 333 }