From 0babe8d589a8a527b39eb23b99b3741bfa97fe1b Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 14 Mar 2019 00:59:10 +0900 Subject: [PATCH] fix: use format_underline for N regions everywhere --- toml/get.hpp | 28 ++-- toml/parser.hpp | 352 +++++++++++++++++++++++++++--------------------- toml/value.hpp | 36 +++-- 3 files changed, 236 insertions(+), 180 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index fe51622..80336ce 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -210,8 +210,9 @@ T get(const value& v) { throw std::out_of_range(detail::format_underline(concat_to_string( "[erorr] toml::get specified container size is ", container.size(), - " but there are ", ar.size(), " elements in toml array."), - detail::get_region(v), "here")); + " but there are ", ar.size(), " elements in toml array."), { + {std::addressof(detail::get_region(v)), "here"} + })); } std::transform(ar.cbegin(), ar.cend(), container.begin(), [](const value& x){return ::toml::get(x);}); @@ -233,7 +234,9 @@ T get(const value& v) { throw std::out_of_range(detail::format_underline(concat_to_string( "[erorr] toml::get specified std::pair but there are ", ar.size(), - " elements in toml array."), detail::get_region(v), "here")); + " elements in toml array."), { + {std::addressof(detail::get_region(v)), "here"} + })); } return std::make_pair(::toml::get(ar.at(0)), ::toml::get(ar.at(1))); @@ -264,7 +267,9 @@ T get(const value& v) throw std::out_of_range(detail::format_underline(concat_to_string( "[erorr] toml::get specified std::tuple with ", std::tuple_size::value, "elements, but there are ", ar.size(), - " elements in toml array."), detail::get_region(v), "here")); + " elements in toml array."), { + {std::addressof(detail::get_region(v)), "here"} + })); } return detail::get_tuple_impl(ar, detail::make_index_sequence::value>{}); @@ -340,8 +345,9 @@ find(const toml::value& v, const toml::key& ky) if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( - "[error] key \"", ky, "\" not found"), detail::get_region(v), - "in this table")); + "[error] key \"", ky, "\" not found"), { + {std::addressof(detail::get_region(v)), "in this table"} + })); } return ::toml::get(tab.at(ky)); } @@ -353,8 +359,9 @@ find(toml::value& v, const toml::key& ky) if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( - "[error] key \"", ky, "\" not found"), detail::get_region(v), - "in this table")); + "[error] key \"", ky, "\" not found"), { + {std::addressof(detail::get_region(v)), "in this table"} + })); } return ::toml::get(tab.at(ky)); } @@ -366,8 +373,9 @@ find(toml::value&& v, const toml::key& ky) if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( - "[error] key \"", ky, "\" not found"), detail::get_region(v), - "in this table")); + "[error] key \"", ky, "\" not found"), { + {std::addressof(detail::get_region(v)), "in this table"} + })); } return ::toml::get(std::move(tab[ky])); } diff --git a/toml/parser.hpp b/toml/parser.hpp index 26b13b1..9c1d562 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -29,13 +29,13 @@ parse_boolean(location& loc) else // internal error. { throw toml::internal_error(format_underline( - "[error] toml::parse_boolean: internal error", reg, - "invalid token")); + "[error] toml::parse_boolean: internal error", + {{std::addressof(reg), "invalid token"}})); } } loc.iter() = first; //rollback - return err(format_underline("[error] toml::parse_boolean: ", loc, - "the next token is not a boolean")); + return err(format_underline("[error] toml::parse_boolean: ", + {{std::addressof(loc), "the next token is not a boolean"}})); } template @@ -57,14 +57,14 @@ parse_binary_integer(location& loc) { throw toml::internal_error(format_underline( "[error] toml::parse_integer: internal error", - token.unwrap(), "invalid token")); + {{std::addressof(token.unwrap()), "invalid token"}})); } } return ok(std::make_pair(retval, token.unwrap())); } loc.iter() = first; - return err(format_underline("[error] toml::parse_binary_integer:", loc, - "the next token is not an integer")); + return err(format_underline("[error] toml::parse_binary_integer:", + {{std::addressof(loc), "the next token is not an integer"}})); } template @@ -84,8 +84,8 @@ parse_octal_integer(location& loc) return ok(std::make_pair(retval, token.unwrap())); } loc.iter() = first; - return err(format_underline("[error] toml::parse_octal_integer:", loc, - "the next token is not an integer")); + return err(format_underline("[error] toml::parse_octal_integer:", + {{std::addressof(loc), "the next token is not an integer"}})); } template @@ -105,8 +105,8 @@ parse_hexadecimal_integer(location& loc) return ok(std::make_pair(retval, token.unwrap())); } loc.iter() = first; - return err(format_underline("[error] toml::parse_hexadecimal_integer", loc, - "the next token is not an integer")); + return err(format_underline("[error] toml::parse_hexadecimal_integer", + {{std::addressof(loc), "the next token is not an integer"}})); } template @@ -133,8 +133,8 @@ parse_integer(location& loc) return ok(std::make_pair(retval, token.unwrap())); } loc.iter() = first; - return err(format_underline("[error] toml::parse_integer: ", loc, - "the next token is not an integer")); + return err(format_underline("[error] toml::parse_integer: ", + {{std::addressof(loc), "the next token is not an integer"}})); } template @@ -222,8 +222,8 @@ parse_floating(location& loc) return ok(std::make_pair(v, token.unwrap())); } loc.iter() = first; - return err(format_underline("[error] toml::parse_floating: ", loc, - "the next token is not a float")); + return err(format_underline("[error] toml::parse_floating: ", + {{std::addressof(loc), "the next token is not a float"}})); } template @@ -252,8 +252,9 @@ std::string read_utf8_codepoint(const region& reg, { std::cerr << format_underline("[warning] " "toml::read_utf8_codepoint: codepoints in the range " - "[0xD800, 0xDFFF] are not valid UTF-8.", - loc, "not a valid UTF-8 codepoint") << std::endl; + "[0xD800, 0xDFFF] are not valid UTF-8.", {{ + std::addressof(loc), "not a valid UTF-8 codepoint" + }}) << std::endl; } assert(codepoint < 0xD800 || 0xDFFF < codepoint); // 1110yyyy 10yxxxxx 10xxxxxx @@ -267,8 +268,8 @@ std::string read_utf8_codepoint(const region& reg, { std::cerr << format_underline("[error] " "toml::read_utf8_codepoint: input codepoint is too large to " - "decode as a unicode character.", loc, - "should be in [0x00..0x10FFFF]") << std::endl; + "decode as a unicode character.", {{std::addressof(loc), + "should be in [0x00..0x10FFFF]"}}) << std::endl; } // 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx character += static_cast(0xF0| codepoint >> 18); @@ -280,7 +281,7 @@ std::string read_utf8_codepoint(const region& reg, { throw std::range_error(format_underline(concat_to_string("[error] " "input codepoint (", str, ") is too large to encode as utf-8."), - reg, "should be in [0x00..0x10FFFF]")); + {{std::addressof(reg), "should be in [0x00..0x10FFFF]"}})); } return character; } @@ -291,8 +292,8 @@ result parse_escape_sequence(location& loc) const auto first = loc.iter(); if(first == loc.end() || *first != '\\') { - return err(format_underline("[error]: toml::parse_escape_sequence: ", loc, - "the next token is not an escape sequence \"\\\"")); + return err(format_underline("[error]: toml::parse_escape_sequence: ", {{ + std::addressof(loc), "the next token is not a backslash \"\\\""}})); } ++loc.iter(); switch(*loc.iter()) @@ -314,7 +315,7 @@ result parse_escape_sequence(location& loc) { return err(format_underline("[error] parse_escape_sequence: " "invalid token found in UTF-8 codepoint uXXXX.", - loc, token.unwrap_err())); + {{std::addressof(loc), token.unwrap_err()}})); } } case 'U': @@ -327,16 +328,16 @@ result parse_escape_sequence(location& loc) { return err(format_underline("[error] parse_escape_sequence: " "invalid token found in UTF-8 codepoint Uxxxxxxxx", - loc, token.unwrap_err())); + {{std::addressof(loc), token.unwrap_err()}})); } } } const auto msg = format_underline("[error] parse_escape_sequence: " - "unknown escape sequence appeared.", loc, "escape sequence is one of" - " \\, \", b, t, n, f, r, uxxxx, Uxxxxxxxx", {"if you want to write " - "backslash as just one backslash, use literal string like:", - "regex = '<\\i\\c*\\s*>'"}); + "unknown escape sequence appeared.", {{std::addressof(loc), + "escape sequence is one of \\, \", b, t, n, f, r, uxxxx, Uxxxxxxxx"}}, + /* Hints = */{"if you want to write backslash as just one backslash, " + "use literal string like: regex = '<\\i\\c*\\s*>'"}); loc.iter() = first; return err(msg); } @@ -359,7 +360,7 @@ parse_ml_basic_string(location& loc) { throw internal_error(format_underline("[error] " "parse_ml_basic_string: invalid token", - inner_loc, "should be \"\"\"")); + {{std::addressof(inner_loc), "should be \"\"\""}})); } // immediate newline is ignored (if exists) /* discard return value */ lex_newline::invoke(inner_loc); @@ -385,7 +386,7 @@ parse_ml_basic_string(location& loc) { throw internal_error(format_underline("[error] " "parse_ml_basic_string: unexpected end of region", - inner_loc, "not sufficient token")); + {{std::addressof(inner_loc), "not sufficient token"}})); } delim = lex_ml_basic_string_delim::invoke(inner_loc); } @@ -412,7 +413,7 @@ parse_basic_string(location& loc) if(!quot) { throw internal_error(format_underline("[error] parse_basic_string: " - "invalid token", inner_loc, "should be \"")); + "invalid token", {{std::addressof(inner_loc), "should be \""}})); } std::string retval; @@ -434,7 +435,7 @@ parse_basic_string(location& loc) { throw internal_error(format_underline("[error] " "parse_ml_basic_string: unexpected end of region", - inner_loc, "not sufficient token")); + {{std::addressof(inner_loc), "not sufficient token"}})); } quot = lex_quotation_mark::invoke(inner_loc); } @@ -461,7 +462,7 @@ parse_ml_literal_string(location& loc) { throw internal_error(format_underline("[error] " "parse_ml_literal_string: invalid token", - inner_loc, "should be '''")); + {{std::addressof(inner_loc), "should be '''"}})); } // immediate newline is ignored (if exists) /* discard return value */ lex_newline::invoke(inner_loc); @@ -473,7 +474,7 @@ parse_ml_literal_string(location& loc) { throw internal_error(format_underline("[error] " "parse_ml_literal_string: invalid token", - inner_loc, "should be '''")); + {{std::addressof(inner_loc), "should be '''"}})); } return ok(std::make_pair( toml::string(body.unwrap().str(), toml::string_t::literal), @@ -500,7 +501,7 @@ parse_literal_string(location& loc) { throw internal_error(format_underline("[error] " "parse_literal_string: invalid token", - inner_loc, "should be '")); + {{std::addressof(inner_loc), "should be '"}})); } const auto body = repeat::invoke(inner_loc); @@ -510,7 +511,7 @@ parse_literal_string(location& loc) { throw internal_error(format_underline("[error] " "parse_literal_string: invalid token", - inner_loc, "should be '")); + {{std::addressof(inner_loc), "should be '"}})); } return ok(std::make_pair( toml::string(body.unwrap().str(), toml::string_t::literal), @@ -531,8 +532,8 @@ parse_string(location& loc) if(const auto rslt = parse_ml_literal_string(loc)) {return rslt;} if(const auto rslt = parse_basic_string(loc)) {return rslt;} if(const auto rslt = parse_literal_string(loc)) {return rslt;} - return err(format_underline("[error] toml::parse_string: ", loc, - "the next token is not a string")); + return err(format_underline("[error] toml::parse_string: ", + {{std::addressof(loc), "the next token is not a string"}})); } template @@ -547,21 +548,23 @@ parse_local_date(location& loc) const auto y = lex_date_fullyear::invoke(inner_loc); if(!y || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-') { + const std::string msg = y.map_err_or_else( + [](const std::string& msg) {return msg;}, "should be `-`"); + throw internal_error(format_underline("[error]: " "toml::parse_inner_local_date: invalid year format", - inner_loc, y.map_err_or_else([](const std::string& msg) { - return msg; - }, "should be `-`"))); + {{std::addressof(inner_loc), msg}})); } ++inner_loc.iter(); const auto m = lex_date_month::invoke(inner_loc); if(!m || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != '-') { + const std::string msg = m.map_err_or_else( + [](const std::string& msg) {return msg;}, "should be `-`"); + throw internal_error(format_underline("[error]: " "toml::parse_local_date: invalid month format", - inner_loc, m.map_err_or_else([](const std::string& msg) { - return msg; - }, "should be `-`"))); + {{std::addressof(inner_loc), msg}})); } ++inner_loc.iter(); const auto d = lex_date_mday::invoke(inner_loc); @@ -569,7 +572,7 @@ parse_local_date(location& loc) { throw internal_error(format_underline("[error]: " "toml::parse_local_date: invalid day format", - inner_loc, d.unwrap_err())); + {{std::addressof(inner_loc), d.unwrap_err()}})); } return ok(std::make_pair(local_date( static_cast(from_string(y.unwrap().str(), 0)), @@ -581,8 +584,8 @@ parse_local_date(location& loc) else { loc.iter() = first; - return err(format_underline("[error]: toml::parse_local_date: ", loc, - "the next token is not a local_date")); + return err(format_underline("[error]: toml::parse_local_date: ", + {{std::addressof(loc), "the next token is not a local_date"}})); } } @@ -598,21 +601,23 @@ parse_local_time(location& loc) const auto h = lex_time_hour::invoke(inner_loc); if(!h || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':') { + const std::string msg = h.map_err_or_else( + [](const std::string& msg) {return msg;}, "should be `:`"); + throw internal_error(format_underline("[error]: " "toml::parse_local_time: invalid year format", - inner_loc, h.map_err_or_else([](const std::string& msg) { - return msg; - }, "should be `:`"))); + {{std::addressof(inner_loc), msg}})); } ++inner_loc.iter(); const auto m = lex_time_minute::invoke(inner_loc); if(!m || inner_loc.iter() == inner_loc.end() || *inner_loc.iter() != ':') { + const std::string msg = m.map_err_or_else( + [](const std::string& msg) {return msg;}, "should be `:`"); + throw internal_error(format_underline("[error]: " "toml::parse_local_time: invalid month format", - inner_loc, m.map_err_or_else([](const std::string& msg) { - return msg; - }, "should be `:`"))); + {{std::addressof(inner_loc), msg}})); } ++inner_loc.iter(); const auto s = lex_time_second::invoke(inner_loc); @@ -620,7 +625,7 @@ parse_local_time(location& loc) { throw internal_error(format_underline("[error]: " "toml::parse_local_time: invalid second format", - inner_loc, s.unwrap_err())); + {{std::addressof(inner_loc), s.unwrap_err()}})); } local_time time( static_cast(from_string(h.unwrap().str(), 0)), @@ -656,7 +661,7 @@ parse_local_time(location& loc) { throw internal_error(format_underline("[error]: " "toml::parse_local_time: invalid subsecond format", - inner_loc, secfrac.unwrap_err())); + {{std::addressof(inner_loc), secfrac.unwrap_err()}})); } } return ok(std::make_pair(time, token.unwrap())); @@ -664,8 +669,8 @@ parse_local_time(location& loc) else { loc.iter() = first; - return err(format_underline("[error]: toml::parse_local_time: ", loc, - "the next token is not a local_time")); + return err(format_underline("[error]: toml::parse_local_time: ", + {{std::addressof(loc), "the next token is not a local_time"}})); } } @@ -680,25 +685,26 @@ parse_local_datetime(location& loc) const auto date = parse_local_date(inner_loc); if(!date || inner_loc.iter() == inner_loc.end()) { + const std::string msg = date.map_err_or_else( + [](const std::string& msg) {return msg;}, "date, not datetime"); + throw internal_error(format_underline("[error]: " "toml::parse_local_datetime: invalid datetime format", - inner_loc, date.map_err_or_else([](const std::string& msg){ - return msg; - }, "date, not datetime"))); + {{std::addressof(inner_loc), msg}})); } const char delim = *(inner_loc.iter()++); if(delim != 'T' && delim != 't' && delim != ' ') { throw internal_error(format_underline("[error]: " "toml::parse_local_datetime: invalid datetime format", - inner_loc, "should be `T` or ` ` (space)")); + {{std::addressof(inner_loc), "should be `T` or ` ` (space)"}})); } const auto time = parse_local_time(inner_loc); if(!time) { throw internal_error(format_underline("[error]: " "toml::parse_local_datetime: invalid datetime format", - inner_loc, "invalid time fomrat")); + {{std::addressof(inner_loc), "invalid time fomrat"}})); } return ok(std::make_pair( local_datetime(date.unwrap().first, time.unwrap().first), @@ -707,8 +713,8 @@ parse_local_datetime(location& loc) else { loc.iter() = first; - return err(format_underline("[error]: toml::parse_local_datetime: ", loc, - "the next token is not a local_datetime")); + return err(format_underline("[error]: toml::parse_local_datetime: ", + {{std::addressof(loc), "the next token is not a local_datetime"}})); } } @@ -723,11 +729,12 @@ parse_offset_datetime(location& loc) const auto datetime = parse_local_datetime(inner_loc); if(!datetime || inner_loc.iter() == inner_loc.end()) { + const std::string msg = datetime.map_err_or_else( + [](const std::string& msg){return msg;}, "date, not datetime"); + throw internal_error(format_underline("[error]: " "toml::parse_offset_datetime: invalid datetime format", - inner_loc, datetime.map_err_or_else([](const std::string& msg){ - return msg; - }, "date, not datetime"))); + {{std::addressof(inner_loc), msg}})); } time_offset offset(0, 0); if(const auto ofs = lex_time_numoffset::invoke(inner_loc)) @@ -748,7 +755,7 @@ parse_offset_datetime(location& loc) { throw internal_error(format_underline("[error]: " "toml::parse_offset_datetime: invalid datetime format", - inner_loc, "should be `Z` or `+HH:MM`")); + {{std::addressof(inner_loc), "should be `Z` or `+HH:MM`"}})); } return ok(std::make_pair(offset_datetime(datetime.unwrap().first, offset), token.unwrap())); @@ -756,8 +763,8 @@ parse_offset_datetime(location& loc) else { loc.iter() = first; - return err(format_underline("[error]: toml::parse_offset_datetime: ", loc, - "the next token is not a local_datetime")); + return err(format_underline("[error]: toml::parse_offset_datetime: ", + {{std::addressof(loc), "the next token is not a local_datetime"}})); } } @@ -778,8 +785,8 @@ parse_simple_key(location& loc) const auto reg = bare.unwrap(); return ok(std::make_pair(reg.str(), reg)); } - return err(format_underline("[error] toml::parse_simple_key: ", loc, - "the next token is not a simple key")); + return err(format_underline("[error] toml::parse_simple_key: ", + {{std::addressof(loc), "the next token is not a simple key"}})); } // dotted key become vector of keys @@ -806,7 +813,7 @@ parse_key(location& loc) { throw internal_error(format_underline("[error] " "toml::detail::parse_key: dotted key contains invalid key", - inner_loc, k.unwrap_err())); + {{std::addressof(inner_loc), k.unwrap_err()}})); } lex_ws::invoke(inner_loc); @@ -821,8 +828,8 @@ parse_key(location& loc) else { throw internal_error(format_underline("[error] toml::parse_key: " - "dotted key contains invalid key ", inner_loc, - "should be `.`")); + "dotted key contains invalid key ", + {{std::addressof(inner_loc), "should be `.`"}})); } } return ok(std::make_pair(keys, reg)); @@ -835,7 +842,8 @@ parse_key(location& loc) return ok(std::make_pair(std::vector(1, smpl.unwrap().first), smpl.unwrap().second)); } - return err(format_underline("[error] toml::parse_key: ", loc, "is not a valid key")); + return err(format_underline("[error] toml::parse_key: ", + {{std::addressof(loc), "is not a valid key"}})); } // forward-decl to implement parse_array and parse_table @@ -880,22 +888,16 @@ parse_array(location& loc) array_start_loc.iter() = first; throw syntax_error(format_underline("[error] toml::parse_array: " - "type of elements should be the same each other.", - std::vector>{ - std::make_pair( - std::addressof(array_start_loc), - std::string("array starts here") - ), - std::make_pair( + "type of elements should be the same each other.", { + {std::addressof(array_start_loc), "array starts here"}, + { std::addressof(get_region(retval.front())), - std::string("value has type ") + - stringize(retval.front().type()) - ), - std::make_pair( + "value has type " + stringize(retval.front().type()) + }, + { std::addressof(get_region(val.unwrap())), - std::string("value has different type, ") + - stringize(val.unwrap().type()) - ) + "value has different type, " + stringize(val.unwrap().type()) + } })); } retval.push_back(std::move(val.unwrap())); @@ -906,9 +908,10 @@ parse_array(location& loc) array_start_loc.iter() = first; throw syntax_error(format_underline("[error] toml::parse_array: " - "value having invalid format appeared in an array", - array_start_loc, "array starts here", - loc, "it is not a valid value.")); + "value having invalid format appeared in an array", { + {std::addressof(array_start_loc), "array starts here"}, + {std::addressof(loc), "it is not a valid value."} + })); } using lex_array_separator = sequence, character<','>>; @@ -928,14 +931,17 @@ parse_array(location& loc) array_start_loc.iter() = first; throw syntax_error(format_underline("[error] toml::parse_array:" - " missing array separator `,` after a value", - array_start_loc, "array starts here", loc, "should be `,`")); + " missing array separator `,` after a value", { + {std::addressof(array_start_loc), "array starts here"}, + {std::addressof(loc), "should be `,`"} + })); } } } loc.iter() = first; throw syntax_error(format_underline("[error] toml::parse_array: " - "array did not closed by `]`", loc, "should be closed")); + "array did not closed by `]`", + {{std::addressof(loc), "should be closed"}})); } template @@ -953,7 +959,8 @@ parse_key_value_pair(location& loc) { loc.iter() = first; msg = format_underline("[error] toml::parse_key_value_pair: " - "empty key is not allowed.", loc, "key expected before '='"); + "empty key is not allowed.", + {{std::addressof(loc), "key expected before '='"}}); } return err(std::move(msg)); } @@ -968,14 +975,16 @@ parse_key_value_pair(location& loc) if(std::find(loc.iter(), line_end, '=') != line_end) { msg = format_underline("[error] toml::parse_key_value_pair: " - "invalid format for key", loc, "invalid character in key", { - "Did you forget '.' to separate dotted-key?", + "invalid format for key", + {{std::addressof(loc), "invalid character in key"}}, + {"Did you forget '.' to separate dotted-key?", "Allowed characters for bare key are [0-9a-zA-Z_-]."}); } else // if not, the error is lack of key-value separator. { msg = format_underline("[error] toml::parse_key_value_pair: " - "missing key-value separator `=`", loc, "should be `=`"); + "missing key-value separator `=`", + {{std::addressof(loc), "should be `=`"}}); } loc.iter() = first; return err(std::move(msg)); @@ -992,8 +1001,8 @@ parse_key_value_pair(location& loc) { loc.iter() = after_kvsp; msg = format_underline("[error] toml::parse_key_value_pair: " - "missing value after key-value separator '='", loc, - "expected value, but got nothing"); + "missing value after key-value separator '='", + {{std::addressof(loc), "expected value, but got nothing"}}); } else // there is something not a comment/whitespace, so invalid format. { @@ -1122,19 +1131,26 @@ insert_nested_key(table& root, const toml::value& v, // show special err msg for conflicting table throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of table (\"", - format_dotted_keys(first, last), "\") cannot insert" - "ed"), get_region(tab->at(k)), "table already defined", - get_region(v), "this conflicts with the previous table")); + format_dotted_keys(first, last), + "\") cannot be defined"), { + {std::addressof(get_region(tab->at(k))), + "table already defined"}, + {std::addressof(get_region(v)), + "this conflicts with the previous table"} + })); } else if(!(tab->at(k).is(value_t::Array))) { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of table (\"", format_dotted_keys(first, last), "\") collides with" - " existing value"), get_region(tab->at(k)), - concat_to_string("this ", tab->at(k).type(), - " value already exists"), get_region(v), - "while inserting this array-of-tables")); + " existing value"), { + {std::addressof(get_region(tab->at(k))), + concat_to_string("this ", tab->at(k).type(), + " value already exists")}, + {std::addressof(get_region(v)), + "while inserting this array-of-tables"} + })); } array& a = tab->at(k).template cast(); if(!(a.front().is(value_t::Table))) @@ -1142,10 +1158,13 @@ insert_nested_key(table& root, const toml::value& v, throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of table (\"", format_dotted_keys(first, last), "\") collides with" - " existing value"), get_region(tab->at(k)), - concat_to_string("this ", tab->at(k).type(), - " value already exists"), get_region(v), - "while inserting this array-of-tables")); + " existing value"), { + {std::addressof(get_region(tab->at(k))), + concat_to_string("this ", tab->at(k).type(), + " value already exists")}, + {std::addressof(get_region(v)), + "while inserting this array-of-tables"} + })); } // avoid conflicting array of table like the following. // ```toml @@ -1167,10 +1186,13 @@ insert_nested_key(table& root, const toml::value& v, throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of table (\"", format_dotted_keys(first, last), "\") collides with" - " existing array-of-tables"), get_region(tab->at(k)), - concat_to_string("this ", tab->at(k).type(), - " value has static size"), get_region(v), - "appending this to the statically sized array")); + " existing array-of-tables"), { + {std::addressof(get_region(tab->at(k))), + concat_to_string("this ", tab->at(k).type(), + " value has static size")}, + {std::addressof(get_region(v)), + "appending it to the statically sized array"} + })); } a.push_back(v); return ok(true); @@ -1191,11 +1213,14 @@ insert_nested_key(table& root, const toml::value& v, tab->at(k), first, iter, last)) { throw syntax_error(format_underline(concat_to_string( - "[error] toml::insert_value: table (\"", - format_dotted_keys(first, last), - "\") already exists."), - get_region(tab->at(k)), "table already exists here", - get_region(v), "table defined twice")); + "[error] toml::insert_value: table (\"", + format_dotted_keys(first, last), + "\") already exists."), { + {std::addressof(get_region(tab->at(k))), + "table already exists here"}, + {std::addressof(get_region(v)), + "table defined twice"} + })); } // to allow the following toml file. // [a.b.c] @@ -1217,18 +1242,23 @@ insert_nested_key(table& root, const toml::value& v, { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: array of tables (\"", - format_dotted_keys(first, last), "\") already exists."), - get_region(tab->at(k)), "array of tables defined here", - get_region(v), "table conflicts with the previous array" - " of table")); + format_dotted_keys(first, last), "\") already exists."), { + {std::addressof(get_region(tab->at(k))), + "array of tables defined here"}, + {std::addressof(get_region(v)), + "table conflicts with the previous array of table"} + })); } else { throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: value (\"", - format_dotted_keys(first, last), "\") already exists."), - get_region(tab->at(k)), "value already exists here", - get_region(v), "value defined twice")); + format_dotted_keys(first, last), "\") already exists."), { + {std::addressof(get_region(tab->at(k))), + "value already exists here"}, + {std::addressof(get_region(v)), + "value defined twice"} + })); } } tab->insert(std::make_pair(k, v)); @@ -1260,9 +1290,11 @@ insert_nested_key(table& root, const toml::value& v, throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: target (", format_dotted_keys(first, std::next(iter)), - ") is neither table nor an array of tables"), - get_region(a.back()), concat_to_string("actual type is ", - a.back().type()), get_region(v), "inserting this")); + ") is neither table nor an array of tables"), { + {std::addressof(get_region(a.back())), + concat_to_string("actual type is ", a.back().type())}, + {std::addressof(get_region(v)), "inserting this"} + })); } tab = std::addressof(a.back().template cast()); } @@ -1271,9 +1303,11 @@ insert_nested_key(table& root, const toml::value& v, throw syntax_error(format_underline(concat_to_string( "[error] toml::insert_value: target (", format_dotted_keys(first, std::next(iter)), - ") is neither table nor an array of tables"), - get_region(tab->at(k)), concat_to_string("actual type is ", - tab->at(k).type()), get_region(v), "inserting this")); + ") is neither table nor an array of tables"), { + {std::addressof(get_region(tab->at(k))), + concat_to_string("actual type is ", tab->at(k).type())}, + {std::addressof(get_region(v)), "inserting this"} + })); } } } @@ -1288,8 +1322,8 @@ parse_inline_table(location& loc) table retval; if(!(loc.iter() != loc.end() && *loc.iter() == '{')) { - return err(format_underline("[error] toml::parse_inline_table: ", loc, - "the next token is not an inline table")); + return err(format_underline("[error] toml::parse_inline_table: ", + {{std::addressof(loc), "the next token is not an inline table"}})); } ++loc.iter(); // it starts from "{". it should be formatted as inline-table @@ -1335,13 +1369,14 @@ parse_inline_table(location& loc) { throw syntax_error(format_underline("[error] " "toml:::parse_inline_table: missing table separator `,` ", - loc, "should be `,`")); + {{std::addressof(loc), "should be `,`"}})); } } } loc.iter() = first; throw syntax_error(format_underline("[error] toml::parse_inline_table: " - "inline table did not closed by `}`", loc, "should be closed")); + "inline table did not closed by `}`", + {{std::addressof(loc), "should be closed"}})); } template @@ -1350,7 +1385,8 @@ result parse_value(location& loc) const auto first = loc.iter(); if(first == loc.end()) { - return err(format_underline("[error] toml::parse_value: input is empty", loc, "")); + return err(format_underline("[error] toml::parse_value: input is empty", + {{std::addressof(loc), ""}})); } if(auto r = parse_string (loc)) {return ok(value(std::move(r.unwrap().first), std::move(r.unwrap().second)));} @@ -1374,7 +1410,7 @@ result parse_value(location& loc) {return ok(value(std::move(r.unwrap().first), std::move(r.unwrap().second)));} const auto msg = format_underline("[error] toml::parse_value: " - "unknown token appeared", loc, "unknown"); + "unknown token appeared", {{std::addressof(loc), "unknown"}}); loc.iter() = first; return err(msg); } @@ -1391,7 +1427,8 @@ parse_table_key(location& loc) if(!open || inner_loc.iter() == inner_loc.end()) { throw internal_error(format_underline("[error] " - "toml::parse_table_key: no `[`", inner_loc, "should be `[`")); + "toml::parse_table_key: no `[`", + {{std::addressof(inner_loc), "should be `[`"}})); } // to skip [ a . b . c ] // ^----------- this whitespace @@ -1400,7 +1437,8 @@ parse_table_key(location& loc) if(!keys) { throw internal_error(format_underline("[error] " - "toml::parse_table_key: invalid key", inner_loc, "not key")); + "toml::parse_table_key: invalid key", + {{std::addressof(inner_loc), "not key"}})); } // to skip [ a . b . c ] // ^-- this whitespace @@ -1409,7 +1447,8 @@ parse_table_key(location& loc) if(!close) { throw internal_error(format_underline("[error] " - "toml::parse_table_key: no `]`", inner_loc, "should be `]`")); + "toml::parse_table_key: no `]`", + {{std::addressof(inner_loc), "should be `]`"}})); } // after [table.key], newline or EOF(empty table) requried. @@ -1422,7 +1461,7 @@ parse_table_key(location& loc) { throw syntax_error(format_underline("[error] " "toml::parse_table_key: newline required after [table.key]", - loc, "expected newline")); + {{std::addressof(loc), "expected newline"}})); } } return ok(std::make_pair(keys.unwrap().first, token.unwrap())); @@ -1445,23 +1484,24 @@ parse_array_table_key(location& loc) if(!open || inner_loc.iter() == inner_loc.end()) { throw internal_error(format_underline("[error] " - "toml::parse_array_table_key: no `[[`", inner_loc, - "should be `[[`")); + "toml::parse_array_table_key: no `[[`", + {{std::addressof(inner_loc), "should be `[[`"}})); } lex_ws::invoke(inner_loc); const auto keys = parse_key(inner_loc); if(!keys) { throw internal_error(format_underline("[error] " - "toml::parse_array_table_key: invalid key", inner_loc, - "not key")); + "toml::parse_array_table_key: invalid key", + {{std::addressof(inner_loc), "not a key"}})); } lex_ws::invoke(inner_loc); const auto close = lex_array_table_close::invoke(inner_loc); if(!close) { throw internal_error(format_underline("[error] " - "toml::parse_table_key: no `]]`", inner_loc, "should be `]]`")); + "toml::parse_table_key: no `]]`", + {{std::addressof(inner_loc), "should be `]]`"}})); } // after [[table.key]], newline or EOF(empty table) requried. @@ -1472,9 +1512,9 @@ parse_array_table_key(location& loc) const auto nl = lex_newline_after_table_key::invoke(loc); if(!nl) { - throw syntax_error(format_underline("[error] " - "toml::parse_array_table_key: newline required after " - "[[table.key]]", loc, "expected newline")); + throw syntax_error(format_underline("[error] toml::" + "parse_array_table_key: newline required after [[table.key]]", + {{std::addressof(loc), "expected newline"}})); } } return ok(std::make_pair(keys.unwrap().first, token.unwrap())); @@ -1550,8 +1590,8 @@ result parse_ml_table(location& loc) const auto before = loc.iter(); lex_ws::invoke(loc); // skip whitespace const auto msg = format_underline("[error] toml::parse_table: " - "invalid line format", loc, concat_to_string( - "expected newline, but got '", show_char(*loc.iter()), "'.")); + "invalid line format", {{std::addressof(loc), concat_to_string( + "expected newline, but got '", show_char(*loc.iter()), "'.")}}); loc.iter() = before; return err(msg); } @@ -1621,7 +1661,7 @@ result parse_toml_file(location& loc) continue; } return err(format_underline("[error]: toml::parse_toml_file: " - "unknown line appeared", loc, "unknown format")); + "unknown line appeared", {{std::addressof(loc), "unknown format"}})); } return ok(data); } diff --git a/toml/value.hpp b/toml/value.hpp index 03812c7..27c2d8a 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -681,9 +681,11 @@ typename detail::toml_default_type::type& value::cast() & { if(T != this->type_) { - throw type_error(format_underline(concat_to_string( - "[error] toml::value bad_cast to ", T), *region_info_, - concat_to_string("the actual type is ", 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_)} + })); } return switch_cast::invoke(*this); } @@ -692,9 +694,11 @@ typename detail::toml_default_type::type const& value::cast() const& { if(T != this->type_) { - throw type_error(format_underline(concat_to_string( - "[error] toml::value bad_cast to ", T), *region_info_, - concat_to_string("the actual type is ", 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_)} + })); } return switch_cast::invoke(*this); } @@ -703,9 +707,11 @@ typename detail::toml_default_type::type&& value::cast() && { if(T != this->type_) { - throw type_error(format_underline(concat_to_string( - "[error] toml::value bad_cast to ", T), *region_info_, - concat_to_string("the actual type is ", 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_)} + })); } return switch_cast::invoke(std::move(*this)); } @@ -792,8 +798,9 @@ 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, detail::get_region(v), comment, - std::move(hints)); + return detail::format_underline(err_msg, { + {std::addressof(detail::get_region(v)), comment} + }, std::move(hints)); } inline std::string format_error(const std::string& err_msg, @@ -801,9 +808,10 @@ inline std::string format_error(const std::string& err_msg, const toml::value& v2, const std::string& comment2, std::vector hints = {}) { - return detail::format_underline(err_msg, detail::get_region(v1), comment1, - detail::get_region(v2), comment2, - std::move(hints)); + return detail::format_underline(err_msg, { + {std::addressof(detail::get_region(v1)), comment1}, + {std::addressof(detail::get_region(v2)), comment2} + }, std::move(hints)); } template