48ltrim(std::basic_string<CharT> & s,
const std::locale & loc)
51 std::find_if(s.begin(), s.end(), [&loc](CharT ch) { return !std::isspace(ch, loc); }));
56rtrim(std::basic_string<CharT> & s,
const std::locale & loc)
58 s.erase(std::find_if(s.rbegin(), s.rend(), [&loc](CharT ch) { return !std::isspace(ch, loc); }).base(),
62template <
class CharT,
class UnaryPredicate>
64rtrim2(std::basic_string<CharT> & s, UnaryPredicate pred)
66 s.erase(std::find_if(s.begin(), s.end(), pred), s.end());
73replace(std::basic_string<CharT> & str,
const std::basic_string<CharT> & from,
const std::basic_string<CharT> & to)
77 while ((start_pos = str.find(from, start_pos)) != std::basic_string<CharT>::npos)
79 str.replace(start_pos, from.length(), to);
80 start_pos += to.length();
88template <
typename CharT,
typename T>
90extract(
const std::basic_string<CharT> & value, T & dst)
93 std::basic_istringstream<CharT> is {value};
95 if ((is >> std::boolalpha >> result) && !(is >> c))
106template <
typename CharT>
108extract(
const std::basic_string<CharT> & value, std::basic_string<CharT> & dst)
114template <
typename CharT,
typename T>
116get_value(
const std::map<std::basic_string<CharT>, std::basic_string<CharT>> & sec,
const std::basic_string<CharT> & key, T & dst)
118 const auto it = sec.find(key);
121 return extract(it->second, dst);
124template <
typename CharT,
typename T>
126get_value(
const std::map<std::basic_string<CharT>, std::basic_string<CharT>> & sec,
const CharT * key, T & dst)
128 return get_value(sec, std::basic_string<CharT>(key), dst);
131template <
class CharT>
153 Format(CharT section_start, CharT section_end, CharT assign, CharT comment, CharT interpol, CharT interpol_start, CharT interpol_sep, CharT interpol_end) :
157 Format(
'[',
']',
'=',
';',
'$',
'{',
':',
'}') { }
159 const std::basic_string<CharT>
local_symbol(
const std::basic_string<CharT> & name)
const
164 const std::basic_string<CharT>
global_symbol(
const std::basic_string<CharT> & sec_name,
const std::basic_string<CharT> & name)
const
170template <
class CharT>
189 void generate(std::basic_ostream<CharT> & os)
const
193 os <<
format->char_section_start << sec.first <<
format->char_section_end << std::endl;
194 for (
auto const & val : sec.second)
196 os << val.first <<
format->char_assign << val.second << std::endl;
202 void parse(std::basic_istream<CharT> & is)
206 const std::locale loc {
"C"};
207 while (std::getline(is, line))
211 const auto length = line.length();
214 const auto pos = std::find_if(line.begin(), line.end(), [
this](CharT ch) { return format->is_assign(ch); });
215 const auto & front = line.front();
216 if (
format->is_comment(front))
219 else if (
format->is_section_start(front))
221 if (
format->is_section_end(line.back()))
222 section = line.substr(1, length - 2);
226 else if (pos != line.begin() && pos != line.end())
228 String variable(line.begin(), pos);
229 String value(pos + 1, line.end());
233 if (sec.find(variable) == sec.end())
234 sec.emplace(variable, value);
248 int global_iteration = 0;
249 auto changed =
false;
252 replace_symbols(local_symbols(sec.first, sec.second), sec.second);
257 const auto syms = global_symbols();
259 changed |= replace_symbols(syms, sec.second);
266 for (
const auto & val : sec)
267 sec2.second.insert(val);
272 const std::locale loc {
"C"};
274 for (
auto & val : sec.second)
276 detail::rtrim2(val.second, [
this](CharT ch) { return format->is_comment(ch); });
288 using Symbols = std::vector<std::pair<String, String>>;
290 const Symbols local_symbols(
const String & sec_name,
const Section & sec)
const
293 for (
const auto & val : sec)
294 result.emplace_back(
format->local_symbol(val.first),
format->global_symbol(sec_name, val.first));
298 const Symbols global_symbols()
const
302 for (const auto & val : sec.second)
303 result.emplace_back(
format->global_symbol(sec.first, val.first), val.second);
307 bool replace_symbols(
const Symbols & syms,
Section & sec)
const
309 auto changed =
false;
310 for (
auto & sym : syms)
312 changed |= detail::
replace(
val.second, sym.first, sym.second);
void default_section(const Section &sec)
Definition inipp.h:263
Sections sections
Definition inipp.h:178
Ini(std::shared_ptr< Format< CharT > > fmt)
Definition inipp.h:186
std::map< String, String > Section
Definition inipp.h:175
static const int max_interpolation_depth
Definition inipp.h:182
void generate(std::basic_ostream< CharT > &os) const
Definition inipp.h:189
void parse(std::basic_istream< CharT > &is)
Definition inipp.h:202
void clear()
Definition inipp.h:281
std::map< String, Section > Sections
Definition inipp.h:176
std::shared_ptr< Format< CharT > > format
Definition inipp.h:180
void interpolate()
Definition inipp.h:246
std::list< String > errors
Definition inipp.h:179
std::basic_string< CharT > String
Definition inipp.h:174
Ini()
Definition inipp.h:184
void strip_trailing_comments()
Definition inipp.h:270
void rtrim(std::basic_string< CharT > &s, const std::locale &loc)
Definition inipp.h:56
void rtrim2(std::basic_string< CharT > &s, UnaryPredicate pred)
Definition inipp.h:64
bool replace(std::basic_string< CharT > &str, const std::basic_string< CharT > &from, const std::basic_string< CharT > &to)
Definition inipp.h:73
void ltrim(std::basic_string< CharT > &s, const std::locale &loc)
Definition inipp.h:48
bool extract(const std::basic_string< CharT > &value, T &dst)
Definition inipp.h:90
bool get_value(const std::map< std::basic_string< CharT >, std::basic_string< CharT > > &sec, const std::basic_string< CharT > &key, T &dst)
Definition inipp.h:116
val
Definition test-case-generator.py:590
for(;;x)
Definition script-test-cases.txt:2