annotate dep/toml11/toml/serializer.hpp @ 327:b5d6c27c308f

anime: refactor Anime::SeriesSeason to Season class ToLocalString has also been altered to take in both season and year because lots of locales actually treat formatting seasons differently! most notably is Russian which adds a suffix at the end to notate seasons(??)
author Paper <paper@paper.us.eu.org>
date Thu, 13 Jun 2024 01:49:18 -0400
parents 3b355fa948c7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
318
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 // Copyright Toru Niina 2019.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2 // Distributed under the MIT License.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
3 #ifndef TOML11_SERIALIZER_HPP
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 #define TOML11_SERIALIZER_HPP
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5 #include <cmath>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 #include <cstdio>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 #include <limits>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
9
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 #if defined(_WIN32)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11 #include <locale.h>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
12 #elif defined(__APPLE__) || defined(__FreeBSD__)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
13 #include <xlocale.h>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
14 #elif defined(__linux__)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
15 #include <locale.h>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
16 #endif
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
17
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
18 #include "lexer.hpp"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
19 #include "value.hpp"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
20
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
21 namespace toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
22 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
23
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
24 // This function serialize a key. It checks a string is a bare key and
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
25 // escapes special characters if the string is not compatible to a bare key.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
26 // ```cpp
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
27 // std::string k("non.bare.key"); // the key itself includes `.`s.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
28 // std::string formatted = toml::format_key(k);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
29 // assert(formatted == "\"non.bare.key\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
30 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
31 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
32 // This function is exposed to make it easy to write a user-defined serializer.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
33 // Since toml restricts characters available in a bare key, generally a string
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
34 // should be escaped. But checking whether a string needs to be surrounded by
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
35 // a `"` and escaping some special character is boring.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
36 template<typename charT, typename traits, typename Alloc>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
37 std::basic_string<charT, traits, Alloc>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
38 format_key(const std::basic_string<charT, traits, Alloc>& k)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
39 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
40 if(k.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
41 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
42 return std::string("\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
43 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
44
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
45 // check the key can be a bare (unquoted) key
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
46 detail::location loc(k, std::vector<char>(k.begin(), k.end()));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
47 detail::lex_unquoted_key::invoke(loc);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
48 if(loc.iter() == loc.end())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
49 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
50 return k; // all the tokens are consumed. the key is unquoted-key.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
51 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
52
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
53 //if it includes special characters, then format it in a "quoted" key.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
54 std::basic_string<charT, traits, Alloc> serialized("\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
55 for(const char c : k)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
56 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
57 switch(c)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
58 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
59 case '\\': {serialized += "\\\\"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
60 case '\"': {serialized += "\\\""; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
61 case '\b': {serialized += "\\b"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
62 case '\t': {serialized += "\\t"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
63 case '\f': {serialized += "\\f"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
64 case '\n': {serialized += "\\n"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
65 case '\r': {serialized += "\\r"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
66 default: {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
67 if (c >= 0x00 && c < 0x20)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
68 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
69 std::array<char, 7> buf;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
70 std::snprintf(buf.data(), buf.size(), "\\u00%02x", static_cast<int>(c));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
71 serialized += buf.data();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
72 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
73 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
74 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
75 serialized += c;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
76 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
77 break;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
78 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
79 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
80 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
81 serialized += "\"";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
82 return serialized;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
83 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
84
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
85 template<typename charT, typename traits, typename Alloc>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
86 std::basic_string<charT, traits, Alloc>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
87 format_keys(const std::vector<std::basic_string<charT, traits, Alloc>>& keys)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
88 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
89 if(keys.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
90 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
91 return std::string("\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
92 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
93
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
94 std::basic_string<charT, traits, Alloc> serialized;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
95 for(const auto& ky : keys)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
96 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
97 serialized += format_key(ky);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
98 serialized += charT('.');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
99 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
100 serialized.pop_back(); // remove the last dot '.'
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
101 return serialized;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
102 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
103
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
104 template<typename Value>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
105 struct serializer
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
106 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
107 static_assert(detail::is_basic_value<Value>::value,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
108 "toml::serializer is for toml::value and its variants, "
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
109 "toml::basic_value<...>.");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
110
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
111 using value_type = Value;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
112 using key_type = typename value_type::key_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
113 using comment_type = typename value_type::comment_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
114 using boolean_type = typename value_type::boolean_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
115 using integer_type = typename value_type::integer_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
116 using floating_type = typename value_type::floating_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
117 using string_type = typename value_type::string_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
118 using local_time_type = typename value_type::local_time_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
119 using local_date_type = typename value_type::local_date_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
120 using local_datetime_type = typename value_type::local_datetime_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
121 using offset_datetime_type = typename value_type::offset_datetime_type;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
122 using array_type = typename value_type::array_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
123 using table_type = typename value_type::table_type ;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
124
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
125 serializer(const std::size_t w = 80u,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
126 const int float_prec = std::numeric_limits<toml::floating>::max_digits10,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
127 const bool can_be_inlined = false,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
128 const bool no_comment = false,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
129 std::vector<toml::key> ks = {},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
130 const bool value_has_comment = false)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131 : can_be_inlined_(can_be_inlined), no_comment_(no_comment),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
132 value_has_comment_(value_has_comment && !no_comment),
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133 float_prec_(float_prec), width_(w), keys_(std::move(ks))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
134 {}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 ~serializer() = default;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
136
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
137 std::string operator()(const boolean_type& b) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
138 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
139 return b ? "true" : "false";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
140 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
141 std::string operator()(const integer_type i) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
142 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
143 #if defined(_WIN32)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
144 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
145 const std::string original_locale(setlocale(LC_NUMERIC, nullptr));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
146 setlocale(LC_NUMERIC, "C");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
147 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
148 const auto c_locale = newlocale(LC_NUMERIC_MASK, "C", locale_t(0));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
149 locale_t original_locale(0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
150 if(c_locale != locale_t(0))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
151 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
152 original_locale = uselocale(c_locale);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
153 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
154 #endif
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
155
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
156 const auto str = std::to_string(i);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
157
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
158 #if defined(_WIN32)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
159 setlocale(LC_NUMERIC, original_locale.c_str());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
160 _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
161 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
162 if(original_locale != locale_t(0))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
163 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
164 uselocale(original_locale);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
165 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
166 #endif
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
167 return str;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
168 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
169 std::string operator()(const floating_type f) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
170 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
171 if(std::isnan(f))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
172 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
173 if(std::signbit(f))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
174 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
175 return std::string("-nan");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
176 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
177 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
178 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
179 return std::string("nan");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
180 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
181 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
182 else if(!std::isfinite(f))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
183 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
184 if(std::signbit(f))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
185 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
186 return std::string("-inf");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
187 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
188 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
189 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
190 return std::string("inf");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
191 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
192 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
193
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
194 // set locale to "C".
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
195 // To make it thread-local, we use OS-specific features.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
196 // If we set process-global locale, it can break other thread that also
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
197 // outputs something simultaneously.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
198 #if defined(_WIN32)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
199 _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
200 const std::string original_locale(setlocale(LC_NUMERIC, nullptr));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
201 setlocale(LC_NUMERIC, "C");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
202 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
203 const auto c_locale = newlocale(LC_NUMERIC_MASK, "C", locale_t(0));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
204 locale_t original_locale(0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
205 if(c_locale != locale_t(0))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
206 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
207 original_locale = uselocale(c_locale);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
208 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
209 #endif
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
210
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
211 const auto fmt = "%.*g";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
212 const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
213 // +1 for null character(\0)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
214 std::vector<char> buf(static_cast<std::size_t>(bsz + 1), '\0');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
215 std::snprintf(buf.data(), buf.size(), fmt, this->float_prec_, f);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
216
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
217 // restore the original locale
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
218 #if defined(_WIN32)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
219 setlocale(LC_NUMERIC, original_locale.c_str());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
220 _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
221 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
222 if(original_locale != locale_t(0))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
223 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
224 uselocale(original_locale);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
225 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
226 #endif
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
227
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
228 std::string token(buf.begin(), std::prev(buf.end()));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
229 if(!token.empty() && token.back() == '.') // 1. => 1.0
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
230 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
231 token += '0';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
232 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
233
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
234 const auto e = std::find_if(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
235 token.cbegin(), token.cend(), [](const char c) noexcept -> bool {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
236 return c == 'e' || c == 'E';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
237 });
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
238 const auto has_exponent = (token.cend() != e);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
239 const auto has_fraction = (token.cend() != std::find(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
240 token.cbegin(), token.cend(), '.'));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
241
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
242 if(!has_exponent && !has_fraction)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
243 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
244 // the resulting value does not have any float specific part!
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
245 token += ".0";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
246 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
247 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
248 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
249 std::string operator()(const string_type& s) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
250 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
251 if(s.kind == string_t::basic)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
252 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
253 if((std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() ||
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
254 std::find(s.str.cbegin(), s.str.cend(), '\"') != s.str.cend()) &&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
255 this->width_ != (std::numeric_limits<std::size_t>::max)())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
256 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
257 // if linefeed or double-quote is contained,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
258 // make it multiline basic string.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
259 const auto escaped = this->escape_ml_basic_string(s.str);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
260 std::string open("\"\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
261 std::string close("\"\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
262 if(escaped.find('\n') != std::string::npos ||
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
263 this->width_ < escaped.size() + 6)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
264 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
265 // if the string body contains newline or is enough long,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
266 // add newlines after and before delimiters.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
267 open += "\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
268 close = std::string("\\\n") + close;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
269 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
270 return open + escaped + close;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
271 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
272
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
273 // no linefeed. try to make it oneline-string.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
274 std::string oneline = this->escape_basic_string(s.str);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
275 if(oneline.size() + 2 < width_ || width_ < 2)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
276 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
277 const std::string quote("\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
278 return quote + oneline + quote;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
279 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
280
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
281 // the line is too long compared to the specified width.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
282 // split it into multiple lines.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
283 std::string token("\"\"\"\n");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
284 while(!oneline.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
285 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
286 if(oneline.size() < width_)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
287 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
288 token += oneline;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
289 oneline.clear();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
290 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
291 else if(oneline.at(width_-2) == '\\')
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
292 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
293 token += oneline.substr(0, width_-2);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
294 token += "\\\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
295 oneline.erase(0, width_-2);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
296 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
297 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
298 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
299 token += oneline.substr(0, width_-1);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
300 token += "\\\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
301 oneline.erase(0, width_-1);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
302 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
303 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
304 return token + std::string("\\\n\"\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
305 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
306 else // the string `s` is literal-string.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
307 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
308 if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() ||
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
309 std::find(s.str.cbegin(), s.str.cend(), '\'') != s.str.cend() )
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
310 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
311 std::string open("'''");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
312 if(this->width_ + 6 < s.str.size())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
313 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
314 open += '\n'; // the first newline is ignored by TOML spec
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
315 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
316 const std::string close("'''");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
317 return open + s.str + close;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
318 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
319 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
320 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
321 const std::string quote("'");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
322 return quote + s.str + quote;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
323 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
324 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
325 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
326
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
327 std::string operator()(const local_date_type& d) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
328 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
329 std::ostringstream oss;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
330 oss << d;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
331 return oss.str();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
332 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
333 std::string operator()(const local_time_type& t) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
334 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
335 std::ostringstream oss;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
336 oss << t;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
337 return oss.str();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
338 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
339 std::string operator()(const local_datetime_type& dt) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
340 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
341 std::ostringstream oss;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
342 oss << dt;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
343 return oss.str();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
344 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
345 std::string operator()(const offset_datetime_type& odt) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
346 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
347 std::ostringstream oss;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
348 oss << odt;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
349 return oss.str();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
350 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
351
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
352 std::string operator()(const array_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
353 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
354 if(v.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
355 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
356 return std::string("[]");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
357 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
358 if(this->is_array_of_tables(v))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
359 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
360 return make_array_of_tables(v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
361 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
362
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
363 // not an array of tables. normal array.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
364 // first, try to make it inline if none of the elements have a comment.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
365 if( ! this->has_comment_inside(v))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
366 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
367 const auto inl = this->make_inline_array(v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
368 if(inl.size() < this->width_ &&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
369 std::find(inl.cbegin(), inl.cend(), '\n') == inl.cend())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
370 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
371 return inl;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
372 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
373 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
374
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
375 // if the length exceeds this->width_, print multiline array.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
376 // key = [
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
377 // # ...
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
378 // 42,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
379 // ...
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
380 // ]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
381 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
382 std::string current_line;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
383 token += "[\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
384 for(const auto& item : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
385 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
386 if( ! item.comments().empty() && !no_comment_)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
387 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
388 // if comment exists, the element must be the only element in the line.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
389 // e.g. the following is not allowed.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
390 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
391 // array = [
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
392 // # comment for what?
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
393 // 1, 2, 3, 4, 5
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
394 // ]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
395 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
396 if(!current_line.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
397 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
398 if(current_line.back() != '\n')
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
399 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
400 current_line += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
401 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
402 token += current_line;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
403 current_line.clear();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
404 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
405 for(const auto& c : item.comments())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
406 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
407 token += '#';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
408 token += c;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
409 token += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
410 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
411 token += toml::visit(*this, item);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
412 if(!token.empty() && token.back() == '\n') {token.pop_back();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
413 token += ",\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
414 continue;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
415 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
416 std::string next_elem;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
417 if(item.is_table())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
418 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
419 serializer ser(*this);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
420 ser.can_be_inlined_ = true;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
421 ser.width_ = (std::numeric_limits<std::size_t>::max)();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
422 next_elem += toml::visit(ser, item);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
423 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
424 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
425 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
426 next_elem += toml::visit(*this, item);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
427 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
428
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
429 // comma before newline.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
430 if(!next_elem.empty() && next_elem.back() == '\n') {next_elem.pop_back();}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
431
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
432 // if current line does not exceeds the width limit, continue.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
433 if(current_line.size() + next_elem.size() + 1 < this->width_)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
434 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
435 current_line += next_elem;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
436 current_line += ',';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
437 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
438 else if(current_line.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
439 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
440 // if current line was empty, force put the next_elem because
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
441 // next_elem is not splittable
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
442 token += next_elem;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
443 token += ",\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
444 // current_line is kept empty
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
445 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
446 else // reset current_line
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
447 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
448 assert(current_line.back() == ',');
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
449 token += current_line;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
450 token += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
451 current_line = next_elem;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
452 current_line += ',';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
453 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
454 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
455 if(!current_line.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
456 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
457 if(!current_line.empty() && current_line.back() != '\n')
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
458 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
459 current_line += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
460 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
461 token += current_line;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
462 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
463 token += "]\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
464 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
465 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
466
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
467 // templatize for any table-like container
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
468 std::string operator()(const table_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
469 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
470 // if an element has a comment, then it can't be inlined.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
471 // table = {# how can we write a comment for this? key = "value"}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
472 if(this->can_be_inlined_ && !(this->has_comment_inside(v)))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
473 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
474 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
475 if(!this->keys_.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
476 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
477 token += format_key(this->keys_.back());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
478 token += " = ";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
479 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
480 token += this->make_inline_table(v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
481 if(token.size() < this->width_ &&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
482 token.end() == std::find(token.begin(), token.end(), '\n'))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
483 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
484 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
485 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
486 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
487
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
488 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
489 if(!keys_.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
490 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
491 token += '[';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
492 token += format_keys(keys_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
493 token += "]\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
494 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
495 token += this->make_multiline_table(v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
496 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
497 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
498
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
499 private:
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
500
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
501 std::string escape_basic_string(const std::string& s) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
502 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
503 //XXX assuming `s` is a valid utf-8 sequence.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
504 std::string retval;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
505 for(const char c : s)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
506 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
507 switch(c)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
508 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
509 case '\\': {retval += "\\\\"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
510 case '\"': {retval += "\\\""; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
511 case '\b': {retval += "\\b"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
512 case '\t': {retval += "\\t"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
513 case '\f': {retval += "\\f"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
514 case '\n': {retval += "\\n"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
515 case '\r': {retval += "\\r"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
516 default :
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
517 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
518 if((0x00 <= c && c <= 0x08) || (0x0A <= c && c <= 0x1F) || c == 0x7F)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
519 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
520 retval += "\\u00";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
521 retval += char(48 + (c / 16));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
522 retval += char((c % 16 < 10 ? 48 : 55) + (c % 16));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
523 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
524 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
525 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
526 retval += c;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
527 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
528 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
529 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
530 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
531 return retval;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
532 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
533
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
534 std::string escape_ml_basic_string(const std::string& s) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
535 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
536 std::string retval;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
537 for(auto i=s.cbegin(), e=s.cend(); i!=e; ++i)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
538 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
539 switch(*i)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
540 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
541 case '\\': {retval += "\\\\"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
542 // One or two consecutive "s are allowed.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
543 // Later we will check there are no three consecutive "s.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
544 // case '\"': {retval += "\\\""; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
545 case '\b': {retval += "\\b"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
546 case '\t': {retval += "\\t"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
547 case '\f': {retval += "\\f"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
548 case '\n': {retval += "\n"; break;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
549 case '\r':
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
550 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
551 if(std::next(i) != e && *std::next(i) == '\n')
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
552 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
553 retval += "\r\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
554 ++i;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
555 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
556 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
557 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
558 retval += "\\r";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
559 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
560 break;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
561 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
562 default :
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
563 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
564 const auto c = *i;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
565 if((0x00 <= c && c <= 0x08) || (0x0A <= c && c <= 0x1F) || c == 0x7F)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
566 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
567 retval += "\\u00";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
568 retval += char(48 + (c / 16));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
569 retval += char((c % 16 < 10 ? 48 : 55) + (c % 16));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
570 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
571 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
572 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
573 retval += c;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
574 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
575 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
576
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
577 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
578 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
579 // Only 1 or 2 consecutive `"`s are allowed in multiline basic string.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
580 // 3 consecutive `"`s are considered as a closing delimiter.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
581 // We need to check if there are 3 or more consecutive `"`s and insert
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
582 // backslash to break them down into several short `"`s like the `str6`
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
583 // in the following example.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
584 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
585 // str4 = """Here are two quotation marks: "". Simple enough."""
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
586 // # str5 = """Here are three quotation marks: """.""" # INVALID
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
587 // str5 = """Here are three quotation marks: ""\"."""
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
588 // str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
589 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
590 auto found_3_quotes = retval.find("\"\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
591 while(found_3_quotes != std::string::npos)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
592 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
593 retval.replace(found_3_quotes, 3, "\"\"\\\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
594 found_3_quotes = retval.find("\"\"\"");
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
595 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
596 return retval;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
597 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
598
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
599 // if an element of a table or an array has a comment, it cannot be inlined.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
600 bool has_comment_inside(const array_type& a) const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
601 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
602 // if no_comment is set, comments would not be written.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
603 if(this->no_comment_) {return false;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
604
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
605 for(const auto& v : a)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
606 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
607 if(!v.comments().empty()) {return true;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
608 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
609 return false;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
610 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
611 bool has_comment_inside(const table_type& t) const noexcept
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
612 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
613 // if no_comment is set, comments would not be written.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
614 if(this->no_comment_) {return false;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
615
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
616 for(const auto& kv : t)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
617 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
618 if(!kv.second.comments().empty()) {return true;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
619 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
620 return false;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
621 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
622
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
623 std::string make_inline_array(const array_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
624 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
625 assert(!has_comment_inside(v));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
626 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
627 token += '[';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
628 bool is_first = true;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
629 for(const auto& item : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
630 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
631 if(is_first) {is_first = false;} else {token += ',';}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
632 token += visit(serializer(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
633 (std::numeric_limits<std::size_t>::max)(), this->float_prec_,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
634 /* inlined */ true, /*no comment*/ false, /*keys*/ {},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
635 /*has_comment*/ !item.comments().empty()), item);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
636 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
637 token += ']';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
638 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
639 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
640
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
641 std::string make_inline_table(const table_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
642 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
643 assert(!has_comment_inside(v));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
644 assert(this->can_be_inlined_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
645 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
646 token += '{';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
647 bool is_first = true;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
648 for(const auto& kv : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
649 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
650 // in inline tables, trailing comma is not allowed (toml-lang #569).
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
651 if(is_first) {is_first = false;} else {token += ',';}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
652 token += format_key(kv.first);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
653 token += '=';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
654 token += visit(serializer(
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
655 (std::numeric_limits<std::size_t>::max)(), this->float_prec_,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
656 /* inlined */ true, /*no comment*/ false, /*keys*/ {},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
657 /*has_comment*/ !kv.second.comments().empty()), kv.second);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
658 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
659 token += '}';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
660 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
661 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
662
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
663 std::string make_multiline_table(const table_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
664 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
665 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
666
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
667 // print non-table elements first.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
668 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
669 // [foo] # a table we're writing now here
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
670 // key = "value" # <- non-table element, "key"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
671 // # ...
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
672 // [foo.bar] # <- table element, "bar"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
673 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
674 // because after printing [foo.bar], the remaining non-table values will
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
675 // be assigned into [foo.bar], not [foo]. Those values should be printed
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
676 // earlier.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
677 for(const auto& kv : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
678 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
679 if(kv.second.is_table() || is_array_of_tables(kv.second))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
680 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
681 continue;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
682 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
683
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
684 token += write_comments(kv.second);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
685
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
686 const auto key_and_sep = format_key(kv.first) + " = ";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
687 const auto residual_width = (this->width_ > key_and_sep.size()) ?
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
688 this->width_ - key_and_sep.size() : 0;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
689 token += key_and_sep;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
690 token += visit(serializer(residual_width, this->float_prec_,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
691 /*can be inlined*/ true, /*no comment*/ false, /*keys*/ {},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
692 /*has_comment*/ !kv.second.comments().empty()), kv.second);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
693
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
694 if(token.back() != '\n')
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
695 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
696 token += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
697 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
698 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
699
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
700 // normal tables / array of tables
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
701
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
702 // after multiline table appeared, the other tables cannot be inline
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
703 // because the table would be assigned into the table.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
704 // [foo]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
705 // ...
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
706 // bar = {...} # <- bar will be a member of [foo].
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
707 bool multiline_table_printed = false;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
708 for(const auto& kv : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
709 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
710 if(!kv.second.is_table() && !is_array_of_tables(kv.second))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
711 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
712 continue; // other stuff are already serialized. skip them.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
713 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
714
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
715 std::vector<toml::key> ks(this->keys_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
716 ks.push_back(kv.first);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
717
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
718 auto tmp = visit(serializer(this->width_, this->float_prec_,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
719 !multiline_table_printed, this->no_comment_, ks,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
720 /*has_comment*/ !kv.second.comments().empty()), kv.second);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
721
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
722 // If it is the first time to print a multi-line table, it would be
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
723 // helpful to separate normal key-value pair and subtables by a
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
724 // newline.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
725 // (this checks if the current key-value pair contains newlines.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
726 // but it is not perfect because multi-line string can also contain
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
727 // a newline. in such a case, an empty line will be written) TODO
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
728 if((!multiline_table_printed) &&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
729 std::find(tmp.cbegin(), tmp.cend(), '\n') != tmp.cend())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
730 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
731 multiline_table_printed = true;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
732 token += '\n'; // separate key-value pairs and subtables
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
733
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
734 token += write_comments(kv.second);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
735 token += tmp;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
736
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
737 // care about recursive tables (all tables in each level prints
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
738 // newline and there will be a full of newlines)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
739 if(tmp.substr(tmp.size() - 2, 2) != "\n\n" &&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
740 tmp.substr(tmp.size() - 4, 4) != "\r\n\r\n" )
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
741 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
742 token += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
743 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
744 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
745 else
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
746 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
747 token += write_comments(kv.second);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
748 token += tmp;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
749 token += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
750 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
751 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
752 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
753 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
754
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
755 std::string make_array_of_tables(const array_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
756 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
757 // if it's not inlined, we need to add `[[table.key]]`.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
758 // but if it can be inlined, we can format it as the following.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
759 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
760 // table.key = [
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
761 // {...},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
762 // # comment
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
763 // {...},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
764 // ]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
765 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
766 // This function checks if inlinization is possible or not, and then
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
767 // format the array-of-tables in a proper way.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
768 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
769 // Note about comments:
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
770 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
771 // If the array itself has a comment (value_has_comment_ == true), we
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
772 // should try to make it inline.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
773 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
774 // # comment about array
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
775 // array = [
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
776 // # comment about table element
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
777 // {of = "table"}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
778 // ]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
779 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
780 // If it is formatted as a multiline table, the two comments becomes
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
781 // indistinguishable.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
782 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
783 // # comment about array
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
784 // # comment about table element
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
785 // [[array]]
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
786 // of = "table"
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
787 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
788 // So we need to try to make it inline, and it force-inlines regardless
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
789 // of the line width limit.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
790 // It may fail if the element of a table has comment. In that case,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
791 // the array-of-tables will be formatted as a multiline table.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
792 if(this->can_be_inlined_ || this->value_has_comment_)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
793 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
794 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
795 if(!keys_.empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
796 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
797 token += format_key(keys_.back());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
798 token += " = ";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
799 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
800
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
801 bool failed = false;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
802 token += "[\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
803 for(const auto& item : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
804 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
805 // if an element of the table has a comment, the table
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
806 // cannot be inlined.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
807 if(this->has_comment_inside(item.as_table()))
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
808 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
809 failed = true;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
810 break;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
811 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
812 // write comments for the table itself
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
813 token += write_comments(item);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
814
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
815 const auto t = this->make_inline_table(item.as_table());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
816
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
817 if(t.size() + 1 > width_ || // +1 for the last comma {...},
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
818 std::find(t.cbegin(), t.cend(), '\n') != t.cend())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
819 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
820 // if the value itself has a comment, ignore the line width limit
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
821 if( ! this->value_has_comment_)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
822 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
823 failed = true;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
824 break;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
825 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
826 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
827 token += t;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
828 token += ",\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
829 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
830
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
831 if( ! failed)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
832 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
833 token += "]\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
834 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
835 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
836 // if failed, serialize them as [[array.of.tables]].
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
837 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
838
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
839 std::string token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
840 for(const auto& item : v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
841 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
842 token += write_comments(item);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
843 token += "[[";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
844 token += format_keys(keys_);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
845 token += "]]\n";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
846 token += this->make_multiline_table(item.as_table());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
847 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
848 return token;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
849 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
850
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
851 std::string write_comments(const value_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
852 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
853 std::string retval;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
854 if(this->no_comment_) {return retval;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
855
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
856 for(const auto& c : v.comments())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
857 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
858 retval += '#';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
859 retval += c;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
860 retval += '\n';
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
861 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
862 return retval;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
863 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
864
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
865 bool is_array_of_tables(const value_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
866 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
867 if(!v.is_array() || v.as_array().empty()) {return false;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
868 return is_array_of_tables(v.as_array());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
869 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
870 bool is_array_of_tables(const array_type& v) const
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
871 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
872 // Since TOML v0.5.0, heterogeneous arrays are allowed. So we need to
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
873 // check all the element in an array to check if the array is an array
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
874 // of tables.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
875 return std::all_of(v.begin(), v.end(), [](const value_type& elem) {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
876 return elem.is_table();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
877 });
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
878 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
879
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
880 private:
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
881
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
882 bool can_be_inlined_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
883 bool no_comment_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
884 bool value_has_comment_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
885 int float_prec_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
886 std::size_t width_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
887 std::vector<toml::key> keys_;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
888 };
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
889
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
890 template<typename C,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
891 template<typename ...> class M, template<typename ...> class V>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
892 std::string
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
893 format(const basic_value<C, M, V>& v, std::size_t w = 80u,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
894 int fprec = std::numeric_limits<toml::floating>::max_digits10,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
895 bool no_comment = false, bool force_inline = false)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
896 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
897 using value_type = basic_value<C, M, V>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
898 // if value is a table, it is considered to be a root object.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
899 // the root object can't be an inline table.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
900 if(v.is_table())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
901 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
902 std::ostringstream oss;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
903 if(!v.comments().empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
904 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
905 oss << v.comments();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
906 oss << '\n'; // to split the file comment from the first element
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
907 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
908 const auto serialized = visit(serializer<value_type>(w, fprec, false, no_comment), v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
909 oss << serialized;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
910 return oss.str();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
911 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
912 return visit(serializer<value_type>(w, fprec, force_inline), v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
913 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
914
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
915 namespace detail
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
916 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
917 template<typename charT, typename traits>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
918 int comment_index(std::basic_ostream<charT, traits>&)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
919 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
920 static const int index = std::ios_base::xalloc();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
921 return index;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
922 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
923 } // detail
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
924
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
925 template<typename charT, typename traits>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
926 std::basic_ostream<charT, traits>&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
927 nocomment(std::basic_ostream<charT, traits>& os)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
928 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
929 // by default, it is zero. and by default, it shows comments.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
930 os.iword(detail::comment_index(os)) = 1;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
931 return os;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
932 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
933
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
934 template<typename charT, typename traits>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
935 std::basic_ostream<charT, traits>&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
936 showcomment(std::basic_ostream<charT, traits>& os)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
937 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
938 // by default, it is zero. and by default, it shows comments.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
939 os.iword(detail::comment_index(os)) = 0;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
940 return os;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
941 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
942
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
943 template<typename charT, typename traits, typename C,
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
944 template<typename ...> class M, template<typename ...> class V>
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
945 std::basic_ostream<charT, traits>&
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
946 operator<<(std::basic_ostream<charT, traits>& os, const basic_value<C, M, V>& v)
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
947 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
948 using value_type = basic_value<C, M, V>;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
949
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
950 // get status of std::setw().
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
951 const auto w = static_cast<std::size_t>(os.width());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
952 const int fprec = static_cast<int>(os.precision());
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
953 os.width(0);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
954
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
955 // by default, iword is initialized by 0. And by default, toml11 outputs
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
956 // comments. So `0` means showcomment. 1 means nocommnet.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
957 const bool no_comment = (1 == os.iword(detail::comment_index(os)));
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
958
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
959 if(!no_comment && v.is_table() && !v.comments().empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
960 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
961 os << v.comments();
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
962 os << '\n'; // to split the file comment from the first element
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
963 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
964 // the root object can't be an inline table. so pass `false`.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
965 const auto serialized = visit(serializer<value_type>(w, fprec, no_comment, false), v);
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
966 os << serialized;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
967
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
968 // if v is a non-table value, and has only one comment, then
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
969 // put a comment just after a value. in the following way.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
970 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
971 // ```toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
972 // key = "value" # comment.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
973 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
974 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
975 // Since the top-level toml object is a table, one who want to put a
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
976 // non-table toml value must use this in a following way.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
977 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
978 // ```cpp
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
979 // toml::value v;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
980 // std::cout << "user-defined-key = " << v << std::endl;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
981 // ```
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
982 //
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
983 // In this case, it is impossible to put comments before key-value pair.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
984 // The only way to preserve comments is to put all of them after a value.
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
985 if(!no_comment && !v.is_table() && !v.comments().empty())
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
986 {
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
987 os << " #";
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
988 for(const auto& c : v.comments()) {os << c;}
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
989 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
990 return os;
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
991 }
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
992
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
993 } // toml
3b355fa948c7 config: use TOML instead of INI
Paper <paper@paper.us.eu.org>
parents:
diff changeset
994 #endif// TOML11_SERIALIZER_HPP