@@ -592,19 +592,22 @@ enum class [[nodiscard]] TypeModifier {
592592 List,
593593};
594594
595- // Specialized to return true for all INPUT_OBJECT types .
595+ // These types are used as scalar arguments even though they are represented with a class .
596596template <typename Type>
597- [[nodiscard]] constexpr bool isInputType () noexcept
598- {
599- return false ;
600- }
597+ concept ScalarArgumentClass = std::is_same_v<Type, std::string> || std::is_same_v<Type,
598+ response::IdType> || std::is_same_v<Type, response::Value>;
601599
602- // Special-case an innermost nullable INPUT_OBJECT type.
600+ // Any non-scalar class used in an argument is a generated INPUT_OBJECT type.
601+ template <typename Type>
602+ concept InputArgumentClass = std::is_class_v<Type> && !ScalarArgumentClass<Type>;
603+
604+ // Test if there are any non-None modifiers left.
603605template <TypeModifier... Other>
604- [[nodiscard]] constexpr bool onlyNoneModifiers () noexcept
605- {
606- return (... && (Other == TypeModifier::None));
607- }
606+ concept OnlyNoneModifiers = (... && (Other == TypeModifier::None));
607+
608+ // Special-case an innermost nullable INPUT_OBJECT type.
609+ template <typename Type, TypeModifier... Other>
610+ concept InputArgumentUniquePtr = InputArgumentClass<Type> && OnlyNoneModifiers<Other...>;
608611
609612// Extract individual arguments with chained type modifiers which add nullable or list wrappers.
610613// If the argument is not optional, use require and let it throw a schema_exception when the
@@ -619,8 +622,8 @@ struct ModifiedArgument
619622 {
620623 // Peel off modifiers until we get to the underlying type.
621624 using type = typename std::conditional_t <TypeModifier::Nullable == Modifier,
622- typename std::conditional_t <isInputType<U>() && onlyNoneModifiers< Other...>() ,
623- std::unique_ptr<U>, std:: optional<typename ArgumentTraits<U, Other...>::type>>,
625+ typename std::conditional_t <InputArgumentUniquePtr<U, Other...>, std::unique_ptr<U> ,
626+ std::optional<typename ArgumentTraits<U, Other...>::type>>,
624627 typename std::conditional_t <TypeModifier::List == Modifier,
625628 std::vector<typename ArgumentTraits<U, Other...>::type>, U>>;
626629 };
@@ -699,7 +702,7 @@ struct ModifiedArgument
699702
700703 auto result = require<Other...>(name, arguments);
701704
702- if constexpr (isInputType <Type>() && onlyNoneModifiers< Other...>() )
705+ if constexpr (InputArgumentUniquePtr <Type, Other...>)
703706 {
704707 return std::make_unique<decltype (result)>(std::move (result));
705708 }
@@ -768,7 +771,7 @@ struct ModifiedArgument
768771
769772 if (nullableValue)
770773 {
771- if constexpr (isInputType <Type>() && onlyNoneModifiers< Other...>() )
774+ if constexpr (InputArgumentUniquePtr <Type, Other...>)
772775 {
773776 // Special case duplicating the std::unique_ptr.
774777 result = std::make_unique<Type>(Type { *nullableValue });
0 commit comments