Program Listing for File Objects.h¶
↰ Return to documentation for file (uconfig/Objects.h
)
#pragma once
#include "detail/detail.h"
#include <memory>
#include <optional>
#include <stdexcept>
#include <typeindex>
#include <unordered_set>
#include <vector>
namespace uconfig {
struct Error: public std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct ParseError: public Error
{
using Error::Error;
};
struct EmitError: public Error
{
using Error::Error;
};
class Object
{
public:
// template <typename F>
// using iface_type;
virtual ~Object() = default;
virtual bool Initialized() const noexcept = 0;
virtual bool Optional() const noexcept = 0;
virtual void Validate() const {};
};
template <typename... FormatTs>
class Config: public Object
{
public:
template <typename F>
using iface_type = ConfigIface<F>;
template <typename F>
friend class ConfigIface;
Config(bool optional = false);
Config(const Config<FormatTs...>& other);
Config<FormatTs...>& operator=(const Config<FormatTs...>& other);
Config(Config<FormatTs...>&& other) noexcept;
Config<FormatTs...>& operator=(Config<FormatTs...>&& other) noexcept;
virtual ~Config() = default;
template <typename F>
bool Parse(const F& parser, const std::string& path, const typename F::source_type* source,
bool throw_on_fail = true);
template <typename F>
void Emit(const F& emitter, const std::string& path, typename F::dest_type* destination, bool throw_on_fail = true);
virtual bool Initialized() const noexcept override;
virtual bool Optional() const noexcept override;
protected:
virtual void Init(const std::string& config_path) = 0;
template <typename F, typename T>
void Register(const std::string& element_path, T* element) noexcept;
private:
void Reset() noexcept;
template <typename F>
void SetFormat() noexcept;
template <typename F>
std::vector<std::unique_ptr<Interface<F>>>& Interfaces() noexcept;
private:
bool optional_ = false;
std::unordered_set<Object*> elements_;
std::unordered_set<std::type_index> register_formats_;
std::tuple<std::vector<std::unique_ptr<Interface<FormatTs>>>...> interfaces_;
};
template <typename T>
class Variable: public Object
{
public:
template <typename F>
using iface_type = VariableIface<T, F>;
template <typename U, typename F>
friend class VariableIface;
Variable();
Variable(T&& init_value);
Variable(const T& init_value);
Variable(const Variable<T>&) = default;
Variable<T>& operator=(const Variable<T>&) = default;
Variable(Variable<T>&& other) noexcept = default;
Variable<T>& operator=(Variable<T>&& other) noexcept = default;
Variable<T>& operator=(T&& other) noexcept;
virtual ~Variable() = default;
virtual bool Initialized() const noexcept override;
virtual bool Optional() const noexcept override;
T& Get();
const T& Get() const;
T& operator*();
const T& operator*() const;
T* operator->();
const T* operator->() const;
explicit operator T&();
explicit operator const T&() const;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/* enable left and right-handed comparisons */
template <typename V, typename U>
friend bool operator==(const Variable<V>& lhs, const Variable<U>& rhs);
template <typename V, typename U, std::enable_if_t<!detail::is_base_of_template<U, Variable>::value, bool>>
friend bool operator==(const U& lhs, const Variable<V>& rhs);
template <typename V, typename U, std::enable_if_t<!detail::is_base_of_template<U, Variable>::value, bool>>
friend bool operator==(const Variable<V>& lhs, const U& rhs);
template <typename V, typename U>
friend bool operator!=(const Variable<V>& lhs, const Variable<U>& rhs);
template <typename V, typename U, std::enable_if_t<!detail::is_base_of_template<U, Variable>::value, bool>>
friend bool operator!=(const U& lhs, const Variable<V>& rhs);
template <typename V, typename U, std::enable_if_t<!detail::is_base_of_template<U, Variable>::value, bool>>
friend bool operator!=(const Variable<V>& lhs, const U& rhs);
template <typename V, typename U>
friend bool operator>(const U& lhs, const Variable<V>& rhs);
template <typename V, typename U>
friend bool operator>(const Variable<V>& lhs, const U& rhs);
template <typename V, typename U>
friend bool operator<(const U& lhs, const Variable<V>& rhs);
template <typename V, typename U>
friend bool operator<(const Variable<V>& lhs, const U& rhs);
template <typename V, typename U>
friend bool operator>=(const U& lhs, const Variable<V>& rhs);
template <typename V, typename U>
friend bool operator>=(const Variable<V>& lhs, const U& rhs);
template <typename V, typename U>
friend bool operator<=(const U& lhs, const Variable<V>& rhs);
template <typename V, typename U>
friend bool operator<=(const Variable<V>& lhs, const U& rhs);
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
protected:
bool optional_ = false;
std::optional<T> value_ = std::nullopt;
};
template <typename T>
class Vector: public Variable<std::vector<T>>
{
public:
template <typename F>
using iface_type = VectorIface<T, F>;
template <typename U, typename F>
friend class VectorIface;
Vector(bool optional = false);
Vector(std::vector<T>&& init_value);
Vector(const std::vector<T>& init_value);
Vector(const Vector<T>&) = default;
Vector<T>& operator=(const Vector<T>&) = default;
Vector(Vector<T>&& other) noexcept = default;
Vector<T>& operator=(Vector<T>&& other) noexcept = default;
Vector<T>& operator=(std::vector<T>&& vector) noexcept;
virtual ~Vector() = default;
T& operator[](std::size_t pos);
const T& operator[](std::size_t pos) const;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// operator== for Vector<Variable<V>> and std::vector<V>.
template <typename V>
friend bool operator==(const Vector<Variable<V>>& lhs, const std::vector<V>& rhs);
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
};
} // namespace uconfig
#include "impl/Objects.ipp"