@@ -349,10 +349,16 @@ struct narrowing_checker
349349 requires requires(T&& t) { { Dest{std::forward<T>(t)} }; };
350350};
351351
352+
352353template <class Exposed , class RuleAttr >
353- concept RuleAttrNeedsNarrowingConversion =
354+ concept RuleAttrConvertible =
354355 X4Attribute<RuleAttr> &&
355- !requires {
356+ std::is_assignable_v<unwrap_container_appender_t <std::remove_const_t <Exposed>>&, RuleAttr>;
357+
358+ template <class Exposed , class RuleAttr >
359+ concept RuleAttrConvertibleWithoutNarrowing =
360+ RuleAttrConvertible<Exposed, RuleAttr> &&
361+ requires {
356362 narrowing_checker<
357363 unwrap_container_appender_t <std::remove_const_t <Exposed>>
358364 >::operator ()(std::declval<RuleAttr>());
@@ -366,8 +372,8 @@ concept RuleAttrTransformable =
366372 X4Attribute<std::remove_const_t <Exposed>> &&
367373 X4Attribute<RuleAttr> &&
368374 std::default_initializable<RuleAttr> &&
369- std::is_assignable_v< unwrap_container_appender_t <std:: remove_const_t < Exposed>>& , RuleAttr> &&
370- !RuleAttrNeedsNarrowingConversion <
375+ RuleAttrConvertible< Exposed, RuleAttr> &&
376+ RuleAttrConvertibleWithoutNarrowing <
371377 unwrap_container_appender_t <std::remove_const_t <Exposed>>,
372378 RuleAttr
373379 >;
@@ -434,7 +440,6 @@ struct rule : parser<rule<RuleID, RuleAttr, ForceAttr>>
434440
435441 } else {
436442 static_assert (detail::RuleAttrTransformable<Exposed, RuleAttr>);
437- static_assert (!detail::RuleAttrNeedsNarrowingConversion<Exposed, RuleAttr>);
438443
439444 // TODO: specialize `container_appender` case, do not create temporary
440445
@@ -461,10 +466,12 @@ struct rule : parser<rule<RuleID, RuleAttr, ForceAttr>>
461466 requires
462467 (!std::same_as<std::remove_const_t <Exposed>, unused_type>) &&
463468 (!detail::RuleAttrCompatible<Exposed, RuleAttr>) &&
464- detail::RuleAttrNeedsNarrowingConversion<Exposed, RuleAttr>
469+ detail::RuleAttrConvertible<Exposed, RuleAttr> &&
470+ (!detail::RuleAttrConvertibleWithoutNarrowing<Exposed, RuleAttr>)
465471 [[nodiscard]] constexpr bool
466472 parse (It&, Se const &, Context const &, Exposed&) const = delete ; // Rule attribute needs narrowing conversion
467473
474+
468475 template <std::forward_iterator It, std::sentinel_for<It> Se, class Context >
469476 [[nodiscard]] constexpr bool
470477 parse (It& first, Se const & last, Context const & ctx, unused_type const &) const
0 commit comments