1 #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
4 #if defined(_MSC_VER) || \
5 (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6 (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
10 #include "yaml-cpp/mark.h"
16 // GraphBuilderInterface
17 // . Abstraction of node creation
18 // . pParentNode is always NULL or the return value of one of the NewXXX()
20 class GraphBuilderInterface {
22 // Create and return a new node with a null value.
23 virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
25 // Create and return a new node with the given tag and value.
26 virtual void *NewScalar(const Mark &mark, const std::string &tag,
27 void *pParentNode, const std::string &value) = 0;
29 // Create and return a new sequence node
30 virtual void *NewSequence(const Mark &mark, const std::string &tag,
31 void *pParentNode) = 0;
33 // Add pNode to pSequence. pNode was created with one of the NewXxx()
34 // functions and pSequence with NewSequence().
35 virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
37 // Note that no moew entries will be added to pSequence
38 virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
40 // Create and return a new map node
41 virtual void *NewMap(const Mark &mark, const std::string &tag,
42 void *pParentNode) = 0;
44 // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
45 // were created with one of the NewXxx() methods and pMap with NewMap().
46 virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
48 // Note that no more assignments will be made in pMap
49 virtual void MapComplete(void *pMap) { (void)pMap; }
51 // Return the node that should be used in place of an alias referencing
52 // pNode (pNode by default)
53 virtual void *AnchorReference(const Mark &mark, void *pNode) {
59 // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
60 // Node, Sequence, and Map types. Sequence and Map must derive from Node
61 // (unless Node is defined as void). Impl must also implement function with
62 // all of the same names as the virtual functions in GraphBuilderInterface
63 // -- including the ones with default implementations -- but with the
64 // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
67 class GraphBuilder : public GraphBuilderInterface {
69 typedef typename Impl::Node Node;
70 typedef typename Impl::Sequence Sequence;
71 typedef typename Impl::Map Map;
73 GraphBuilder(Impl &impl) : m_impl(impl) {
75 Sequence *pSeq = NULL;
78 // Type consistency checks
83 GraphBuilderInterface &AsBuilderInterface() { return *this; }
85 virtual void *NewNull(const Mark &mark, void *pParentNode) {
86 return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
89 virtual void *NewScalar(const Mark &mark, const std::string &tag,
90 void *pParentNode, const std::string &value) {
91 return CheckType<Node>(
92 m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
95 virtual void *NewSequence(const Mark &mark, const std::string &tag,
97 return CheckType<Sequence>(
98 m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
100 virtual void AppendToSequence(void *pSequence, void *pNode) {
101 m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
103 virtual void SequenceComplete(void *pSequence) {
104 m_impl.SequenceComplete(AsSequence(pSequence));
107 virtual void *NewMap(const Mark &mark, const std::string &tag,
109 return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
111 virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
112 m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
114 virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
116 virtual void *AnchorReference(const Mark &mark, void *pNode) {
117 return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
123 // Static check for pointer to T
124 template <class T, class U>
125 static T *CheckType(U *p) {
129 static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
130 static Sequence *AsSequence(void *pSeq) {
131 return static_cast<Sequence *>(pSeq);
133 static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
136 void *BuildGraphOfNextDocument(Parser &parser,
137 GraphBuilderInterface &graphBuilder);
139 template <class Impl>
140 typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
141 GraphBuilder<Impl> graphBuilder(impl);
142 return static_cast<typename Impl::Node *>(
143 BuildGraphOfNextDocument(parser, graphBuilder));
147 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66