diff --git a/src/env_base.cpp b/src/env_base.cpp index 1c45d66..826565b 100644 --- a/src/env_base.cpp +++ b/src/env_base.cpp @@ -16,9 +16,26 @@ */ #include "env_base.hpp" +#include "string_view_cat.hpp" namespace duck { bool EnvBase::empty() const noexcept { return 0 == this->size(); } + +std::string_view EnvBase::operator[] (std::string_view name) const noexcept { + return this->get(name, ""); +} + +detail::EnvVarProxy EnvBase::operator[] (std::string_view name) noexcept { + return {name, this}; +} + +detail::EnvVarProxy EnvBase::operator[] (std::string&& name) noexcept { + return {std::move(name), this}; +} + +detail::EnvVarProxy EnvBase::operator[] (const std::string& name) noexcept { + return {to_string(name), this}; +} } //namespace duck diff --git a/src/env_base.hpp b/src/env_base.hpp index ad68f52..6bf1957 100644 --- a/src/env_base.hpp +++ b/src/env_base.hpp @@ -22,6 +22,23 @@ #include namespace duck { + class EnvBase; + + namespace detail { + template + class EnvVarProxy { + public: + template + EnvVarProxy (S1&& name, EnvBase* env) noexcept; + EnvVarProxy& operator= (std::string_view new_val); + operator std::string_view() const noexcept; + + private: + S m_name; + EnvBase* m_env; + }; + } //namespace detail + class EnvBase { public: typedef std::string_view mapped_type; @@ -33,7 +50,11 @@ namespace duck { EnvBase() = default; virtual ~EnvBase() noexcept = default; - virtual std::string_view operator[] (std::string_view name) const noexcept = 0; + std::string_view operator[] (std::string_view name) const noexcept; + detail::EnvVarProxy operator[] (std::string_view name) noexcept; + detail::EnvVarProxy operator[] (std::string&& name) noexcept; + detail::EnvVarProxy operator[] (const std::string& name) noexcept; + virtual std::optional get (std::string_view name) const noexcept = 0; virtual std::string_view get (std::string_view name, std::string_view def) const noexcept = 0; virtual void set (std::string_view name, std::string_view value) = 0; @@ -43,4 +64,26 @@ namespace duck { virtual bool empty() const noexcept; virtual void clear() noexcept = 0; }; + + namespace detail { + template + template + inline EnvVarProxy::EnvVarProxy (S1&& name, EnvBase* env) noexcept : + m_name(std::forward(name)), + m_env(env) + { + } + + template + inline auto EnvVarProxy::operator= (std::string_view new_val) -> EnvVarProxy& { + m_env->set(m_name, new_val); + return *this; + } + + template + inline EnvVarProxy::operator std::string_view() const noexcept { + return (*m_env)[m_name]; + } + } //namespace detail + } //namespace duck diff --git a/src/env_real.cpp b/src/env_real.cpp index bd3903f..f799b17 100644 --- a/src/env_real.cpp +++ b/src/env_real.cpp @@ -165,10 +165,6 @@ EnvReal::EnvReal() : { } -std::string_view EnvReal::operator[] (std::string_view name) const noexcept { - return this->get(name, ""); -} - std::optional EnvReal::get (std::string_view name) const noexcept { const char* const ret = this->raw_fetch_env(name); if (ret) diff --git a/src/env_real.hpp b/src/env_real.hpp index ab90e79..a592196 100644 --- a/src/env_real.hpp +++ b/src/env_real.hpp @@ -26,7 +26,6 @@ namespace duck { EnvReal(); virtual ~EnvReal() noexcept = default; - virtual std::string_view operator[] (std::string_view name) const noexcept override; virtual std::optional get (std::string_view name) const noexcept override; virtual std::string_view get (std::string_view name, std::string_view def) const noexcept override; virtual void set (std::string_view name, std::string_view value) override;