diff --git a/include/iris/x4/rule.hpp b/include/iris/x4/rule.hpp index e6fd90bfd..53ea9f2b4 100644 --- a/include/iris/x4/rule.hpp +++ b/include/iris/x4/rule.hpp @@ -349,10 +349,16 @@ struct narrowing_checker requires requires(T&& t) { { Dest{std::forward(t)} }; }; }; + template -concept RuleAttrNeedsNarrowingConversion = +concept RuleAttrConvertible = X4Attribute && - !requires { + std::is_assignable_v>&, RuleAttr>; + +template +concept RuleAttrConvertibleWithoutNarrowing = + RuleAttrConvertible && + requires { narrowing_checker< unwrap_container_appender_t> >::operator()(std::declval()); @@ -366,8 +372,8 @@ concept RuleAttrTransformable = X4Attribute> && X4Attribute && std::default_initializable && - std::is_assignable_v>&, RuleAttr> && - !RuleAttrNeedsNarrowingConversion< + RuleAttrConvertible && + RuleAttrConvertibleWithoutNarrowing< unwrap_container_appender_t>, RuleAttr >; @@ -434,7 +440,6 @@ struct rule : parser> } else { static_assert(detail::RuleAttrTransformable); - static_assert(!detail::RuleAttrNeedsNarrowingConversion); // TODO: specialize `container_appender` case, do not create temporary @@ -461,10 +466,12 @@ struct rule : parser> requires (!std::same_as, unused_type>) && (!detail::RuleAttrCompatible) && - detail::RuleAttrNeedsNarrowingConversion + detail::RuleAttrConvertible && + (!detail::RuleAttrConvertibleWithoutNarrowing) [[nodiscard]] constexpr bool parse(It&, Se const&, Context const&, Exposed&) const = delete; // Rule attribute needs narrowing conversion + template Se, class Context> [[nodiscard]] constexpr bool parse(It& first, Se const& last, Context const& ctx, unused_type const&) const