#ifndef POM_HPP_ #define POM_HPP_ #include #include #include #include #include #include #include namespace pom { class Error: public std::exception { public: ~Error(); Error(Error &other) = delete; std::string_view file() const noexcept; uint64_t line() const noexcept; std::string_view message() const noexcept; inline const Error *next() const noexcept { return m_next.get(); } std::string_view to_string() noexcept; /// You should only call this on the first error in an error list. /// (This can't be enforced with constness because it needs to /// override `std::exception::what`.) virtual const char *what() const noexcept override; private: friend class Configuration; friend class Parser; Error() = delete; Error(void *C_error); Error(const void *C_error); void *C; bool m_is_original; std::unique_ptr m_next; }; std::ostream &operator<<(std::ostream &, Error &); class Allocator { public: inline virtual ~Allocator() {}; virtual void *calloc(size_t, size_t) = 0; virtual void *realloc(void *, size_t) = 0; virtual void free(void *) = 0; }; class Settings { public: inline Settings() {}; /// Set allocator. inline void set_allocator(std::shared_ptr allocator) { m_allocator = allocator; } void set_error_language(std::string_view lang); private: void check_version() const; void to_C(void *C) const; friend class Configuration; char m_error_lang[16] = {}; std::shared_ptr m_allocator; // to allow for future extensions without breaking backwards compatibility const uint32_t version = 1; }; class Reader { public: virtual size_t read(char *buf, size_t count) = 0; }; /// An item in a configuration /// /// This is an abstract class so that items can be given /// more members in the future. class Item { public: inline virtual ~Item() {}; virtual std::string_view key() const noexcept = 0; virtual std::string_view value() const noexcept = 0; virtual std::string_view file() const noexcept = 0; virtual uint64_t line() const noexcept = 0; }; class Location { public: inline std::string_view file() const { return m_file; } inline uint64_t line() const { return m_line; } private: inline Location(std::string file, uint64_t line): m_file(file), m_line(line) {} friend class Configuration; std::string m_file; uint64_t m_line; void *_reserved[4] = {}; }; std::ostream &operator<<(std::ostream &, const Location &); class Configuration { public: Configuration(); Configuration &operator=(const Configuration &other); inline Configuration(const Configuration &other) { *this = other; }; Configuration(std::string_view filename, Reader &source, const Settings *settings = nullptr); Configuration(std::string_view filename, std::istream &stream, const Settings *settings = nullptr); Configuration(std::string_view path, const Settings *settings = nullptr); Configuration(std::string_view filename, std::string_view string, const Settings *settings = nullptr); ~Configuration(); std::optional location(std::string_view key) const; std::optional get(std::string_view key) const; std::string get_or_default(std::string_view key, std::string_view dflt) const; std::optional get_int(std::string_view key) const; int64_t get_int_or_default(std::string_view key, int64_t dflt) const; std::optional get_uint(std::string_view key) const; uint64_t get_uint_or_default(std::string_view key, uint64_t dflt) const; std::optional get_float(std::string_view key) const; double get_float_or_default(std::string_view key, double dflt) const; std::optional get_bool(std::string_view key) const; bool get_bool_or_default(std::string_view key, bool dflt) const; std::optional> get_list(std::string_view key) const; std::vector get_list_or_default(std::string_view key, const std::vector &dflt) const; Configuration section(std::string_view name) const; std::vector unread_keys() const; std::vector keys() const; std::vector> items() const; void merge(const Configuration &other); private: void load(std::string_view filename, Reader &source, const Settings *settings); explicit Configuration(void *c): C(c) {} void *C; }; std::ostream &operator<<(std::ostream &, const Configuration &); } // namespace pom #endif // POM_HPP_