BRE12
graphbuilder.h
1 #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
2 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
3 
4 #if defined(_MSC_VER) || \
5  (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
6  (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
7 #pragma once
8 #endif
9 
10 #include "yaml-cpp/mark.h"
11 #include <string>
12 
13 namespace YAML {
14 class Parser;
15 
16 // GraphBuilderInterface
17 // . Abstraction of node creation
18 // . pParentNode is always NULL or the return value of one of the NewXXX()
19 // functions.
21  public:
22  // Create and return a new node with a null value.
23  virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
24 
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;
28 
29  // Create and return a new sequence node
30  virtual void *NewSequence(const Mark &mark, const std::string &tag,
31  void *pParentNode) = 0;
32 
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;
36 
37  // Note that no moew entries will be added to pSequence
38  virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
39 
40  // Create and return a new map node
41  virtual void *NewMap(const Mark &mark, const std::string &tag,
42  void *pParentNode) = 0;
43 
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;
47 
48  // Note that no more assignments will be made in pMap
49  virtual void MapComplete(void *pMap) { (void)pMap; }
50 
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) {
54  (void)mark;
55  return pNode;
56  }
57 };
58 
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
65 // appropriate.
66 template <class Impl>
68  public:
69  typedef typename Impl::Node Node;
70  typedef typename Impl::Sequence Sequence;
71  typedef typename Impl::Map Map;
72 
73  GraphBuilder(Impl &impl) : m_impl(impl) {
74  Map *pMap = NULL;
75  Sequence *pSeq = NULL;
76  Node *pNode = NULL;
77 
78  // Type consistency checks
79  pNode = pMap;
80  pNode = pSeq;
81  }
82 
83  GraphBuilderInterface &AsBuilderInterface() { return *this; }
84 
85  virtual void *NewNull(const Mark &mark, void *pParentNode) {
86  return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
87  }
88 
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));
93  }
94 
95  virtual void *NewSequence(const Mark &mark, const std::string &tag,
96  void *pParentNode) {
97  return CheckType<Sequence>(
98  m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
99  }
100  virtual void AppendToSequence(void *pSequence, void *pNode) {
101  m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
102  }
103  virtual void SequenceComplete(void *pSequence) {
104  m_impl.SequenceComplete(AsSequence(pSequence));
105  }
106 
107  virtual void *NewMap(const Mark &mark, const std::string &tag,
108  void *pParentNode) {
109  return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
110  }
111  virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
112  m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
113  }
114  virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
115 
116  virtual void *AnchorReference(const Mark &mark, void *pNode) {
117  return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
118  }
119 
120  private:
121  Impl &m_impl;
122 
123  // Static check for pointer to T
124  template <class T, class U>
125  static T *CheckType(U *p) {
126  return p;
127  }
128 
129  static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
130  static Sequence *AsSequence(void *pSeq) {
131  return static_cast<Sequence *>(pSeq);
132  }
133  static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
134 };
135 
136 void *BuildGraphOfNextDocument(Parser &parser,
137  GraphBuilderInterface &graphBuilder);
138 
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));
144 }
145 }
146 
147 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: mark.h:13
A parser turns a stream of bytes into one stream of "events" per YAML document in the input stream...
Definition: parser.h:27
Definition: DrawableObjectLoader.h:10
Definition: graphbuilder.h:67
Definition: graphbuilder.h:20