Mercurial > code
view C++/Ini.h @ 325:d52a69f9f029
Add Ini, brand new replacement for Parser
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 28 Feb 2015 18:53:27 +0100 |
parents | |
children | 78e8f9a3b233 |
line wrap: on
line source
/* * Ini.h -- .ini file parsing * * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _INI_H_ #define _INI_H_ #include <algorithm> #include <deque> #include <fstream> #include <istream> #include <stdexcept> #include <string> /** * @class IniOption * @brief Option definition */ class IniOption { private: std::string m_key; std::string m_value; public: inline IniOption(std::string key, std::string value) : m_key(std::move(key)) , m_value(std::move(value)) { } inline const std::string &key() const noexcept { return m_key; } inline const std::string &value() const noexcept { return m_value; } }; /** * @class IniSection * @brief Section that contains one or more options */ class IniSection { private: std::string m_key; std::deque<IniOption> m_options; template <typename T> T find(const std::string &key) const { auto it = std::find_if(m_options.begin(), m_options.end(), [&] (const IniOption &o) { return o.key() == key; }); if (it == m_options.end()) throw std::out_of_range("option " + key + " not found"); return const_cast<T>(*it); } public: IniSection() = default; inline IniSection(std::string key, std::deque<IniOption> options = {}) : m_key(std::move(key)) , m_options(std::move(options)) { } inline const std::string &key() const noexcept { return m_key; } inline auto begin() noexcept { return m_options.begin(); } inline auto begin() const noexcept { return m_options.begin(); } inline auto cbegin() const noexcept { return m_options.cbegin(); } inline auto end() noexcept { return m_options.end(); } inline auto end() const noexcept { return m_options.end(); } inline auto cend() const noexcept { return m_options.cend(); } inline void push_back(IniOption option) { m_options.push_back(std::move(option)); } inline void push_front(IniOption option) { m_options.push_front(std::move(option)); } inline unsigned size() const noexcept { return m_options.size(); } inline IniOption &operator[](int index) noexcept { return m_options[index]; } inline const IniOption &operator[](int index) const noexcept { return m_options[index]; } inline IniOption &operator[](const std::string &key) { return find<IniOption &>(key); } inline const IniOption &operator[](const std::string &key) const { return find<const IniOption &>(key); } }; /** * @class Ini * @brief Ini config file loader */ class Ini { private: std::deque<IniSection> m_sections; template <typename T> T find(const std::string &key) const { auto it = std::find_if(m_sections.begin(), m_sections.end(), [&] (const IniSection &s) { return s.key() == key; }); if (it == m_sections.end()) throw std::out_of_range("section " + key + " not found"); return const_cast<T>(*it); } public: Ini() = default; Ini(std::istream &stream); inline Ini(std::istream &&stream) : Ini(stream) { } inline auto begin() noexcept { return m_sections.begin(); } inline auto begin() const noexcept { return m_sections.begin(); } inline auto cbegin() const noexcept { return m_sections.cbegin(); } inline auto end() noexcept { return m_sections.end(); } inline auto end() const noexcept { return m_sections.end(); } inline auto cend() const noexcept { return m_sections.cend(); } inline unsigned size() const noexcept { return m_sections.size(); } inline void push_back(IniSection section) { m_sections.push_back(std::move(section)); } inline void push_front(IniSection section) { m_sections.push_front(std::move(section)); } inline IniSection &operator[](int index) noexcept { return m_sections[index]; } inline const IniSection &operator[](int index) const noexcept { return m_sections[index]; } inline IniSection &operator[](const std::string &key) { return find<IniSection &>(key); } inline const IniSection &operator[](const std::string &key) const { return find<IniSection &>(key); } }; #endif // !_INI_H_