From fa2bd86078790371106a7d969de4ad520a799c89 Mon Sep 17 00:00:00 2001 From: Levente Batuska Date: Wed, 28 Jan 2026 21:20:45 +0100 Subject: [PATCH] feat: env_var --- include/cpputils/env_var.h | 101 +++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 include/cpputils/env_var.h diff --git a/include/cpputils/env_var.h b/include/cpputils/env_var.h new file mode 100644 index 0000000..3427a31 --- /dev/null +++ b/include/cpputils/env_var.h @@ -0,0 +1,101 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace cpputils { +namespace env_var { + +class EnvVarRegistry { + public: + static EnvVarRegistry& instance() { + static EnvVarRegistry inst; + return inst; + } + + void register_var(std::string const& name, char const* default_val) { + if (vars_.find(name) != vars_.end()) { + std::cerr << "ENV VAR \"" << name << "\" already registered!"; + exit(EXIT_FAILURE); + } + vars_.emplace(name, std::string(default_val)); + } + + template + void register_var(std::string const& name, T const& default_val) { + static_assert(std::is_arithmetic_v, + "Only arithmetic types supported here"); + if (vars_.find(name) != vars_.end()) { + std::cerr << "ENV VAR \"" << name << "\" already registered!"; + exit(EXIT_FAILURE); + } + vars_.emplace(name, std::to_string(default_val)); + } + + std::unordered_map const& get_vars() const { + return vars_; + } + + private: + std::unordered_map vars_; + + public: + struct EnvVarAutoRegister { + template + EnvVarAutoRegister(char const* name, T const& default_value) { + EnvVarRegistry::instance().register_var(name, default_value); + } + }; +}; + +#define DEFINE_ENV_VAR_STRING(name, DEFAULT_VALUE, MIN_LEN) \ + namespace EnvVars { \ + struct name { \ + static constexpr char const* DEFAULT = DEFAULT_VALUE; \ + static constexpr char const* NAME = #name; \ + static char const* GET() { \ + auto c = std::getenv(#name); \ + if (c) { \ + if (std::strlen(c) > MIN_LEN) { \ + return c; \ + } \ + } \ + return DEFAULT_VALUE; \ + } \ + static inline ::cpputils::env_var::EnvVarRegistry::EnvVarAutoRegister \ + _env_register{#name, DEFAULT_VALUE}; \ + }; \ + } + +#define DEFINE_ENV_VAR_INT(TYPE, name, DEFAULT_VALUE) \ + namespace EnvVars { \ + struct name { \ + static constexpr TYPE DEFAULT = DEFAULT_VALUE; \ + static constexpr char const* NAME = #name; \ + static TYPE GET() { \ + auto c = std::getenv(#name); \ + if (c) { \ + if (std::strlen(c) > 0) { \ + try { \ + if constexpr (std::is_unsigned_v) { \ + TYPE x = static_cast(std::stoull(c)); \ + return x; \ + } else { \ + TYPE x = static_cast(std::stoll(c)); \ + return x; \ + } \ + } catch (...) {} \ + } \ + } \ + return DEFAULT_VALUE; \ + } \ + static inline ::cpputils::env_var::EnvVarRegistry::EnvVarAutoRegister \ + _env_register{#name, DEFAULT_VALUE}; \ + }; \ + } + +} // namespace env_var +} // namespace cpputils