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 |
