Mercurial > minori
comparison dep/toml11/toml/value.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_VALUE_HPP | |
| 4 #define TOML11_VALUE_HPP | |
| 5 #include <cassert> | |
| 6 | |
| 7 #include "comments.hpp" | |
| 8 #include "exception.hpp" | |
| 9 #include "into.hpp" | |
| 10 #include "region.hpp" | |
| 11 #include "source_location.hpp" | |
| 12 #include "storage.hpp" | |
| 13 #include "traits.hpp" | |
| 14 #include "types.hpp" | |
| 15 #include "utility.hpp" | |
| 16 | |
| 17 namespace toml | |
| 18 { | |
| 19 | |
| 20 namespace detail | |
| 21 { | |
| 22 | |
| 23 // to show error messages. not recommended for users. | |
| 24 template<typename Value> | |
| 25 inline region_base const* get_region(const Value& v) | |
| 26 { | |
| 27 return v.region_info_.get(); | |
| 28 } | |
| 29 | |
| 30 template<typename Value> | |
| 31 void change_region(Value& v, region reg) | |
| 32 { | |
| 33 v.region_info_ = std::make_shared<region>(std::move(reg)); | |
| 34 return; | |
| 35 } | |
| 36 | |
| 37 template<value_t Expected, typename Value> | |
| 38 [[noreturn]] inline void | |
| 39 throw_bad_cast(const std::string& funcname, value_t actual, const Value& v) | |
| 40 { | |
| 41 throw type_error(detail::format_underline( | |
| 42 concat_to_string(funcname, "bad_cast to ", Expected), { | |
| 43 {v.location(), concat_to_string("the actual type is ", actual)} | |
| 44 }), v.location()); | |
| 45 } | |
| 46 | |
| 47 // Throw `out_of_range` from `toml::value::at()` and `toml::find()` | |
| 48 // after generating an error message. | |
| 49 // | |
| 50 // The implementation is a bit complicated and there are many edge-cases. | |
| 51 // If you are not interested in the error message generation, just skip this. | |
| 52 template<typename Value> | |
| 53 [[noreturn]] void | |
| 54 throw_key_not_found_error(const Value& v, const key& ky) | |
| 55 { | |
| 56 // The top-level table has its region at the first character of the file. | |
| 57 // That means that, in the case when a key is not found in the top-level | |
| 58 // table, the error message points to the first character. If the file has | |
| 59 // its first table at the first line, the error message would be like this. | |
| 60 // ```console | |
| 61 // [error] key "a" not found | |
| 62 // --> example.toml | |
| 63 // | | |
| 64 // 1 | [table] | |
| 65 // | ^------ in this table | |
| 66 // ``` | |
| 67 // It actually points to the top-level table at the first character, | |
| 68 // not `[table]`. But it is too confusing. To avoid the confusion, the error | |
| 69 // message should explicitly say "key not found in the top-level table", | |
| 70 // or "the parsed file is empty" if there is no content at all (0 bytes in file). | |
| 71 const auto loc = v.location(); | |
| 72 if(loc.line() == 1 && loc.region() == 0) | |
| 73 { | |
| 74 // First line with a zero-length region means "empty file". | |
| 75 // The region will be generated at `parse_toml_file` function | |
| 76 // if the file contains no bytes. | |
| 77 throw std::out_of_range(format_underline(concat_to_string( | |
| 78 "key \"", ky, "\" not found in the top-level table"), { | |
| 79 {loc, "the parsed file is empty"} | |
| 80 })); | |
| 81 } | |
| 82 else if(loc.line() == 1 && loc.region() == 1) | |
| 83 { | |
| 84 // Here it assumes that top-level table starts at the first character. | |
| 85 // The region corresponds to the top-level table will be generated at | |
| 86 // `parse_toml_file` function. | |
| 87 // It also assumes that the top-level table size is just one and | |
| 88 // the line number is `1`. It is always satisfied. And those conditions | |
| 89 // are satisfied only if the table is the top-level table. | |
| 90 // | |
| 91 // 1. one-character dot-key at the first line | |
| 92 // ```toml | |
| 93 // a.b = "c" | |
| 94 // ``` | |
| 95 // toml11 counts whole key as the table key. Here, `a.b` is the region | |
| 96 // of the table "a". It could be counter intuitive, but it works. | |
| 97 // The size of the region is 3, not 1. The above example is the shortest | |
| 98 // dot-key example. The size cannot be 1. | |
| 99 // | |
| 100 // 2. one-character inline-table at the first line | |
| 101 // ```toml | |
| 102 // a = {b = "c"} | |
| 103 // ``` | |
| 104 // toml11 considers the inline table body as the table region. Here, | |
| 105 // `{b = "c"}` is the region of the table "a". The size of the region | |
| 106 // is 9, not 1. The shotest inline table still has two characters, `{` | |
| 107 // and `}`. The size cannot be 1. | |
| 108 // | |
| 109 // 3. one-character table declaration at the first line | |
| 110 // ```toml | |
| 111 // [a] | |
| 112 // ``` | |
| 113 // toml11 considers the whole table key as the table region. Here, | |
| 114 // `[a]` is the table region. The size is 3, not 1. | |
| 115 // | |
| 116 throw std::out_of_range(format_underline(concat_to_string( | |
| 117 "key \"", ky, "\" not found in the top-level table"), { | |
| 118 {loc, "the top-level table starts here"} | |
| 119 })); | |
| 120 } | |
| 121 else | |
| 122 { | |
| 123 // normal table. | |
| 124 throw std::out_of_range(format_underline(concat_to_string( | |
| 125 "key \"", ky, "\" not found"), { {loc, "in this table"} })); | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 // switch by `value_t` at the compile time. | |
| 130 template<value_t T> | |
| 131 struct switch_cast {}; | |
| 132 #define TOML11_GENERATE_SWITCH_CASTER(TYPE) \ | |
| 133 template<> \ | |
| 134 struct switch_cast<value_t::TYPE> \ | |
| 135 { \ | |
| 136 template<typename Value> \ | |
| 137 static typename Value::TYPE##_type& invoke(Value& v) \ | |
| 138 { \ | |
| 139 return v.as_##TYPE(); \ | |
| 140 } \ | |
| 141 template<typename Value> \ | |
| 142 static typename Value::TYPE##_type const& invoke(const Value& v) \ | |
| 143 { \ | |
| 144 return v.as_##TYPE(); \ | |
| 145 } \ | |
| 146 template<typename Value> \ | |
| 147 static typename Value::TYPE##_type&& invoke(Value&& v) \ | |
| 148 { \ | |
| 149 return std::move(v).as_##TYPE(); \ | |
| 150 } \ | |
| 151 }; \ | |
| 152 /**/ | |
| 153 TOML11_GENERATE_SWITCH_CASTER(boolean) | |
| 154 TOML11_GENERATE_SWITCH_CASTER(integer) | |
| 155 TOML11_GENERATE_SWITCH_CASTER(floating) | |
| 156 TOML11_GENERATE_SWITCH_CASTER(string) | |
| 157 TOML11_GENERATE_SWITCH_CASTER(offset_datetime) | |
| 158 TOML11_GENERATE_SWITCH_CASTER(local_datetime) | |
| 159 TOML11_GENERATE_SWITCH_CASTER(local_date) | |
| 160 TOML11_GENERATE_SWITCH_CASTER(local_time) | |
| 161 TOML11_GENERATE_SWITCH_CASTER(array) | |
| 162 TOML11_GENERATE_SWITCH_CASTER(table) | |
| 163 | |
| 164 #undef TOML11_GENERATE_SWITCH_CASTER | |
| 165 | |
| 166 }// detail | |
| 167 | |
| 168 template<typename Comment, // discard/preserve_comment | |
| 169 template<typename ...> class Table = std::unordered_map, | |
| 170 template<typename ...> class Array = std::vector> | |
| 171 class basic_value | |
| 172 { | |
| 173 template<typename T, typename U> | |
| 174 static void assigner(T& dst, U&& v) | |
| 175 { | |
| 176 const auto tmp = ::new(std::addressof(dst)) T(std::forward<U>(v)); | |
| 177 assert(tmp == std::addressof(dst)); | |
| 178 (void)tmp; | |
| 179 } | |
| 180 | |
| 181 using region_base = detail::region_base; | |
| 182 | |
| 183 template<typename C, template<typename ...> class T, | |
| 184 template<typename ...> class A> | |
| 185 friend class basic_value; | |
| 186 | |
| 187 public: | |
| 188 | |
| 189 using comment_type = Comment; | |
| 190 using key_type = ::toml::key; | |
| 191 using value_type = basic_value<comment_type, Table, Array>; | |
| 192 using boolean_type = ::toml::boolean; | |
| 193 using integer_type = ::toml::integer; | |
| 194 using floating_type = ::toml::floating; | |
| 195 using string_type = ::toml::string; | |
| 196 using local_time_type = ::toml::local_time; | |
| 197 using local_date_type = ::toml::local_date; | |
| 198 using local_datetime_type = ::toml::local_datetime; | |
| 199 using offset_datetime_type = ::toml::offset_datetime; | |
| 200 using array_type = Array<value_type>; | |
| 201 using table_type = Table<key_type, value_type>; | |
| 202 | |
| 203 public: | |
| 204 | |
| 205 basic_value() noexcept | |
| 206 : type_(value_t::empty), | |
| 207 region_info_(std::make_shared<region_base>(region_base{})) | |
| 208 {} | |
| 209 ~basic_value() noexcept {this->cleanup();} | |
| 210 | |
| 211 basic_value(const basic_value& v) | |
| 212 : type_(v.type()), region_info_(v.region_info_), comments_(v.comments_) | |
| 213 { | |
| 214 switch(v.type()) | |
| 215 { | |
| 216 case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; | |
| 217 case value_t::integer : assigner(integer_ , v.integer_ ); break; | |
| 218 case value_t::floating : assigner(floating_ , v.floating_ ); break; | |
| 219 case value_t::string : assigner(string_ , v.string_ ); break; | |
| 220 case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; | |
| 221 case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; | |
| 222 case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; | |
| 223 case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; | |
| 224 case value_t::array : assigner(array_ , v.array_ ); break; | |
| 225 case value_t::table : assigner(table_ , v.table_ ); break; | |
| 226 default: break; | |
| 227 } | |
| 228 } | |
| 229 basic_value(basic_value&& v) | |
| 230 : type_(v.type()), region_info_(std::move(v.region_info_)), | |
| 231 comments_(std::move(v.comments_)) | |
| 232 { | |
| 233 switch(this->type_) // here this->type_ is already initialized | |
| 234 { | |
| 235 case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; | |
| 236 case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; | |
| 237 case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; | |
| 238 case value_t::string : assigner(string_ , std::move(v.string_ )); break; | |
| 239 case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; | |
| 240 case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; | |
| 241 case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; | |
| 242 case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; | |
| 243 case value_t::array : assigner(array_ , std::move(v.array_ )); break; | |
| 244 case value_t::table : assigner(table_ , std::move(v.table_ )); break; | |
| 245 default: break; | |
| 246 } | |
| 247 } | |
| 248 basic_value& operator=(const basic_value& v) | |
| 249 { | |
| 250 if(this == std::addressof(v)) {return *this;} | |
| 251 this->cleanup(); | |
| 252 this->region_info_ = v.region_info_; | |
| 253 this->comments_ = v.comments_; | |
| 254 this->type_ = v.type(); | |
| 255 switch(this->type_) | |
| 256 { | |
| 257 case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; | |
| 258 case value_t::integer : assigner(integer_ , v.integer_ ); break; | |
| 259 case value_t::floating : assigner(floating_ , v.floating_ ); break; | |
| 260 case value_t::string : assigner(string_ , v.string_ ); break; | |
| 261 case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; | |
| 262 case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; | |
| 263 case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; | |
| 264 case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; | |
| 265 case value_t::array : assigner(array_ , v.array_ ); break; | |
| 266 case value_t::table : assigner(table_ , v.table_ ); break; | |
| 267 default: break; | |
| 268 } | |
| 269 return *this; | |
| 270 } | |
| 271 basic_value& operator=(basic_value&& v) | |
| 272 { | |
| 273 if(this == std::addressof(v)) {return *this;} | |
| 274 this->cleanup(); | |
| 275 this->region_info_ = std::move(v.region_info_); | |
| 276 this->comments_ = std::move(v.comments_); | |
| 277 this->type_ = v.type(); | |
| 278 switch(this->type_) | |
| 279 { | |
| 280 case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; | |
| 281 case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; | |
| 282 case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; | |
| 283 case value_t::string : assigner(string_ , std::move(v.string_ )); break; | |
| 284 case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; | |
| 285 case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; | |
| 286 case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; | |
| 287 case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; | |
| 288 case value_t::array : assigner(array_ , std::move(v.array_ )); break; | |
| 289 case value_t::table : assigner(table_ , std::move(v.table_ )); break; | |
| 290 default: break; | |
| 291 } | |
| 292 return *this; | |
| 293 } | |
| 294 | |
| 295 // overwrite comments ---------------------------------------------------- | |
| 296 | |
| 297 basic_value(const basic_value& v, std::vector<std::string> com) | |
| 298 : type_(v.type()), region_info_(v.region_info_), | |
| 299 comments_(std::move(com)) | |
| 300 { | |
| 301 switch(v.type()) | |
| 302 { | |
| 303 case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; | |
| 304 case value_t::integer : assigner(integer_ , v.integer_ ); break; | |
| 305 case value_t::floating : assigner(floating_ , v.floating_ ); break; | |
| 306 case value_t::string : assigner(string_ , v.string_ ); break; | |
| 307 case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; | |
| 308 case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; | |
| 309 case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; | |
| 310 case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; | |
| 311 case value_t::array : assigner(array_ , v.array_ ); break; | |
| 312 case value_t::table : assigner(table_ , v.table_ ); break; | |
| 313 default: break; | |
| 314 } | |
| 315 } | |
| 316 | |
| 317 basic_value(basic_value&& v, std::vector<std::string> com) | |
| 318 : type_(v.type()), region_info_(std::move(v.region_info_)), | |
| 319 comments_(std::move(com)) | |
| 320 { | |
| 321 switch(this->type_) // here this->type_ is already initialized | |
| 322 { | |
| 323 case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; | |
| 324 case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; | |
| 325 case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; | |
| 326 case value_t::string : assigner(string_ , std::move(v.string_ )); break; | |
| 327 case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; | |
| 328 case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; | |
| 329 case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; | |
| 330 case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; | |
| 331 case value_t::array : assigner(array_ , std::move(v.array_ )); break; | |
| 332 case value_t::table : assigner(table_ , std::move(v.table_ )); break; | |
| 333 default: break; | |
| 334 } | |
| 335 } | |
| 336 | |
| 337 // ----------------------------------------------------------------------- | |
| 338 // conversion between different basic_values. | |
| 339 template<typename C, | |
| 340 template<typename ...> class T, | |
| 341 template<typename ...> class A> | |
| 342 basic_value(const basic_value<C, T, A>& v) | |
| 343 : type_(v.type()), region_info_(v.region_info_), comments_(v.comments()) | |
| 344 { | |
| 345 switch(v.type()) | |
| 346 { | |
| 347 case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; | |
| 348 case value_t::integer : assigner(integer_ , v.integer_ ); break; | |
| 349 case value_t::floating : assigner(floating_ , v.floating_ ); break; | |
| 350 case value_t::string : assigner(string_ , v.string_ ); break; | |
| 351 case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; | |
| 352 case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; | |
| 353 case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; | |
| 354 case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; | |
| 355 case value_t::array : | |
| 356 { | |
| 357 array_type tmp(v.as_array(std::nothrow).begin(), | |
| 358 v.as_array(std::nothrow).end()); | |
| 359 assigner(array_, std::move(tmp)); | |
| 360 break; | |
| 361 } | |
| 362 case value_t::table : | |
| 363 { | |
| 364 table_type tmp(v.as_table(std::nothrow).begin(), | |
| 365 v.as_table(std::nothrow).end()); | |
| 366 assigner(table_, std::move(tmp)); | |
| 367 break; | |
| 368 } | |
| 369 default: break; | |
| 370 } | |
| 371 } | |
| 372 template<typename C, | |
| 373 template<typename ...> class T, | |
| 374 template<typename ...> class A> | |
| 375 basic_value(const basic_value<C, T, A>& v, std::vector<std::string> com) | |
| 376 : type_(v.type()), region_info_(v.region_info_), | |
| 377 comments_(std::move(com)) | |
| 378 { | |
| 379 switch(v.type()) | |
| 380 { | |
| 381 case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; | |
| 382 case value_t::integer : assigner(integer_ , v.integer_ ); break; | |
| 383 case value_t::floating : assigner(floating_ , v.floating_ ); break; | |
| 384 case value_t::string : assigner(string_ , v.string_ ); break; | |
| 385 case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; | |
| 386 case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; | |
| 387 case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; | |
| 388 case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; | |
| 389 case value_t::array : | |
| 390 { | |
| 391 array_type tmp(v.as_array(std::nothrow).begin(), | |
| 392 v.as_array(std::nothrow).end()); | |
| 393 assigner(array_, std::move(tmp)); | |
| 394 break; | |
| 395 } | |
| 396 case value_t::table : | |
| 397 { | |
| 398 table_type tmp(v.as_table(std::nothrow).begin(), | |
| 399 v.as_table(std::nothrow).end()); | |
| 400 assigner(table_, std::move(tmp)); | |
| 401 break; | |
| 402 } | |
| 403 default: break; | |
| 404 } | |
| 405 } | |
| 406 template<typename C, | |
| 407 template<typename ...> class T, | |
| 408 template<typename ...> class A> | |
| 409 basic_value& operator=(const basic_value<C, T, A>& v) | |
| 410 { | |
| 411 this->region_info_ = v.region_info_; | |
| 412 this->comments_ = comment_type(v.comments()); | |
| 413 this->type_ = v.type(); | |
| 414 switch(v.type()) | |
| 415 { | |
| 416 case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; | |
| 417 case value_t::integer : assigner(integer_ , v.integer_ ); break; | |
| 418 case value_t::floating : assigner(floating_ , v.floating_ ); break; | |
| 419 case value_t::string : assigner(string_ , v.string_ ); break; | |
| 420 case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; | |
| 421 case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; | |
| 422 case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; | |
| 423 case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; | |
| 424 case value_t::array : | |
| 425 { | |
| 426 array_type tmp(v.as_array(std::nothrow).begin(), | |
| 427 v.as_array(std::nothrow).end()); | |
| 428 assigner(array_, std::move(tmp)); | |
| 429 break; | |
| 430 } | |
| 431 case value_t::table : | |
| 432 { | |
| 433 table_type tmp(v.as_table(std::nothrow).begin(), | |
| 434 v.as_table(std::nothrow).end()); | |
| 435 assigner(table_, std::move(tmp)); | |
| 436 break; | |
| 437 } | |
| 438 default: break; | |
| 439 } | |
| 440 return *this; | |
| 441 } | |
| 442 | |
| 443 // boolean ============================================================== | |
| 444 | |
| 445 basic_value(boolean b) | |
| 446 : type_(value_t::boolean), | |
| 447 region_info_(std::make_shared<region_base>(region_base{})) | |
| 448 { | |
| 449 assigner(this->boolean_, b); | |
| 450 } | |
| 451 basic_value& operator=(boolean b) | |
| 452 { | |
| 453 this->cleanup(); | |
| 454 this->type_ = value_t::boolean; | |
| 455 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 456 assigner(this->boolean_, b); | |
| 457 return *this; | |
| 458 } | |
| 459 basic_value(boolean b, std::vector<std::string> com) | |
| 460 : type_(value_t::boolean), | |
| 461 region_info_(std::make_shared<region_base>(region_base{})), | |
| 462 comments_(std::move(com)) | |
| 463 { | |
| 464 assigner(this->boolean_, b); | |
| 465 } | |
| 466 | |
| 467 // integer ============================================================== | |
| 468 | |
| 469 template<typename T, typename std::enable_if<detail::conjunction< | |
| 470 std::is_integral<T>, detail::negation<std::is_same<T, boolean>>>::value, | |
| 471 std::nullptr_t>::type = nullptr> | |
| 472 basic_value(T i) | |
| 473 : type_(value_t::integer), | |
| 474 region_info_(std::make_shared<region_base>(region_base{})) | |
| 475 { | |
| 476 assigner(this->integer_, static_cast<integer>(i)); | |
| 477 } | |
| 478 | |
| 479 template<typename T, typename std::enable_if<detail::conjunction< | |
| 480 std::is_integral<T>, detail::negation<std::is_same<T, boolean>>>::value, | |
| 481 std::nullptr_t>::type = nullptr> | |
| 482 basic_value& operator=(T i) | |
| 483 { | |
| 484 this->cleanup(); | |
| 485 this->type_ = value_t::integer; | |
| 486 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 487 assigner(this->integer_, static_cast<integer>(i)); | |
| 488 return *this; | |
| 489 } | |
| 490 | |
| 491 template<typename T, typename std::enable_if<detail::conjunction< | |
| 492 std::is_integral<T>, detail::negation<std::is_same<T, boolean>>>::value, | |
| 493 std::nullptr_t>::type = nullptr> | |
| 494 basic_value(T i, std::vector<std::string> com) | |
| 495 : type_(value_t::integer), | |
| 496 region_info_(std::make_shared<region_base>(region_base{})), | |
| 497 comments_(std::move(com)) | |
| 498 { | |
| 499 assigner(this->integer_, static_cast<integer>(i)); | |
| 500 } | |
| 501 | |
| 502 // floating ============================================================= | |
| 503 | |
| 504 template<typename T, typename std::enable_if< | |
| 505 std::is_floating_point<T>::value, std::nullptr_t>::type = nullptr> | |
| 506 basic_value(T f) | |
| 507 : type_(value_t::floating), | |
| 508 region_info_(std::make_shared<region_base>(region_base{})) | |
| 509 { | |
| 510 assigner(this->floating_, static_cast<floating>(f)); | |
| 511 } | |
| 512 | |
| 513 | |
| 514 template<typename T, typename std::enable_if< | |
| 515 std::is_floating_point<T>::value, std::nullptr_t>::type = nullptr> | |
| 516 basic_value& operator=(T f) | |
| 517 { | |
| 518 this->cleanup(); | |
| 519 this->type_ = value_t::floating; | |
| 520 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 521 assigner(this->floating_, static_cast<floating>(f)); | |
| 522 return *this; | |
| 523 } | |
| 524 | |
| 525 template<typename T, typename std::enable_if< | |
| 526 std::is_floating_point<T>::value, std::nullptr_t>::type = nullptr> | |
| 527 basic_value(T f, std::vector<std::string> com) | |
| 528 : type_(value_t::floating), | |
| 529 region_info_(std::make_shared<region_base>(region_base{})), | |
| 530 comments_(std::move(com)) | |
| 531 { | |
| 532 assigner(this->floating_, f); | |
| 533 } | |
| 534 | |
| 535 // string =============================================================== | |
| 536 | |
| 537 basic_value(toml::string s) | |
| 538 : type_(value_t::string), | |
| 539 region_info_(std::make_shared<region_base>(region_base{})) | |
| 540 { | |
| 541 assigner(this->string_, std::move(s)); | |
| 542 } | |
| 543 basic_value& operator=(toml::string s) | |
| 544 { | |
| 545 this->cleanup(); | |
| 546 this->type_ = value_t::string ; | |
| 547 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 548 assigner(this->string_, s); | |
| 549 return *this; | |
| 550 } | |
| 551 basic_value(toml::string s, std::vector<std::string> com) | |
| 552 : type_(value_t::string), | |
| 553 region_info_(std::make_shared<region_base>(region_base{})), | |
| 554 comments_(std::move(com)) | |
| 555 { | |
| 556 assigner(this->string_, std::move(s)); | |
| 557 } | |
| 558 | |
| 559 basic_value(std::string s) | |
| 560 : type_(value_t::string), | |
| 561 region_info_(std::make_shared<region_base>(region_base{})) | |
| 562 { | |
| 563 assigner(this->string_, toml::string(std::move(s))); | |
| 564 } | |
| 565 basic_value& operator=(std::string s) | |
| 566 { | |
| 567 this->cleanup(); | |
| 568 this->type_ = value_t::string ; | |
| 569 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 570 assigner(this->string_, toml::string(std::move(s))); | |
| 571 return *this; | |
| 572 } | |
| 573 basic_value(std::string s, string_t kind) | |
| 574 : type_(value_t::string), | |
| 575 region_info_(std::make_shared<region_base>(region_base{})) | |
| 576 { | |
| 577 assigner(this->string_, toml::string(std::move(s), kind)); | |
| 578 } | |
| 579 basic_value(std::string s, std::vector<std::string> com) | |
| 580 : type_(value_t::string), | |
| 581 region_info_(std::make_shared<region_base>(region_base{})), | |
| 582 comments_(std::move(com)) | |
| 583 { | |
| 584 assigner(this->string_, toml::string(std::move(s))); | |
| 585 } | |
| 586 basic_value(std::string s, string_t kind, std::vector<std::string> com) | |
| 587 : type_(value_t::string), | |
| 588 region_info_(std::make_shared<region_base>(region_base{})), | |
| 589 comments_(std::move(com)) | |
| 590 { | |
| 591 assigner(this->string_, toml::string(std::move(s), kind)); | |
| 592 } | |
| 593 | |
| 594 basic_value(const char* s) | |
| 595 : type_(value_t::string), | |
| 596 region_info_(std::make_shared<region_base>(region_base{})) | |
| 597 { | |
| 598 assigner(this->string_, toml::string(std::string(s))); | |
| 599 } | |
| 600 basic_value& operator=(const char* s) | |
| 601 { | |
| 602 this->cleanup(); | |
| 603 this->type_ = value_t::string ; | |
| 604 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 605 assigner(this->string_, toml::string(std::string(s))); | |
| 606 return *this; | |
| 607 } | |
| 608 basic_value(const char* s, string_t kind) | |
| 609 : type_(value_t::string), | |
| 610 region_info_(std::make_shared<region_base>(region_base{})) | |
| 611 { | |
| 612 assigner(this->string_, toml::string(std::string(s), kind)); | |
| 613 } | |
| 614 basic_value(const char* s, std::vector<std::string> com) | |
| 615 : type_(value_t::string), | |
| 616 region_info_(std::make_shared<region_base>(region_base{})), | |
| 617 comments_(std::move(com)) | |
| 618 { | |
| 619 assigner(this->string_, toml::string(std::string(s))); | |
| 620 } | |
| 621 basic_value(const char* s, string_t kind, std::vector<std::string> com) | |
| 622 : type_(value_t::string), | |
| 623 region_info_(std::make_shared<region_base>(region_base{})), | |
| 624 comments_(std::move(com)) | |
| 625 { | |
| 626 assigner(this->string_, toml::string(std::string(s), kind)); | |
| 627 } | |
| 628 | |
| 629 #if defined(TOML11_USING_STRING_VIEW) && TOML11_USING_STRING_VIEW>0 | |
| 630 basic_value(std::string_view s) | |
| 631 : type_(value_t::string), | |
| 632 region_info_(std::make_shared<region_base>(region_base{})) | |
| 633 { | |
| 634 assigner(this->string_, toml::string(s)); | |
| 635 } | |
| 636 basic_value& operator=(std::string_view s) | |
| 637 { | |
| 638 this->cleanup(); | |
| 639 this->type_ = value_t::string ; | |
| 640 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 641 assigner(this->string_, toml::string(s)); | |
| 642 return *this; | |
| 643 } | |
| 644 basic_value(std::string_view s, std::vector<std::string> com) | |
| 645 : type_(value_t::string), | |
| 646 region_info_(std::make_shared<region_base>(region_base{})), | |
| 647 comments_(std::move(com)) | |
| 648 { | |
| 649 assigner(this->string_, toml::string(s)); | |
| 650 } | |
| 651 basic_value(std::string_view s, string_t kind) | |
| 652 : type_(value_t::string), | |
| 653 region_info_(std::make_shared<region_base>(region_base{})) | |
| 654 { | |
| 655 assigner(this->string_, toml::string(s, kind)); | |
| 656 } | |
| 657 basic_value(std::string_view s, string_t kind, std::vector<std::string> com) | |
| 658 : type_(value_t::string), | |
| 659 region_info_(std::make_shared<region_base>(region_base{})), | |
| 660 comments_(std::move(com)) | |
| 661 { | |
| 662 assigner(this->string_, toml::string(s, kind)); | |
| 663 } | |
| 664 #endif | |
| 665 | |
| 666 // local date =========================================================== | |
| 667 | |
| 668 basic_value(const local_date& ld) | |
| 669 : type_(value_t::local_date), | |
| 670 region_info_(std::make_shared<region_base>(region_base{})) | |
| 671 { | |
| 672 assigner(this->local_date_, ld); | |
| 673 } | |
| 674 basic_value& operator=(const local_date& ld) | |
| 675 { | |
| 676 this->cleanup(); | |
| 677 this->type_ = value_t::local_date; | |
| 678 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 679 assigner(this->local_date_, ld); | |
| 680 return *this; | |
| 681 } | |
| 682 basic_value(const local_date& ld, std::vector<std::string> com) | |
| 683 : type_(value_t::local_date), | |
| 684 region_info_(std::make_shared<region_base>(region_base{})), | |
| 685 comments_(std::move(com)) | |
| 686 { | |
| 687 assigner(this->local_date_, ld); | |
| 688 } | |
| 689 | |
| 690 // local time =========================================================== | |
| 691 | |
| 692 basic_value(const local_time& lt) | |
| 693 : type_(value_t::local_time), | |
| 694 region_info_(std::make_shared<region_base>(region_base{})) | |
| 695 { | |
| 696 assigner(this->local_time_, lt); | |
| 697 } | |
| 698 basic_value(const local_time& lt, std::vector<std::string> com) | |
| 699 : type_(value_t::local_time), | |
| 700 region_info_(std::make_shared<region_base>(region_base{})), | |
| 701 comments_(std::move(com)) | |
| 702 { | |
| 703 assigner(this->local_time_, lt); | |
| 704 } | |
| 705 basic_value& operator=(const local_time& lt) | |
| 706 { | |
| 707 this->cleanup(); | |
| 708 this->type_ = value_t::local_time; | |
| 709 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 710 assigner(this->local_time_, lt); | |
| 711 return *this; | |
| 712 } | |
| 713 | |
| 714 template<typename Rep, typename Period> | |
| 715 basic_value(const std::chrono::duration<Rep, Period>& dur) | |
| 716 : type_(value_t::local_time), | |
| 717 region_info_(std::make_shared<region_base>(region_base{})) | |
| 718 { | |
| 719 assigner(this->local_time_, local_time(dur)); | |
| 720 } | |
| 721 template<typename Rep, typename Period> | |
| 722 basic_value(const std::chrono::duration<Rep, Period>& dur, | |
| 723 std::vector<std::string> com) | |
| 724 : type_(value_t::local_time), | |
| 725 region_info_(std::make_shared<region_base>(region_base{})), | |
| 726 comments_(std::move(com)) | |
| 727 { | |
| 728 assigner(this->local_time_, local_time(dur)); | |
| 729 } | |
| 730 template<typename Rep, typename Period> | |
| 731 basic_value& operator=(const std::chrono::duration<Rep, Period>& dur) | |
| 732 { | |
| 733 this->cleanup(); | |
| 734 this->type_ = value_t::local_time; | |
| 735 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 736 assigner(this->local_time_, local_time(dur)); | |
| 737 return *this; | |
| 738 } | |
| 739 | |
| 740 // local datetime ======================================================= | |
| 741 | |
| 742 basic_value(const local_datetime& ldt) | |
| 743 : type_(value_t::local_datetime), | |
| 744 region_info_(std::make_shared<region_base>(region_base{})) | |
| 745 { | |
| 746 assigner(this->local_datetime_, ldt); | |
| 747 } | |
| 748 basic_value(const local_datetime& ldt, std::vector<std::string> com) | |
| 749 : type_(value_t::local_datetime), | |
| 750 region_info_(std::make_shared<region_base>(region_base{})), | |
| 751 comments_(std::move(com)) | |
| 752 { | |
| 753 assigner(this->local_datetime_, ldt); | |
| 754 } | |
| 755 basic_value& operator=(const local_datetime& ldt) | |
| 756 { | |
| 757 this->cleanup(); | |
| 758 this->type_ = value_t::local_datetime; | |
| 759 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 760 assigner(this->local_datetime_, ldt); | |
| 761 return *this; | |
| 762 } | |
| 763 | |
| 764 // offset datetime ====================================================== | |
| 765 | |
| 766 basic_value(const offset_datetime& odt) | |
| 767 : type_(value_t::offset_datetime), | |
| 768 region_info_(std::make_shared<region_base>(region_base{})) | |
| 769 { | |
| 770 assigner(this->offset_datetime_, odt); | |
| 771 } | |
| 772 basic_value(const offset_datetime& odt, std::vector<std::string> com) | |
| 773 : type_(value_t::offset_datetime), | |
| 774 region_info_(std::make_shared<region_base>(region_base{})), | |
| 775 comments_(std::move(com)) | |
| 776 { | |
| 777 assigner(this->offset_datetime_, odt); | |
| 778 } | |
| 779 basic_value& operator=(const offset_datetime& odt) | |
| 780 { | |
| 781 this->cleanup(); | |
| 782 this->type_ = value_t::offset_datetime; | |
| 783 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 784 assigner(this->offset_datetime_, odt); | |
| 785 return *this; | |
| 786 } | |
| 787 basic_value(const std::chrono::system_clock::time_point& tp) | |
| 788 : type_(value_t::offset_datetime), | |
| 789 region_info_(std::make_shared<region_base>(region_base{})) | |
| 790 { | |
| 791 assigner(this->offset_datetime_, offset_datetime(tp)); | |
| 792 } | |
| 793 basic_value(const std::chrono::system_clock::time_point& tp, | |
| 794 std::vector<std::string> com) | |
| 795 : type_(value_t::offset_datetime), | |
| 796 region_info_(std::make_shared<region_base>(region_base{})), | |
| 797 comments_(std::move(com)) | |
| 798 { | |
| 799 assigner(this->offset_datetime_, offset_datetime(tp)); | |
| 800 } | |
| 801 basic_value& operator=(const std::chrono::system_clock::time_point& tp) | |
| 802 { | |
| 803 this->cleanup(); | |
| 804 this->type_ = value_t::offset_datetime; | |
| 805 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 806 assigner(this->offset_datetime_, offset_datetime(tp)); | |
| 807 return *this; | |
| 808 } | |
| 809 | |
| 810 // array ================================================================ | |
| 811 | |
| 812 basic_value(const array_type& ary) | |
| 813 : type_(value_t::array), | |
| 814 region_info_(std::make_shared<region_base>(region_base{})) | |
| 815 { | |
| 816 assigner(this->array_, ary); | |
| 817 } | |
| 818 basic_value(const array_type& ary, std::vector<std::string> com) | |
| 819 : type_(value_t::array), | |
| 820 region_info_(std::make_shared<region_base>(region_base{})), | |
| 821 comments_(std::move(com)) | |
| 822 { | |
| 823 assigner(this->array_, ary); | |
| 824 } | |
| 825 basic_value& operator=(const array_type& ary) | |
| 826 { | |
| 827 this->cleanup(); | |
| 828 this->type_ = value_t::array ; | |
| 829 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 830 assigner(this->array_, ary); | |
| 831 return *this; | |
| 832 } | |
| 833 | |
| 834 // array (initializer_list) ---------------------------------------------- | |
| 835 | |
| 836 template<typename T, typename std::enable_if< | |
| 837 std::is_convertible<T, value_type>::value, | |
| 838 std::nullptr_t>::type = nullptr> | |
| 839 basic_value(std::initializer_list<T> list) | |
| 840 : type_(value_t::array), | |
| 841 region_info_(std::make_shared<region_base>(region_base{})) | |
| 842 { | |
| 843 array_type ary(list.begin(), list.end()); | |
| 844 assigner(this->array_, std::move(ary)); | |
| 845 } | |
| 846 template<typename T, typename std::enable_if< | |
| 847 std::is_convertible<T, value_type>::value, | |
| 848 std::nullptr_t>::type = nullptr> | |
| 849 basic_value(std::initializer_list<T> list, std::vector<std::string> com) | |
| 850 : type_(value_t::array), | |
| 851 region_info_(std::make_shared<region_base>(region_base{})), | |
| 852 comments_(std::move(com)) | |
| 853 { | |
| 854 array_type ary(list.begin(), list.end()); | |
| 855 assigner(this->array_, std::move(ary)); | |
| 856 } | |
| 857 template<typename T, typename std::enable_if< | |
| 858 std::is_convertible<T, value_type>::value, | |
| 859 std::nullptr_t>::type = nullptr> | |
| 860 basic_value& operator=(std::initializer_list<T> list) | |
| 861 { | |
| 862 this->cleanup(); | |
| 863 this->type_ = value_t::array; | |
| 864 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 865 | |
| 866 array_type ary(list.begin(), list.end()); | |
| 867 assigner(this->array_, std::move(ary)); | |
| 868 return *this; | |
| 869 } | |
| 870 | |
| 871 // array (STL Containers) ------------------------------------------------ | |
| 872 | |
| 873 template<typename T, typename std::enable_if<detail::conjunction< | |
| 874 detail::negation<std::is_same<T, array_type>>, | |
| 875 detail::is_container<T> | |
| 876 >::value, std::nullptr_t>::type = nullptr> | |
| 877 basic_value(const T& list) | |
| 878 : type_(value_t::array), | |
| 879 region_info_(std::make_shared<region_base>(region_base{})) | |
| 880 { | |
| 881 static_assert(std::is_convertible<typename T::value_type, value_type>::value, | |
| 882 "elements of a container should be convertible to toml::value"); | |
| 883 | |
| 884 array_type ary(list.size()); | |
| 885 std::copy(list.begin(), list.end(), ary.begin()); | |
| 886 assigner(this->array_, std::move(ary)); | |
| 887 } | |
| 888 template<typename T, typename std::enable_if<detail::conjunction< | |
| 889 detail::negation<std::is_same<T, array_type>>, | |
| 890 detail::is_container<T> | |
| 891 >::value, std::nullptr_t>::type = nullptr> | |
| 892 basic_value(const T& list, std::vector<std::string> com) | |
| 893 : type_(value_t::array), | |
| 894 region_info_(std::make_shared<region_base>(region_base{})), | |
| 895 comments_(std::move(com)) | |
| 896 { | |
| 897 static_assert(std::is_convertible<typename T::value_type, value_type>::value, | |
| 898 "elements of a container should be convertible to toml::value"); | |
| 899 | |
| 900 array_type ary(list.size()); | |
| 901 std::copy(list.begin(), list.end(), ary.begin()); | |
| 902 assigner(this->array_, std::move(ary)); | |
| 903 } | |
| 904 template<typename T, typename std::enable_if<detail::conjunction< | |
| 905 detail::negation<std::is_same<T, array_type>>, | |
| 906 detail::is_container<T> | |
| 907 >::value, std::nullptr_t>::type = nullptr> | |
| 908 basic_value& operator=(const T& list) | |
| 909 { | |
| 910 static_assert(std::is_convertible<typename T::value_type, value_type>::value, | |
| 911 "elements of a container should be convertible to toml::value"); | |
| 912 | |
| 913 this->cleanup(); | |
| 914 this->type_ = value_t::array; | |
| 915 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 916 | |
| 917 array_type ary(list.size()); | |
| 918 std::copy(list.begin(), list.end(), ary.begin()); | |
| 919 assigner(this->array_, std::move(ary)); | |
| 920 return *this; | |
| 921 } | |
| 922 | |
| 923 // table ================================================================ | |
| 924 | |
| 925 basic_value(const table_type& tab) | |
| 926 : type_(value_t::table), | |
| 927 region_info_(std::make_shared<region_base>(region_base{})) | |
| 928 { | |
| 929 assigner(this->table_, tab); | |
| 930 } | |
| 931 basic_value(const table_type& tab, std::vector<std::string> com) | |
| 932 : type_(value_t::table), | |
| 933 region_info_(std::make_shared<region_base>(region_base{})), | |
| 934 comments_(std::move(com)) | |
| 935 { | |
| 936 assigner(this->table_, tab); | |
| 937 } | |
| 938 basic_value& operator=(const table_type& tab) | |
| 939 { | |
| 940 this->cleanup(); | |
| 941 this->type_ = value_t::table; | |
| 942 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 943 assigner(this->table_, tab); | |
| 944 return *this; | |
| 945 } | |
| 946 | |
| 947 // initializer-list ------------------------------------------------------ | |
| 948 | |
| 949 basic_value(std::initializer_list<std::pair<key, basic_value>> list) | |
| 950 : type_(value_t::table), | |
| 951 region_info_(std::make_shared<region_base>(region_base{})) | |
| 952 { | |
| 953 table_type tab; | |
| 954 for(const auto& elem : list) {tab[elem.first] = elem.second;} | |
| 955 assigner(this->table_, std::move(tab)); | |
| 956 } | |
| 957 | |
| 958 basic_value(std::initializer_list<std::pair<key, basic_value>> list, | |
| 959 std::vector<std::string> com) | |
| 960 : type_(value_t::table), | |
| 961 region_info_(std::make_shared<region_base>(region_base{})), | |
| 962 comments_(std::move(com)) | |
| 963 { | |
| 964 table_type tab; | |
| 965 for(const auto& elem : list) {tab[elem.first] = elem.second;} | |
| 966 assigner(this->table_, std::move(tab)); | |
| 967 } | |
| 968 basic_value& operator=(std::initializer_list<std::pair<key, basic_value>> list) | |
| 969 { | |
| 970 this->cleanup(); | |
| 971 this->type_ = value_t::table; | |
| 972 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 973 | |
| 974 table_type tab; | |
| 975 for(const auto& elem : list) {tab[elem.first] = elem.second;} | |
| 976 assigner(this->table_, std::move(tab)); | |
| 977 return *this; | |
| 978 } | |
| 979 | |
| 980 // other table-like ----------------------------------------------------- | |
| 981 | |
| 982 template<typename Map, typename std::enable_if<detail::conjunction< | |
| 983 detail::negation<std::is_same<Map, table_type>>, | |
| 984 detail::is_map<Map> | |
| 985 >::value, std::nullptr_t>::type = nullptr> | |
| 986 basic_value(const Map& mp) | |
| 987 : type_(value_t::table), | |
| 988 region_info_(std::make_shared<region_base>(region_base{})) | |
| 989 { | |
| 990 table_type tab; | |
| 991 for(const auto& elem : mp) {tab[elem.first] = elem.second;} | |
| 992 assigner(this->table_, std::move(tab)); | |
| 993 } | |
| 994 template<typename Map, typename std::enable_if<detail::conjunction< | |
| 995 detail::negation<std::is_same<Map, table_type>>, | |
| 996 detail::is_map<Map> | |
| 997 >::value, std::nullptr_t>::type = nullptr> | |
| 998 basic_value(const Map& mp, std::vector<std::string> com) | |
| 999 : type_(value_t::table), | |
| 1000 region_info_(std::make_shared<region_base>(region_base{})), | |
| 1001 comments_(std::move(com)) | |
| 1002 { | |
| 1003 table_type tab; | |
| 1004 for(const auto& elem : mp) {tab[elem.first] = elem.second;} | |
| 1005 assigner(this->table_, std::move(tab)); | |
| 1006 } | |
| 1007 template<typename Map, typename std::enable_if<detail::conjunction< | |
| 1008 detail::negation<std::is_same<Map, table_type>>, | |
| 1009 detail::is_map<Map> | |
| 1010 >::value, std::nullptr_t>::type = nullptr> | |
| 1011 basic_value& operator=(const Map& mp) | |
| 1012 { | |
| 1013 this->cleanup(); | |
| 1014 this->type_ = value_t::table; | |
| 1015 this->region_info_ = std::make_shared<region_base>(region_base{}); | |
| 1016 | |
| 1017 table_type tab; | |
| 1018 for(const auto& elem : mp) {tab[elem.first] = elem.second;} | |
| 1019 assigner(this->table_, std::move(tab)); | |
| 1020 return *this; | |
| 1021 } | |
| 1022 | |
| 1023 // user-defined ========================================================= | |
| 1024 | |
| 1025 // convert using into_toml() method ------------------------------------- | |
| 1026 | |
| 1027 template<typename T, typename std::enable_if< | |
| 1028 detail::has_into_toml_method<T>::value, std::nullptr_t>::type = nullptr> | |
| 1029 basic_value(const T& ud): basic_value(ud.into_toml()) {} | |
| 1030 | |
| 1031 template<typename T, typename std::enable_if< | |
| 1032 detail::has_into_toml_method<T>::value, std::nullptr_t>::type = nullptr> | |
| 1033 basic_value(const T& ud, std::vector<std::string> com) | |
| 1034 : basic_value(ud.into_toml(), std::move(com)) | |
| 1035 {} | |
| 1036 template<typename T, typename std::enable_if< | |
| 1037 detail::has_into_toml_method<T>::value, std::nullptr_t>::type = nullptr> | |
| 1038 basic_value& operator=(const T& ud) | |
| 1039 { | |
| 1040 *this = ud.into_toml(); | |
| 1041 return *this; | |
| 1042 } | |
| 1043 | |
| 1044 // convert using into<T> struct ----------------------------------------- | |
| 1045 | |
| 1046 template<typename T, std::size_t S = sizeof(::toml::into<T>)> | |
| 1047 basic_value(const T& ud): basic_value(::toml::into<T>::into_toml(ud)) {} | |
| 1048 template<typename T, std::size_t S = sizeof(::toml::into<T>)> | |
| 1049 basic_value(const T& ud, std::vector<std::string> com) | |
| 1050 : basic_value(::toml::into<T>::into_toml(ud), std::move(com)) | |
| 1051 {} | |
| 1052 template<typename T, std::size_t S = sizeof(::toml::into<T>)> | |
| 1053 basic_value& operator=(const T& ud) | |
| 1054 { | |
| 1055 *this = ::toml::into<T>::into_toml(ud); | |
| 1056 return *this; | |
| 1057 } | |
| 1058 | |
| 1059 // for internal use ------------------------------------------------------ | |
| 1060 // | |
| 1061 // Those constructors take detail::region that contains parse result. | |
| 1062 | |
| 1063 basic_value(boolean b, detail::region reg, std::vector<std::string> cm) | |
| 1064 : type_(value_t::boolean), | |
| 1065 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1066 comments_(std::move(cm)) | |
| 1067 { | |
| 1068 assigner(this->boolean_, b); | |
| 1069 } | |
| 1070 template<typename T, typename std::enable_if< | |
| 1071 detail::conjunction< | |
| 1072 std::is_integral<T>, detail::negation<std::is_same<T, boolean>> | |
| 1073 >::value, std::nullptr_t>::type = nullptr> | |
| 1074 basic_value(T i, detail::region reg, std::vector<std::string> cm) | |
| 1075 : type_(value_t::integer), | |
| 1076 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1077 comments_(std::move(cm)) | |
| 1078 { | |
| 1079 assigner(this->integer_, static_cast<integer>(i)); | |
| 1080 } | |
| 1081 template<typename T, typename std::enable_if< | |
| 1082 std::is_floating_point<T>::value, std::nullptr_t>::type = nullptr> | |
| 1083 basic_value(T f, detail::region reg, std::vector<std::string> cm) | |
| 1084 : type_(value_t::floating), | |
| 1085 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1086 comments_(std::move(cm)) | |
| 1087 { | |
| 1088 assigner(this->floating_, static_cast<floating>(f)); | |
| 1089 } | |
| 1090 basic_value(toml::string s, detail::region reg, | |
| 1091 std::vector<std::string> cm) | |
| 1092 : type_(value_t::string), | |
| 1093 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1094 comments_(std::move(cm)) | |
| 1095 { | |
| 1096 assigner(this->string_, std::move(s)); | |
| 1097 } | |
| 1098 basic_value(const local_date& ld, detail::region reg, | |
| 1099 std::vector<std::string> cm) | |
| 1100 : type_(value_t::local_date), | |
| 1101 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1102 comments_(std::move(cm)) | |
| 1103 { | |
| 1104 assigner(this->local_date_, ld); | |
| 1105 } | |
| 1106 basic_value(const local_time& lt, detail::region reg, | |
| 1107 std::vector<std::string> cm) | |
| 1108 : type_(value_t::local_time), | |
| 1109 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1110 comments_(std::move(cm)) | |
| 1111 { | |
| 1112 assigner(this->local_time_, lt); | |
| 1113 } | |
| 1114 basic_value(const local_datetime& ldt, detail::region reg, | |
| 1115 std::vector<std::string> cm) | |
| 1116 : type_(value_t::local_datetime), | |
| 1117 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1118 comments_(std::move(cm)) | |
| 1119 { | |
| 1120 assigner(this->local_datetime_, ldt); | |
| 1121 } | |
| 1122 basic_value(const offset_datetime& odt, detail::region reg, | |
| 1123 std::vector<std::string> cm) | |
| 1124 : type_(value_t::offset_datetime), | |
| 1125 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1126 comments_(std::move(cm)) | |
| 1127 { | |
| 1128 assigner(this->offset_datetime_, odt); | |
| 1129 } | |
| 1130 basic_value(const array_type& ary, detail::region reg, | |
| 1131 std::vector<std::string> cm) | |
| 1132 : type_(value_t::array), | |
| 1133 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1134 comments_(std::move(cm)) | |
| 1135 { | |
| 1136 assigner(this->array_, ary); | |
| 1137 } | |
| 1138 basic_value(const table_type& tab, detail::region reg, | |
| 1139 std::vector<std::string> cm) | |
| 1140 : type_(value_t::table), | |
| 1141 region_info_(std::make_shared<detail::region>(std::move(reg))), | |
| 1142 comments_(std::move(cm)) | |
| 1143 { | |
| 1144 assigner(this->table_, tab); | |
| 1145 } | |
| 1146 | |
| 1147 template<typename T, typename std::enable_if< | |
| 1148 detail::is_exact_toml_type<T, value_type>::value, | |
| 1149 std::nullptr_t>::type = nullptr> | |
| 1150 basic_value(std::pair<T, detail::region> parse_result, std::vector<std::string> com) | |
| 1151 : basic_value(std::move(parse_result.first), | |
| 1152 std::move(parse_result.second), | |
| 1153 std::move(com)) | |
| 1154 {} | |
| 1155 | |
| 1156 // type checking and casting ============================================ | |
| 1157 | |
| 1158 template<typename T, typename std::enable_if< | |
| 1159 detail::is_exact_toml_type<T, value_type>::value, | |
| 1160 std::nullptr_t>::type = nullptr> | |
| 1161 bool is() const noexcept | |
| 1162 { | |
| 1163 return detail::type_to_enum<T, value_type>::value == this->type_; | |
| 1164 } | |
| 1165 bool is(value_t t) const noexcept {return t == this->type_;} | |
| 1166 | |
| 1167 bool is_uninitialized() const noexcept {return this->is(value_t::empty );} | |
| 1168 bool is_boolean() const noexcept {return this->is(value_t::boolean );} | |
| 1169 bool is_integer() const noexcept {return this->is(value_t::integer );} | |
| 1170 bool is_floating() const noexcept {return this->is(value_t::floating );} | |
| 1171 bool is_string() const noexcept {return this->is(value_t::string );} | |
| 1172 bool is_offset_datetime() const noexcept {return this->is(value_t::offset_datetime);} | |
| 1173 bool is_local_datetime() const noexcept {return this->is(value_t::local_datetime );} | |
| 1174 bool is_local_date() const noexcept {return this->is(value_t::local_date );} | |
| 1175 bool is_local_time() const noexcept {return this->is(value_t::local_time );} | |
| 1176 bool is_array() const noexcept {return this->is(value_t::array );} | |
| 1177 bool is_table() const noexcept {return this->is(value_t::table );} | |
| 1178 | |
| 1179 value_t type() const noexcept {return type_;} | |
| 1180 | |
| 1181 template<value_t T> | |
| 1182 typename detail::enum_to_type<T, value_type>::type& cast() & | |
| 1183 { | |
| 1184 if(this->type_ != T) | |
| 1185 { | |
| 1186 detail::throw_bad_cast<T>("toml::value::cast: ", this->type_, *this); | |
| 1187 } | |
| 1188 return detail::switch_cast<T>::invoke(*this); | |
| 1189 } | |
| 1190 template<value_t T> | |
| 1191 typename detail::enum_to_type<T, value_type>::type const& cast() const& | |
| 1192 { | |
| 1193 if(this->type_ != T) | |
| 1194 { | |
| 1195 detail::throw_bad_cast<T>("toml::value::cast: ", this->type_, *this); | |
| 1196 } | |
| 1197 return detail::switch_cast<T>::invoke(*this); | |
| 1198 } | |
| 1199 template<value_t T> | |
| 1200 typename detail::enum_to_type<T, value_type>::type&& cast() && | |
| 1201 { | |
| 1202 if(this->type_ != T) | |
| 1203 { | |
| 1204 detail::throw_bad_cast<T>("toml::value::cast: ", this->type_, *this); | |
| 1205 } | |
| 1206 return detail::switch_cast<T>::invoke(std::move(*this)); | |
| 1207 } | |
| 1208 | |
| 1209 // ------------------------------------------------------------------------ | |
| 1210 // nothrow version | |
| 1211 | |
| 1212 boolean const& as_boolean (const std::nothrow_t&) const& noexcept {return this->boolean_;} | |
| 1213 integer const& as_integer (const std::nothrow_t&) const& noexcept {return this->integer_;} | |
| 1214 floating const& as_floating (const std::nothrow_t&) const& noexcept {return this->floating_;} | |
| 1215 string const& as_string (const std::nothrow_t&) const& noexcept {return this->string_;} | |
| 1216 offset_datetime const& as_offset_datetime(const std::nothrow_t&) const& noexcept {return this->offset_datetime_;} | |
| 1217 local_datetime const& as_local_datetime (const std::nothrow_t&) const& noexcept {return this->local_datetime_;} | |
| 1218 local_date const& as_local_date (const std::nothrow_t&) const& noexcept {return this->local_date_;} | |
| 1219 local_time const& as_local_time (const std::nothrow_t&) const& noexcept {return this->local_time_;} | |
| 1220 array_type const& as_array (const std::nothrow_t&) const& noexcept {return this->array_.value();} | |
| 1221 table_type const& as_table (const std::nothrow_t&) const& noexcept {return this->table_.value();} | |
| 1222 | |
| 1223 boolean & as_boolean (const std::nothrow_t&) & noexcept {return this->boolean_;} | |
| 1224 integer & as_integer (const std::nothrow_t&) & noexcept {return this->integer_;} | |
| 1225 floating & as_floating (const std::nothrow_t&) & noexcept {return this->floating_;} | |
| 1226 string & as_string (const std::nothrow_t&) & noexcept {return this->string_;} | |
| 1227 offset_datetime& as_offset_datetime(const std::nothrow_t&) & noexcept {return this->offset_datetime_;} | |
| 1228 local_datetime & as_local_datetime (const std::nothrow_t&) & noexcept {return this->local_datetime_;} | |
| 1229 local_date & as_local_date (const std::nothrow_t&) & noexcept {return this->local_date_;} | |
| 1230 local_time & as_local_time (const std::nothrow_t&) & noexcept {return this->local_time_;} | |
| 1231 array_type & as_array (const std::nothrow_t&) & noexcept {return this->array_.value();} | |
| 1232 table_type & as_table (const std::nothrow_t&) & noexcept {return this->table_.value();} | |
| 1233 | |
| 1234 boolean && as_boolean (const std::nothrow_t&) && noexcept {return std::move(this->boolean_);} | |
| 1235 integer && as_integer (const std::nothrow_t&) && noexcept {return std::move(this->integer_);} | |
| 1236 floating && as_floating (const std::nothrow_t&) && noexcept {return std::move(this->floating_);} | |
| 1237 string && as_string (const std::nothrow_t&) && noexcept {return std::move(this->string_);} | |
| 1238 offset_datetime&& as_offset_datetime(const std::nothrow_t&) && noexcept {return std::move(this->offset_datetime_);} | |
| 1239 local_datetime && as_local_datetime (const std::nothrow_t&) && noexcept {return std::move(this->local_datetime_);} | |
| 1240 local_date && as_local_date (const std::nothrow_t&) && noexcept {return std::move(this->local_date_);} | |
| 1241 local_time && as_local_time (const std::nothrow_t&) && noexcept {return std::move(this->local_time_);} | |
| 1242 array_type && as_array (const std::nothrow_t&) && noexcept {return std::move(this->array_.value());} | |
| 1243 table_type && as_table (const std::nothrow_t&) && noexcept {return std::move(this->table_.value());} | |
| 1244 | |
| 1245 // ======================================================================== | |
| 1246 // throw version | |
| 1247 // ------------------------------------------------------------------------ | |
| 1248 // const reference {{{ | |
| 1249 | |
| 1250 boolean const& as_boolean() const& | |
| 1251 { | |
| 1252 if(this->type_ != value_t::boolean) | |
| 1253 { | |
| 1254 detail::throw_bad_cast<value_t::boolean>( | |
| 1255 "toml::value::as_boolean(): ", this->type_, *this); | |
| 1256 } | |
| 1257 return this->boolean_; | |
| 1258 } | |
| 1259 integer const& as_integer() const& | |
| 1260 { | |
| 1261 if(this->type_ != value_t::integer) | |
| 1262 { | |
| 1263 detail::throw_bad_cast<value_t::integer>( | |
| 1264 "toml::value::as_integer(): ", this->type_, *this); | |
| 1265 } | |
| 1266 return this->integer_; | |
| 1267 } | |
| 1268 floating const& as_floating() const& | |
| 1269 { | |
| 1270 if(this->type_ != value_t::floating) | |
| 1271 { | |
| 1272 detail::throw_bad_cast<value_t::floating>( | |
| 1273 "toml::value::as_floating(): ", this->type_, *this); | |
| 1274 } | |
| 1275 return this->floating_; | |
| 1276 } | |
| 1277 string const& as_string() const& | |
| 1278 { | |
| 1279 if(this->type_ != value_t::string) | |
| 1280 { | |
| 1281 detail::throw_bad_cast<value_t::string>( | |
| 1282 "toml::value::as_string(): ", this->type_, *this); | |
| 1283 } | |
| 1284 return this->string_; | |
| 1285 } | |
| 1286 offset_datetime const& as_offset_datetime() const& | |
| 1287 { | |
| 1288 if(this->type_ != value_t::offset_datetime) | |
| 1289 { | |
| 1290 detail::throw_bad_cast<value_t::offset_datetime>( | |
| 1291 "toml::value::as_offset_datetime(): ", this->type_, *this); | |
| 1292 } | |
| 1293 return this->offset_datetime_; | |
| 1294 } | |
| 1295 local_datetime const& as_local_datetime() const& | |
| 1296 { | |
| 1297 if(this->type_ != value_t::local_datetime) | |
| 1298 { | |
| 1299 detail::throw_bad_cast<value_t::local_datetime>( | |
| 1300 "toml::value::as_local_datetime(): ", this->type_, *this); | |
| 1301 } | |
| 1302 return this->local_datetime_; | |
| 1303 } | |
| 1304 local_date const& as_local_date() const& | |
| 1305 { | |
| 1306 if(this->type_ != value_t::local_date) | |
| 1307 { | |
| 1308 detail::throw_bad_cast<value_t::local_date>( | |
| 1309 "toml::value::as_local_date(): ", this->type_, *this); | |
| 1310 } | |
| 1311 return this->local_date_; | |
| 1312 } | |
| 1313 local_time const& as_local_time() const& | |
| 1314 { | |
| 1315 if(this->type_ != value_t::local_time) | |
| 1316 { | |
| 1317 detail::throw_bad_cast<value_t::local_time>( | |
| 1318 "toml::value::as_local_time(): ", this->type_, *this); | |
| 1319 } | |
| 1320 return this->local_time_; | |
| 1321 } | |
| 1322 array_type const& as_array() const& | |
| 1323 { | |
| 1324 if(this->type_ != value_t::array) | |
| 1325 { | |
| 1326 detail::throw_bad_cast<value_t::array>( | |
| 1327 "toml::value::as_array(): ", this->type_, *this); | |
| 1328 } | |
| 1329 return this->array_.value(); | |
| 1330 } | |
| 1331 table_type const& as_table() const& | |
| 1332 { | |
| 1333 if(this->type_ != value_t::table) | |
| 1334 { | |
| 1335 detail::throw_bad_cast<value_t::table>( | |
| 1336 "toml::value::as_table(): ", this->type_, *this); | |
| 1337 } | |
| 1338 return this->table_.value(); | |
| 1339 } | |
| 1340 // }}} | |
| 1341 // ------------------------------------------------------------------------ | |
| 1342 // nonconst reference {{{ | |
| 1343 | |
| 1344 boolean & as_boolean() & | |
| 1345 { | |
| 1346 if(this->type_ != value_t::boolean) | |
| 1347 { | |
| 1348 detail::throw_bad_cast<value_t::boolean>( | |
| 1349 "toml::value::as_boolean(): ", this->type_, *this); | |
| 1350 } | |
| 1351 return this->boolean_; | |
| 1352 } | |
| 1353 integer & as_integer() & | |
| 1354 { | |
| 1355 if(this->type_ != value_t::integer) | |
| 1356 { | |
| 1357 detail::throw_bad_cast<value_t::integer>( | |
| 1358 "toml::value::as_integer(): ", this->type_, *this); | |
| 1359 } | |
| 1360 return this->integer_; | |
| 1361 } | |
| 1362 floating & as_floating() & | |
| 1363 { | |
| 1364 if(this->type_ != value_t::floating) | |
| 1365 { | |
| 1366 detail::throw_bad_cast<value_t::floating>( | |
| 1367 "toml::value::as_floating(): ", this->type_, *this); | |
| 1368 } | |
| 1369 return this->floating_; | |
| 1370 } | |
| 1371 string & as_string() & | |
| 1372 { | |
| 1373 if(this->type_ != value_t::string) | |
| 1374 { | |
| 1375 detail::throw_bad_cast<value_t::string>( | |
| 1376 "toml::value::as_string(): ", this->type_, *this); | |
| 1377 } | |
| 1378 return this->string_; | |
| 1379 } | |
| 1380 offset_datetime & as_offset_datetime() & | |
| 1381 { | |
| 1382 if(this->type_ != value_t::offset_datetime) | |
| 1383 { | |
| 1384 detail::throw_bad_cast<value_t::offset_datetime>( | |
| 1385 "toml::value::as_offset_datetime(): ", this->type_, *this); | |
| 1386 } | |
| 1387 return this->offset_datetime_; | |
| 1388 } | |
| 1389 local_datetime & as_local_datetime() & | |
| 1390 { | |
| 1391 if(this->type_ != value_t::local_datetime) | |
| 1392 { | |
| 1393 detail::throw_bad_cast<value_t::local_datetime>( | |
| 1394 "toml::value::as_local_datetime(): ", this->type_, *this); | |
| 1395 } | |
| 1396 return this->local_datetime_; | |
| 1397 } | |
| 1398 local_date & as_local_date() & | |
| 1399 { | |
| 1400 if(this->type_ != value_t::local_date) | |
| 1401 { | |
| 1402 detail::throw_bad_cast<value_t::local_date>( | |
| 1403 "toml::value::as_local_date(): ", this->type_, *this); | |
| 1404 } | |
| 1405 return this->local_date_; | |
| 1406 } | |
| 1407 local_time & as_local_time() & | |
| 1408 { | |
| 1409 if(this->type_ != value_t::local_time) | |
| 1410 { | |
| 1411 detail::throw_bad_cast<value_t::local_time>( | |
| 1412 "toml::value::as_local_time(): ", this->type_, *this); | |
| 1413 } | |
| 1414 return this->local_time_; | |
| 1415 } | |
| 1416 array_type & as_array() & | |
| 1417 { | |
| 1418 if(this->type_ != value_t::array) | |
| 1419 { | |
| 1420 detail::throw_bad_cast<value_t::array>( | |
| 1421 "toml::value::as_array(): ", this->type_, *this); | |
| 1422 } | |
| 1423 return this->array_.value(); | |
| 1424 } | |
| 1425 table_type & as_table() & | |
| 1426 { | |
| 1427 if(this->type_ != value_t::table) | |
| 1428 { | |
| 1429 detail::throw_bad_cast<value_t::table>( | |
| 1430 "toml::value::as_table(): ", this->type_, *this); | |
| 1431 } | |
| 1432 return this->table_.value(); | |
| 1433 } | |
| 1434 | |
| 1435 // }}} | |
| 1436 // ------------------------------------------------------------------------ | |
| 1437 // rvalue reference {{{ | |
| 1438 | |
| 1439 boolean && as_boolean() && | |
| 1440 { | |
| 1441 if(this->type_ != value_t::boolean) | |
| 1442 { | |
| 1443 detail::throw_bad_cast<value_t::boolean>( | |
| 1444 "toml::value::as_boolean(): ", this->type_, *this); | |
| 1445 } | |
| 1446 return std::move(this->boolean_); | |
| 1447 } | |
| 1448 integer && as_integer() && | |
| 1449 { | |
| 1450 if(this->type_ != value_t::integer) | |
| 1451 { | |
| 1452 detail::throw_bad_cast<value_t::integer>( | |
| 1453 "toml::value::as_integer(): ", this->type_, *this); | |
| 1454 } | |
| 1455 return std::move(this->integer_); | |
| 1456 } | |
| 1457 floating && as_floating() && | |
| 1458 { | |
| 1459 if(this->type_ != value_t::floating) | |
| 1460 { | |
| 1461 detail::throw_bad_cast<value_t::floating>( | |
| 1462 "toml::value::as_floating(): ", this->type_, *this); | |
| 1463 } | |
| 1464 return std::move(this->floating_); | |
| 1465 } | |
| 1466 string && as_string() && | |
| 1467 { | |
| 1468 if(this->type_ != value_t::string) | |
| 1469 { | |
| 1470 detail::throw_bad_cast<value_t::string>( | |
| 1471 "toml::value::as_string(): ", this->type_, *this); | |
| 1472 } | |
| 1473 return std::move(this->string_); | |
| 1474 } | |
| 1475 offset_datetime && as_offset_datetime() && | |
| 1476 { | |
| 1477 if(this->type_ != value_t::offset_datetime) | |
| 1478 { | |
| 1479 detail::throw_bad_cast<value_t::offset_datetime>( | |
| 1480 "toml::value::as_offset_datetime(): ", this->type_, *this); | |
| 1481 } | |
| 1482 return std::move(this->offset_datetime_); | |
| 1483 } | |
| 1484 local_datetime && as_local_datetime() && | |
| 1485 { | |
| 1486 if(this->type_ != value_t::local_datetime) | |
| 1487 { | |
| 1488 detail::throw_bad_cast<value_t::local_datetime>( | |
| 1489 "toml::value::as_local_datetime(): ", this->type_, *this); | |
| 1490 } | |
| 1491 return std::move(this->local_datetime_); | |
| 1492 } | |
| 1493 local_date && as_local_date() && | |
| 1494 { | |
| 1495 if(this->type_ != value_t::local_date) | |
| 1496 { | |
| 1497 detail::throw_bad_cast<value_t::local_date>( | |
| 1498 "toml::value::as_local_date(): ", this->type_, *this); | |
| 1499 } | |
| 1500 return std::move(this->local_date_); | |
| 1501 } | |
| 1502 local_time && as_local_time() && | |
| 1503 { | |
| 1504 if(this->type_ != value_t::local_time) | |
| 1505 { | |
| 1506 detail::throw_bad_cast<value_t::local_time>( | |
| 1507 "toml::value::as_local_time(): ", this->type_, *this); | |
| 1508 } | |
| 1509 return std::move(this->local_time_); | |
| 1510 } | |
| 1511 array_type && as_array() && | |
| 1512 { | |
| 1513 if(this->type_ != value_t::array) | |
| 1514 { | |
| 1515 detail::throw_bad_cast<value_t::array>( | |
| 1516 "toml::value::as_array(): ", this->type_, *this); | |
| 1517 } | |
| 1518 return std::move(this->array_.value()); | |
| 1519 } | |
| 1520 table_type && as_table() && | |
| 1521 { | |
| 1522 if(this->type_ != value_t::table) | |
| 1523 { | |
| 1524 detail::throw_bad_cast<value_t::table>( | |
| 1525 "toml::value::as_table(): ", this->type_, *this); | |
| 1526 } | |
| 1527 return std::move(this->table_.value()); | |
| 1528 } | |
| 1529 // }}} | |
| 1530 | |
| 1531 // accessors ============================================================= | |
| 1532 // | |
| 1533 // may throw type_error or out_of_range | |
| 1534 // | |
| 1535 value_type& at(const key& k) | |
| 1536 { | |
| 1537 if(!this->is_table()) | |
| 1538 { | |
| 1539 detail::throw_bad_cast<value_t::table>( | |
| 1540 "toml::value::at(key): ", this->type_, *this); | |
| 1541 } | |
| 1542 if(this->as_table(std::nothrow).count(k) == 0) | |
| 1543 { | |
| 1544 detail::throw_key_not_found_error(*this, k); | |
| 1545 } | |
| 1546 return this->as_table(std::nothrow).at(k); | |
| 1547 } | |
| 1548 value_type const& at(const key& k) const | |
| 1549 { | |
| 1550 if(!this->is_table()) | |
| 1551 { | |
| 1552 detail::throw_bad_cast<value_t::table>( | |
| 1553 "toml::value::at(key): ", this->type_, *this); | |
| 1554 } | |
| 1555 if(this->as_table(std::nothrow).count(k) == 0) | |
| 1556 { | |
| 1557 detail::throw_key_not_found_error(*this, k); | |
| 1558 } | |
| 1559 return this->as_table(std::nothrow).at(k); | |
| 1560 } | |
| 1561 value_type& operator[](const key& k) | |
| 1562 { | |
| 1563 if(this->is_uninitialized()) | |
| 1564 { | |
| 1565 *this = table_type{}; | |
| 1566 } | |
| 1567 else if(!this->is_table()) // initialized, but not a table | |
| 1568 { | |
| 1569 detail::throw_bad_cast<value_t::table>( | |
| 1570 "toml::value::operator[](key): ", this->type_, *this); | |
| 1571 } | |
| 1572 return this->as_table(std::nothrow)[k]; | |
| 1573 } | |
| 1574 | |
| 1575 value_type& at(const std::size_t idx) | |
| 1576 { | |
| 1577 if(!this->is_array()) | |
| 1578 { | |
| 1579 detail::throw_bad_cast<value_t::array>( | |
| 1580 "toml::value::at(idx): ", this->type_, *this); | |
| 1581 } | |
| 1582 if(this->as_array(std::nothrow).size() <= idx) | |
| 1583 { | |
| 1584 throw std::out_of_range(detail::format_underline( | |
| 1585 "toml::value::at(idx): no element corresponding to the index", { | |
| 1586 {this->location(), concat_to_string("the length is ", | |
| 1587 this->as_array(std::nothrow).size(), | |
| 1588 ", and the specified index is ", idx)} | |
| 1589 })); | |
| 1590 } | |
| 1591 return this->as_array().at(idx); | |
| 1592 } | |
| 1593 value_type const& at(const std::size_t idx) const | |
| 1594 { | |
| 1595 if(!this->is_array()) | |
| 1596 { | |
| 1597 detail::throw_bad_cast<value_t::array>( | |
| 1598 "toml::value::at(idx): ", this->type_, *this); | |
| 1599 } | |
| 1600 if(this->as_array(std::nothrow).size() <= idx) | |
| 1601 { | |
| 1602 throw std::out_of_range(detail::format_underline( | |
| 1603 "toml::value::at(idx): no element corresponding to the index", { | |
| 1604 {this->location(), concat_to_string("the length is ", | |
| 1605 this->as_array(std::nothrow).size(), | |
| 1606 ", and the specified index is ", idx)} | |
| 1607 })); | |
| 1608 } | |
| 1609 return this->as_array(std::nothrow).at(idx); | |
| 1610 } | |
| 1611 | |
| 1612 value_type& operator[](const std::size_t idx) noexcept | |
| 1613 { | |
| 1614 // no check... | |
| 1615 return this->as_array(std::nothrow)[idx]; | |
| 1616 } | |
| 1617 value_type const& operator[](const std::size_t idx) const noexcept | |
| 1618 { | |
| 1619 // no check... | |
| 1620 return this->as_array(std::nothrow)[idx]; | |
| 1621 } | |
| 1622 | |
| 1623 void push_back(const value_type& x) | |
| 1624 { | |
| 1625 if(!this->is_array()) | |
| 1626 { | |
| 1627 detail::throw_bad_cast<value_t::array>( | |
| 1628 "toml::value::push_back(value): ", this->type_, *this); | |
| 1629 } | |
| 1630 this->as_array(std::nothrow).push_back(x); | |
| 1631 return; | |
| 1632 } | |
| 1633 void push_back(value_type&& x) | |
| 1634 { | |
| 1635 if(!this->is_array()) | |
| 1636 { | |
| 1637 detail::throw_bad_cast<value_t::array>( | |
| 1638 "toml::value::push_back(value): ", this->type_, *this); | |
| 1639 } | |
| 1640 this->as_array(std::nothrow).push_back(std::move(x)); | |
| 1641 return; | |
| 1642 } | |
| 1643 | |
| 1644 template<typename ... Ts> | |
| 1645 value_type& emplace_back(Ts&& ... args) | |
| 1646 { | |
| 1647 if(!this->is_array()) | |
| 1648 { | |
| 1649 detail::throw_bad_cast<value_t::array>( | |
| 1650 "toml::value::emplace_back(...): ", this->type_, *this); | |
| 1651 } | |
| 1652 this->as_array(std::nothrow).emplace_back(std::forward<Ts>(args) ...); | |
| 1653 return this->as_array(std::nothrow).back(); | |
| 1654 } | |
| 1655 | |
| 1656 std::size_t size() const | |
| 1657 { | |
| 1658 switch(this->type_) | |
| 1659 { | |
| 1660 case value_t::array: | |
| 1661 { | |
| 1662 return this->as_array(std::nothrow).size(); | |
| 1663 } | |
| 1664 case value_t::table: | |
| 1665 { | |
| 1666 return this->as_table(std::nothrow).size(); | |
| 1667 } | |
| 1668 case value_t::string: | |
| 1669 { | |
| 1670 return this->as_string(std::nothrow).str.size(); | |
| 1671 } | |
| 1672 default: | |
| 1673 { | |
| 1674 throw type_error(detail::format_underline( | |
| 1675 "toml::value::size(): bad_cast to container types", { | |
| 1676 {this->location(), | |
| 1677 concat_to_string("the actual type is ", this->type_)} | |
| 1678 }), this->location()); | |
| 1679 } | |
| 1680 } | |
| 1681 } | |
| 1682 | |
| 1683 std::size_t count(const key_type& k) const | |
| 1684 { | |
| 1685 if(!this->is_table()) | |
| 1686 { | |
| 1687 detail::throw_bad_cast<value_t::table>( | |
| 1688 "toml::value::count(key): ", this->type_, *this); | |
| 1689 } | |
| 1690 return this->as_table(std::nothrow).count(k); | |
| 1691 } | |
| 1692 | |
| 1693 bool contains(const key_type& k) const | |
| 1694 { | |
| 1695 if(!this->is_table()) | |
| 1696 { | |
| 1697 detail::throw_bad_cast<value_t::table>( | |
| 1698 "toml::value::contains(key): ", this->type_, *this); | |
| 1699 } | |
| 1700 return (this->as_table(std::nothrow).count(k) != 0); | |
| 1701 } | |
| 1702 | |
| 1703 source_location location() const | |
| 1704 { | |
| 1705 return source_location(this->region_info_.get()); | |
| 1706 } | |
| 1707 | |
| 1708 comment_type const& comments() const noexcept {return this->comments_;} | |
| 1709 comment_type& comments() noexcept {return this->comments_;} | |
| 1710 | |
| 1711 private: | |
| 1712 | |
| 1713 void cleanup() noexcept | |
| 1714 { | |
| 1715 switch(this->type_) | |
| 1716 { | |
| 1717 case value_t::string : {string_.~string(); return;} | |
| 1718 case value_t::array : {array_.~array_storage(); return;} | |
| 1719 case value_t::table : {table_.~table_storage(); return;} | |
| 1720 default : return; | |
| 1721 } | |
| 1722 } | |
| 1723 | |
| 1724 // for error messages | |
| 1725 template<typename Value> | |
| 1726 friend region_base const* detail::get_region(const Value& v); | |
| 1727 | |
| 1728 template<typename Value> | |
| 1729 friend void detail::change_region(Value& v, detail::region reg); | |
| 1730 | |
| 1731 private: | |
| 1732 | |
| 1733 using array_storage = detail::storage<array_type>; | |
| 1734 using table_storage = detail::storage<table_type>; | |
| 1735 | |
| 1736 value_t type_; | |
| 1737 union | |
| 1738 { | |
| 1739 boolean boolean_; | |
| 1740 integer integer_; | |
| 1741 floating floating_; | |
| 1742 string string_; | |
| 1743 offset_datetime offset_datetime_; | |
| 1744 local_datetime local_datetime_; | |
| 1745 local_date local_date_; | |
| 1746 local_time local_time_; | |
| 1747 array_storage array_; | |
| 1748 table_storage table_; | |
| 1749 }; | |
| 1750 std::shared_ptr<region_base> region_info_; | |
| 1751 comment_type comments_; | |
| 1752 }; | |
| 1753 | |
| 1754 // default toml::value and default array/table. | |
| 1755 // TOML11_DEFAULT_COMMENT_STRATEGY is defined in comments.hpp | |
| 1756 using value = basic_value<TOML11_DEFAULT_COMMENT_STRATEGY, std::unordered_map, std::vector>; | |
| 1757 using array = typename value::array_type; | |
| 1758 using table = typename value::table_type; | |
| 1759 | |
| 1760 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1761 inline bool | |
| 1762 operator==(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs) | |
| 1763 { | |
| 1764 if(lhs.type() != rhs.type()) {return false;} | |
| 1765 if(lhs.comments() != rhs.comments()) {return false;} | |
| 1766 | |
| 1767 switch(lhs.type()) | |
| 1768 { | |
| 1769 case value_t::boolean : | |
| 1770 { | |
| 1771 return lhs.as_boolean() == rhs.as_boolean(); | |
| 1772 } | |
| 1773 case value_t::integer : | |
| 1774 { | |
| 1775 return lhs.as_integer() == rhs.as_integer(); | |
| 1776 } | |
| 1777 case value_t::floating : | |
| 1778 { | |
| 1779 return lhs.as_floating() == rhs.as_floating(); | |
| 1780 } | |
| 1781 case value_t::string : | |
| 1782 { | |
| 1783 return lhs.as_string() == rhs.as_string(); | |
| 1784 } | |
| 1785 case value_t::offset_datetime: | |
| 1786 { | |
| 1787 return lhs.as_offset_datetime() == rhs.as_offset_datetime(); | |
| 1788 } | |
| 1789 case value_t::local_datetime: | |
| 1790 { | |
| 1791 return lhs.as_local_datetime() == rhs.as_local_datetime(); | |
| 1792 } | |
| 1793 case value_t::local_date: | |
| 1794 { | |
| 1795 return lhs.as_local_date() == rhs.as_local_date(); | |
| 1796 } | |
| 1797 case value_t::local_time: | |
| 1798 { | |
| 1799 return lhs.as_local_time() == rhs.as_local_time(); | |
| 1800 } | |
| 1801 case value_t::array : | |
| 1802 { | |
| 1803 return lhs.as_array() == rhs.as_array(); | |
| 1804 } | |
| 1805 case value_t::table : | |
| 1806 { | |
| 1807 return lhs.as_table() == rhs.as_table(); | |
| 1808 } | |
| 1809 case value_t::empty : {return true; } | |
| 1810 default: {return false;} | |
| 1811 } | |
| 1812 } | |
| 1813 | |
| 1814 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1815 inline bool operator!=(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs) | |
| 1816 { | |
| 1817 return !(lhs == rhs); | |
| 1818 } | |
| 1819 | |
| 1820 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1821 typename std::enable_if<detail::conjunction< | |
| 1822 detail::is_comparable<typename basic_value<C, T, A>::array_type>, | |
| 1823 detail::is_comparable<typename basic_value<C, T, A>::table_type> | |
| 1824 >::value, bool>::type | |
| 1825 operator<(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs) | |
| 1826 { | |
| 1827 if(lhs.type() != rhs.type()){return (lhs.type() < rhs.type());} | |
| 1828 switch(lhs.type()) | |
| 1829 { | |
| 1830 case value_t::boolean : | |
| 1831 { | |
| 1832 return lhs.as_boolean() < rhs.as_boolean() || | |
| 1833 (lhs.as_boolean() == rhs.as_boolean() && | |
| 1834 lhs.comments() < rhs.comments()); | |
| 1835 } | |
| 1836 case value_t::integer : | |
| 1837 { | |
| 1838 return lhs.as_integer() < rhs.as_integer() || | |
| 1839 (lhs.as_integer() == rhs.as_integer() && | |
| 1840 lhs.comments() < rhs.comments()); | |
| 1841 } | |
| 1842 case value_t::floating : | |
| 1843 { | |
| 1844 return lhs.as_floating() < rhs.as_floating() || | |
| 1845 (lhs.as_floating() == rhs.as_floating() && | |
| 1846 lhs.comments() < rhs.comments()); | |
| 1847 } | |
| 1848 case value_t::string : | |
| 1849 { | |
| 1850 return lhs.as_string() < rhs.as_string() || | |
| 1851 (lhs.as_string() == rhs.as_string() && | |
| 1852 lhs.comments() < rhs.comments()); | |
| 1853 } | |
| 1854 case value_t::offset_datetime: | |
| 1855 { | |
| 1856 return lhs.as_offset_datetime() < rhs.as_offset_datetime() || | |
| 1857 (lhs.as_offset_datetime() == rhs.as_offset_datetime() && | |
| 1858 lhs.comments() < rhs.comments()); | |
| 1859 } | |
| 1860 case value_t::local_datetime: | |
| 1861 { | |
| 1862 return lhs.as_local_datetime() < rhs.as_local_datetime() || | |
| 1863 (lhs.as_local_datetime() == rhs.as_local_datetime() && | |
| 1864 lhs.comments() < rhs.comments()); | |
| 1865 } | |
| 1866 case value_t::local_date: | |
| 1867 { | |
| 1868 return lhs.as_local_date() < rhs.as_local_date() || | |
| 1869 (lhs.as_local_date() == rhs.as_local_date() && | |
| 1870 lhs.comments() < rhs.comments()); | |
| 1871 } | |
| 1872 case value_t::local_time: | |
| 1873 { | |
| 1874 return lhs.as_local_time() < rhs.as_local_time() || | |
| 1875 (lhs.as_local_time() == rhs.as_local_time() && | |
| 1876 lhs.comments() < rhs.comments()); | |
| 1877 } | |
| 1878 case value_t::array : | |
| 1879 { | |
| 1880 return lhs.as_array() < rhs.as_array() || | |
| 1881 (lhs.as_array() == rhs.as_array() && | |
| 1882 lhs.comments() < rhs.comments()); | |
| 1883 } | |
| 1884 case value_t::table : | |
| 1885 { | |
| 1886 return lhs.as_table() < rhs.as_table() || | |
| 1887 (lhs.as_table() == rhs.as_table() && | |
| 1888 lhs.comments() < rhs.comments()); | |
| 1889 } | |
| 1890 case value_t::empty : | |
| 1891 { | |
| 1892 return lhs.comments() < rhs.comments(); | |
| 1893 } | |
| 1894 default: | |
| 1895 { | |
| 1896 return lhs.comments() < rhs.comments(); | |
| 1897 } | |
| 1898 } | |
| 1899 } | |
| 1900 | |
| 1901 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1902 typename std::enable_if<detail::conjunction< | |
| 1903 detail::is_comparable<typename basic_value<C, T, A>::array_type>, | |
| 1904 detail::is_comparable<typename basic_value<C, T, A>::table_type> | |
| 1905 >::value, bool>::type | |
| 1906 operator<=(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs) | |
| 1907 { | |
| 1908 return (lhs < rhs) || (lhs == rhs); | |
| 1909 } | |
| 1910 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1911 typename std::enable_if<detail::conjunction< | |
| 1912 detail::is_comparable<typename basic_value<C, T, A>::array_type>, | |
| 1913 detail::is_comparable<typename basic_value<C, T, A>::table_type> | |
| 1914 >::value, bool>::type | |
| 1915 operator>(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs) | |
| 1916 { | |
| 1917 return !(lhs <= rhs); | |
| 1918 } | |
| 1919 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1920 typename std::enable_if<detail::conjunction< | |
| 1921 detail::is_comparable<typename basic_value<C, T, A>::array_type>, | |
| 1922 detail::is_comparable<typename basic_value<C, T, A>::table_type> | |
| 1923 >::value, bool>::type | |
| 1924 operator>=(const basic_value<C, T, A>& lhs, const basic_value<C, T, A>& rhs) | |
| 1925 { | |
| 1926 return !(lhs < rhs); | |
| 1927 } | |
| 1928 | |
| 1929 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1930 inline std::string format_error(const std::string& err_msg, | |
| 1931 const basic_value<C, T, A>& v, const std::string& comment, | |
| 1932 std::vector<std::string> hints = {}, | |
| 1933 const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) | |
| 1934 { | |
| 1935 return detail::format_underline(err_msg, {{v.location(), comment}}, | |
| 1936 std::move(hints), colorize); | |
| 1937 } | |
| 1938 | |
| 1939 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1940 inline std::string format_error(const std::string& err_msg, | |
| 1941 const toml::basic_value<C, T, A>& v1, const std::string& comment1, | |
| 1942 const toml::basic_value<C, T, A>& v2, const std::string& comment2, | |
| 1943 std::vector<std::string> hints = {}, | |
| 1944 const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) | |
| 1945 { | |
| 1946 return detail::format_underline(err_msg, { | |
| 1947 {v1.location(), comment1}, {v2.location(), comment2} | |
| 1948 }, std::move(hints), colorize); | |
| 1949 } | |
| 1950 | |
| 1951 template<typename C, template<typename ...> class T, template<typename ...> class A> | |
| 1952 inline std::string format_error(const std::string& err_msg, | |
| 1953 const toml::basic_value<C, T, A>& v1, const std::string& comment1, | |
| 1954 const toml::basic_value<C, T, A>& v2, const std::string& comment2, | |
| 1955 const toml::basic_value<C, T, A>& v3, const std::string& comment3, | |
| 1956 std::vector<std::string> hints = {}, | |
| 1957 const bool colorize = TOML11_ERROR_MESSAGE_COLORIZED) | |
| 1958 { | |
| 1959 return detail::format_underline(err_msg, {{v1.location(), comment1}, | |
| 1960 {v2.location(), comment2}, {v3.location(), comment3} | |
| 1961 }, std::move(hints), colorize); | |
| 1962 } | |
| 1963 | |
| 1964 template<typename Visitor, typename C, | |
| 1965 template<typename ...> class T, template<typename ...> class A> | |
| 1966 detail::return_type_of_t<Visitor, const toml::boolean&> | |
| 1967 visit(Visitor&& visitor, const toml::basic_value<C, T, A>& v) | |
| 1968 { | |
| 1969 switch(v.type()) | |
| 1970 { | |
| 1971 case value_t::boolean : {return visitor(v.as_boolean ());} | |
| 1972 case value_t::integer : {return visitor(v.as_integer ());} | |
| 1973 case value_t::floating : {return visitor(v.as_floating ());} | |
| 1974 case value_t::string : {return visitor(v.as_string ());} | |
| 1975 case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} | |
| 1976 case value_t::local_datetime : {return visitor(v.as_local_datetime ());} | |
| 1977 case value_t::local_date : {return visitor(v.as_local_date ());} | |
| 1978 case value_t::local_time : {return visitor(v.as_local_time ());} | |
| 1979 case value_t::array : {return visitor(v.as_array ());} | |
| 1980 case value_t::table : {return visitor(v.as_table ());} | |
| 1981 case value_t::empty : break; | |
| 1982 default: break; | |
| 1983 } | |
| 1984 throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " | |
| 1985 "does not have any valid basic_value.", v, "here")); | |
| 1986 } | |
| 1987 | |
| 1988 template<typename Visitor, typename C, | |
| 1989 template<typename ...> class T, template<typename ...> class A> | |
| 1990 detail::return_type_of_t<Visitor, toml::boolean&> | |
| 1991 visit(Visitor&& visitor, toml::basic_value<C, T, A>& v) | |
| 1992 { | |
| 1993 switch(v.type()) | |
| 1994 { | |
| 1995 case value_t::boolean : {return visitor(v.as_boolean ());} | |
| 1996 case value_t::integer : {return visitor(v.as_integer ());} | |
| 1997 case value_t::floating : {return visitor(v.as_floating ());} | |
| 1998 case value_t::string : {return visitor(v.as_string ());} | |
| 1999 case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} | |
| 2000 case value_t::local_datetime : {return visitor(v.as_local_datetime ());} | |
| 2001 case value_t::local_date : {return visitor(v.as_local_date ());} | |
| 2002 case value_t::local_time : {return visitor(v.as_local_time ());} | |
| 2003 case value_t::array : {return visitor(v.as_array ());} | |
| 2004 case value_t::table : {return visitor(v.as_table ());} | |
| 2005 case value_t::empty : break; | |
| 2006 default: break; | |
| 2007 } | |
| 2008 throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " | |
| 2009 "does not have any valid basic_value.", v, "here")); | |
| 2010 } | |
| 2011 | |
| 2012 template<typename Visitor, typename C, | |
| 2013 template<typename ...> class T, template<typename ...> class A> | |
| 2014 detail::return_type_of_t<Visitor, toml::boolean&&> | |
| 2015 visit(Visitor&& visitor, toml::basic_value<C, T, A>&& v) | |
| 2016 { | |
| 2017 switch(v.type()) | |
| 2018 { | |
| 2019 case value_t::boolean : {return visitor(std::move(v.as_boolean ()));} | |
| 2020 case value_t::integer : {return visitor(std::move(v.as_integer ()));} | |
| 2021 case value_t::floating : {return visitor(std::move(v.as_floating ()));} | |
| 2022 case value_t::string : {return visitor(std::move(v.as_string ()));} | |
| 2023 case value_t::offset_datetime: {return visitor(std::move(v.as_offset_datetime()));} | |
| 2024 case value_t::local_datetime : {return visitor(std::move(v.as_local_datetime ()));} | |
| 2025 case value_t::local_date : {return visitor(std::move(v.as_local_date ()));} | |
| 2026 case value_t::local_time : {return visitor(std::move(v.as_local_time ()));} | |
| 2027 case value_t::array : {return visitor(std::move(v.as_array ()));} | |
| 2028 case value_t::table : {return visitor(std::move(v.as_table ()));} | |
| 2029 case value_t::empty : break; | |
| 2030 default: break; | |
| 2031 } | |
| 2032 throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " | |
| 2033 "does not have any valid basic_value.", v, "here")); | |
| 2034 } | |
| 2035 | |
| 2036 }// toml | |
| 2037 #endif// TOML11_VALUE |
