diff --git a/include/boost/parser/detail/printing.hpp b/include/boost/parser/detail/printing.hpp index e79d5260..52722a67 100644 --- a/include/boost/parser/detail/printing.hpp +++ b/include/boost/parser/detail/printing.hpp @@ -263,17 +263,14 @@ namespace boost { namespace parser { namespace detail { std::ostream & os, int components = 0); - template + template< + typename Context, + typename StrIter, + typename StrSentinel, + typename ParserMods> void print_parser( Context const & context, - string_parser const & parser, - std::ostream & os, - int components = 0); - - template - void print_parser( - Context const & context, - omit_parser> const & parser, + string_parser const & parser, std::ostream & os, int components = 0); diff --git a/include/boost/parser/detail/printing_impl.hpp b/include/boost/parser/detail/printing_impl.hpp index 4deefe00..0c8ac699 100644 --- a/include/boost/parser/detail/printing_impl.hpp +++ b/include/boost/parser/detail/printing_impl.hpp @@ -660,37 +660,30 @@ namespace boost { namespace parser { namespace detail { os << "upper"; } - template + template< + typename Context, + typename StrIter, + typename StrSentinel, + typename ParserMods> void print_parser( Context const & context, - string_parser const & parser, + string_parser const & parser, std::ostream & os, int components) { - os << "string(\""; + if constexpr (!parser.mods_.omit_attr) { + os << "string("; + } + os << "\""; for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE( parser.expected_first_, parser.expected_last_) | text::as_utf8) { detail::print_char(os, c); } - os << "\")"; - } - - template - void print_parser( - Context const & context, - omit_parser> const & parser, - std::ostream & os, - int components) - { os << "\""; - for (auto c : BOOST_PARSER_DETAIL_TEXT_SUBRANGE( - parser.parser_.expected_first_, - parser.parser_.expected_last_) | - text::as_utf8) { - detail::print_char(os, c); + if constexpr (!parser.mods_.omit_attr) { + os << ")"; } - os << "\""; } template diff --git a/include/boost/parser/parser.hpp b/include/boost/parser/parser.hpp index 8f933282..74faba22 100644 --- a/include/boost/parser/parser.hpp +++ b/include/boost/parser/parser.hpp @@ -7161,10 +7161,13 @@ namespace boost { namespace parser { #ifndef BOOST_PARSER_DOXYGEN - template + template struct string_parser { - constexpr string_parser() : expected_first_(), expected_last_() {} + using attribute_type = std:: + conditional_t; + + constexpr string_parser() = default; #if BOOST_PARSER_USE_CONCEPTS template @@ -7179,12 +7182,16 @@ namespace boost { namespace parser { expected_last_(detail::make_view_end(r)) {} + constexpr string_parser(StrIter f, StrSentinel l, ParserMods mods) : + expected_first_(f), expected_last_(l), mods_(mods) + {} + template< typename Iter, typename Sentinel, typename Context, typename SkipParser> - std::string call( + attribute_type call( Iter & first, Sentinel last, Context const & context, @@ -7192,7 +7199,7 @@ namespace boost { namespace parser { detail::flags flags, bool & success) const { - std::string retval; + attribute_type retval; call(first, last, context, skip, flags, success, retval); return retval; } @@ -7238,8 +7245,13 @@ namespace boost { namespace parser { return; } - detail::append( - retval, first, mismatch.first, detail::gen_attrs(flags)); + if constexpr (!ParserMods::omit_attr) { + detail::append( + retval, + first, + mismatch.first, + detail::gen_attrs(flags)); + } first = mismatch.first; } else { @@ -7254,15 +7266,28 @@ namespace boost { namespace parser { return; } - detail::append( - retval, first, mismatch.first, detail::gen_attrs(flags)); + if constexpr (!ParserMods::omit_attr) { + detail::append( + retval, + first, + mismatch.first, + detail::gen_attrs(flags)); + } first = mismatch.first; } } + template + constexpr auto with_parser_mods(ParserMods2 mods) + { + return string_parser{ + expected_first_, expected_last_, std::move(mods)}; + } + StrIter expected_first_; StrSentinel expected_last_; + [[no_unique_address]] ParserMods mods_; }; #if BOOST_PARSER_USE_CONCEPTS @@ -7271,8 +7296,9 @@ namespace boost { namespace parser { template #endif string_parser(R r) -> string_parser< - decltype(detail::make_view_begin(r)), - decltype(detail::make_view_end(r))>; + decltype(detail::make_view_begin(r)), + decltype(detail::make_view_end(r)), + parser_modifiers<>>; #endif @@ -7602,7 +7628,8 @@ namespace boost { namespace parser { #endif constexpr auto lit(R && str) noexcept { - return omit[parser::string(str)]; + return parser_interface{parser::string(str).parser_.with_parser_mods( + parser_modifiers{})}; } #ifndef BOOST_PARSER_DOXYGEN diff --git a/include/boost/parser/parser_fwd.hpp b/include/boost/parser/parser_fwd.hpp index d641daab..6bc7ffa6 100644 --- a/include/boost/parser/parser_fwd.hpp +++ b/include/boost/parser/parser_fwd.hpp @@ -384,7 +384,7 @@ namespace boost { namespace parser { /** Matches a particular string, delimited by an iterator sentinel pair; produces no attribute. */ - template + template struct string_parser; /** Matches a string delimited by quotation marks; produces a