Skip to content

Commit a610521

Browse files
authored
Merge pull request #326 from wravery/visitor-queue
fix: #320
2 parents 44bc921 + 9664efd commit a610521

38 files changed

+7671
-353
lines changed

include/ClientGenerator.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,55 @@ class [[nodiscard("unnecessary construction")]] Generator
6464
const std::string& outerScope, const ResponseField& responseField) const noexcept;
6565
[[nodiscard("unnecessary memory copy")]] static std::string getTypeModifierList(
6666
const TypeModifierStack& modifiers) noexcept;
67+
void outputResponseFieldVisitorStates(std::ostream& sourceFile,
68+
const ResponseField& responseField, std::string_view parent = {}) const noexcept;
69+
void outputResponseFieldVisitorAddValue(std::ostream& sourceFile,
70+
const ResponseField& responseField, bool arrayElement = false,
71+
std::string_view parentState = {}, std::string_view parentAccessor = {},
72+
std::string_view parentCppType = {}) const noexcept;
73+
void outputResponseFieldVisitorReserve(std::ostream& sourceFile,
74+
const ResponseField& responseField, std::string_view parentState = {},
75+
std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept;
76+
void outputResponseFieldVisitorStartObject(std::ostream& sourceFile,
77+
const ResponseField& responseField, std::string_view parentState = {},
78+
std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept;
79+
void outputResponseFieldVisitorAddMember(std::ostream& sourceFile,
80+
const ResponseFieldList& children, bool arrayElement = false,
81+
std::string_view parentState = {}) const noexcept;
82+
void outputResponseFieldVisitorEndObject(std::ostream& sourceFile,
83+
const ResponseField& responseField, bool arrayElement = false,
84+
std::string_view parentState = {}) const noexcept;
85+
void outputResponseFieldVisitorStartArray(std::ostream& sourceFile,
86+
const ResponseField& responseField, std::string_view parentState = {},
87+
std::string_view parentAccessor = {}, std::string_view parentCppType = {}) const noexcept;
88+
void outputResponseFieldVisitorEndArray(std::ostream& sourceFilearrayElement,
89+
const ResponseField& responseField, bool arrayElement = false,
90+
std::string_view parentState = {}) const noexcept;
91+
void outputResponseFieldVisitorAddNull(std::ostream& sourceFilearrayElement,
92+
const ResponseField& responseField, bool arrayElement = false,
93+
std::string_view parentState = {}, std::string_view parentAccessor = {}) const noexcept;
94+
void outputResponseFieldVisitorAddMovedValue(std::ostream& sourceFile,
95+
const ResponseField& responseField, std::string_view movedCppType,
96+
bool arrayElement = false, std::string_view parentState = {},
97+
std::string_view parentAccessor = {}) const noexcept;
98+
void outputResponseFieldVisitorAddString(
99+
std::ostream& sourceFile, const ResponseField& responseField) const noexcept;
100+
void outputResponseFieldVisitorAddEnum(std::ostream& sourceFile,
101+
const ResponseField& responseField, bool arrayElement = false,
102+
std::string_view parentState = {}, std::string_view parentAccessor = {},
103+
std::string_view parentCppType = {}) const noexcept;
104+
void outputResponseFieldVisitorAddId(
105+
std::ostream& sourceFile, const ResponseField& responseField) const noexcept;
106+
void outputResponseFieldVisitorAddCopiedValue(std::ostream& sourceFile,
107+
const ResponseField& responseField, std::string_view copiedCppType,
108+
bool arrayElement = false, std::string_view parentState = {},
109+
std::string_view parentAccessor = {}) const noexcept;
110+
void outputResponseFieldVisitorAddBool(
111+
std::ostream& sourceFile, const ResponseField& responseField) const noexcept;
112+
void outputResponseFieldVisitorAddInt(
113+
std::ostream& sourceFile, const ResponseField& responseField) const noexcept;
114+
void outputResponseFieldVisitorAddFloat(
115+
std::ostream& sourceFile, const ResponseField& responseField) const noexcept;
67116

68117
const SchemaLoader _schemaLoader;
69118
const RequestLoader _requestLoader;

include/graphqlservice/GraphQLResponse.h

Lines changed: 288 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
#ifndef GRAPHQLRESPONSE_H
77
#define GRAPHQLRESPONSE_H
88

9-
#include "internal/DllExports.h"
109
#include "internal/Awaitable.h"
10+
#include "internal/DllExports.h"
1111

1212
#include <cstddef>
1313
#include <cstdint>
1414
#include <initializer_list>
1515
#include <iterator>
16+
#include <list>
1617
#include <memory>
1718
#include <string>
1819
#include <string_view>
@@ -375,6 +376,292 @@ GRAPHQLRESPONSE_EXPORT IdType Value::release<IdType>();
375376

376377
using AwaitableValue = internal::Awaitable<Value>;
377378

379+
// Type-erased visitor for alternate representations of Value.
380+
class [[nodiscard("unnecessary construction")]] ValueVisitor final
381+
: public std::enable_shared_from_this<ValueVisitor>
382+
{
383+
private:
384+
struct Concept
385+
{
386+
virtual ~Concept() = default;
387+
388+
virtual void add_value(std::shared_ptr<const Value>&& value) = 0;
389+
390+
virtual void reserve(std::size_t count) = 0;
391+
392+
virtual void start_object() = 0;
393+
virtual void add_member(std::string&& key) = 0;
394+
virtual void end_object() = 0;
395+
396+
virtual void start_array() = 0;
397+
virtual void end_array() = 0;
398+
399+
virtual void add_null() = 0;
400+
virtual void add_string(std::string&& value) = 0;
401+
virtual void add_enum(std::string&& value) = 0;
402+
virtual void add_id(IdType&& value) = 0;
403+
virtual void add_bool(bool value) = 0;
404+
virtual void add_int(int value) = 0;
405+
virtual void add_float(double value) = 0;
406+
407+
virtual void complete() = 0;
408+
};
409+
410+
template <class T>
411+
struct Model : Concept
412+
{
413+
explicit Model(std::shared_ptr<T> pimpl) noexcept
414+
: _pimpl { std::move(pimpl) }
415+
{
416+
}
417+
418+
void add_value(std::shared_ptr<const Value>&& value) final
419+
{
420+
_pimpl->add_value(std::move(value));
421+
}
422+
423+
void reserve(std::size_t count) final
424+
{
425+
_pimpl->reserve(count);
426+
}
427+
428+
void start_object() final
429+
{
430+
_pimpl->start_object();
431+
}
432+
433+
void add_member(std::string&& key) final
434+
{
435+
_pimpl->add_member(std::move(key));
436+
}
437+
438+
void end_object() final
439+
{
440+
_pimpl->end_object();
441+
}
442+
443+
void start_array() final
444+
{
445+
_pimpl->start_array();
446+
}
447+
448+
void end_array() final
449+
{
450+
_pimpl->end_array();
451+
}
452+
453+
void add_null() final
454+
{
455+
_pimpl->add_null();
456+
}
457+
458+
void add_string(std::string&& value) final
459+
{
460+
_pimpl->add_string(std::move(value));
461+
}
462+
463+
void add_enum(std::string&& value) final
464+
{
465+
_pimpl->add_enum(std::move(value));
466+
}
467+
468+
void add_id(IdType&& value) final
469+
{
470+
_pimpl->add_id(std::move(value));
471+
}
472+
473+
void add_bool(bool value) final
474+
{
475+
_pimpl->add_bool(value);
476+
}
477+
478+
void add_int(int value) final
479+
{
480+
_pimpl->add_int(value);
481+
}
482+
483+
void add_float(double value) final
484+
{
485+
_pimpl->add_float(value);
486+
}
487+
488+
void complete() final
489+
{
490+
_pimpl->complete();
491+
}
492+
493+
private:
494+
std::shared_ptr<T> _pimpl;
495+
};
496+
497+
const std::shared_ptr<Concept> _concept;
498+
499+
public:
500+
template <class T>
501+
ValueVisitor(std::shared_ptr<T> writer) noexcept
502+
: _concept { std::static_pointer_cast<Concept>(
503+
std::make_shared<Model<T>>(std::move(writer))) }
504+
{
505+
}
506+
507+
GRAPHQLRESPONSE_EXPORT void add_value(std::shared_ptr<const Value>&& value);
508+
509+
GRAPHQLRESPONSE_EXPORT void reserve(std::size_t count);
510+
511+
GRAPHQLRESPONSE_EXPORT void start_object();
512+
GRAPHQLRESPONSE_EXPORT void add_member(std::string&& key);
513+
GRAPHQLRESPONSE_EXPORT void end_object();
514+
515+
GRAPHQLRESPONSE_EXPORT void start_array();
516+
GRAPHQLRESPONSE_EXPORT void end_array();
517+
518+
GRAPHQLRESPONSE_EXPORT void add_null();
519+
GRAPHQLRESPONSE_EXPORT void add_string(std::string&& value);
520+
GRAPHQLRESPONSE_EXPORT void add_enum(std::string&& value);
521+
GRAPHQLRESPONSE_EXPORT void add_id(IdType&& value);
522+
GRAPHQLRESPONSE_EXPORT void add_bool(bool value);
523+
GRAPHQLRESPONSE_EXPORT void add_int(int value);
524+
GRAPHQLRESPONSE_EXPORT void add_float(double value);
525+
526+
GRAPHQLRESPONSE_EXPORT void complete();
527+
};
528+
529+
// Pending token for ValueVisitor.
530+
struct [[nodiscard("unnecessary construction")]] ValueToken
531+
{
532+
using OpaqueValue = std::shared_ptr<const Value>;
533+
534+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(OpaqueValue&& value);
535+
536+
struct Reserve
537+
{
538+
std::size_t capacity;
539+
};
540+
541+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(Reserve&& value);
542+
543+
struct StartObject
544+
{
545+
};
546+
547+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(StartObject&& value);
548+
549+
struct AddMember
550+
{
551+
std::string key;
552+
};
553+
554+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(AddMember&& value);
555+
556+
struct EndObject
557+
{
558+
};
559+
560+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(EndObject&& value);
561+
562+
struct StartArray
563+
{
564+
};
565+
566+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(StartArray&& value);
567+
568+
struct EndArray
569+
{
570+
};
571+
572+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(EndArray&& value);
573+
574+
struct NullValue
575+
{
576+
};
577+
578+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(NullValue&& value);
579+
580+
struct StringValue
581+
{
582+
std::string value;
583+
};
584+
585+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(StringValue&& value);
586+
587+
struct EnumValue
588+
{
589+
std::string value;
590+
};
591+
592+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(EnumValue&& value);
593+
594+
struct IdValue
595+
{
596+
IdType value;
597+
};
598+
599+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(IdValue&& value);
600+
601+
struct BoolValue
602+
{
603+
bool value;
604+
};
605+
606+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(BoolValue&& value);
607+
608+
struct IntValue
609+
{
610+
int value;
611+
};
612+
613+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(IntValue&& value);
614+
615+
struct FloatValue
616+
{
617+
double value;
618+
};
619+
620+
GRAPHQLRESPONSE_EXPORT explicit ValueToken(FloatValue&& value);
621+
622+
GRAPHQLRESPONSE_EXPORT void visit(const std::shared_ptr<ValueVisitor>& visitor) &&;
623+
624+
private:
625+
using variant_type =
626+
std::variant<OpaqueValue, Reserve, StartObject, AddMember, EndObject, StartArray, EndArray,
627+
NullValue, StringValue, EnumValue, IdValue, BoolValue, IntValue, FloatValue>;
628+
629+
variant_type _value;
630+
};
631+
632+
class [[nodiscard("unnecessary construction")]] ValueTokenStream final
633+
{
634+
public:
635+
ValueTokenStream() noexcept = default;
636+
~ValueTokenStream() = default;
637+
638+
ValueTokenStream(ValueTokenStream&&) noexcept = default;
639+
ValueTokenStream& operator=(ValueTokenStream&&) noexcept = default;
640+
641+
ValueTokenStream(const ValueTokenStream&) = delete;
642+
ValueTokenStream& operator=(const ValueTokenStream&) = delete;
643+
644+
template <class TArg>
645+
ValueTokenStream(TArg&& arg)
646+
: _tokens { ValueToken { std::forward<TArg>(arg) } }
647+
{
648+
}
649+
650+
template <class TArg>
651+
void push_back(TArg&& arg)
652+
{
653+
_tokens.push_back(ValueToken { std::forward<TArg>(arg) });
654+
}
655+
656+
GRAPHQLRESPONSE_EXPORT void append(ValueTokenStream&& other);
657+
658+
GRAPHQLRESPONSE_EXPORT void visit(const std::shared_ptr<ValueVisitor>& visitor) &&;
659+
GRAPHQLRESPONSE_EXPORT Value value() &&;
660+
661+
private:
662+
std::list<ValueToken> _tokens;
663+
};
664+
378665
class [[nodiscard("unnecessary construction")]] Writer final
379666
{
380667
private:

0 commit comments

Comments
 (0)