diff --git a/toml/combinator.hpp b/toml/combinator.hpp index 52aaaae..36d367c 100644 --- a/toml/combinator.hpp +++ b/toml/combinator.hpp @@ -56,7 +56,8 @@ struct character static constexpr char target = C; template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); @@ -67,8 +68,12 @@ struct character const char c = *(loc.iter()); if(c != target) { - return err(concat_to_string("expected '", show_char(target), - "' but got '", show_char(c), "'.")); + if(msg) + { + return err(concat_to_string("expected '", show_char(target), + "' but got '", show_char(c), "'.")); + } + return err(""); } loc.advance(); // update location @@ -91,7 +96,8 @@ struct in_range static constexpr char lower = Low; template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); @@ -102,9 +108,13 @@ struct in_range const char c = *(loc.iter()); if(c < lower || upper < c) { - return err(concat_to_string("expected character in range " - "[", show_char(lower), ", ", show_char(upper), "] but got ", - "'", show_char(c), "'.")); + if(msg) + { + return err(concat_to_string("expected character in range " + "[", show_char(lower), ", ", show_char(upper), "] but got ", + "'", show_char(c), "'.")); + } + return err(""); } loc.advance(); @@ -125,7 +135,8 @@ template struct exclude { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); @@ -133,13 +144,16 @@ struct exclude if(loc.iter() == loc.end()) {return err("not sufficient characters");} auto first = loc.iter(); - auto rslt = Combinator::invoke(loc); + auto rslt = Combinator::invoke(loc, msg); if(rslt.is_ok()) { loc.reset(first); - return err(concat_to_string( - "invalid pattern (", Combinator::pattern(), ") appeared ", - rslt.unwrap().str())); + if(msg) + { + return err(concat_to_string("invalid pattern (", + Combinator::pattern(), ") appeared ", rslt.unwrap().str())); + } + return err(""); } loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but... return ok(region(loc, first, loc.iter())); @@ -156,12 +170,13 @@ template struct maybe { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); - const auto rslt = Combinator::invoke(loc); + const auto rslt = Combinator::invoke(loc, msg); if(rslt.is_ok()) { return rslt; @@ -182,34 +197,36 @@ template struct sequence { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); const auto first = loc.iter(); - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_err()) { loc.reset(first); return err(rslt.unwrap_err()); } - return sequence::invoke(loc, std::move(rslt.unwrap()), first); + return sequence::invoke(loc, std::move(rslt.unwrap()), first, msg); } // called from the above function only, recursively. template static result, std::string> - invoke(location& loc, region reg, Iterator first) + invoke(location& loc, region reg, Iterator first, + const bool msg = false) { - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_err()) { loc.reset(first); return err(rslt.unwrap_err()); } reg += rslt.unwrap(); // concat regions - return sequence::invoke(loc, std::move(reg), first); + return sequence::invoke(loc, std::move(reg), first, msg); } static std::string pattern() @@ -224,9 +241,10 @@ struct sequence // would be called from sequence::invoke only. template static result, std::string> - invoke(location& loc, region reg, Iterator first) + invoke(location& loc, region reg, Iterator first, + const bool msg = false) { - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_err()) { loc.reset(first); @@ -245,14 +263,15 @@ template struct either { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); - const auto rslt = Head::invoke(loc); + const auto rslt = Head::invoke(loc, msg); if(rslt.is_ok()) {return rslt;} - return either::invoke(loc); + return either::invoke(loc, msg); } static std::string pattern() @@ -264,11 +283,12 @@ template struct either { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { static_assert(std::is_same::value, "internal error: container::value_type should be `char`."); - return Head::invoke(loc); + return Head::invoke(loc, msg); } static std::string pattern() { @@ -287,13 +307,14 @@ template struct repeat> { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { region retval(loc); const auto first = loc.iter(); for(std::size_t i=0; i struct repeat> { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { region retval(loc); const auto first = loc.iter(); for(std::size_t i=0; i> } while(true) { - auto rslt = T::invoke(loc); + auto rslt = T::invoke(loc, msg); if(rslt.is_err()) { return ok(std::move(retval)); @@ -348,12 +370,13 @@ template struct repeat { template - static result, std::string> invoke(location& loc) + static result, std::string> + invoke(location& loc, const bool msg = false) { region retval(loc); while(true) { - auto rslt = T::invoke(loc); + auto rslt = T::invoke(loc, msg); if(rslt.is_err()) { return ok(std::move(retval));