diff --git a/toml/value.hpp b/toml/value.hpp index e42e6f5..6687ccd 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -4,44 +4,245 @@ #define TOML11_VALUE_HPP #include "traits.hpp" #include "into.hpp" +#include "from.hpp" #include "utility.hpp" #include "exception.hpp" #include "storage.hpp" #include "region.hpp" #include "types.hpp" -#include -#include -#include +#include "source_location.hpp" #include -#include -#if __cplusplus >= 201703L -#include -#endif namespace toml { namespace detail { + // to show error messages. not recommended for users. -region_base const& get_region(const value&); -template -void change_region(value&, Region&&); +template class T, template class A> +region_base const& get_region(const basic_value&); +template class T, template class A> +void change_region(basic_value&, Region&&); + +template class T, template class A> +[[noreturn]] inline void +throw_bad_cast(value_t actual, const ::toml::basic_value& v) +{ + throw type_error(detail::format_underline(concat_to_string( + "[error] toml::value bad_cast to ", Expected), { + {std::addressof(get_region(v)), + concat_to_string("the actual type is ", actual)} + })); +} + +// switch by `value_t` and call the corresponding `value::as_xxx()`. +template +struct switch_cast {}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::boolean& invoke(basic_value& v) noexcept + { + return v.as_boolean(); + } + template class T, template class A> + static ::toml::boolean const& invoke(basic_value const& v) noexcept + { + return v.as_boolean(); + } + template class T, template class A> + static ::toml::boolean&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_boolean(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::integer& invoke(basic_value& v) noexcept + { + return v.as_integer(); + } + template class T, template class A> + static ::toml::integer const& invoke(basic_value const& v) noexcept + { + return v.as_integer(); + } + template class T, template class A> + static ::toml::integer&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_integer(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::floating& invoke(basic_value& v) noexcept + { + return v.as_floating(); + } + template class T, template class A> + static ::toml::floating const& invoke(basic_value const& v) noexcept + { + return v.as_floating(); + } + template class T, template class A> + static ::toml::floating&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_floating(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::string& invoke(basic_value& v) noexcept + { + return v.as_string(); + } + template class T, template class A> + static ::toml::string const& invoke(basic_value const& v) noexcept + { + return v.as_string(); + } + template class T, template class A> + static ::toml::string&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_string(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::offset_datetime& invoke(basic_value& v) noexcept + { + return v.as_offset_datetime(); + } + template class T, template class A> + static ::toml::offset_datetime const& invoke(basic_value const& v) noexcept + { + return v.as_offset_datetime(); + } + template class T, template class A> + static ::toml::offset_datetime&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_offset_datetime(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::local_datetime& invoke(basic_value& v) noexcept + { + return v.as_local_datetime(); + } + template class T, template class A> + static ::toml::local_datetime const& invoke(basic_value const& v) noexcept + { + return v.as_local_datetime(); + } + template class T, template class A> + static ::toml::local_datetime&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_local_datetime(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::local_date& invoke(basic_value& v) noexcept + { + return v.as_local_date(); + } + template class T, template class A> + static ::toml::local_date const& invoke(basic_value const& v) noexcept + { + return v.as_local_date(); + } + template class T, template class A> + static ::toml::local_date&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_local_date(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::local_time& invoke(basic_value& v) noexcept + { + return v.as_local_time(); + } + template class T, template class A> + static ::toml::local_time const& invoke(basic_value const& v) noexcept + { + return v.as_local_time(); + } + template class T, template class A> + static ::toml::local_time&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_local_time(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static typename basic_value::array_type& + invoke(basic_value& v) noexcept + { + return v.as_array(); + } + template class T, template class A> + static typename basic_value::array_type const& + invoke(basic_value const& v) noexcept + { + return v.as_array(); + } + template class T, template class A> + static typename basic_value::array_type && + invoke(basic_value&& v) noexcept + { + return std::move(v).as_array(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static typename basic_value::table_type& + invoke(basic_value& v) noexcept + { + return v.as_table(); + } + template class T, template class A> + static typename basic_value::table_type const& + invoke(basic_value const& v) noexcept + { + return v.as_table(); + } + template class T, template class A> + static typename basic_value::table_type && + invoke(basic_value&& v) noexcept + { + return std::move(v).as_table(); + } +}; }// detail -template -struct value_traits -{ - constexpr static value_t type_index = detail::check_type(); - constexpr static bool is_toml_type = detail::is_valid(detail::check_type()); - typedef typename detail::toml_default_type::type type; -}; -template -constexpr value_t value_traits::type_index; -template -constexpr bool value_traits::is_toml_type; - -class value +template class Table, // map-like class + template class Array> // vector-like class +class basic_value { template static void assigner(T& dst, U&& v) @@ -55,85 +256,102 @@ class value public: - value() noexcept - : type_(value_t::Empty), + using comment_type = Comment; + using key_type = ::toml::key; + using value_type = basic_value; + using boolean_type = ::toml::boolean; + using integer_type = ::toml::integer; + using floating_type = ::toml::floating; + using string_type = ::toml::string; + using local_time = ::toml::local_time; + using local_date = ::toml::local_date; + using local_datetime = ::toml::local_datetime; + using offset_datetime = ::toml::offset_datetime; + using array_type = Array; + using table_type = Table; + + public: + + basic_value() noexcept + : type_(value_t::empty), region_info_(std::make_shared(region_base{})) {} + ~basic_value() noexcept {this->cleanup();} - ~value() noexcept {this->cleanup();} - - value(const value& v): type_(v.type()), region_info_(v.region_info_) + basic_value(const basic_value& v) + : type_(v.type()), region_info_(v.region_info_) { switch(v.type()) { - case value_t::Boolean : assigner(boolean_ , v.boolean_ ); break; - case value_t::Integer : assigner(integer_ , v.integer_ ); break; - case value_t::Float : assigner(floating_ , v.floating_ ); break; - case value_t::String : assigner(string_ , v.string_ ); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, v.offset_datetime_); break; - case value_t::LocalDatetime : assigner(local_datetime_ , v.local_datetime_ ); break; - case value_t::LocalDate : assigner(local_date_ , v.local_date_ ); break; - case value_t::LocalTime : assigner(local_time_ , v.local_time_ ); break; - case value_t::Array : assigner(array_ , v.array_ ); break; - case value_t::Table : assigner(table_ , v.table_ ); break; + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; default: break; } } - value(value&& v): type_(v.type()), region_info_(std::move(v.region_info_)) + basic_value(basic_value&& v) + : type_(v.type()), region_info_(std::move(v.region_info_)) { - switch(this->type_) + switch(this->type_) // here this->type_ is already initialized { - case value_t::Boolean : assigner(boolean_ , std::move(v.boolean_ )); break; - case value_t::Integer : assigner(integer_ , std::move(v.integer_ )); break; - case value_t::Float : assigner(floating_ , std::move(v.floating_ )); break; - case value_t::String : assigner(string_ , std::move(v.string_ )); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; - case value_t::LocalDatetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; - case value_t::LocalDate : assigner(local_date_ , std::move(v.local_date_ )); break; - case value_t::LocalTime : assigner(local_time_ , std::move(v.local_time_ )); break; - case value_t::Array : assigner(array_ , std::move(v.array_ )); break; - case value_t::Table : assigner(table_ , std::move(v.table_ )); break; + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; default: break; } } - value& operator=(const value& v) + basic_value& operator=(const basic_value& v) { this->cleanup(); this->region_info_ = v.region_info_; this->type_ = v.type(); switch(this->type_) { - case value_t::Boolean : assigner(boolean_ , v.boolean_ ); break; - case value_t::Integer : assigner(integer_ , v.integer_ ); break; - case value_t::Float : assigner(floating_ , v.floating_ ); break; - case value_t::String : assigner(string_ , v.string_ ); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, v.offset_datetime_); break; - case value_t::LocalDatetime : assigner(local_datetime_ , v.local_datetime_ ); break; - case value_t::LocalDate : assigner(local_date_ , v.local_date_ ); break; - case value_t::LocalTime : assigner(local_time_ , v.local_time_ ); break; - case value_t::Array : assigner(array_ , v.array_ ); break; - case value_t::Table : assigner(table_ , v.table_ ); break; + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; default: break; } return *this; } - value& operator=(value&& v) + basic_value& operator=(basic_value&& v) { this->cleanup(); this->region_info_ = std::move(v.region_info_); this->type_ = v.type(); switch(this->type_) { - case value_t::Boolean : assigner(boolean_ , std::move(v.boolean_ )); break; - case value_t::Integer : assigner(integer_ , std::move(v.integer_ )); break; - case value_t::Float : assigner(floating_ , std::move(v.floating_ )); break; - case value_t::String : assigner(string_ , std::move(v.string_ )); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; - case value_t::LocalDatetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; - case value_t::LocalDate : assigner(local_date_ , std::move(v.local_date_ )); break; - case value_t::LocalTime : assigner(local_time_ , std::move(v.local_time_ )); break; - case value_t::Array : assigner(array_ , std::move(v.array_ )); break; - case value_t::Table : assigner(table_ , std::move(v.table_ )); break; + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; default: break; } return *this; @@ -141,25 +359,25 @@ class value // boolean ============================================================== - value(boolean b) - : type_(value_t::Boolean), + basic_value(boolean b) + : type_(value_t::boolean), region_info_(std::make_shared(region_base{})) { assigner(this->boolean_, b); } - value& operator=(boolean b) + basic_value& operator=(boolean b) { this->cleanup(); - this->type_ = value_t::Boolean; + this->type_ = value_t::boolean; this->region_info_ = std::make_shared(region_base{}); assigner(this->boolean_, b); return *this; } template - value(boolean b, detail::region reg) - : type_(value_t::Boolean), + basic_value(boolean b, detail::region reg) + : type_(value_t::boolean), region_info_(std::make_shared>(std::move(reg))) { assigner(this->boolean_, b); @@ -170,19 +388,20 @@ class value template, detail::negation>>::value, std::nullptr_t>::type = nullptr> - value(T i) - : type_(value_t::Integer), + basic_value(T i) + : type_(value_t::integer), region_info_(std::make_shared(region_base{})) { assigner(this->integer_, static_cast(i)); } template, - detail::negation> + detail::conjunction< + std::is_integral, + detail::negation> >::value, std::nullptr_t>::type = nullptr> - value(T i, detail::region reg) - : type_(value_t::Integer), + basic_value(T i, detail::region reg) + : type_(value_t::integer), region_info_(std::make_shared>(std::move(reg))) { assigner(this->integer_, static_cast(i)); @@ -191,10 +410,10 @@ class value template, detail::negation>>::value, std::nullptr_t>::type = nullptr> - value& operator=(T i) + basic_value& operator=(T i) { this->cleanup(); - this->type_ = value_t::Integer; + this->type_ = value_t::integer; this->region_info_ = std::make_shared(region_base{}); assigner(this->integer_, static_cast(i)); return *this; @@ -204,8 +423,8 @@ class value template::value, std::nullptr_t>::type = nullptr> - value(T f) - : type_(value_t::Float), + basic_value(T f) + : type_(value_t::floating), region_info_(std::make_shared(region_base{})) { assigner(this->floating_, f); @@ -213,8 +432,8 @@ class value template::value, std::nullptr_t>::type = nullptr> - value(T f, detail::region reg) - : type_(value_t::Float), + basic_value(T f, detail::region reg) + : type_(value_t::floating), region_info_(std::make_shared>(std::move(reg))) { assigner(this->floating_, f); @@ -222,10 +441,10 @@ class value template::value, std::nullptr_t>::type = nullptr> - value& operator=(T f) + basic_value& operator=(T f) { this->cleanup(); - this->type_ = value_t::Float; + this->type_ = value_t::floating; this->region_info_ = std::make_shared(region_base{}); assigner(this->floating_, f); return *this; @@ -233,87 +452,87 @@ class value // string =============================================================== - value(toml::string s) - : type_(value_t::String), + basic_value(toml::string s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, std::move(s)); } template - value(toml::string s, detail::region reg) - : type_(value_t::String), + basic_value(toml::string s, detail::region reg) + : type_(value_t::string), region_info_(std::make_shared>(std::move(reg))) { assigner(this->string_, std::move(s)); } - value& operator=(toml::string s) + basic_value& operator=(toml::string s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, s); return *this; } - value(std::string s) - : type_(value_t::String), + basic_value(std::string s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::move(s))); } - value& operator=(std::string s) + basic_value& operator=(std::string s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, toml::string(std::move(s))); return *this; } - value(std::string s, string_t kind) - : type_(value_t::String), + basic_value(std::string s, string_t kind) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::move(s), kind)); } - value(const char* s) - : type_(value_t::String), + basic_value(const char* s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::string(s))); } - value& operator=(const char* s) + basic_value& operator=(const char* s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, toml::string(std::string(s))); return *this; } - value(const char* s, string_t kind) - : type_(value_t::String), + basic_value(const char* s, string_t kind) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::string(s), kind)); } #if __cplusplus >= 201703L - value(std::string_view s) - : type_(value_t::String), + basic_value(std::string_view s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(s)); } - value& operator=(std::string_view s) + basic_value& operator=(std::string_view s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, toml::string(s)); return *this; } - value(std::string_view s, string_t kind) - : type_(value_t::String), + basic_value(std::string_view s, string_t kind) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(s, kind)); @@ -322,23 +541,23 @@ class value // local date =========================================================== - value(const local_date& ld) - : type_(value_t::LocalDate), + basic_value(const local_date& ld) + : type_(value_t::local_date), region_info_(std::make_shared(region_base{})) { assigner(this->local_date_, ld); } template - value(const local_date& ld, detail::region reg) - : type_(value_t::LocalDate), + basic_value(const local_date& ld, detail::region reg) + : type_(value_t::local_date), region_info_(std::make_shared>(std::move(reg))) { assigner(this->local_date_, ld); } - value& operator=(const local_date& ld) + basic_value& operator=(const local_date& ld) { this->cleanup(); - this->type_ = value_t::LocalDate; + this->type_ = value_t::local_date; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_date_, ld); return *this; @@ -346,39 +565,39 @@ class value // local time =========================================================== - value(const local_time& lt) - : type_(value_t::LocalTime), + basic_value(const local_time& lt) + : type_(value_t::local_time), region_info_(std::make_shared(region_base{})) { assigner(this->local_time_, lt); } template - value(const local_time& lt, detail::region reg) - : type_(value_t::LocalTime), + basic_value(const local_time& lt, detail::region reg) + : type_(value_t::local_time), region_info_(std::make_shared>(std::move(reg))) { assigner(this->local_time_, lt); } - value& operator=(const local_time& lt) + basic_value& operator=(const local_time& lt) { this->cleanup(); - this->type_ = value_t::LocalTime; + this->type_ = value_t::local_time; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_time_, lt); return *this; } template - value(const std::chrono::duration& dur) - : type_(value_t::LocalTime), + basic_value(const std::chrono::duration& dur) + : type_(value_t::local_time), region_info_(std::make_shared(region_base{})) { assigner(this->local_time_, local_time(dur)); } template - value& operator=(const std::chrono::duration& dur) + basic_value& operator=(const std::chrono::duration& dur) { this->cleanup(); - this->type_ = value_t::LocalTime; + this->type_ = value_t::local_time; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_time_, local_time(dur)); return *this; @@ -386,23 +605,23 @@ class value // local datetime ======================================================= - value(const local_datetime& ldt) - : type_(value_t::LocalDatetime), + basic_value(const local_datetime& ldt) + : type_(value_t::local_datetime), region_info_(std::make_shared(region_base{})) { assigner(this->local_datetime_, ldt); } template - value(const local_datetime& ldt, detail::region reg) - : type_(value_t::LocalDatetime), + basic_value(const local_datetime& ldt, detail::region reg) + : type_(value_t::local_datetime), region_info_(std::make_shared>(std::move(reg))) { assigner(this->local_datetime_, ldt); } - value& operator=(const local_datetime& ldt) + basic_value& operator=(const local_datetime& ldt) { this->cleanup(); - this->type_ = value_t::LocalDatetime; + this->type_ = value_t::local_datetime; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_datetime_, ldt); return *this; @@ -410,37 +629,37 @@ class value // offset datetime ====================================================== - value(const offset_datetime& odt) - : type_(value_t::OffsetDatetime), + basic_value(const offset_datetime& odt) + : type_(value_t::offset_datetime), region_info_(std::make_shared(region_base{})) { assigner(this->offset_datetime_, odt); } template - value(const offset_datetime& odt, detail::region reg) - : type_(value_t::OffsetDatetime), + basic_value(const offset_datetime& odt, detail::region reg) + : type_(value_t::offset_datetime), region_info_(std::make_shared>(std::move(reg))) { assigner(this->offset_datetime_, odt); } - value& operator=(const offset_datetime& odt) + basic_value& operator=(const offset_datetime& odt) { this->cleanup(); - this->type_ = value_t::OffsetDatetime; + this->type_ = value_t::offset_datetime; this->region_info_ = std::make_shared(region_base{}); assigner(this->offset_datetime_, odt); return *this; } - value(const std::chrono::system_clock::time_point& tp) - : type_(value_t::OffsetDatetime), + basic_value(const std::chrono::system_clock::time_point& tp) + : type_(value_t::offset_datetime), region_info_(std::make_shared(region_base{})) { assigner(this->offset_datetime_, offset_datetime(tp)); } - value& operator=(const std::chrono::system_clock::time_point& tp) + basic_value& operator=(const std::chrono::system_clock::time_point& tp) { this->cleanup(); - this->type_ = value_t::OffsetDatetime; + this->type_ = value_t::offset_datetime; this->region_info_ = std::make_shared(region_base{}); assigner(this->offset_datetime_, offset_datetime(tp)); return *this; @@ -448,47 +667,49 @@ class value // array ================================================================ - value(const array& ary) - : type_(value_t::Array), + basic_value(const array_type& ary) + : type_(value_t::array), region_info_(std::make_shared(region_base{})) { assigner(this->array_, ary); } template - value(const array& ary, detail::region reg) - : type_(value_t::Array), + basic_value(const array_type& ary, detail::region reg) + : type_(value_t::array), region_info_(std::make_shared>(std::move(reg))) { assigner(this->array_, ary); } - value& operator=(const array& ary) + basic_value& operator=(const array_type& ary) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); assigner(this->array_, ary); return *this; } - template::is_toml_type, + template::value, std::nullptr_t>::type = nullptr> - value(std::initializer_list list) - : type_(value_t::Array), + basic_value(std::initializer_list list) + : type_(value_t::array), region_info_(std::make_shared(region_base{})) { - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(auto& elem : list) {ary.emplace_back(std::move(elem));} assigner(this->array_, std::move(ary)); } - template::is_toml_type, + template::value, std::nullptr_t>::type = nullptr> - value& operator=(std::initializer_list list) + basic_value& operator=(std::initializer_list list) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(auto& elem : list) {ary.emplace_back(std::move(elem));} assigner(this->array_, std::move(ary)); return *this; @@ -496,23 +717,23 @@ class value template::value, std::nullptr_t>::type = nullptr> - value(T&& list) - : type_(value_t::Array), + basic_value(T&& list) + : type_(value_t::array), region_info_(std::make_shared(region_base{})) { - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(const auto& elem : list) {ary.emplace_back(elem);} assigner(this->array_, std::move(ary)); } template::value, std::nullptr_t>::type = nullptr> - value& operator=(T&& list) + basic_value& operator=(T&& list) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(const auto& elem : list) {ary.emplace_back(elem);} assigner(this->array_, std::move(ary)); return *this; @@ -520,42 +741,42 @@ class value // table ================================================================ - value(const table& tab) - : type_(value_t::Table), + basic_value(const table_type& tab) + : type_(value_t::table), region_info_(std::make_shared(region_base{})) { assigner(this->table_, tab); } template - value(const table& tab, detail::region reg) - : type_(value_t::Table), + basic_value(const table_type& tab, detail::region reg) + : type_(value_t::table), region_info_(std::make_shared>(std::move(reg))) { assigner(this->table_, tab); } - value& operator=(const table& tab) + basic_value& operator=(const table_type& tab) { this->cleanup(); - this->type_ = value_t::Table; + this->type_ = value_t::table ; this->region_info_ = std::make_shared(region_base{}); assigner(this->table_, tab); return *this; } - value(std::initializer_list> list) - : type_(value_t::Table), + basic_value(std::initializer_list> list) + : type_(value_t::table), region_info_(std::make_shared(region_base{})) { - table tab; + table_type tab; for(const auto& elem : list) {tab[elem.first] = elem.second;} assigner(this->table_, std::move(tab)); } - value& operator=(std::initializer_list> list) + basic_value& operator=(std::initializer_list> list) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); - table tab; + table_type tab; for(const auto& elem : list) {tab[elem.first] = elem.second;} assigner(this->table_, std::move(tab)); return *this; @@ -565,17 +786,13 @@ class value // convert using into_toml() method ------------------------------------- - template>, // not a toml::value - detail::has_into_toml_method // but has `into_toml` method - >::value, std::nullptr_t>::type = nullptr> - value(const T& ud): value(ud.into_toml()) {} + template::value, std::nullptr_t>::type = nullptr> + basic_value(const T& ud): basic_value(ud.into_toml()) {} - template>, // not a toml::value - detail::has_into_toml_method // but has `into_toml` method - >::value, std::nullptr_t>::type = nullptr> - value& operator=(const T& ud) + template::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(const T& ud) { *this = ud.into_toml(); return *this; @@ -583,17 +800,11 @@ class value // convert using into struct ----------------------------------------- - template>::value, - std::nullptr_t>::type = nullptr, - std::size_t S = sizeof(::toml::into)> - value(const T& ud): value(::toml::into::into_toml(ud)) {} + template)> + basic_value(const T& ud): basic_value(::toml::into::into_toml(ud)) {} - template>::value, - std::nullptr_t>::type = nullptr, - std::size_t S = sizeof(::toml::into)> - value& operator=(const T& ud) + template)> + basic_value& operator=(const T& ud) { *this = ::toml::into::into_toml(ud); return *this; @@ -602,37 +813,64 @@ class value // for internal use ------------------------------------------------------ template::value, std::nullptr_t>::type = nullptr> - value(std::pair> parse_result) - : value(std::move(parse_result.first), std::move(parse_result.second)) + detail::is_exact_toml_type::value, + std::nullptr_t>::type = nullptr> + basic_value(std::pair> parse_result) + : basic_value(std::move(parse_result.first), std::move(parse_result.second)) {} // type checking and casting ============================================ - template - bool is() const noexcept {return value_traits::type_index == this->type_;} + template::value, + std::nullptr_t>::type = nullptr> + bool is() const noexcept + { + return detail::type_to_enum::value == this->type_; + } bool is(value_t t) const noexcept {return t == this->type_;} - bool is_uninitialized() const noexcept {return this->is(value_t::Empty );} - bool is_boolean() const noexcept {return this->is(value_t::Boolean );} - bool is_integer() const noexcept {return this->is(value_t::Integer );} - bool is_float() const noexcept {return this->is(value_t::Float );} - bool is_string() const noexcept {return this->is(value_t::String );} - bool is_offset_datetime() const noexcept {return this->is(value_t::OffsetDatetime);} - bool is_local_datetime() const noexcept {return this->is(value_t::LocalDatetime );} - bool is_local_date() const noexcept {return this->is(value_t::LocalDate );} - bool is_local_time() const noexcept {return this->is(value_t::LocalTime );} - bool is_array() const noexcept {return this->is(value_t::Array );} - bool is_table() const noexcept {return this->is(value_t::Table );} + bool is_uninitialized() const noexcept {return this->is(value_t::empty );} + bool is_boolean() const noexcept {return this->is(value_t::boolean );} + bool is_integer() const noexcept {return this->is(value_t::integer );} + bool is_float() const noexcept {return this->is(value_t::floating );} + bool is_string() const noexcept {return this->is(value_t::string );} + bool is_offset_datetime() const noexcept {return this->is(value_t::offset_datetime);} + bool is_local_datetime() const noexcept {return this->is(value_t::local_datetime );} + bool is_local_date() const noexcept {return this->is(value_t::local_date );} + bool is_local_time() const noexcept {return this->is(value_t::local_time );} + bool is_array() const noexcept {return this->is(value_t::array );} + bool is_table() const noexcept {return this->is(value_t::table );} value_t type() const {return type_;} template - typename detail::toml_default_type::type& cast() &; + typename detail::enum_to_type::type& cast() & + { + if(this->type_ != T) + { + detail::throw_bad_cast(this->type_, *this); + } + return detail::switch_cast::invoke(*this); + } template - typename detail::toml_default_type::type const& cast() const&; + typename detail::enum_to_type::type const& cast() const& + { + if(this->type_ != T) + { + detail::throw_bad_cast(this->type_, *this); + } + return detail::switch_cast::invoke(*this); + } template - typename detail::toml_default_type::type&& cast() &&; + typename detail::enum_to_type::type&& cast() && + { + if(this->type_ != T) + { + detail::throw_bad_cast(this->type_, *this); + } + return detail::switch_cast::invoke(std::move(*this)); + } boolean const& as_boolean() const& noexcept {return this->boolean_;} integer const& as_integer() const& noexcept {return this->integer_;} @@ -642,8 +880,8 @@ class value local_datetime const& as_local_datetime() const& noexcept {return this->local_datetime_;} local_date const& as_local_date() const& noexcept {return this->local_date_;} local_time const& as_local_time() const& noexcept {return this->local_time_;} - array const& as_array() const& noexcept {return this->array_.value();} - table const& as_table() const& noexcept {return this->table_.value();} + array_type const& as_array() const& noexcept {return this->array_.value();} + table_type const& as_table() const& noexcept {return this->table_.value();} boolean & as_boolean() & noexcept {return this->boolean_;} integer & as_integer() & noexcept {return this->integer_;} @@ -653,8 +891,8 @@ class value local_datetime & as_local_datetime() & noexcept {return this->local_datetime_;} local_date & as_local_date() & noexcept {return this->local_date_;} local_time & as_local_time() & noexcept {return this->local_time_;} - array & as_array() & noexcept {return this->array_.value();} - table & as_table() & noexcept {return this->table_.value();} + array_type & as_array() & noexcept {return this->array_.value();} + table_type & as_table() & noexcept {return this->table_.value();} boolean && as_boolean() && noexcept {return std::move(this->boolean_);} integer && as_integer() && noexcept {return std::move(this->integer_);} @@ -664,20 +902,17 @@ class value local_datetime && as_local_datetime() && noexcept {return std::move(this->local_datetime_);} local_date && as_local_date() && noexcept {return std::move(this->local_date_);} local_time && as_local_time() && noexcept {return std::move(this->local_time_);} - array && as_array() && noexcept {return std::move(this->array_.value());} - table && as_table() && noexcept {return std::move(this->table_.value());} + array_type && as_array() && noexcept {return std::move(this->array_.value());} + table_type && as_table() && noexcept {return std::move(this->table_.value());} - std::string comment() const + comment_type const& comments() const noexcept { - return this->region_info_->comment(); + return this->comments_; } - std::string comment_before() const + + source_location location() const { - return this->region_info_->comment_before(); - } - std::string comment_inline() const - { - return this->region_info_->comment_inline(); + return source_location(this->region_info_); } private: @@ -686,29 +921,30 @@ class value { switch(this->type_) { - case value_t::String : {string_.~string(); return;} - case value_t::Array : {array_.~array_storage(); return;} - case value_t::Table : {table_.~table_storage(); return;} + case value_t::string : {string_.~string(); return;} + case value_t::array : {array_.~array_storage(); return;} + case value_t::table : {table_.~table_storage(); return;} default : return; } } // for error messages - friend region_base const& detail::get_region(const value&); + template class T, template class A> + friend region_base const& detail::get_region(const basic_value&); - template - friend void detail::change_region(value&, Region&&); + template class T, template class A> + friend void detail::change_region(basic_value&, Region&&); private: - using array_storage = detail::storage; - using table_storage = detail::storage; + using array_storage = detail::storage; + using table_storage = detail::storage; - value_t type_; - - // for error message information. + comment_type comments_; std::shared_ptr region_info_; - + value_t type_; union { boolean boolean_; @@ -726,13 +962,16 @@ class value namespace detail { -inline region_base const& get_region(const value& v) +template class T, template class A> +inline region_base const& get_region(const basic_value& v) { return *(v.region_info_); } -template -void change_region(value& v, Region&& reg) +template class T, template class A> +void change_region(basic_value& v, Region&& reg) { using region_type = typename std::remove_reference< typename std::remove_cv::type @@ -743,343 +982,238 @@ void change_region(value& v, Region&& reg) v.region_info_ = new_reg; return; } - -template -[[noreturn]] inline void throw_bad_cast(value_t actual, const ::toml::value& v) -{ - throw type_error(detail::format_underline(concat_to_string( - "[error] toml::value bad_cast to ", Expected), { - {std::addressof(get_region(v)), - concat_to_string("the actual type is ", actual)} - })); -} - -template -struct switch_cast; -template<> -struct switch_cast -{ - static ::toml::boolean& invoke(value& v) {return v.as_boolean();} - static ::toml::boolean const& invoke(value const& v) {return v.as_boolean();} - static ::toml::boolean&& invoke(value&& v) {return std::move(v).as_boolean();} -}; -template<> -struct switch_cast -{ - static ::toml::integer& invoke(value& v) {return v.as_integer();} - static ::toml::integer const& invoke(value const& v) {return v.as_integer();} - static ::toml::integer&& invoke(value&& v) {return std::move(v).as_integer();} -}; -template<> -struct switch_cast -{ - static ::toml::floating& invoke(value& v) {return v.as_float();} - static ::toml::floating const& invoke(value const& v) {return v.as_float();} - static ::toml::floating&& invoke(value&& v) {return std::move(v).as_float();} -}; -template<> -struct switch_cast -{ - static ::toml::string& invoke(value& v) {return v.as_string();} - static ::toml::string const& invoke(value const& v) {return v.as_string();} - static ::toml::string&& invoke(value&& v) {return std::move(v).as_string();} -}; -template<> -struct switch_cast -{ - static ::toml::offset_datetime& invoke(value& v) {return v.as_offset_datetime();} - static ::toml::offset_datetime const& invoke(value const& v) {return v.as_offset_datetime();} - static ::toml::offset_datetime&& invoke(value&& v) {return std::move(v).as_offset_datetime();} -}; -template<> -struct switch_cast -{ - static ::toml::local_datetime& invoke(value& v) {return v.as_local_datetime();} - static ::toml::local_datetime const& invoke(value const& v) {return v.as_local_datetime();} - static ::toml::local_datetime&& invoke(value&& v) {return std::move(v).as_local_datetime();} -}; -template<> -struct switch_cast -{ - static ::toml::local_date& invoke(value& v) {return v.as_local_date();} - static ::toml::local_date const& invoke(value const& v) {return v.as_local_date();} - static ::toml::local_date&& invoke(value&& v) {return std::move(v).as_local_date();} -}; -template<> -struct switch_cast -{ - static ::toml::local_time& invoke(value& v) {return v.as_local_time();} - static ::toml::local_time const& invoke(value const& v) {return v.as_local_time();} - static ::toml::local_time&& invoke(value&& v) {return std::move(v).as_local_time();} -}; -template<> -struct switch_cast -{ - static ::toml::array& invoke(value& v) {return v.as_array();} - static ::toml::array const& invoke(value const& v) {return v.as_array();} - static ::toml::array&& invoke(value&& v) {return std::move(v).as_array();} -}; -template<> -struct switch_cast -{ - static ::toml::table& invoke(value& v) {return v.as_table();} - static ::toml::table const& invoke(value const& v) {return v.as_table();} - static ::toml::table&& invoke(value&& v) {return std::move(v).as_table();} -}; }// detail -template -typename detail::toml_default_type::type& value::cast() & -{ - if(T != this->type_) - { - detail::throw_bad_cast(this->type_, *this); - } - return detail::switch_cast::invoke(*this); -} -template -typename detail::toml_default_type::type const& value::cast() const& -{ - if(T != this->type_) - { - detail::throw_bad_cast(this->type_, *this); - } - return detail::switch_cast::invoke(*this); -} -template -typename detail::toml_default_type::type&& value::cast() && -{ - if(T != this->type_) - { - detail::throw_bad_cast(this->type_, *this); - } - return detail::switch_cast::invoke(std::move(*this)); -} - -inline bool operator==(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool +operator==(const basic_value& lhs, const basic_value& rhs) { if(lhs.type() != rhs.type()){return false;} switch(lhs.type()) { - case value_t::Boolean : + case value_t::boolean : { return lhs.as_boolean() == rhs.as_boolean(); } - case value_t::Integer : + case value_t::integer : { return lhs.as_integer() == rhs.as_integer(); } - case value_t::Float : + case value_t::floating : { return lhs.as_float() == rhs.as_float(); } - case value_t::String : + case value_t::string : { return lhs.as_string() == rhs.as_string(); } - case value_t::OffsetDatetime: + case value_t::offset_datetime: { return lhs.as_offset_datetime() == rhs.as_offset_datetime(); } - case value_t::LocalDatetime: + case value_t::local_datetime: { return lhs.as_local_datetime() == rhs.as_local_datetime(); } - case value_t::LocalDate: + case value_t::local_date: { return lhs.as_local_date() == rhs.as_local_date(); } - case value_t::LocalTime: + case value_t::local_time: { return lhs.as_local_time() == rhs.as_local_time(); } - case value_t::Array : + case value_t::array : { return lhs.as_array() == rhs.as_array(); } - case value_t::Table : + case value_t::table : { return lhs.as_table() == rhs.as_table(); } - case value_t::Empty : {return true; } - case value_t::Unknown : {return false;} - default: {return false;} + case value_t::empty : {return true; } + default: {return false;} } } -inline bool operator<(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool +operator<(const basic_value& lhs, const basic_value& rhs) { if(lhs.type() != rhs.type()){return (lhs.type() < rhs.type());} switch(lhs.type()) { - case value_t::Boolean : + case value_t::boolean : { return lhs.as_boolean() < rhs.as_boolean(); } - case value_t::Integer : + case value_t::integer : { return lhs.as_integer() < rhs.as_integer(); } - case value_t::Float : + case value_t::floating : { return lhs.as_float() < rhs.as_float(); } - case value_t::String : + case value_t::string : { return lhs.as_string() < rhs.as_string(); } - case value_t::OffsetDatetime: + case value_t::offset_datetime: { return lhs.as_offset_datetime() < rhs.as_offset_datetime(); } - case value_t::LocalDatetime: + case value_t::local_datetime: { return lhs.as_local_datetime() < rhs.as_local_datetime(); } - case value_t::LocalDate: + case value_t::local_date: { return lhs.as_local_date() < rhs.as_local_date(); } - case value_t::LocalTime: + case value_t::local_time: { return lhs.as_local_time() < rhs.as_local_time(); } - case value_t::Array : + case value_t::array : { return lhs.as_array() < rhs.as_array(); } - case value_t::Table : + case value_t::table : { return lhs.as_table() < rhs.as_table(); } - case value_t::Empty : {return false;} - case value_t::Unknown : {return false;} - default: {return false;} + case value_t::empty : {return false;} + default: {return false;} } } -inline bool operator!=(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator!=(const basic_value& lhs, const basic_value& rhs) { return !(lhs == rhs); } -inline bool operator<=(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator<=(const basic_value& lhs, const basic_value& rhs) { return (lhs < rhs) || (lhs == rhs); } -inline bool operator>(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator>(const basic_value& lhs, const basic_value& rhs) { return !(lhs <= rhs); } -inline bool operator>=(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator>=(const basic_value& lhs, const basic_value& rhs) { return !(lhs < rhs); } -inline std::string format_error(const std::string& err_msg, - const toml::value& v, const std::string& comment, - std::vector hints = {}) -{ - return detail::format_underline(err_msg, - std::vector>{ - {std::addressof(detail::get_region(v)), comment} - }, std::move(hints)); -} +// inline std::string format_error(const std::string& err_msg, +// const toml::basic_value& v, const std::string& comment, +// std::vector hints = {}) +// { +// return detail::format_underline(err_msg, +// std::vector>{ +// {std::addressof(detail::get_region(v)), comment} +// }, std::move(hints)); +// } +// +// inline std::string format_error(const std::string& err_msg, +// const toml::basic_value& v1, const std::string& comment1, +// const toml::basic_value& v2, const std::string& comment2, +// std::vector hints = {}) +// { +// return detail::format_underline(err_msg, +// std::vector>{ +// {std::addressof(detail::get_region(v1)), comment1}, +// {std::addressof(detail::get_region(v2)), comment2} +// }, std::move(hints)); +// } +// +// inline std::string format_error(const std::string& err_msg, +// const toml::basic_value& v1, const std::string& comment1, +// const toml::basic_value& v2, const std::string& comment2, +// const toml::basic_value& v3, const std::string& comment3, +// std::vector hints = {}) +// { +// return detail::format_underline(err_msg, +// std::vector>{ +// {std::addressof(detail::get_region(v1)), comment1}, +// {std::addressof(detail::get_region(v2)), comment2}, +// {std::addressof(detail::get_region(v3)), comment3} +// }, std::move(hints)); +// } -inline std::string format_error(const std::string& err_msg, - const toml::value& v1, const std::string& comment1, - const toml::value& v2, const std::string& comment2, - std::vector hints = {}) -{ - return detail::format_underline(err_msg, - std::vector>{ - {std::addressof(detail::get_region(v1)), comment1}, - {std::addressof(detail::get_region(v2)), comment2} - }, std::move(hints)); -} - -inline std::string format_error(const std::string& err_msg, - const toml::value& v1, const std::string& comment1, - const toml::value& v2, const std::string& comment2, - const toml::value& v3, const std::string& comment3, - std::vector hints = {}) -{ - return detail::format_underline(err_msg, - std::vector>{ - {std::addressof(detail::get_region(v1)), comment1}, - {std::addressof(detail::get_region(v2)), comment2}, - {std::addressof(detail::get_region(v3)), comment3} - }, std::move(hints)); -} - -template +template class T, template class A> detail::return_type_of_t -visit(Visitor&& visitor, const toml::value& v) +visit(Visitor&& visitor, const toml::basic_value& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(v.as_boolean ());} - case value_t::Integer : {return visitor(v.as_integer ());} - case value_t::Float : {return visitor(v.as_float ());} - case value_t::String : {return visitor(v.as_string ());} - case value_t::OffsetDatetime: {return visitor(v.as_offset_datetime());} - case value_t::LocalDatetime : {return visitor(v.as_local_datetime ());} - case value_t::LocalDate : {return visitor(v.as_local_date ());} - case value_t::LocalTime : {return visitor(v.as_local_time ());} - case value_t::Array : {return visitor(v.as_array ());} - case value_t::Table : {return visitor(v.as_table ());} - case value_t::Empty : break; - case value_t::Unknown : break; + case value_t::boolean : {return visitor(v.as_boolean ());} + case value_t::integer : {return visitor(v.as_integer ());} + case value_t::floating : {return visitor(v.as_float ());} + case value_t::string : {return visitor(v.as_string ());} + case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} + case value_t::local_datetime : {return visitor(v.as_local_datetime ());} + case value_t::local_date : {return visitor(v.as_local_date ());} + case value_t::local_time : {return visitor(v.as_local_time ());} + case value_t::array : {return visitor(v.as_array ());} + case value_t::table : {return visitor(v.as_table ());} + case value_t::empty : break; default: break; } - throw std::runtime_error(format_error("[error] toml::visit: toml::value " - "does not have any valid value.", v, "here")); + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); } -template +template class T, template class A> detail::return_type_of_t -visit(Visitor&& visitor, toml::value& v) +visit(Visitor&& visitor, toml::basic_value& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(v.as_boolean ());} - case value_t::Integer : {return visitor(v.as_integer ());} - case value_t::Float : {return visitor(v.as_float ());} - case value_t::String : {return visitor(v.as_string ());} - case value_t::OffsetDatetime: {return visitor(v.as_offset_datetime());} - case value_t::LocalDatetime : {return visitor(v.as_local_datetime ());} - case value_t::LocalDate : {return visitor(v.as_local_date ());} - case value_t::LocalTime : {return visitor(v.as_local_time ());} - case value_t::Array : {return visitor(v.as_array ());} - case value_t::Table : {return visitor(v.as_table ());} - case value_t::Empty : break; - case value_t::Unknown : break; + case value_t::boolean : {return visitor(v.as_boolean ());} + case value_t::integer : {return visitor(v.as_integer ());} + case value_t::floating : {return visitor(v.as_float ());} + case value_t::string : {return visitor(v.as_string ());} + case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} + case value_t::local_datetime : {return visitor(v.as_local_datetime ());} + case value_t::local_date : {return visitor(v.as_local_date ());} + case value_t::local_time : {return visitor(v.as_local_time ());} + case value_t::array : {return visitor(v.as_array ());} + case value_t::table : {return visitor(v.as_table ());} + case value_t::empty : break; default: break; } - throw std::runtime_error(format_error("[error] toml::visit: toml::value " - "does not have any valid value.", v, "here")); + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); } -template +template class T, template class A> detail::return_type_of_t -visit(Visitor&& visitor, toml::value&& v) +visit(Visitor&& visitor, toml::basic_value&& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(std::move(v.as_boolean ()));} - case value_t::Integer : {return visitor(std::move(v.as_integer ()));} - case value_t::Float : {return visitor(std::move(v.as_float ()));} - case value_t::String : {return visitor(std::move(v.as_string ()));} - case value_t::OffsetDatetime: {return visitor(std::move(v.as_offset_datetime()));} - case value_t::LocalDatetime : {return visitor(std::move(v.as_local_datetime ()));} - case value_t::LocalDate : {return visitor(std::move(v.as_local_date ()));} - case value_t::LocalTime : {return visitor(std::move(v.as_local_time ()));} - case value_t::Array : {return visitor(std::move(v.as_array ()));} - case value_t::Table : {return visitor(std::move(v.as_table ()));} - case value_t::Empty : break; - case value_t::Unknown : break; + case value_t::boolean : {return visitor(std::move(v.as_boolean ()));} + case value_t::integer : {return visitor(std::move(v.as_integer ()));} + case value_t::floating : {return visitor(std::move(v.as_float ()));} + case value_t::string : {return visitor(std::move(v.as_string ()));} + case value_t::offset_datetime: {return visitor(std::move(v.as_offset_datetime()));} + case value_t::local_datetime : {return visitor(std::move(v.as_local_datetime ()));} + case value_t::local_date : {return visitor(std::move(v.as_local_date ()));} + case value_t::local_time : {return visitor(std::move(v.as_local_time ()));} + case value_t::array : {return visitor(std::move(v.as_array ()));} + case value_t::table : {return visitor(std::move(v.as_table ()));} + case value_t::empty : break; default: break; } - throw std::runtime_error(format_error("[error] toml::visit: toml::value " - "does not have any valid value.", v, "here")); + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); } }// toml