126 lines
3.6 KiB
C++
126 lines
3.6 KiB
C++
/* Copyright 2020, Michele Santullo
|
|
* This file is part of user-gcc.
|
|
*
|
|
* User-gcc is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* User-gcc is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with user-gcc. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "env_base.hpp"
|
|
#include "string_view_cat.hpp"
|
|
#include "safe_print.hpp"
|
|
#include <stdexcept>
|
|
#include <type_traits>
|
|
|
|
namespace duck {
|
|
namespace {
|
|
template <typename F, typename R=decltype(std::declval<F>()())>
|
|
R call_noexcept (F func, std::string_view err_location) noexcept {
|
|
typedef R return_type;
|
|
|
|
try {
|
|
return func();
|
|
}
|
|
catch (const std::runtime_error& err) {
|
|
safe_print_error("Unexpected exception in ");
|
|
safe_print_error(err_location);
|
|
safe_print_error(": ");
|
|
safe_print_error_ln(err.what());
|
|
}
|
|
catch (...) {
|
|
safe_print_error("Unknown exception in ");
|
|
safe_print_error_ln(err_location);
|
|
}
|
|
|
|
if constexpr (not std::is_same<void, return_type>::value)
|
|
return return_type{};
|
|
}
|
|
} //unnamed namespace
|
|
|
|
class StdMutex : public EnvBase::Mutex {
|
|
public:
|
|
StdMutex (std::mutex& m) noexcept :
|
|
m_mutex(m)
|
|
{
|
|
}
|
|
virtual void lock() override { m_mutex.lock(); }
|
|
virtual void try_lock() override {m_mutex.try_lock(); }
|
|
virtual void unlock() noexcept override {m_mutex.unlock(); }
|
|
private:
|
|
std::mutex& m_mutex;
|
|
};
|
|
|
|
class EmptyMutex : public EnvBase::Mutex {
|
|
public:
|
|
EmptyMutex() noexcept = default;
|
|
virtual void lock() override { }
|
|
virtual void try_lock() override { }
|
|
virtual void unlock() noexcept override { }
|
|
};
|
|
|
|
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<std::string_view> EnvBase::operator[] (std::string_view name) noexcept {
|
|
return {name, this};
|
|
}
|
|
|
|
detail::EnvVarProxy<std::string> EnvBase::operator[] (std::string&& name) noexcept {
|
|
return {std::move(name), this};
|
|
}
|
|
|
|
detail::EnvVarProxy<std::string> EnvBase::operator[] (const std::string& name) noexcept {
|
|
return {to_string(name), this};
|
|
}
|
|
|
|
void EnvBase::set (std::string_view name, std::string_view value) {
|
|
StdMutex m(this->mutex());
|
|
this->set_implem(name, value, m);
|
|
}
|
|
|
|
void EnvBase::unset (std::string_view name) noexcept {
|
|
StdMutex m(this->mutex());
|
|
call_noexcept([&,this](){this->unset_implem(name, m);}, to_string_view(__func__));
|
|
}
|
|
|
|
bool EnvBase::is_set (std::string_view name) const noexcept {
|
|
StdMutex m(this->mutex());
|
|
return call_noexcept([&,this](){return this->is_set_implem(name, m);}, to_string_view(__func__));
|
|
}
|
|
|
|
auto EnvBase::size() const noexcept -> size_type {
|
|
StdMutex m(this->mutex());
|
|
return call_noexcept([this,&m](){return this->size_implem(m);}, to_string_view(__func__));
|
|
}
|
|
|
|
void EnvBase::set_nolock (EnvBase& obj, std::string_view name, std::string_view value) {
|
|
EmptyMutex m;
|
|
obj.set_implem(name, value, m);
|
|
}
|
|
|
|
void EnvBase::clear() noexcept {
|
|
StdMutex m(this->mutex());
|
|
call_noexcept([this,&m](){this->clear_implem(m);}, to_string_view(__func__));
|
|
return;
|
|
}
|
|
|
|
void EnvBase::clear_nolock (EnvBase& obj) noexcept {
|
|
EmptyMutex m;
|
|
call_noexcept([&](){obj.clear_implem(m);}, to_string_view(__func__));
|
|
return;
|
|
}
|
|
} //namespace duck
|