Mercurial > minori
comparison dep/toml11/toml/string.hpp @ 318:3b355fa948c7
config: use TOML instead of INI
unfortunately, INI is not enough, and causes some paths including
semicolons to break with our current storage of the library folders.
so, I decided to switch to TOML which does support real arrays...
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 12 Jun 2024 05:25:41 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
317:b1f4d1867ab1 | 318:3b355fa948c7 |
---|---|
1 // Copyright Toru Niina 2017. | |
2 // Distributed under the MIT License. | |
3 #ifndef TOML11_STRING_HPP | |
4 #define TOML11_STRING_HPP | |
5 | |
6 #include "version.hpp" | |
7 | |
8 #include <cstdint> | |
9 | |
10 #include <algorithm> | |
11 #include <string> | |
12 | |
13 #if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L | |
14 #if __has_include(<string_view>) | |
15 #define TOML11_USING_STRING_VIEW 1 | |
16 #include <string_view> | |
17 #endif | |
18 #endif | |
19 | |
20 namespace toml | |
21 { | |
22 | |
23 enum class string_t : std::uint8_t | |
24 { | |
25 basic = 0, | |
26 literal = 1, | |
27 }; | |
28 | |
29 struct string | |
30 { | |
31 string() = default; | |
32 ~string() = default; | |
33 string(const string& s) = default; | |
34 string(string&& s) = default; | |
35 string& operator=(const string& s) = default; | |
36 string& operator=(string&& s) = default; | |
37 | |
38 string(const std::string& s): kind(string_t::basic), str(s){} | |
39 string(const std::string& s, string_t k): kind(k), str(s){} | |
40 string(const char* s): kind(string_t::basic), str(s){} | |
41 string(const char* s, string_t k): kind(k), str(s){} | |
42 | |
43 string(std::string&& s): kind(string_t::basic), str(std::move(s)){} | |
44 string(std::string&& s, string_t k): kind(k), str(std::move(s)){} | |
45 | |
46 string& operator=(const std::string& s) | |
47 {kind = string_t::basic; str = s; return *this;} | |
48 string& operator=(std::string&& s) | |
49 {kind = string_t::basic; str = std::move(s); return *this;} | |
50 | |
51 operator std::string& () & noexcept {return str;} | |
52 operator std::string const& () const& noexcept {return str;} | |
53 operator std::string&& () && noexcept {return std::move(str);} | |
54 | |
55 string& operator+=(const char* rhs) {str += rhs; return *this;} | |
56 string& operator+=(const char rhs) {str += rhs; return *this;} | |
57 string& operator+=(const std::string& rhs) {str += rhs; return *this;} | |
58 string& operator+=(const string& rhs) {str += rhs.str; return *this;} | |
59 | |
60 #if defined(TOML11_USING_STRING_VIEW) && TOML11_USING_STRING_VIEW>0 | |
61 explicit string(std::string_view s): kind(string_t::basic), str(s){} | |
62 string(std::string_view s, string_t k): kind(k), str(s){} | |
63 | |
64 string& operator=(std::string_view s) | |
65 {kind = string_t::basic; str = s; return *this;} | |
66 | |
67 explicit operator std::string_view() const noexcept | |
68 {return std::string_view(str);} | |
69 | |
70 string& operator+=(const std::string_view& rhs) {str += rhs; return *this;} | |
71 #endif | |
72 | |
73 string_t kind; | |
74 std::string str; | |
75 }; | |
76 | |
77 inline bool operator==(const string& lhs, const string& rhs) | |
78 { | |
79 return lhs.kind == rhs.kind && lhs.str == rhs.str; | |
80 } | |
81 inline bool operator!=(const string& lhs, const string& rhs) | |
82 { | |
83 return !(lhs == rhs); | |
84 } | |
85 inline bool operator<(const string& lhs, const string& rhs) | |
86 { | |
87 return (lhs.kind == rhs.kind) ? (lhs.str < rhs.str) : (lhs.kind < rhs.kind); | |
88 } | |
89 inline bool operator>(const string& lhs, const string& rhs) | |
90 { | |
91 return rhs < lhs; | |
92 } | |
93 inline bool operator<=(const string& lhs, const string& rhs) | |
94 { | |
95 return !(rhs < lhs); | |
96 } | |
97 inline bool operator>=(const string& lhs, const string& rhs) | |
98 { | |
99 return !(lhs < rhs); | |
100 } | |
101 | |
102 inline bool | |
103 operator==(const string& lhs, const std::string& rhs) {return lhs.str == rhs;} | |
104 inline bool | |
105 operator!=(const string& lhs, const std::string& rhs) {return lhs.str != rhs;} | |
106 inline bool | |
107 operator< (const string& lhs, const std::string& rhs) {return lhs.str < rhs;} | |
108 inline bool | |
109 operator> (const string& lhs, const std::string& rhs) {return lhs.str > rhs;} | |
110 inline bool | |
111 operator<=(const string& lhs, const std::string& rhs) {return lhs.str <= rhs;} | |
112 inline bool | |
113 operator>=(const string& lhs, const std::string& rhs) {return lhs.str >= rhs;} | |
114 | |
115 inline bool | |
116 operator==(const std::string& lhs, const string& rhs) {return lhs == rhs.str;} | |
117 inline bool | |
118 operator!=(const std::string& lhs, const string& rhs) {return lhs != rhs.str;} | |
119 inline bool | |
120 operator< (const std::string& lhs, const string& rhs) {return lhs < rhs.str;} | |
121 inline bool | |
122 operator> (const std::string& lhs, const string& rhs) {return lhs > rhs.str;} | |
123 inline bool | |
124 operator<=(const std::string& lhs, const string& rhs) {return lhs <= rhs.str;} | |
125 inline bool | |
126 operator>=(const std::string& lhs, const string& rhs) {return lhs >= rhs.str;} | |
127 | |
128 inline bool | |
129 operator==(const string& lhs, const char* rhs) {return lhs.str == std::string(rhs);} | |
130 inline bool | |
131 operator!=(const string& lhs, const char* rhs) {return lhs.str != std::string(rhs);} | |
132 inline bool | |
133 operator< (const string& lhs, const char* rhs) {return lhs.str < std::string(rhs);} | |
134 inline bool | |
135 operator> (const string& lhs, const char* rhs) {return lhs.str > std::string(rhs);} | |
136 inline bool | |
137 operator<=(const string& lhs, const char* rhs) {return lhs.str <= std::string(rhs);} | |
138 inline bool | |
139 operator>=(const string& lhs, const char* rhs) {return lhs.str >= std::string(rhs);} | |
140 | |
141 inline bool | |
142 operator==(const char* lhs, const string& rhs) {return std::string(lhs) == rhs.str;} | |
143 inline bool | |
144 operator!=(const char* lhs, const string& rhs) {return std::string(lhs) != rhs.str;} | |
145 inline bool | |
146 operator< (const char* lhs, const string& rhs) {return std::string(lhs) < rhs.str;} | |
147 inline bool | |
148 operator> (const char* lhs, const string& rhs) {return std::string(lhs) > rhs.str;} | |
149 inline bool | |
150 operator<=(const char* lhs, const string& rhs) {return std::string(lhs) <= rhs.str;} | |
151 inline bool | |
152 operator>=(const char* lhs, const string& rhs) {return std::string(lhs) >= rhs.str;} | |
153 | |
154 template<typename charT, typename traits> | |
155 std::basic_ostream<charT, traits>& | |
156 operator<<(std::basic_ostream<charT, traits>& os, const string& s) | |
157 { | |
158 if(s.kind == string_t::basic) | |
159 { | |
160 if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend()) | |
161 { | |
162 // it contains newline. make it multiline string. | |
163 os << "\"\"\"\n"; | |
164 for(auto i=s.str.cbegin(), e=s.str.cend(); i!=e; ++i) | |
165 { | |
166 switch(*i) | |
167 { | |
168 case '\\': {os << "\\\\"; break;} | |
169 case '\"': {os << "\\\""; break;} | |
170 case '\b': {os << "\\b"; break;} | |
171 case '\t': {os << "\\t"; break;} | |
172 case '\f': {os << "\\f"; break;} | |
173 case '\n': {os << '\n'; break;} | |
174 case '\r': | |
175 { | |
176 // since it is a multiline string, | |
177 // CRLF is not needed to be escaped. | |
178 if(std::next(i) != e && *std::next(i) == '\n') | |
179 { | |
180 os << "\r\n"; | |
181 ++i; | |
182 } | |
183 else | |
184 { | |
185 os << "\\r"; | |
186 } | |
187 break; | |
188 } | |
189 default: {os << *i; break;} | |
190 } | |
191 } | |
192 os << "\\\n\"\"\""; | |
193 return os; | |
194 } | |
195 // no newline. make it inline. | |
196 os << "\""; | |
197 for(const auto c : s.str) | |
198 { | |
199 switch(c) | |
200 { | |
201 case '\\': {os << "\\\\"; break;} | |
202 case '\"': {os << "\\\""; break;} | |
203 case '\b': {os << "\\b"; break;} | |
204 case '\t': {os << "\\t"; break;} | |
205 case '\f': {os << "\\f"; break;} | |
206 case '\n': {os << "\\n"; break;} | |
207 case '\r': {os << "\\r"; break;} | |
208 default : {os << c; break;} | |
209 } | |
210 } | |
211 os << "\""; | |
212 return os; | |
213 } | |
214 // the string `s` is literal-string. | |
215 if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() || | |
216 std::find(s.str.cbegin(), s.str.cend(), '\'') != s.str.cend() ) | |
217 { | |
218 // contains newline or single quote. make it multiline. | |
219 os << "'''\n" << s.str << "'''"; | |
220 return os; | |
221 } | |
222 // normal literal string | |
223 os << '\'' << s.str << '\''; | |
224 return os; | |
225 } | |
226 | |
227 } // toml | |
228 #endif// TOML11_STRING_H |