cpp_mp/mp/int.hpp
2025-11-22 19:36:26 +01:00

97 lines
2.0 KiB
C++

#pragma once
#include <ranges>
#include "utils.hpp"
#include "storage.hpp"
namespace mp
{
template <ElementSuitable TElem, size_t MaxBytes>
class BasicInt
{
public:
using ElementType = TElem;
constexpr static size_t MAX_BYTES = MaxBytes;
constexpr static size_t ELEMENT_BYTES = sizeof(TElem);
constexpr static size_t MAX_ELEMS = (MAX_BYTES + ELEMENT_BYTES - 1) / ELEMENT_BYTES;
constexpr static TElem LAST_ELEM_MASK = calculate_last_elem_mask<TElem, MAX_BYTES>();
BasicInt() = default;
BasicInt(std::initializer_list<ElementType> init)
{
for (size_t i = 0; i < init.size(); ++i)
{
set(i, *(init.begin() + i));
}
}
TElem& operator[](size_t index) { return m_data[index]; }
const TElem& operator[](size_t index) const { return m_data[index]; }
void resize(size_t new_size)
{
m_data.resize(new_size);
}
void zero() { m_data.clear(); }
bool try_set(size_t idx, TElem value)
{
if (idx >= m_data.size())
{
if (value == 0)
{
return true;
}
if (idx >= MAX_ELEMS)
{
return false;
}
m_data.resize(idx + 1);
}
m_data[idx] = value;
if (idx == MAX_ELEMS - 1 && value > LAST_ELEM_MASK)
{
m_data[idx] &= LAST_ELEM_MASK;
return false;
}
return true;
}
void set(size_t idx, TElem value)
{
if (!try_set(idx, value))
{
throw std::out_of_range("Value exceeds maximum size");
}
}
TElem get(size_t idx) const
{
if (idx >= m_data.size())
{
return TElem{0};
}
return m_data[idx];
}
//std::span<TElem> data() { return m_data; }
size_t size_elems() const { return m_data.size(); }
private:
Container<TElem, MAX_ELEMS> m_data;
};
template<size_t MaxBytes>
using Int = BasicInt<LongestElementSuitableType, MaxBytes>;
} // namespace mp