annotate dep/toml11/toml/serializer.hpp @ 326:10096c5489e3

anime/db: refactor anime_season_db out
author Paper <paper@paper.us.eu.org>
date Thu, 13 Jun 2024 00:42:00 -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