@@ -70,6 +70,33 @@ enum class [[nodiscard]] TypeModifier {
7070 List,
7171};
7272
73+ // Serialize a single variable input value.
74+ template <typename Type>
75+ struct Variable
76+ {
77+ // Serialize a single value to the variables document.
78+ [[nodiscard]] static response::Value serialize (Type&& value);
79+ };
80+
81+ #ifdef GRAPHQL_DLLEXPORTS
82+ // Export all of the built-in converters
83+ template <>
84+ GRAPHQLCLIENT_EXPORT response::Value Variable<int >::serialize(int && value);
85+ template <>
86+ GRAPHQLCLIENT_EXPORT response::Value Variable<double >::serialize(double && value);
87+ template <>
88+ GRAPHQLCLIENT_EXPORT response::Value Variable<std::string>::serialize(std::string&& value);
89+ template <>
90+ GRAPHQLCLIENT_EXPORT response::Value Variable<bool >::serialize(bool && value);
91+ template <>
92+ GRAPHQLCLIENT_EXPORT response::Value Variable<response::IdType>::serialize(
93+ response::IdType&& value);
94+ template <>
95+ GRAPHQLCLIENT_EXPORT response::Value Variable<response::Value>::serialize(response::Value&& value);
96+ #endif // GRAPHQL_DLLEXPORTS
97+
98+ namespace {
99+
73100// These types are used as scalar variables even though they are represented with a class.
74101template <typename Type>
75102concept ScalarVariableClass = std::is_same_v<Type, std::string> || std::is_same_v<Type,
@@ -83,11 +110,18 @@ concept InputVariableClass = std::is_class_v<Type> && !ScalarVariableClass<Type>
83110template <TypeModifier... Other>
84111concept OnlyNoneModifiers = (... && (Other == TypeModifier::None));
85112
113+ // Test if the next modifier is Nullable.
114+ template <TypeModifier Modifier>
115+ concept NullableModifier = Modifier == TypeModifier::Nullable;
116+
117+ // Test if the next modifier is List.
118+ template <TypeModifier Modifier>
119+ concept ListModifier = Modifier == TypeModifier::List;
120+
86121// Special-case an innermost nullable INPUT_OBJECT type.
87122template <typename Type, TypeModifier... Other>
88123concept InputVariableUniquePtr = InputVariableClass<Type> && OnlyNoneModifiers<Other...>;
89124
90-
91125// Serialize variable input values with chained type modifiers which add nullable or list wrappers.
92126template <typename Type>
93127struct ModifiedVariable
@@ -110,25 +144,20 @@ struct ModifiedVariable
110144 using type = U;
111145 };
112146
113- // Serialize a single value to the variables document.
114- [[nodiscard]] static response::Value serialize (Type&& value);
115-
116147 // Peel off the none modifier. If it's included, it should always be last in the list.
117148 template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
118- [[nodiscard]] static
119- typename std::enable_if_t <TypeModifier::None == Modifier && sizeof ...(Other) == 0 ,
120- response::Value>
121- serialize (Type&& value)
149+ [[nodiscard]] static inline response::Value serialize (
150+ Type&& value) requires OnlyNoneModifiers<Modifier, Other...>
122151 {
123152 // Just call through to the non-template method without the modifiers.
124- return serialize (std::move (value));
153+ return Variable<Type>:: serialize (std::move (value));
125154 }
126155
127156 // Peel off nullable modifiers.
128157 template <TypeModifier Modifier, TypeModifier... Other>
129- [[nodiscard]] static
130- typename std:: enable_if_t <TypeModifier::Nullable == Modifier, response::Value>
131- serialize ( typename VariableTraits<Type, Modifier, Other...>::type&& nullableValue)
158+ [[nodiscard]] static inline response::Value serialize (
159+ typename VariableTraits<Type, Modifier, Other...>::type&& nullableValue) requires
160+ NullableModifier< Modifier>
132161 {
133162 response::Value result;
134163
@@ -143,8 +172,9 @@ struct ModifiedVariable
143172
144173 // Peel off list modifiers.
145174 template <TypeModifier Modifier, TypeModifier... Other>
146- [[nodiscard]] static typename std::enable_if_t <TypeModifier::List == Modifier, response::Value>
147- serialize (typename VariableTraits<Type, Modifier, Other...>::type&& listValue)
175+ [[nodiscard]] static inline response::Value serialize (
176+ typename VariableTraits<Type, Modifier, Other...>::type&& listValue) requires
177+ ListModifier<Modifier>
148178 {
149179 response::Value result { response::Type::List };
150180
@@ -159,19 +189,18 @@ struct ModifiedVariable
159189
160190 // Peel off the none modifier. If it's included, it should always be last in the list.
161191 template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
162- [[nodiscard]] static
163- typename std::enable_if_t <TypeModifier::None == Modifier && sizeof ...(Other) == 0 , Type>
164- duplicate (const Type& value)
192+ [[nodiscard]] static inline Type duplicate (
193+ const Type& value) requires OnlyNoneModifiers<Modifier, Other...>
165194 {
166195 // Just copy the value.
167196 return Type { value };
168197 }
169198
170199 // Peel off nullable modifiers.
171200 template <TypeModifier Modifier, TypeModifier... Other>
172- [[nodiscard]] static typename std:: enable_if_t <TypeModifier::Nullable == Modifier,
173- typename VariableTraits<Type, Modifier, Other...>::type>
174- duplicate ( const typename VariableTraits<Type, Modifier, Other...>::type& nullableValue)
201+ [[nodiscard]] static inline typename VariableTraits<Type, Modifier, Other...>::type duplicate (
202+ const typename VariableTraits<Type, Modifier, Other...>::type& nullableValue) requires
203+ NullableModifier< Modifier>
175204 {
176205 typename VariableTraits<Type, Modifier, Other...>::type result {};
177206
@@ -193,9 +222,9 @@ struct ModifiedVariable
193222
194223 // Peel off list modifiers.
195224 template <TypeModifier Modifier, TypeModifier... Other>
196- [[nodiscard]] static typename std:: enable_if_t <TypeModifier::List == Modifier,
197- typename VariableTraits<Type, Modifier, Other...>::type>
198- duplicate ( const typename VariableTraits<Type, Modifier, Other...>::type& listValue)
225+ [[nodiscard]] static inline typename VariableTraits<Type, Modifier, Other...>::type duplicate (
226+ const typename VariableTraits<Type, Modifier, Other...>::type& listValue) requires
227+ ListModifier< Modifier>
199228 {
200229 typename VariableTraits<Type, Modifier, Other...>::type result (listValue.size ());
201230
@@ -215,24 +244,35 @@ using BooleanVariable = ModifiedVariable<bool>;
215244using IdVariable = ModifiedVariable<response::IdType>;
216245using ScalarVariable = ModifiedVariable<response::Value>;
217246
247+ } // namespace
248+
249+ // Parse a single response output value. This is the inverse of Variable for output types instead of
250+ // input types.
251+ template <typename Type>
252+ struct Response
253+ {
254+ // Parse a single value of the response document.
255+ [[nodiscard]] static Type parse (response::Value&& response);
256+ };
257+
218258#ifdef GRAPHQL_DLLEXPORTS
219259// Export all of the built-in converters
220260template <>
221- GRAPHQLCLIENT_EXPORT response::Value ModifiedVariable <int >::serialize( int && value );
261+ GRAPHQLCLIENT_EXPORT int Response <int >::parse(response::Value && response );
222262template <>
223- GRAPHQLCLIENT_EXPORT response::Value ModifiedVariable <double >::serialize( double && value );
263+ GRAPHQLCLIENT_EXPORT double Response <double >::parse(response::Value && response );
224264template <>
225- GRAPHQLCLIENT_EXPORT response::Value ModifiedVariable <std::string>::serialize(std::string && value );
265+ GRAPHQLCLIENT_EXPORT std::string Response <std::string>::parse(response::Value && response );
226266template <>
227- GRAPHQLCLIENT_EXPORT response::Value ModifiedVariable <bool >::serialize( bool && value );
267+ GRAPHQLCLIENT_EXPORT bool Response <bool >::parse(response::Value && response );
228268template <>
229- GRAPHQLCLIENT_EXPORT response::Value ModifiedVariable<response::IdType>::serialize(
230- response::IdType&& value);
269+ GRAPHQLCLIENT_EXPORT response::IdType Response<response::IdType>::parse(response::Value&& response);
231270template <>
232- GRAPHQLCLIENT_EXPORT response::Value ModifiedVariable<response::Value>::serialize(
233- response::Value&& value);
271+ GRAPHQLCLIENT_EXPORT response::Value Response<response::Value>::parse(response::Value&& response);
234272#endif // GRAPHQL_DLLEXPORTS
235273
274+ namespace {
275+
236276// Parse response output values with chained type modifiers that add nullable or list wrappers.
237277// This is the inverse of ModifiedVariable for output types instead of input types.
238278template <typename Type>
@@ -254,23 +294,18 @@ struct ModifiedResponse
254294 using type = U;
255295 };
256296
257- // Parse a single value of the response document.
258- [[nodiscard]] static Type parse (response::Value&& response);
259-
260297 // Peel off the none modifier. If it's included, it should always be last in the list.
261298 template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
262- [[nodiscard]] static
263- typename std::enable_if_t <TypeModifier::None == Modifier && sizeof ...(Other) == 0 , Type>
264- parse (response::Value&& response)
299+ [[nodiscard]] static inline Type parse (
300+ response::Value&& response) requires OnlyNoneModifiers<Modifier, Other...>
265301 {
266- return parse (std::move (response));
302+ return Response<Type>:: parse (std::move (response));
267303 }
268304
269305 // Peel off nullable modifiers.
270306 template <TypeModifier Modifier, TypeModifier... Other>
271- [[nodiscard]] static typename std::enable_if_t <TypeModifier::Nullable == Modifier,
272- std::optional<typename ResponseTraits<Type, Other...>::type>>
273- parse (response::Value&& response)
307+ [[nodiscard]] static inline std::optional<typename ResponseTraits<Type, Other...>::type> parse (
308+ response::Value&& response) requires NullableModifier<Modifier>
274309 {
275310 if (response.type () == response::Type::Null)
276311 {
@@ -283,9 +318,8 @@ struct ModifiedResponse
283318
284319 // Peel off list modifiers.
285320 template <TypeModifier Modifier, TypeModifier... Other>
286- [[nodiscard]] static typename std::enable_if_t <TypeModifier::List == Modifier,
287- std::vector<typename ResponseTraits<Type, Other...>::type>>
288- parse (response::Value&& response)
321+ [[nodiscard]] static inline std::vector<typename ResponseTraits<Type, Other...>::type> parse (
322+ response::Value&& response) requires ListModifier<Modifier>
289323 {
290324 std::vector<typename ResponseTraits<Type, Other...>::type> result;
291325
@@ -316,24 +350,7 @@ using BooleanResponse = ModifiedResponse<bool>;
316350using IdResponse = ModifiedResponse<response::IdType>;
317351using ScalarResponse = ModifiedResponse<response::Value>;
318352
319- #ifdef GRAPHQL_DLLEXPORTS
320- // Export all of the built-in converters
321- template <>
322- GRAPHQLCLIENT_EXPORT int ModifiedResponse<int >::parse(response::Value&& response);
323- template <>
324- GRAPHQLCLIENT_EXPORT double ModifiedResponse<double >::parse(response::Value&& response);
325- template <>
326- GRAPHQLCLIENT_EXPORT std::string ModifiedResponse<std::string>::parse(response::Value&& response);
327- template <>
328- GRAPHQLCLIENT_EXPORT bool ModifiedResponse<bool >::parse(response::Value&& response);
329- template <>
330- GRAPHQLCLIENT_EXPORT response::IdType ModifiedResponse<response::IdType>::parse(
331- response::Value&& response);
332- template <>
333- GRAPHQLCLIENT_EXPORT response::Value ModifiedResponse<response::Value>::parse(
334- response::Value&& response);
335- #endif // GRAPHQL_DLLEXPORTS
336-
353+ } // namespace
337354} // namespace graphql::client
338355
339356#endif // GRAPHQLCLIENT_H
0 commit comments