#pragma once #include #include #include #include "mp_math.hpp" #include "mp_utils.hpp" namespace mp { static constexpr size_t UNLIMITED = std::numeric_limits().max(); // template // struct ElemContainerImpl // { // using type = std::vector; // }; // template // struct ElemContainerImpl // { // using type = std::array; // }; // template // using ElemContainer = typename ElemContainerImpl::type; template class BasicInt; template >> using IntOpResultType = BasicInt; template class BasicInt { public: using ElementType = TElem; static constexpr size_t MAX_SIZE = MaxSize; using ThisType = BasicInt; static constexpr size_t ELEMENT_BYTES = sizeof(ElementType); static constexpr size_t MAX_ELEMS = utils::AlignUp(MaxSize, ELEMENT_BYTES) / ELEMENT_BYTES; static constexpr ElementType LAST_ELEM_MASK = utils::GetNBytesMask(MAX_SIZE % ELEMENT_BYTES); static constexpr ElementType ELEMENT_MAX = std::numeric_limits().max(); // static constexpr size_t LAST_ELEM_MASK = GetNBytesMask(3); BasicInt(std::initializer_list init) : m_elems{init} { } // template Int(TArgs&&... args) // { // (m_value.push_back(args), ...); // } size_t GetNumElements() const { return m_elems.size(); } TElem GetElement(size_t index) const { if (index >= m_elems.size()) return 0; return m_elems[index]; } void SetElement(size_t index, TElem value) { if (index >= m_elems.size()) { if (value == 0) { return; } m_elems.resize(index + 1, 0); } m_elems[index] = value; } template void BinaryOp(TR& r, const TRhs& rhs) const { TOp::Op(r, *this, rhs); } template IntOpResultType ExtBinaryOp(const TRhs& rhs) const { IntOpResultType result{}; BinaryOp(result, rhs); return result; } template ThisType& CompoundBinaryOp(const TRhs& rhs) { BinaryOp(*this, rhs); return *this; } template auto operator+(const TRhs& rhs) const { return ExtBinaryOp(rhs); } template auto operator+=(const TRhs& rhs) { return CompoundBinaryOp(rhs); } template auto operator-(const TRhs& rhs) const { return ExtBinaryOp(rhs); } template auto& operator-=(const TRhs& rhs) { return CompoundBinaryOp(rhs); } private: std::vector m_elems; }; // using UnlimitedInt = Int; using DefaultElemType = size_t; template using Int = BasicInt; using UnlimitedInt = Int; } // namespace mp