diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index a1f5b5d7..13ce6cdf 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -168,9 +168,16 @@ struct ModifiedVariable response::Value result { response::Type::List }; result.reserve(listValue.size()); - std::ranges::for_each(listValue, [&result](auto& value) { - result.emplace_back(serialize(std::move(value))); - }); + if constexpr(std::is_same_v){ + for (auto const v: listValue) + result.emplace_back(Variable::serialize(bool{v})); + } + else{ + std::ranges::for_each(listValue, [&result](auto& value) { + result.emplace_back(serialize(std::move(value))); + }); + } + listValue.clear(); return result; @@ -217,11 +224,19 @@ struct ModifiedVariable duplicate(const typename VariableTraits::type& listValue) requires ListModifier { - typename VariableTraits::type result(listValue.size()); - - std::ranges::transform(listValue, result.begin(), duplicate); - - return result; + if constexpr(std::is_same_v){ + typename VariableTraits::type result; + result.reserve(listValue.size()); + for (auto const v: listValue) + result.push_back(v); + return result; + } + else + { + typename VariableTraits::type result(listValue.size()); + std::ranges::transform(listValue, result.begin(), duplicate); + return result; + } } }; diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index b6c6eac2..dacf9ce5 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -795,11 +795,19 @@ struct ModifiedArgument duplicate(const typename ArgumentTraits::type& listValue) requires ListModifier { - typename ArgumentTraits::type result(listValue.size()); - - std::ranges::transform(listValue, result.begin(), duplicate); - - return result; + if constexpr(std::is_same_v){ + typename ArgumentTraits::type result; + result.reserve(listValue.size()); + for (auto const v: listValue) + result.push_back(v); + return result; + } + else + { + typename ArgumentTraits::type result(listValue.size()); + std::ranges::transform(listValue, result.begin(), duplicate); + return result; + } } }; diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index 1644ddcb..177380a0 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -131,6 +131,7 @@ CompleteTaskInput::CompleteTaskInput() noexcept , testTaskState {} , isComplete {} , clientMutationId {} + , boolList {} { // Explicit definition to prevent ODR violations when LTO is enabled. } @@ -139,11 +140,13 @@ CompleteTaskInput::CompleteTaskInput( response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept : id { std::move(idArg) } , testTaskState { std::move(testTaskStateArg) } , isComplete { std::move(isCompleteArg) } , clientMutationId { std::move(clientMutationIdArg) } + , boolList { std::move(boolListArg) } { } @@ -152,6 +155,7 @@ CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) , testTaskState { ModifiedVariable::duplicate(other.testTaskState) } , isComplete { ModifiedVariable::duplicate(other.isComplete) } , clientMutationId { ModifiedVariable::duplicate(other.clientMutationId) } + , boolList { ModifiedVariable::duplicate(other.boolList) } { } @@ -160,6 +164,7 @@ CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept , testTaskState { std::move(other.testTaskState) } , isComplete { std::move(other.isComplete) } , clientMutationId { std::move(other.clientMutationId) } + , boolList { std::move(other.boolList) } { } @@ -179,6 +184,7 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc testTaskState = std::move(other.testTaskState); isComplete = std::move(other.isComplete); clientMutationId = std::move(other.clientMutationId); + boolList = std::move(other.boolList); return *this; } @@ -2316,6 +2322,7 @@ response::Value Variable::serialize(CompleteTaskInput&& input result.emplace_back(R"js(testTaskState)js"s, ModifiedVariable::serialize(std::move(inputValue.testTaskState))); result.emplace_back(R"js(isComplete)js"s, ModifiedVariable::serialize(std::move(inputValue.isComplete))); result.emplace_back(R"js(clientMutationId)js"s, ModifiedVariable::serialize(std::move(inputValue.clientMutationId))); + result.emplace_back(R"js(boolList)js"s, ModifiedVariable::serialize(std::move(inputValue.boolList))); return result; } diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index 4e711034..a7c7460e 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -132,7 +132,8 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept; CompleteTaskInput(const CompleteTaskInput& other); CompleteTaskInput(CompleteTaskInput&& other) noexcept; ~CompleteTaskInput(); @@ -144,6 +145,7 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional testTaskState; std::optional isComplete; std::optional clientMutationId; + std::optional> boolList; }; namespace client { diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index f54db298..248b86a8 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -64,6 +64,7 @@ CompleteTaskInput::CompleteTaskInput() noexcept , testTaskState {} , isComplete {} , clientMutationId {} + , boolList {} { // Explicit definition to prevent ODR violations when LTO is enabled. } @@ -72,11 +73,13 @@ CompleteTaskInput::CompleteTaskInput( response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept : id { std::move(idArg) } , testTaskState { std::move(testTaskStateArg) } , isComplete { std::move(isCompleteArg) } , clientMutationId { std::move(clientMutationIdArg) } + , boolList { std::move(boolListArg) } { } @@ -85,6 +88,7 @@ CompleteTaskInput::CompleteTaskInput(const CompleteTaskInput& other) , testTaskState { ModifiedVariable::duplicate(other.testTaskState) } , isComplete { ModifiedVariable::duplicate(other.isComplete) } , clientMutationId { ModifiedVariable::duplicate(other.clientMutationId) } + , boolList { ModifiedVariable::duplicate(other.boolList) } { } @@ -93,6 +97,7 @@ CompleteTaskInput::CompleteTaskInput(CompleteTaskInput&& other) noexcept , testTaskState { std::move(other.testTaskState) } , isComplete { std::move(other.isComplete) } , clientMutationId { std::move(other.clientMutationId) } + , boolList { std::move(other.boolList) } { } @@ -112,6 +117,7 @@ CompleteTaskInput& CompleteTaskInput::operator=(CompleteTaskInput&& other) noexc testTaskState = std::move(other.testTaskState); isComplete = std::move(other.isComplete); clientMutationId = std::move(other.clientMutationId); + boolList = std::move(other.boolList); return *this; } @@ -148,6 +154,7 @@ response::Value Variable::serialize(CompleteTaskInput&& input result.emplace_back(R"js(testTaskState)js"s, ModifiedVariable::serialize(std::move(inputValue.testTaskState))); result.emplace_back(R"js(isComplete)js"s, ModifiedVariable::serialize(std::move(inputValue.isComplete))); result.emplace_back(R"js(clientMutationId)js"s, ModifiedVariable::serialize(std::move(inputValue.clientMutationId))); + result.emplace_back(R"js(boolList)js"s, ModifiedVariable::serialize(std::move(inputValue.boolList))); return result; } diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index 4c945b24..72a67a45 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -65,7 +65,8 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput response::IdType idArg, std::optional testTaskStateArg, std::optional isCompleteArg, - std::optional clientMutationIdArg) noexcept; + std::optional clientMutationIdArg, + std::optional> boolListArg) noexcept; CompleteTaskInput(const CompleteTaskInput& other); CompleteTaskInput(CompleteTaskInput&& other) noexcept; ~CompleteTaskInput(); @@ -77,6 +78,7 @@ struct [[nodiscard("unnecessary construction")]] CompleteTaskInput std::optional testTaskState; std::optional isComplete; std::optional clientMutationId; + std::optional> boolList; }; namespace client { diff --git a/samples/today/schema.today.graphql b/samples/today/schema.today.graphql index 8c794450..94e9770a 100644 --- a/samples/today/schema.today.graphql +++ b/samples/today/schema.today.graphql @@ -87,6 +87,7 @@ input CompleteTaskInput { testTaskState: TaskState isComplete: Boolean = true clientMutationId: String + boolList: [Boolean!] } type CompleteTaskPayload { diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 26a1bcb9..4f674d00 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -246,7 +246,8 @@ TEST_F(ClientCase, MutateCompleteTask) { std::make_unique(CompleteTaskInput { today::getFakeTaskId(), std::nullopt, std::make_optional(true), - std::make_optional("Hi There!"s) }) }); + std::make_optional("Hi There!"s), + std::vector({true,false}) }) }); auto state = std::make_shared(5); auto result =