@@ -592,6 +592,18 @@ enum class [[nodiscard]] TypeModifier {
592
592
List,
593
593
};
594
594
595
+ // Test if there are any non-None modifiers left.
596
+ template <TypeModifier... Other>
597
+ concept OnlyNoneModifiers = (... && (Other == TypeModifier::None));
598
+
599
+ // Test if the next modifier is Nullable.
600
+ template <TypeModifier Modifier>
601
+ concept NullableModifier = Modifier == TypeModifier::Nullable;
602
+
603
+ // Test if the next modifier is List.
604
+ template <TypeModifier Modifier>
605
+ concept ListModifier = Modifier == TypeModifier::List;
606
+
595
607
// These types are used as scalar arguments even though they are represented with a class.
596
608
template <typename Type>
597
609
concept ScalarArgumentClass = std::is_same_v<Type, std::string> || std::is_same_v<Type,
@@ -601,10 +613,6 @@ concept ScalarArgumentClass = std::is_same_v<Type, std::string> || std::is_same_
601
613
template <typename Type>
602
614
concept InputArgumentClass = std::is_class_v<Type> && !ScalarArgumentClass<Type>;
603
615
604
- // Test if there are any non-None modifiers left.
605
- template <TypeModifier... Other>
606
- concept OnlyNoneModifiers = (... && (Other == TypeModifier::None));
607
-
608
616
// Special-case an innermost nullable INPUT_OBJECT type.
609
617
template <typename Type, TypeModifier... Other>
610
618
concept InputArgumentUniquePtr = InputArgumentClass<Type> && OnlyNoneModifiers<Other...>;
@@ -678,9 +686,8 @@ struct ModifiedArgument
678
686
679
687
// Peel off the none modifier. If it's included, it should always be last in the list.
680
688
template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
681
- [[nodiscard]] static inline typename std::enable_if_t <TypeModifier::None == Modifier, Type>
682
- require (
683
- std::string_view name, const response::Value& arguments)
689
+ [[nodiscard]] static inline Type require (std::string_view name,
690
+ const response::Value& arguments) requires OnlyNoneModifiers<Modifier, Other...>
684
691
{
685
692
static_assert (sizeof ...(Other) == 0 , " None modifier should always be last" );
686
693
@@ -690,9 +697,8 @@ struct ModifiedArgument
690
697
691
698
// Peel off nullable modifiers.
692
699
template <TypeModifier Modifier, TypeModifier... Other>
693
- [[nodiscard]] static inline typename std::enable_if_t <TypeModifier::Nullable == Modifier,
694
- typename ArgumentTraits<Type, Modifier, Other...>::type>
695
- require (std::string_view name, const response::Value& arguments)
700
+ [[nodiscard]] static inline typename ArgumentTraits<Type, Modifier, Other...>::type require (
701
+ std::string_view name, const response::Value& arguments) requires NullableModifier<Modifier>
696
702
{
697
703
const auto & valueItr = arguments.find (name);
698
704
@@ -716,9 +722,8 @@ struct ModifiedArgument
716
722
717
723
// Peel off list modifiers.
718
724
template <TypeModifier Modifier, TypeModifier... Other>
719
- [[nodiscard]] static inline typename std::enable_if_t <TypeModifier::List == Modifier,
720
- typename ArgumentTraits<Type, Modifier, Other...>::type>
721
- require (std::string_view name, const response::Value& arguments)
725
+ [[nodiscard]] static inline typename ArgumentTraits<Type, Modifier, Other...>::type require (
726
+ std::string_view name, const response::Value& arguments) requires ListModifier<Modifier>
722
727
{
723
728
const auto & values = arguments[name];
724
729
typename ArgumentTraits<Type, Modifier, Other...>::type result (values.size ());
@@ -756,19 +761,18 @@ struct ModifiedArgument
756
761
757
762
// Peel off the none modifier. If it's included, it should always be last in the list.
758
763
template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
759
- [[nodiscard]] static inline
760
- typename std::enable_if_t <TypeModifier::None == Modifier && sizeof ...(Other) == 0 , Type>
761
- duplicate (const Type& value)
764
+ [[nodiscard]] static inline Type duplicate (
765
+ const Type& value) requires OnlyNoneModifiers<Modifier, Other...>
762
766
{
763
767
// Just copy the value.
764
768
return Type { value };
765
769
}
766
770
767
771
// Peel off nullable modifiers.
768
772
template <TypeModifier Modifier, TypeModifier... Other>
769
- [[nodiscard]] static inline typename std:: enable_if_t <TypeModifier::Nullable == Modifier,
770
- typename ArgumentTraits<Type, Modifier, Other...>::type>
771
- duplicate ( const typename ArgumentTraits<Type, Modifier, Other...>::type& nullableValue)
773
+ [[nodiscard]] static inline typename ArgumentTraits<Type, Modifier, Other...>::type duplicate (
774
+ const typename ArgumentTraits<Type, Modifier, Other...>::type& nullableValue) requires
775
+ NullableModifier< Modifier>
772
776
{
773
777
typename ArgumentTraits<Type, Modifier, Other...>::type result {};
774
778
@@ -790,9 +794,9 @@ struct ModifiedArgument
790
794
791
795
// Peel off list modifiers.
792
796
template <TypeModifier Modifier, TypeModifier... Other>
793
- [[nodiscard]] static inline typename std:: enable_if_t <TypeModifier::List == Modifier,
794
- typename ArgumentTraits<Type, Modifier, Other...>::type>
795
- duplicate ( const typename ArgumentTraits<Type, Modifier, Other...>::type& listValue)
797
+ [[nodiscard]] static inline typename ArgumentTraits<Type, Modifier, Other...>::type duplicate (
798
+ const typename ArgumentTraits<Type, Modifier, Other...>::type& listValue) requires
799
+ ListModifier< Modifier>
796
800
{
797
801
typename ArgumentTraits<Type, Modifier, Other...>::type result (listValue.size ());
798
802
@@ -868,6 +872,22 @@ class [[nodiscard]] Object : public std::enable_shared_from_this<Object>
868
872
ResolverMap _resolvers;
869
873
};
870
874
875
+ // Test if this Type is Object.
876
+ template <typename Type>
877
+ concept ObjectType = std::is_same_v<Object, Type>;
878
+
879
+ // Test if this Type inherits from Object.
880
+ template <typename Type>
881
+ concept ObjectBaseType = std::is_base_of_v<Object, Type>;
882
+
883
+ // Test if this Type inherits from Object but is not Object itself.
884
+ template <typename Type>
885
+ concept ObjectDerivedType = ObjectBaseType<Type> && !ObjectType<Type>;
886
+
887
+ // Test if ResultType is std::shared_ptr<Type>.
888
+ template <typename ResultType, typename Type>
889
+ concept ResultTypeSharedPtr = std::is_same_v<ResultType, std::shared_ptr<Type>>;
890
+
871
891
// Convert the result of a resolver function with chained type modifiers that add nullable or
872
892
// list wrappers. This is the inverse of ModifiedArgument for output types instead of input types.
873
893
template <typename Type>
@@ -879,12 +899,12 @@ struct ModifiedResult
879
899
{
880
900
using type = typename std::conditional_t <TypeModifier::Nullable == Modifier,
881
901
typename std::conditional_t <
882
- std::is_base_of_v<Object,
902
+ ObjectBaseType<
883
903
U> && std::is_same_v<std::shared_ptr<U>, typename ResultTraits<U, Other...>::type>,
884
904
std::shared_ptr<U>, std::optional<typename ResultTraits<U, Other...>::type>>,
885
905
typename std::conditional_t <TypeModifier::List == Modifier,
886
906
std::vector<typename ResultTraits<U, Other...>::type>,
887
- typename std::conditional_t <std::is_base_of_v<Object, U>, std::shared_ptr<U>, U>>>;
907
+ typename std::conditional_t <ObjectBaseType< U>, std::shared_ptr<U>, U>>>;
888
908
889
909
using future_type = typename std::conditional_t <std::is_base_of_v<Object, U>,
890
910
AwaitableObject<type>, AwaitableScalar<type>>;
@@ -893,10 +913,9 @@ struct ModifiedResult
893
913
template <typename U>
894
914
struct ResultTraits <U, TypeModifier::None>
895
915
{
896
- using type =
897
- typename std::conditional_t <std::is_base_of_v<Object, U>, std::shared_ptr<U>, U>;
916
+ using type = typename std::conditional_t <ObjectBaseType<U>, std::shared_ptr<U>, U>;
898
917
899
- using future_type = typename std::conditional_t <std::is_base_of_v<Object, U>,
918
+ using future_type = typename std::conditional_t <ObjectBaseType< U>,
900
919
AwaitableObject<std::shared_ptr<const Object>>, AwaitableScalar<type>>;
901
920
};
902
921
@@ -906,10 +925,9 @@ struct ModifiedResult
906
925
907
926
// Peel off the none modifier. If it's included, it should always be last in the list.
908
927
template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
909
- [[nodiscard]] static inline typename std::enable_if_t <TypeModifier::None == Modifier
910
- && !std::is_same_v<Object, Type> && std::is_base_of_v<Object, Type>,
911
- AwaitableResolver>
912
- convert (AwaitableObject<typename ResultTraits<Type>::type> result, ResolverParams params)
928
+ [[nodiscard]] static inline AwaitableResolver convert (
929
+ AwaitableObject<typename ResultTraits<Type>::type> result, ResolverParams params) requires
930
+ OnlyNoneModifiers<Modifier, Other...> && ObjectDerivedType<Type>
913
931
{
914
932
// Call through to the Object specialization with a static_pointer_cast for subclasses of
915
933
// Object.
@@ -928,10 +946,9 @@ struct ModifiedResult
928
946
929
947
// Peel off the none modifier. If it's included, it should always be last in the list.
930
948
template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
931
- [[nodiscard]] static inline typename std::enable_if_t <TypeModifier::None == Modifier
932
- && (std::is_same_v<Object, Type> || !std::is_base_of_v<Object, Type>),
933
- AwaitableResolver>
934
- convert (typename ResultTraits<Type>::future_type result, ResolverParams params)
949
+ [[nodiscard]] static inline AwaitableResolver convert (
950
+ typename ResultTraits<Type>::future_type result, ResolverParams params) requires
951
+ OnlyNoneModifiers<Modifier, Other...> && !ObjectDerivedType<Type>
935
952
{
936
953
static_assert (sizeof ...(Other) == 0 , " None modifier should always be last" );
937
954
@@ -941,11 +958,11 @@ struct ModifiedResult
941
958
942
959
// Peel off final nullable modifiers for std::shared_ptr of Object and subclasses of Object.
943
960
template <TypeModifier Modifier, TypeModifier... Other>
944
- [[nodiscard]] static inline typename std:: enable_if_t <TypeModifier::Nullable == Modifier
945
- && std::is_same_v<std::shared_ptr<Type>, typename ResultTraits<Type, Other...>::type> ,
946
- AwaitableResolver>
947
- convert (
948
- typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
961
+ [[nodiscard]] static inline AwaitableResolver convert (
962
+ typename ResultTraits<Type, Modifier, Other...>::future_type result ,
963
+ ResolverParams params) requires
964
+ NullableModifier<Modifier> && ResultTypeSharedPtr<
965
+ typename ResultTraits<Type, Other...>::type, Type>
949
966
{
950
967
co_await params.launch ;
951
968
@@ -964,11 +981,11 @@ struct ModifiedResult
964
981
965
982
// Peel off nullable modifiers for anything else, which should all be std::optional.
966
983
template <TypeModifier Modifier, TypeModifier... Other>
967
- [[nodiscard]] static inline typename std:: enable_if_t <TypeModifier::Nullable == Modifier
968
- && !std::is_same_v<std::shared_ptr<Type>, typename ResultTraits<Type, Other...>::type> ,
969
- AwaitableResolver>
970
- convert (
971
- typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
984
+ [[nodiscard]] static inline AwaitableResolver convert (
985
+ typename ResultTraits<Type, Modifier, Other...>::future_type result ,
986
+ ResolverParams params) requires
987
+ NullableModifier<Modifier> && !ResultTypeSharedPtr<
988
+ typename ResultTraits<Type, Other...>::type, Type>
972
989
{
973
990
static_assert (std::is_same_v<std::optional<typename ResultTraits<Type, Other...>::type>,
974
991
typename ResultTraits<Type, Modifier, Other...>::type>,
@@ -1003,10 +1020,9 @@ struct ModifiedResult
1003
1020
1004
1021
// Peel off list modifiers.
1005
1022
template <TypeModifier Modifier, TypeModifier... Other>
1006
- [[nodiscard]] static inline
1007
- typename std::enable_if_t <TypeModifier::List == Modifier, AwaitableResolver>
1008
- convert (typename ResultTraits<Type, Modifier, Other...>::future_type result,
1009
- ResolverParams params)
1023
+ [[nodiscard]] static inline AwaitableResolver convert (
1024
+ typename ResultTraits<Type, Modifier, Other...>::future_type result,
1025
+ ResolverParams params) requires ListModifier<Modifier>
1010
1026
{
1011
1027
if constexpr (!std::is_base_of_v<Object, Type>)
1012
1028
{
@@ -1111,7 +1127,7 @@ struct ModifiedResult
1111
1127
// Peel off the none modifier. If it's included, it should always be last in the list.
1112
1128
template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
1113
1129
static inline void validateScalar (
1114
- typename std:: enable_if_t <TypeModifier::None == Modifier, const response::Value&> value)
1130
+ const response::Value& value) requires OnlyNoneModifiers<Modifier, Other...>
1115
1131
{
1116
1132
static_assert (sizeof ...(Other) == 0 , " None modifier should always be last" );
1117
1133
@@ -1121,8 +1137,7 @@ struct ModifiedResult
1121
1137
1122
1138
// Peel off nullable modifiers.
1123
1139
template <TypeModifier Modifier, TypeModifier... Other>
1124
- static inline void validateScalar (
1125
- typename std::enable_if_t <TypeModifier::Nullable == Modifier, const response::Value&> value)
1140
+ static inline void validateScalar (const response::Value& value) requires NullableModifier<Modifier>
1126
1141
{
1127
1142
if (value.type () != response::Type::Null)
1128
1143
{
@@ -1132,8 +1147,7 @@ struct ModifiedResult
1132
1147
1133
1148
// Peel off list modifiers.
1134
1149
template <TypeModifier Modifier, TypeModifier... Other>
1135
- static inline void validateScalar (
1136
- typename std::enable_if_t <TypeModifier::List == Modifier, const response::Value&> value)
1150
+ static inline void validateScalar (const response::Value& value) requires ListModifier<Modifier>
1137
1151
{
1138
1152
if (value.type () != response::Type::List)
1139
1153
{
@@ -1150,8 +1164,8 @@ struct ModifiedResult
1150
1164
std::function<response::Value(typename ResultTraits<Type>::type, const ResolverParams&)>;
1151
1165
1152
1166
[[nodiscard]] static inline AwaitableResolver resolve (
1153
- typename ResultTraits<Type>::future_type result,
1154
- ResolverParams params, ResolverCallback&& resolver)
1167
+ typename ResultTraits<Type>::future_type result, ResolverParams params,
1168
+ ResolverCallback&& resolver)
1155
1169
{
1156
1170
static_assert (!std::is_base_of_v<Object, Type>,
1157
1171
" ModfiedResult<Object> needs special handling" );
0 commit comments