.. _program_listing_file_uconfig_impl_Objects.ipp: Program Listing for File Objects.ipp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``uconfig/impl/Objects.ipp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include namespace uconfig { template Config::Config(bool optional) : optional_(optional) { } template Config::Config(const Config& other) : optional_(other.optional_) { } template Config& Config::operator=(const Config& other) { if (this != &other) { Reset(); optional_ = other.optional_; } return *this; } template Config::Config(Config&& other) noexcept : optional_(std::move(other.optional_)) { } template Config& Config::operator=(Config&& other) noexcept { if (this != &other) { Reset(); optional_ = std::move(other.optional_); } return *this; } template template bool Config::Parse(const F& parser, const std::string& path, const typename F::source_type* source, bool throw_on_fail) { return iface_type{path, this}.Parse(parser, source, throw_on_fail); } template template void Config::Emit(const F& emitter, const std::string& path, typename F::dest_type* destination, bool throw_on_fail) { return iface_type{path, this}.Emit(emitter, destination, throw_on_fail); } template bool Config::Initialized() const noexcept { if (elements_.empty()) { // Populate elements_ if they are not const_cast*>(this)->Init(""); } for (const auto* elem : elements_) { if (!elem->Optional() && !elem->Initialized()) { return false; } } return true; } template bool Config::Optional() const noexcept { return optional_; } template template void Config::Register(const std::string& element_path, T* element) noexcept { elements_.insert(element); if (register_formats_.count(std::type_index(typeid(F)))) { using elem_iface_type = typename T::template iface_type; auto& fmt_ifaces = Interfaces(); fmt_ifaces.emplace_back(std::make_unique(element_path, element)); } } template void Config::Reset() noexcept { elements_ = {}; interfaces_ = {}; register_formats_ = {}; } template template void Config::SetFormat() noexcept { register_formats_.insert(std::type_index(typeid(F))); } template template std::vector>>& Config::Interfaces() noexcept { return std::get>>>(interfaces_); } template Variable::Variable() : optional_(false) , value_(std::nullopt) { } template Variable::Variable(T&& init_value) : optional_(true) , value_(std::move(init_value)) { } template Variable::Variable(const T& init_value) : optional_(true) , value_(init_value) { } template Variable& Variable::operator=(T&& other) noexcept { value_ = std::move(other); return *this; } template bool Variable::Initialized() const noexcept { return value_ != std::nullopt; } template bool Variable::Optional() const noexcept { return optional_; } template T& Variable::Get() { if (!Initialized()) { throw Error("failed to get variable value: it is not set"); } return *value_; } template const T& Variable::Get() const { if (!Initialized()) { throw Error("failed to get variable value: it is not set"); } return *value_; } template T& Variable::operator*() { return Get(); } template const T& Variable::operator*() const { return Get(); } template T* Variable::operator->() { return &Get(); } template const T* Variable::operator->() const { return &Get(); } template Variable::operator T&() { return Get(); } template Variable::operator const T&() const { return Get(); } template Vector::Vector(bool optional) { this->optional_ = optional; this->value_ = std::nullopt; } template Vector::Vector(std::vector&& init_value) { this->optional_ = true; this->value_ = std::move(init_value); } template Vector::Vector(const std::vector& init_value) { this->optional_ = true; this->value_ = init_value; } template Vector& Vector::operator=(std::vector&& vector) noexcept { this->value_ = std::move(vector); return *this; } template T& Vector::operator[](std::size_t pos) { return this->Get()[pos]; } template const T& Vector::operator[](std::size_t pos) const { return this->Get()[pos]; } template ::value, bool> = true> std::ostream& operator<<(std::ostream& out, const Variable& var) { if (!var.Initialized()) { return out << "[not set]"; } return out << var.Get(); } template V operator+(const V& lhs, const Variable& rhs) { return lhs + rhs.Get(); } template V operator+(const Variable& lhs, const V& rhs) { return lhs.Get() + rhs; } inline std::string operator+(const char* lhs, const Variable& rhs) { return std::string(lhs) + rhs.Get(); } inline std::string operator+(const Variable& lhs, const char* rhs) { return lhs.Get() + std::string(rhs); } template V operator-(const V& lhs, const Variable& rhs) { return lhs - rhs.Get(); } template Variable operator-(const Variable& lhs, const V& rhs) { return Variable(lhs.Get() - rhs); } template bool operator==(const Variable& lhs, const Variable& rhs) { return lhs.value_ == rhs.value_; } template ::value, bool>> bool operator==(const U& lhs, const Variable& rhs) { return lhs == rhs.value_; } template ::value, bool>> bool operator==(const Variable& lhs, const U& rhs) { return lhs.value_ == rhs; } template bool operator==(const Vector>& lhs, const std::vector& rhs) { if (!lhs.value_.has_value()) { return false; } if (lhs.value_->size() != rhs.size()) { return false; } for (std::size_t pos = 0; pos < rhs.size(); ++pos) { if (lhs.value_->at(pos) != rhs.at(pos)) { return false; } } return true; } template bool operator==(const std::vector& lhs, const Vector>& rhs) { return rhs == lhs; } template bool operator!=(const Variable& lhs, const Variable& rhs) { return lhs.value_ != rhs.value_; } template ::value, bool>> bool operator!=(const U& lhs, const Variable& rhs) { return lhs != rhs.value_; } template ::value, bool>> bool operator!=(const Variable& lhs, const U& rhs) { return lhs.value_ != rhs; } template bool operator!=(const Vector>& lhs, const std::vector& rhs) { return !(lhs == rhs); } template bool operator!=(const std::vector& lhs, const Vector>& rhs) { return !(lhs == rhs); } template bool operator>(const U& lhs, const Variable& rhs) { return lhs > rhs.value_; } template bool operator>(const Variable& lhs, const U& rhs) { return lhs.value_ > rhs; } template bool operator<(const U& lhs, const Variable& rhs) { return lhs < rhs.value_; } template bool operator<(const Variable& lhs, const U& rhs) { return lhs.value_ < rhs; } template bool operator>=(const U& lhs, const Variable& rhs) { return lhs >= rhs.value_; } template bool operator>=(const Variable& lhs, const U& rhs) { return lhs.value_ >= rhs; } template bool operator<=(const U& lhs, const Variable& rhs) { return lhs <= rhs.value_; } template bool operator<=(const Variable& lhs, const U& rhs) { return lhs.value_ <= rhs; } } // namespace uconfig