// // SizedCounter.hpp // Clock Signal // // Created by Thomas Harte on 22/09/2025. // Copyright © 2025 Thomas Harte. All rights reserved. // #pragma once #include "Sizes.hpp" namespace Numeric { /*! Provides a counter that is strictly limited to the requested of bits but attempts otherwise to act like a standard C++ numeric type. */ template struct SizedCounter { using IntT = MinIntForValue<1 << bits>::type; inline static constexpr IntT Mask = (1 << bits) - 1; constexpr SizedCounter(const IntT start_value) noexcept : counter_(start_value & Mask) {} SizedCounter() = default; operator IntT() const { return counter_; } SizedCounter &operator++(int) { (*this) ++; return *this; } SizedCounter &operator++() { counter_ = (counter_ + 1) & Mask; return *this; } SizedCounter &operator+=(const IntT rhs) { counter_ = (counter_ + rhs) & Mask; return *this; } auto operator <=>(const SizedCounter &) const = default; /// Replaces the bits in the range [begin, end) with those in the low-order bits of @c vlaue. template void load(const MinIntForValue<1 << (end - begin)>::type value) { const auto mask = (1 << end) - (1 << begin); counter_ &= ~mask; counter_ |= IntT((value << begin) & mask); } template void load(const IntT value) { load(value); } private: IntT counter_{}; }; }