diff --git a/toml/parser.hpp b/toml/parser.hpp index da7a201..29131cb 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -1167,7 +1167,7 @@ insert_nested_key(table& root, const toml::value& v, { if(tab->count(k) == 1) // there is already an array of table { - if(tab->at(k).is(value_t::Table)) + if(tab->at(k).is_table()) { // show special err msg for conflicting table throw syntax_error(format_underline(concat_to_string( @@ -1180,7 +1180,7 @@ insert_nested_key(table& root, const toml::value& v, "this conflicts with the previous table"} })); } - else if(!(tab->at(k).is(value_t::Array))) + else if(!(tab->at(k).is_array())) { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of table (\"", @@ -1193,8 +1193,9 @@ insert_nested_key(table& root, const toml::value& v, "while inserting this array-of-tables"} })); } - array& a = tab->at(k).template cast(); - if(!(a.front().is(value_t::Table))) + // the above if-else-if checks tab->at(k) is an array + array& a = tab->at(k).as_array(); + if(!(a.front().is_table())) { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of table (\"", @@ -1248,7 +1249,7 @@ insert_nested_key(table& root, const toml::value& v, if(tab->count(k) == 1) { - if(tab->at(k).is(value_t::Table) && v.is(value_t::Table)) + if(tab->at(k).is_table() && v.is_table()) { if(!is_valid_forward_table_definition( tab->at(k), first, iter, last)) @@ -1268,18 +1269,18 @@ insert_nested_key(table& root, const toml::value& v, // d = 42 // [a] // e = 2.71 - auto& t = tab->at(k).cast(); - for(const auto& kv : v.cast()) + auto& t = tab->at(k).as_table(); + for(const auto& kv : v.as_table()) { t[kv.first] = kv.second; } detail::change_region(tab->at(k), key_reg); return ok(true); } - else if(v.is(value_t::Table) && - tab->at(k).is(value_t::Array) && - tab->at(k).cast().size() > 0 && - tab->at(k).cast().front().is(value_t::Table)) + else if(v.is_table() && + tab->at(k).is_array() && + tab->at(k).as_array().size() > 0 && + tab->at(k).as_array().front().is_table()) { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of tables (\"", @@ -1319,14 +1320,14 @@ insert_nested_key(table& root, const toml::value& v, } // type checking... - if(tab->at(k).is(value_t::Table)) + if(tab->at(k).is_table()) { - tab = std::addressof((*tab)[k].template cast()); + tab = std::addressof((*tab)[k].as_table()); } - else if(tab->at(k).is(value_t::Array)) // inserting to array-of-tables? + else if(tab->at(k).is_array()) // inserting to array-of-tables? { - array& a = (*tab)[k].template cast(); - if(!a.back().is(value_t::Table)) + array& a = (*tab)[k].as_array(); + if(!a.back().is_table()) { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: target (", @@ -1337,7 +1338,7 @@ insert_nested_key(table& root, const toml::value& v, {std::addressof(get_region(v)), "inserting this"} })); } - tab = std::addressof(a.back().template cast()); + tab = std::addressof(a.back().as_table()); } else { diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 3854ead..299d019 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -157,7 +157,7 @@ struct serializer std::string operator()(const array& v) const { - if(!v.empty() && v.front().is(value_t::Table))// v is an array of tables + if(!v.empty() && v.front().is_table())// v is an array of tables { // if it's not inlined, we need to add `[[table.key]]`. // but if it can be inlined, we need `table.key = [...]`. @@ -411,7 +411,7 @@ struct serializer // remaining non-table values will be assigned into [foo.bar], not [foo] for(const auto kv : v) { - if(kv.second.is(value_t::Table) || is_array_of_tables(kv.second)) + if(kv.second.is_table() || is_array_of_tables(kv.second)) { continue; } @@ -438,7 +438,7 @@ struct serializer bool multiline_table_printed = false; for(const auto& kv : v) { - if(!kv.second.is(value_t::Table) && !is_array_of_tables(kv.second)) + if(!kv.second.is_table() && !is_array_of_tables(kv.second)) { continue; // other stuff are already serialized. skip them. } @@ -467,10 +467,9 @@ struct serializer bool is_array_of_tables(const value& v) const { - if(!v.is(value_t::Array)) {return false;} - - const auto& a = v.cast(); - return !a.empty() && a.front().is(value_t::Table); + if(!v.is_array()) {return false;} + const auto& a = v.as_array(); + return !a.empty() && a.front().is_table(); } private: diff --git a/toml/value.hpp b/toml/value.hpp index cad416b..7f6f42b 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -634,27 +634,38 @@ class value template typename detail::toml_default_type::type&& cast() &&; - boolean const& as_boolean() const {return this->cast();} - integer const& as_integer() const {return this->cast();} - floating const& as_float() const {return this->cast();} - string const& as_string() const {return this->cast();} - offset_datetime const& as_offset_datetime() const {return this->cast();} - local_datetime const& as_local_datetime() const {return this->cast();} - local_date const& as_local_date() const {return this->cast();} - local_time const& as_local_time() const {return this->cast();} - array const& as_array() const {return this->cast();} - table const& as_table() const {return this->cast();} + boolean const& as_boolean() const& noexcept {return this->boolean_;} + integer const& as_integer() const& noexcept {return this->integer_;} + floating const& as_float() const& noexcept {return this->floating_;} + string const& as_string() const& noexcept {return this->string_;} + offset_datetime const& as_offset_datetime() const& noexcept {return this->offset_datetime_;} + 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();} - boolean& as_boolean() {return this->cast();} - integer& as_integer() {return this->cast();} - floating& as_float() {return this->cast();} - string& as_string() {return this->cast();} - offset_datetime& as_offset_datetime() {return this->cast();} - local_datetime& as_local_datetime() {return this->cast();} - local_date& as_local_date() {return this->cast();} - local_time& as_local_time() {return this->cast();} - array& as_array() {return this->cast();} - table& as_table() {return this->cast();} + boolean & as_boolean() & noexcept {return this->boolean_;} + integer & as_integer() & noexcept {return this->integer_;} + floating & as_float() & noexcept {return this->floating_;} + string & as_string() & noexcept {return this->string_;} + offset_datetime& as_offset_datetime() & noexcept {return this->offset_datetime_;} + 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();} + + boolean && as_boolean() && noexcept {return std::move(this->boolean_);} + integer && as_integer() && noexcept {return std::move(this->integer_);} + floating && as_float() && noexcept {return std::move(this->floating_);} + string && as_string() && noexcept {return std::move(this->string_);} + offset_datetime&& as_offset_datetime() && noexcept {return std::move(this->offset_datetime_);} + 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());} std::string comment() const { @@ -688,9 +699,6 @@ class value template friend void detail::change_region(value&, Region&&); - template - struct switch_cast; - private: using array_storage = detail::storage; @@ -736,107 +744,116 @@ void change_region(value& v, Region&& reg) return; } -}// detail +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 value::switch_cast +template +struct switch_cast; +template<> +struct switch_cast { - static Boolean& invoke(value& v) {return v.boolean_;} - static Boolean const& invoke(value const& v) {return v.boolean_;} - static Boolean&& invoke(value&& v) {return std::move(v.boolean_);} + static Boolean& invoke(value& v) {return v.as_boolean();} + static Boolean const& invoke(value const& v) {return v.as_boolean();} + static Boolean&& invoke(value&& v) {return std::move(v).as_boolean();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static Integer& invoke(value& v) {return v.integer_;} - static Integer const& invoke(value const& v) {return v.integer_;} - static Integer&& invoke(value&& v) {return std::move(v.integer_);} + static Integer& invoke(value& v) {return v.as_integer();} + static Integer const& invoke(value const& v) {return v.as_integer();} + static Integer&& invoke(value&& v) {return std::move(v).as_integer();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static Float& invoke(value& v) {return v.floating_;} - static Float const& invoke(value const& v) {return v.floating_;} - static Float&& invoke(value&& v) {return std::move(v.floating_);} + static Float& invoke(value& v) {return v.as_float();} + static Float const& invoke(value const& v) {return v.as_float();} + static Float&& invoke(value&& v) {return std::move(v).as_float();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static String& invoke(value& v) {return v.string_;} - static String const& invoke(value const& v) {return v.string_;} - static String&& invoke(value&& v) {return std::move(v.string_);} + static String& invoke(value& v) {return v.as_string();} + static String const& invoke(value const& v) {return v.as_string();} + static String&& invoke(value&& v) {return std::move(v).as_string();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static OffsetDatetime& invoke(value& v) {return v.offset_datetime_;} - static OffsetDatetime const& invoke(value const& v) {return v.offset_datetime_;} - static OffsetDatetime&& invoke(value&& v) {return std::move(v.offset_datetime_);} + static OffsetDatetime& invoke(value& v) {return v.as_offset_datetime();} + static OffsetDatetime const& invoke(value const& v) {return v.as_offset_datetime();} + static OffsetDatetime&& invoke(value&& v) {return std::move(v).as_offset_datetime();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static LocalDatetime& invoke(value& v) {return v.local_datetime_;} - static LocalDatetime const& invoke(value const& v) {return v.local_datetime_;} - static LocalDatetime&& invoke(value&& v) {return std::move(v.local_datetime_);} + static LocalDatetime& invoke(value& v) {return v.as_local_datetime();} + static LocalDatetime const& invoke(value const& v) {return v.as_local_datetime();} + static LocalDatetime&& invoke(value&& v) {return std::move(v).as_local_datetime();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static LocalDate& invoke(value& v) {return v.local_date_;} - static LocalDate const& invoke(value const& v) {return v.local_date_;} - static LocalDate&& invoke(value&& v) {return std::move(v.local_date_);} + static LocalDate& invoke(value& v) {return v.as_local_date();} + static LocalDate const& invoke(value const& v) {return v.as_local_date();} + static LocalDate&& invoke(value&& v) {return std::move(v).as_local_date();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static LocalTime& invoke(value& v) {return v.local_time_;} - static LocalTime const& invoke(value const& v) {return v.local_time_;} - static LocalTime&& invoke(value&& v) {return std::move(v.local_time_);} + static LocalTime& invoke(value& v) {return v.as_local_time();} + static LocalTime const& invoke(value const& v) {return v.as_local_time();} + static LocalTime&& invoke(value&& v) {return std::move(v).as_local_time();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static Array& invoke(value& v) {return v.array_.value();} - static Array const& invoke(value const& v) {return v.array_.value();} - static Array&& invoke(value&& v) {return std::move(v.array_.value());} + static Array& invoke(value& v) {return v.as_array();} + static Array const& invoke(value const& v) {return v.as_array();} + static Array&& invoke(value&& v) {return std::move(v).as_array();} }; -template<> struct value::switch_cast +template<> +struct switch_cast { - static Table& invoke(value& v) {return v.table_.value();} - static Table const& invoke(value const& v) {return v.table_.value();} - static Table&& invoke(value&& v) {return std::move(v.table_.value());} + static Table& invoke(value& v) {return v.as_table();} + static Table const& invoke(value const& v) {return v.as_table();} + static Table&& invoke(value&& v) {return std::move(v).as_table();} }; +}// detail template typename detail::toml_default_type::type& value::cast() & { if(T != this->type_) { - throw type_error(detail::format_underline(concat_to_string( - "[error] toml::value bad_cast to ", T), { - {this->region_info_.get(), - concat_to_string("the actual type is ", this->type_)} - })); + detail::throw_bad_cast(this->type_, *this); } - return switch_cast::invoke(*this); + return detail::switch_cast::invoke(*this); } template typename detail::toml_default_type::type const& value::cast() const& { if(T != this->type_) { - throw type_error(detail::format_underline(concat_to_string( - "[error] toml::value bad_cast to ", T), { - {this->region_info_.get(), - concat_to_string("the actual type is ", this->type_)} - })); + detail::throw_bad_cast(this->type_, *this); } - return switch_cast::invoke(*this); + return detail::switch_cast::invoke(*this); } template typename detail::toml_default_type::type&& value::cast() && { if(T != this->type_) { - throw type_error(detail::format_underline(concat_to_string( - "[error] toml::value bad_cast to ", T), { - {this->region_info_.get(), - concat_to_string("the actual type is ", this->type_)} - })); + detail::throw_bad_cast(this->type_, *this); } - return switch_cast::invoke(std::move(*this)); + return detail::switch_cast::invoke(std::move(*this)); } inline bool operator==(const toml::value& lhs, const toml::value& rhs) @@ -845,28 +862,48 @@ inline bool operator==(const toml::value& lhs, const toml::value& rhs) switch(lhs.type()) { case value_t::Boolean : - return lhs.cast() == rhs.cast(); + { + return lhs.as_boolean() == rhs.as_boolean(); + } case value_t::Integer : - return lhs.cast() == rhs.cast(); + { + return lhs.as_integer() == rhs.as_integer(); + } case value_t::Float : - return lhs.cast() == rhs.cast(); + { + return lhs.as_float() == rhs.as_float(); + } case value_t::String : - return lhs.cast() == rhs.cast(); + { + return lhs.as_string() == rhs.as_string(); + } case value_t::OffsetDatetime: - return lhs.cast() == rhs.cast(); + { + return lhs.as_offset_datetime() == rhs.as_offset_datetime(); + } case value_t::LocalDatetime: - return lhs.cast() == rhs.cast(); + { + return lhs.as_local_datetime() == rhs.as_local_datetime(); + } case value_t::LocalDate: - return lhs.cast() == rhs.cast(); + { + return lhs.as_local_date() == rhs.as_local_date(); + } case value_t::LocalTime: - return lhs.cast() == rhs.cast(); + { + return lhs.as_local_time() == rhs.as_local_time(); + } case value_t::Array : - return lhs.cast() == rhs.cast(); + { + return lhs.as_array() == rhs.as_array(); + } case value_t::Table : - return lhs.cast() == rhs.cast(); - case value_t::Empty : return true; - case value_t::Unknown : return false; - default: return false; + { + return lhs.as_table() == rhs.as_table(); + } + case value_t::Empty : {return true; } + case value_t::Unknown : {return false;} + default: {return false;} } } inline bool operator<(const toml::value& lhs, const toml::value& rhs) @@ -875,28 +912,48 @@ inline bool operator<(const toml::value& lhs, const toml::value& rhs) switch(lhs.type()) { case value_t::Boolean : - return lhs.cast() < rhs.cast(); + { + return lhs.as_boolean() < rhs.as_boolean(); + } case value_t::Integer : - return lhs.cast() < rhs.cast(); + { + return lhs.as_integer() < rhs.as_integer(); + } case value_t::Float : - return lhs.cast() < rhs.cast(); + { + return lhs.as_float() < rhs.as_float(); + } case value_t::String : - return lhs.cast() < rhs.cast(); + { + return lhs.as_string() < rhs.as_string(); + } case value_t::OffsetDatetime: - return lhs.cast() < rhs.cast(); + { + return lhs.as_offset_datetime() < rhs.as_offset_datetime(); + } case value_t::LocalDatetime: - return lhs.cast() < rhs.cast(); + { + return lhs.as_local_datetime() < rhs.as_local_datetime(); + } case value_t::LocalDate: - return lhs.cast() < rhs.cast(); + { + return lhs.as_local_date() < rhs.as_local_date(); + } case value_t::LocalTime: - return lhs.cast() < rhs.cast(); + { + return lhs.as_local_time() < rhs.as_local_time(); + } case value_t::Array : - return lhs.cast() < rhs.cast(); + { + return lhs.as_array() < rhs.as_array(); + } case value_t::Table : - return lhs.cast() < rhs.cast(); - case value_t::Empty : return false; - case value_t::Unknown : return false; - default: return false; + { + return lhs.as_table() < rhs.as_table(); + } + case value_t::Empty : {return false;} + case value_t::Unknown : {return false;} + default: {return false;} } } @@ -959,16 +1016,16 @@ visit(Visitor&& visitor, const toml::value& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(v.cast());} - case value_t::Integer : {return visitor(v.cast());} - case value_t::Float : {return visitor(v.cast());} - case value_t::String : {return visitor(v.cast());} - case value_t::OffsetDatetime: {return visitor(v.cast());} - case value_t::LocalDatetime : {return visitor(v.cast());} - case value_t::LocalDate : {return visitor(v.cast());} - case value_t::LocalTime : {return visitor(v.cast());} - case value_t::Array : {return visitor(v.cast());} - case value_t::Table : {return visitor(v.cast());} + 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; default: break; @@ -983,16 +1040,16 @@ visit(Visitor&& visitor, toml::value& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(v.cast());} - case value_t::Integer : {return visitor(v.cast());} - case value_t::Float : {return visitor(v.cast());} - case value_t::String : {return visitor(v.cast());} - case value_t::OffsetDatetime: {return visitor(v.cast());} - case value_t::LocalDatetime : {return visitor(v.cast());} - case value_t::LocalDate : {return visitor(v.cast());} - case value_t::LocalTime : {return visitor(v.cast());} - case value_t::Array : {return visitor(v.cast());} - case value_t::Table : {return visitor(v.cast());} + 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; default: break; @@ -1007,16 +1064,16 @@ visit(Visitor&& visitor, toml::value&& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(std::move(v.cast()));} - case value_t::Integer : {return visitor(std::move(v.cast()));} - case value_t::Float : {return visitor(std::move(v.cast()));} - case value_t::String : {return visitor(std::move(v.cast()));} - case value_t::OffsetDatetime: {return visitor(std::move(v.cast()));} - case value_t::LocalDatetime : {return visitor(std::move(v.cast()));} - case value_t::LocalDate : {return visitor(std::move(v.cast()));} - case value_t::LocalTime : {return visitor(std::move(v.cast()));} - case value_t::Array : {return visitor(std::move(v.cast()));} - case value_t::Table : {return visitor(std::move(v.cast()));} + 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; default: break;