// SPDX-License-Identifier: BSD-2-Clause // Copyright (c) 2025 Kirill Dmitrievich // File: number.hh // Description: Arithmetic config value #ifndef CORE_CONFIG_NUMBER_HH #define CORE_CONFIG_NUMBER_HH #pragma once #include "core/config/ivalue.hh" #include "core/math/concepts.hh" namespace config { template class Number : public IValue { public: explicit Number(T default_value = T(0)); explicit Number(T default_value, T min_value, T max_value); virtual ~Number(void) = default; virtual void set(std::string_view value) override; virtual std::string_view get(void) const override; T get_value(void) const; void set_value(T value); T get_min_value(void) const; T get_max_value(void) const; void set_limits(T min_value, T max_value); private: T m_value; T m_min_value; T m_max_value; std::string m_string; }; } // namespace config namespace config { class Int final : public Number { public: using Number::Number; }; class Float final : public Number { public: using Number::Number; }; class Unsigned final : public Number { public: using Number::Number; }; class Unsigned64 final : public Number { public: using Number::Number; }; class SizeType final : public Number { public: using Number::Number; }; } // namespace config template inline config::Number::Number(T default_value) { m_value = default_value; m_min_value = std::numeric_limits::lowest(); m_max_value = std::numeric_limits::max(); m_string = std::to_string(default_value); } template inline config::Number::Number(T default_value, T min_value, T max_value) { m_value = default_value; m_min_value = min_value; m_max_value = max_value; m_string = std::to_string(default_value); } template inline void config::Number::set(std::string_view value) { T parsed_value; auto result = std::from_chars(value.data(), value.data() + value.size(), parsed_value); if(result.ec == std::errc()) { m_value = std::clamp(parsed_value, m_min_value, m_max_value); m_string = std::to_string(m_value); } } template inline std::string_view config::Number::get(void) const { return m_string; } template inline T config::Number::get_value(void) const { return m_value; } template inline void config::Number::set_value(T value) { m_value = std::clamp(value, m_min_value, m_max_value); m_string = std::to_string(m_value); } template inline T config::Number::get_min_value(void) const { return m_min_value; } template inline T config::Number::get_max_value(void) const { return m_max_value; } template inline void config::Number::set_limits(T min_value, T max_value) { m_min_value = min_value; m_max_value = max_value; m_value = std::clamp(m_value, m_min_value, m_max_value); m_string = std::to_string(m_value); } #endif