#pragma once #include #include #include namespace big { template concept ArgumentLimit = sizeof(T) <= sizeof(uint64_t); class command_arguments { private: const std::size_t m_argument_count; std::vector m_argument_data; mutable std::size_t m_idx; public: command_arguments(std::size_t argument_count = 0) : m_argument_count(argument_count), m_argument_data(), m_idx(0) { m_argument_data.reserve(argument_count); } command_arguments(std::size_t argument_count, const command_arguments& other) : command_arguments(argument_count) { std::copy_n(other.m_argument_data.begin(), std::min(argument_count, other.m_argument_data.size()), m_argument_data.begin()); } command_arguments(const std::vector& vec) : command_arguments(vec.size()) { m_argument_data = vec; } template requires ArgumentLimit T get(std::size_t idx) const { return reinterpret_cast(m_argument_data[idx]); } template requires ArgumentLimit std::enable_if_t, T> get(std::size_t idx) const { return static_cast(m_argument_data[idx]); } template requires ArgumentLimit T shift() const { if (m_idx >= m_argument_count) { throw std::runtime_error("Attempted to shift argument beyond allocated argument size."); } return reinterpret_cast(m_argument_data[m_idx++]); } template requires ArgumentLimit std::enable_if_t, T> shift() const { if (m_idx >= m_argument_count) { throw std::runtime_error("Attempted to shift argument beyond allocated argument size."); } return static_cast(m_argument_data[m_idx++]); } template requires ArgumentLimit void push(T arg) { if (m_idx++ >= m_argument_count) { throw std::runtime_error("Attempted to push argument beyond allocated argument size."); } m_argument_data.push_back(reinterpret_cast(arg)); } template requires ArgumentLimit void set(std::size_t idx, T arg) { if (idx >= m_argument_count) { throw std::runtime_error("Attempted to set argument beyond allocated argument size."); } m_argument_data[idx] = reinterpret_cast(arg); } command_arguments& reset_idx() { m_idx = 0; return *this; } std::size_t size() const { return m_argument_data.size(); } }; }