1#ifndef MSTL_CORE_FILE_INI_INI_VALUE_HPP__
2#define MSTL_CORE_FILE_INI_INI_VALUE_HPP__
3#include "MSTL/core/container/unordered_map.hpp"
5#include "MSTL/core/interface/istringify.hpp"
15class MSTL_API ini_value : public istringify<ini_value> {
22 virtual ~ini_value() =
default;
23 MSTL_NODISCARD
virtual types type() const noexcept = 0;
25 MSTL_NODISCARD virtual const ini_section* as_section() const noexcept {
return nullptr; }
26 MSTL_NODISCARD
virtual const ini_property* as_property() const noexcept {
return nullptr; }
28 MSTL_NODISCARD
bool is_section() const noexcept {
return type() == Section; }
29 MSTL_NODISCARD
bool is_property() const noexcept {
return type() == Property; }
31 MSTL_NODISCARD
string to_string()
const;
32 MSTL_NODISCARD
string to_document()
const;
38class MSTL_API ini_property final :
public ini_value {
43 explicit ini_property(
string v) noexcept : value_(
_MSTL move(v)) {}
45 MSTL_NODISCARD types type() const noexcept
override {
return Property; }
46 MSTL_NODISCARD
const ini_property* as_property() const noexcept
override {
return this; }
48 MSTL_NODISCARD
const string& get_value() const noexcept {
return value_; }
49 void set_value(
string v)
noexcept { value_ =
_MSTL move(v); }
51 MSTL_NODISCARD
int get_int(
int default_value = 0) const noexcept;
52 MSTL_NODISCARD
double get_double(
double default_value = 0.0) const noexcept;
53 MSTL_NODISCARD
bool get_bool(
bool default_value = false) const noexcept;
56class MSTL_API ini_section final : public ini_value {
58 unordered_map<string, unique_ptr<ini_property>> properties_;
62 explicit ini_section(
string name =
"") noexcept : name_(
_MSTL move(name)) {}
64 ini_section(
const ini_section&) =
delete;
65 ini_section& operator =(
const ini_section&) =
delete;
66 ini_section(ini_section&&) =
default;
67 ini_section& operator =(ini_section&&) =
default;
69 MSTL_NODISCARD types type() const noexcept
override {
return Section; }
70 MSTL_NODISCARD
const ini_section* as_section() const noexcept
override {
return this; }
72 MSTL_NODISCARD
const string& get_name() const noexcept {
return name_; }
73 void set_name(
string name)
noexcept { name_ =
_MSTL move(name); }
75 void add_property(
const string& key, unique_ptr<ini_property> property) {
79 void set_property(
const string& key,
const string& value) {
83 MSTL_NODISCARD
const ini_property* get_property(
const string& key)
const {
84 const auto it = properties_.find(key);
85 if (it != properties_.end())
return it->second.get();
89 MSTL_NODISCARD ini_property* get_property(
const string& key) {
90 const auto it = properties_.find(key);
91 if (it != properties_.end())
return it->second.get();
95 MSTL_NODISCARD
bool has_property(
const string& key)
const {
96 return properties_.find(key) != properties_.end();
99 MSTL_NODISCARD
const unordered_map<string, unique_ptr<ini_property>>& get_properties() const noexcept {
103 MSTL_NODISCARD
string get_string(
const string& key,
const string& default_value =
"")
const {
104 const auto* prop = get_property(key);
105 return prop ? prop->get_value() : default_value;
108 MSTL_NODISCARD
int get_int(
const string& key,
int default_value = 0)
const {
109 const auto* prop = get_property(key);
110 return prop ? prop->get_int(default_value) : default_value;
113 MSTL_NODISCARD
double get_double(
const string& key,
double default_value = 0.0)
const {
114 const auto* prop = get_property(key);
115 return prop ? prop->get_double(default_value) : default_value;
118 MSTL_NODISCARD
bool get_bool(
const string& key,
bool default_value =
false)
const {
119 const auto* prop = get_property(key);
120 return prop ? prop->get_bool(default_value) : default_value;
124class MSTL_API ini_document final {
126 unordered_map<string, unique_ptr<ini_section>> sections_;
127 unique_ptr<ini_section> global_section_;
130 ini_document() : global_section_(
make_unique<ini_section>(
"")) {}
132 ini_document(
const ini_document&) =
delete;
133 ini_document& operator =(
const ini_document&) =
delete;
134 ini_document(ini_document&&) =
default;
135 ini_document& operator =(ini_document&&) =
default;
137 void add_section(
const string& name, unique_ptr<ini_section> section) {
145 MSTL_NODISCARD
const ini_section* get_section(
const string& name)
const {
146 if (name.empty())
return global_section_.
get();
147 const auto it = sections_.find(name);
148 if (it != sections_.end())
return it->second.get();
152 MSTL_NODISCARD ini_section* get_section(
const string& name) {
153 if (name.empty())
return global_section_.
get();
154 const auto it = sections_.find(name);
155 if (it != sections_.end())
return it->second.get();
159 MSTL_NODISCARD
bool has_section(
const string& name)
const {
160 if (name.empty())
return global_section_ !=
nullptr;
161 return sections_.find(name) != sections_.end();
164 MSTL_NODISCARD
const unordered_map<string, unique_ptr<ini_section>>& get_sections() const noexcept {
168 MSTL_NODISCARD
const ini_section* get_global_section() const noexcept {
169 return global_section_.
get();
172 MSTL_NODISCARD ini_section* get_global_section() noexcept {
173 return global_section_.
get();
176 MSTL_NODISCARD
string get_string(
const string& section,
const string& key,
const string& default_value =
"")
const {
177 const auto* sec = get_section(section);
178 return sec ? sec->get_string(key, default_value) : default_value;
181 MSTL_NODISCARD
int get_int(
const string& section,
const string& key,
int default_value = 0)
const {
182 const auto* sec = get_section(section);
183 return sec ? sec->get_int(key, default_value) : default_value;
186 MSTL_NODISCARD
double get_double(
const string& section,
const string& key,
double default_value = 0.0)
const {
187 const auto* sec = get_section(section);
188 return sec ? sec->get_double(key, default_value) : default_value;
191 MSTL_NODISCARD
bool get_bool(
const string& section,
const string& key,
bool default_value =
false)
const {
192 const auto* sec = get_section(section);
193 return sec ? sec->get_bool(key, default_value) : default_value;
196 MSTL_NODISCARD
string to_string()
const;
200string MSTL_API ini_value_to_string(
const ini_value* value);
201string MSTL_API ini_document_to_string(
const ini_document* doc);
204MSTL_ALWAYS_INLINE_INLINE
string to_string(
const ini_value* value) {
205 return _INNER ini_value_to_string(value);
207MSTL_ALWAYS_INLINE_INLINE
string to_string(
const ini_value& value) {
208 return _INNER ini_value_to_string(&value);
210MSTL_ALWAYS_INLINE_INLINE
string to_string(
const ini_ptr& value) {
211 return _INNER ini_value_to_string(value.
get());
213MSTL_ALWAYS_INLINE_INLINE
string to_string(
const ini_document& doc) {
214 return _INNER ini_document_to_string(&doc);
217MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE
string ini_value::to_string()
const {
218 return _INNER ini_value_to_string(
this);
221MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE
string ini_value::to_document()
const {
222 return _INNER ini_value_to_string(
this);
225MSTL_NODISCARD MSTL_ALWAYS_INLINE_INLINE
string ini_document::to_string()
const {
226 return _INNER ini_document_to_string(
this);
MSTL_CONSTEXPR20 pointer get() const noexcept
获取原始指针
#define MSTL_ERROR_BUILD_FINAL_CLASS(THIS, BASE, INFO)
构建最终异常类宏
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
MSTL_CONSTEXPR20 unique_ptr< T > make_unique(Args &&... args)
创建unique_ptr