diff --git a/include/boost/spirit/home/x3/core/skip_over.hpp b/include/boost/spirit/home/x3/core/skip_over.hpp index 627c8096d..b3202b4e7 100644 --- a/include/boost/spirit/home/x3/core/skip_over.hpp +++ b/include/boost/spirit/home/x3/core/skip_over.hpp @@ -1,7 +1,7 @@ /*============================================================================= Copyright (c) 2001-2014 Joel de Guzman Copyright (c) 2017 wanghan02 - Copyright (c) 2024-2025 Nana Sakisaka + Copyright (c) 2024 Nana Sakisaka Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,86 +13,61 @@ #include #include #include +#include +#include +#include +#include +#include +#include -#include - -#include -#include - -namespace boost::spirit::x3 +namespace boost { namespace spirit { namespace x3 { - // Tag used to find the skipper from the context - struct skipper_tag; - + /////////////////////////////////////////////////////////////////////////// // Move the /first/ iterator to the first non-matching position // given a skip-parser. The function is a no-op if unused_type or // unused_skipper is passed as the skip-parser. - template - struct [[nodiscard]] unused_skipper + /////////////////////////////////////////////////////////////////////////// + template + struct unused_skipper : unused_type { - constexpr unused_skipper(Skipper const& skipper) noexcept - : skipper(skipper) - {} - + unused_skipper(Skipper const& skipper) + : skipper(skipper) {} Skipper const& skipper; }; - template - using unused_skipper_t = unused_skipper(std::declval()))>>; - namespace detail { template - struct is_unused_skipper : std::false_type - { - static_assert(X3Subject); - }; + struct is_unused_skipper + : mpl::false_ {}; template - struct is_unused_skipper> : std::true_type {}; + struct is_unused_skipper> + : mpl::true_ {}; template <> - struct is_unused_skipper : std::true_type {}; + struct is_unused_skipper + : mpl::true_ {}; template - [[nodiscard]] constexpr Skipper const& - get_unused_skipper(Skipper const& skipper) noexcept + inline Skipper const& + get_unused_skipper(Skipper const& skipper) { - static_assert(X3Subject); return skipper; } - template - [[nodiscard]] constexpr Skipper const& - get_unused_skipper(unused_skipper const& unused_skipper) noexcept + inline Skipper const& + get_unused_skipper(unused_skipper const& unused_skipper) { - static_assert(X3Subject); return unused_skipper.skipper; } - template - struct skip_over_context - { - using type = unused_type; - }; - - template - requires (!std::is_same_v, unused_type>) - struct skip_over_context - { - using type = std::remove_cvref_t( - x3::get(std::declval()) - ))>; - }; - - template Se, typename Context, X3Subject Skipper> - constexpr void skip_over( - It& first, Se const& last, Context& context, Skipper const& skipper - ) - noexcept(is_nothrow_parsable_v::type, unused_type, unused_type>) + template + inline void skip_over( + Iterator& first, Iterator const& last, Context& context, Skipper const& skipper) { #if BOOST_SPIRIT_X3_THROW_EXPECTATION_FAILURE - (void)context; + boost::ignore_unused(context); while (skipper.parse(first, last, unused, unused, unused)) /* loop */; #else @@ -142,7 +117,7 @@ namespace boost::spirit::x3 // For this reason we're going to cherry-pick the reference // and repack it into a brand new context. - auto const local_ctx = x3::make_context( + auto const local_ctx = make_context( x3::get(context)); while (skipper.parse(first, last, local_ctx, unused, unused)) @@ -151,33 +126,35 @@ namespace boost::spirit::x3 #endif } - template Se, typename Context> - constexpr void skip_over(It&, Se const&, Context&, unused_type) noexcept + template + inline void skip_over(Iterator&, Iterator const&, Context&, unused_type) { } - template Se, typename Context, typename Skipper> - constexpr void skip_over(It&, Se const&, Context&, unused_skipper const&) noexcept + template + inline void skip_over( + Iterator&, Iterator const&, Context&, unused_skipper const&) { } } + // this tag is used to find the skipper from the context + struct skipper_tag; + template struct has_skipper - : std::bool_constant(std::declval()))> - >::value> - {}; + : mpl::not_(boost::declval())) + >::type>::type + >> {}; - template - constexpr bool has_skipper_v = has_skipper::value; - - template Se, typename Context> - constexpr void skip_over(It& first, Se const& last, Context& context) - noexcept(noexcept(detail::skip_over(first, last, context, x3::get(context)))) + template + inline void skip_over( + Iterator& first, Iterator const& last, Context& context) { detail::skip_over(first, last, context, x3::get(context)); } -} // boost::spirit::x3 +}}} #endif diff --git a/include/boost/spirit/home/x3/directive/lexeme.hpp b/include/boost/spirit/home/x3/directive/lexeme.hpp index 47b1b3479..942957b2c 100644 --- a/include/boost/spirit/home/x3/directive/lexeme.hpp +++ b/include/boost/spirit/home/x3/directive/lexeme.hpp @@ -1,6 +1,5 @@ /*============================================================================= Copyright (c) 2001-2014 Joel de Guzman - Copyright (c) 2025 Nana Sakisaka Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -12,85 +11,68 @@ #include #include #include +#include +#include -#include -#include -#include - -namespace boost::spirit::x3 +namespace boost { namespace spirit { namespace x3 { template struct lexeme_directive : unary_parser> { - using base_type = unary_parser>; - static constexpr bool is_pass_through_unary = true; - static constexpr bool handles_container = Subject::handles_container; + typedef unary_parser > base_type; + static bool const is_pass_through_unary = true; + static bool const handles_container = Subject::handles_container; - template - requires std::is_constructible_v - constexpr lexeme_directive(SubjectT&& subject) - noexcept(std::is_nothrow_constructible_v) - : base_type(std::forward(subject)) - {} + constexpr lexeme_directive(Subject const& subject) + : base_type(subject) {} - template - using pre_skip_context_t = std::remove_cvref_t(std::declval&>(), std::declval()) - )>; - - template Se, typename Context, typename RContext, typename Attribute> - requires has_skipper_v - [[nodiscard]] constexpr bool parse( - It& first, Se const& last, Context const& context, RContext& rcontext, Attribute& attr - ) const - noexcept( - noexcept(x3::skip_over(first, last, context)) && - is_nothrow_parsable_v, RContext, Attribute> - ) + template + typename enable_if, bool>::type + parse(Iterator& first, Iterator const& last + , Context const& context, RContext& rcontext, Attribute& attr) const { x3::skip_over(first, last, context); - auto const& skipper = x3::get(context); - unused_skipper_t unused_skipper(skipper); + + typedef unused_skipper< + typename remove_reference::type> + unused_skipper_type; + unused_skipper_type unused_skipper(skipper); return this->subject.parse( - first, last, - x3::make_context(unused_skipper, context), - rcontext, - attr - ); + first, last + , make_context(unused_skipper, context) + , rcontext + , attr); } - template Se, typename Context, typename RContext, typename Attribute> - requires (!has_skipper_v) - [[nodiscard]] constexpr bool parse( - It& first, Se const& last, Context const& context, RContext& rcontext, Attribute& attr - ) const - noexcept(is_nothrow_parsable_v) + template + typename disable_if, bool>::type + parse(Iterator& first, Iterator const& last + , Context const& context, RContext& rcontext, Attribute& attr) const { // no need to pre-skip if skipper is unused - return this->subject.parse(first, last, context, rcontext, attr); + return this->subject.parse( + first, last + , context + , rcontext + , attr); } }; - namespace detail + struct lexeme_gen { - struct lexeme_gen + template + constexpr lexeme_directive::value_type> + operator[](Subject const& subject) const { - template - [[nodiscard]] constexpr lexeme_directive> - operator[](Subject&& subject) const - noexcept(is_parser_nothrow_constructible_v>, Subject>) - { - return { as_parser(std::forward(subject)) }; - } - }; - } // detail + return { as_parser(subject) }; + } + }; - inline namespace cpos - { - inline constexpr detail::lexeme_gen lexeme{}; - } -} // boost::spirit::x3 + constexpr auto lexeme = lexeme_gen{}; +}}} #endif diff --git a/test/x3/lexeme.cpp b/test/x3/lexeme.cpp index b816779ce..483196559 100644 --- a/test/x3/lexeme.cpp +++ b/test/x3/lexeme.cpp @@ -1,22 +1,21 @@ /*============================================================================= Copyright (c) 2001-2015 Joel de Guzman - Copyright (c) 2025 Nana Sakisaka Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "test.hpp" - #include #include +#include "test.hpp" -int main() +int +main() { using spirit_test::test; - using boost::spirit::x3::standard::space; - using boost::spirit::x3::standard::space_type; - using boost::spirit::x3::standard::digit; + using boost::spirit::x3::ascii::space; + using boost::spirit::x3::ascii::space_type; + using boost::spirit::x3::ascii::digit; using boost::spirit::x3::lexeme; using boost::spirit::x3::rule;