diff options
Diffstat (limited to 'cpp/pom.hpp')
-rw-r--r-- | cpp/pom.hpp | 118 |
1 files changed, 101 insertions, 17 deletions
diff --git a/cpp/pom.hpp b/cpp/pom.hpp index 4e20727..ba65b25 100644 --- a/cpp/pom.hpp +++ b/cpp/pom.hpp @@ -42,6 +42,7 @@ #include <memory> #include <optional> +/// libpom++ namespace namespace pom { /// A libpom++ error. @@ -100,12 +101,11 @@ public: inline Settings() {} /// Set language for error messages. /// - /// `lang` should be an IETF-like language tag. + /// Currently supported languages: `en`, `fr`. /// + /// \param lang IETF-like language tag. /// The closest supported language will be used /// (e.g. `fr-CA` will currently redirect to `fr`). - /// - /// Currently supported: `en`, `fr`. void set_error_language(std::string_view lang); private: void check_version() const; @@ -122,25 +122,51 @@ private: class Reader { public: /// Read up to `count` bytes of data into `buf`. + /// + /// This method will not be called excessively/with lots of tiny reads—it's + /// okay to do unbuffered reads in it. + /// + /// \param buf Place to put data. + /// \param count (Non-zero) number of bytes to read + /// + /// \returns 0 to indicate the end of the file, + /// or a positive value ≤ `count`, to indicate the number of bytes read. 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. +/// An item in a configuration (returned by \ref Configuration::items). 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; + /// Name of the key. + /// + /// The returned string view is valid for the lifetime of `this`. + std::string_view key() const noexcept { return m_key; } + /// Value of the key. + /// + /// The returned string view is valid for the lifetime of `this`. + std::string_view value() const noexcept { return m_value; } + /// File name where key was defined. + /// + /// The returned string view is valid for the lifetime of `this`. + std::string_view file() const noexcept { return m_file; } + /// Line number where key was defined. + uint64_t line() const noexcept { return m_line; } +private: + Item(std::string_view key, std::string_view value, std::string_view file, uint64_t line): + m_key(key), m_value(value), m_file(file), m_line(line) {} + friend class Configuration; + std::string m_key, m_value, m_file; + uint64_t m_line; }; +/// A source location. class Location { public: + /// File name + /// + /// The returned string view is valid for the lifetime of `this`. inline std::string_view file() const { return m_file; } + /// Line number inline uint64_t line() const { return m_line; } private: inline Location(std::string file, uint64_t line): @@ -151,40 +177,100 @@ private: // to allow for future extensions without breaking backwards compatibility const uint32_t version = 1; }; +/// Print location as `file``:``line` (exact format may change in future). std::ostream &operator<<(std::ostream &, const Location &); +/// A POM configuration. class Configuration { public: + /// Create empty configuration. Configuration(); + /// Set `this` to `other`, deleting the current configuration in `this`. Configuration &operator=(const Configuration &other); + /// Copy configuration from `other`. inline Configuration(const Configuration &other) { *this = other; }; /// Load configuration from abstract \ref Reader. /// /// Most of the time, you will be able to use another constructor to load a configuration. /// But if you have special functions for performing reads, you may need this. + /// + /// \param filename File name for error messages. + /// \param source Abstract reader to get file data from. + /// \param settings Settings for parsing the file, or `nullptr` to use defaults. Configuration(std::string_view filename, Reader &source, const Settings *settings = nullptr); + /// Load configuration from a `std::istream`. + /// + /// \param filename File name for error messages. + /// \param stream Stream to read file from. + /// \param settings Settings for parsing the file, or `nullptr` to use defaults. Configuration(std::string_view filename, std::istream &stream, const Settings *settings = nullptr); + /// Load configuration from a file path. + /// + /// \param path File name for error messages and to load configuration from. + /// \param settings Settings for parsing the file, or `nullptr` to use defaults. Configuration(std::string_view path, const Settings *settings = nullptr); + /// Load configuration from a string. + /// + /// \param filename File name for error messages. + /// \param string String containing the configuration. + /// \param settings Settings for parsing the file, or `nullptr` to use defaults. Configuration(std::string_view filename, std::string_view string, const Settings *settings = nullptr); ~Configuration(); - std::optional<Location> location(std::string_view key) const; + /// Get value of `key` in configuration. std::optional<std::string> get(std::string_view key) const; + /// Get value of `key` in configuration, or `dflt` if `key` isn't defined. std::string get_or_default(std::string_view key, std::string_view dflt) const; + /// Get signed integer value of `key` in configuration. + /// + /// Throws an \ref Error if `key` exists but isn't a valid signed integer. std::optional<int64_t> get_int(std::string_view key) const; + /// Get signed integer value of `key` in configuration, or `dflt` if `key` isn't defined. + /// + /// Throws an \ref Error if `key` exists but isn't a valid signed integer. int64_t get_int_or_default(std::string_view key, int64_t dflt) const; + /// Get unsigned integer value of `key` in configuration. + /// + /// Throws an \ref Error if `key` exists but isn't a valid unsigned integer. std::optional<uint64_t> get_uint(std::string_view key) const; + /// Get unsigned integer value of `key` in configuration, or `dflt` if `key` isn't defined. + /// + /// Throws an \ref Error if `key` exists but isn't a valid unsigned integer. uint64_t get_uint_or_default(std::string_view key, uint64_t dflt) const; + /// Get floating-point value of `key` in configuration. + /// + /// Throws an \ref Error if `key` exists but isn't a valid floating-point number. std::optional<double> get_float(std::string_view key) const; + /// Get floating-point value of `key` in configuration, or `dflt` if `key` isn't defined. + /// + /// Throws an \ref Error if `key` exists but isn't a valid floating-point number. double get_float_or_default(std::string_view key, double dflt) const; + /// Get boolean value of `key` in configuration. + /// + /// Throws an \ref Error if `key` exists but isn't a valid boolean (`on`/`off`/`yes`/`no`/`true`/`false`). std::optional<bool> get_bool(std::string_view key) const; + /// Get boolean value of `key` in configuration, or `dflt` if `key` isn't defined. + /// + /// Throws an \ref Error if `key` exists but isn't a valid boolean (`on`/`off`/`yes`/`no`/`true`/`false`). bool get_bool_or_default(std::string_view key, bool dflt) const; + /// Get list value of `key` in configuration. std::optional<std::vector<std::string>> get_list(std::string_view key) const; + /// Get list value of `key` in configuration, or `dflt` if `key` isn't defined. std::vector<std::string> get_list_or_default(std::string_view key, const std::vector<std::string> &dflt) const; + /// Returns whether `key` is in this configuration. + bool has(std::string_view key) const; + /// Returns location of `key` in this configuration. + std::optional<Location> location(std::string_view key) const; + /// Extract section of configuration consisting of all keys starting with `name.` and their values. Configuration section(std::string_view name) const; /// Get list of keys which haven't been the target of a `get_*` method. std::vector<std::string> unread_keys() const; + /// Get list of all "direct" keys (unique first components of keys) in this configuration. std::vector<std::string> keys() const; - std::vector<std::shared_ptr<Item>> items() const; + /// Get all key-value pairs in this configuration. + /// + /// This returns a vector of pointers, so that more fields can be added to items in the future + /// without breaking binary backwards compatibility. + std::vector<std::unique_ptr<Item>> items() const; /// Merge `other` configuration into `this`. /// /// Puts all the key-value pairs of `other` into this configuration. @@ -196,11 +282,9 @@ private: explicit Configuration(void *c): C(c) {} void *C; }; +/// Print configuration. std::ostream &operator<<(std::ostream &, const Configuration &); - - - } // namespace pom #endif // POM_HPP_ |