Skip to content

Commit

Permalink
rewrite ProportionalUnsigned as uintn_t
Browse files Browse the repository at this point in the history
  • Loading branch information
TomSaw committed Sep 10, 2023
1 parent 4ef2ae0 commit a298341
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
171 changes: 171 additions & 0 deletions src/modm/math/uintn_t.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2022, Thomas Sommer
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------
#pragma once

#include <algorithm>
#include <concepts>

#include <modm/math/utils/integer_traits.hpp>
#include <modm/architecture/interface/assert.hpp>

namespace modm {

/**
* @brief Unsigned integer with arbitrary number of digits.
* Artihmetic over- and underflows wrap by default, just like builtin integral types.
*
* @tparam Bits Resolution of the unsigned integer
*
* @author Thomas Sommer
* @ingroup modm_math
*/
template<int Bits>
requires (Bits > 0)
class uintn_t {
public:
static constexpr int digits = Bits;

using T = uint_t<Bits>::least;
static constexpr T bitmask = ::modm::bitmask<Bits>();

static constexpr T min = 0;
static constexpr T max = bitmask;

/// constructors
constexpr uintn_t() = default;

constexpr uintn_t(T value) {
#ifdef MODM_DEBUG_BUILD
if(not modm_assert_continue_ignore_debug(value <= max, "uintn_t.ctor", "value exceeded max", max)) {
value_ = std::min(max, value);
return;
}
#endif

value_ = value;
}

#if 0
template <int E>
requires (Bits <= E)
constexpr uintn_t(const uintn_t<E>& other)
: value_(other.value_ >> (E - Bits))
{}

template <int E>
requires (Bits > E)
constexpr uintn_t(const uintn_t<E>& other)
: value_(other.value_ * max / other.max)
{}
#endif

/// assignment operators
void operator=(T value) {
#ifdef MODM_DEBUG_BUILD
if(not modm_assert_continue_ignore_debug(value <= max, "uintn_t.assign", "value exceeded max", max)) {
value_ = std::min(max, value);
return;
}
#endif

value_ = value;
}

#if 0
template <int E>
requires (Bits <= E)
constexpr void operator=(const uintn_t<E>& other) {
value_ = other.value_ >> (E - Bits);
}

template <int E>
requires (Bits > E)
constexpr void operator=(const uintn_t<E>& other) {
value_ = other.value_ * max / other.max;
}
#endif

constexpr T value() const { return value_; }
constexpr T& value() { return value_; }

bool operator<=>(const uintn_t& other) const = default;

/// operator +, -, *, /
template<std::integral U>
uintn_t
operator+(U value)
{
return {T(value_ + value) & uintn_t::max};
}

template<std::integral U>
uintn_t
operator-(U value)
{
return {T(value_ - value) & uintn_t::max};
}

template<std::integral U>
uintn_t
operator*(U value)
{
return {T(value_ * value) & uintn_t::max};
}

template<std::integral U>
uintn_t
operator/(U value)
{
return {T(value_ / value) & uintn_t::max};
}

/// operator +=, -=, *=, /=
template<std::integral U>
uintn_t&
operator+=(U value)
{
value_ = T(value_ + value) & uintn_t::max;
return *this;
}

template<std::integral U>
uintn_t&
operator-=(U value)
{
value_ = T(value_ - value) & uintn_t::max;
return *this;
}

template<std::integral U>
uintn_t&
operator*(U value)
{
value_ = T(value_ * value) & uintn_t::max;
return *this;
}

template<std::integral U>
uintn_t&
operator/(U value)
{
value_ = T(value_ / value) & uintn_t::max;
return this;
}

protected:
T value_{0};

private:
template<int>
friend class uintn_t;
};

}
26 changes: 26 additions & 0 deletions src/modm/math/uintn_t.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022, Thomas Sommer
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------

def init(module):
module.name = ":math:uintn_t"
# module.description = FileReader("proportional_unsigned.md")

def prepare(module, options):
module.depends(
":utils",
":architecture:assert"
)
return True

def build(env):
env.outbasepath = "modm/src/modm/math"
env.copy("uintn_t.hpp")

0 comments on commit a298341

Please sign in to comment.