Loading [MathJax]/extensions/tex2jax.js
Free Electron
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 nullptr or the return value of one of the NewXXX()
19 // functions.
20 class GraphBuilderInterface {
21  public:
22  virtual ~GraphBuilderInterface() = 0;
23 
24  // Create and return a new node with a null value.
25  virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
26 
27  // Create and return a new node with the given tag and value.
28  virtual void *NewScalar(const Mark &mark, const std::string &tag,
29  void *pParentNode, const std::string &value) = 0;
30 
31  // Create and return a new sequence node
32  virtual void *NewSequence(const Mark &mark, const std::string &tag,
33  void *pParentNode) = 0;
34 
35  // Add pNode to pSequence. pNode was created with one of the NewXxx()
36  // functions and pSequence with NewSequence().
37  virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
38 
39  // Note that no moew entries will be added to pSequence
40  virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
41 
42  // Create and return a new map node
43  virtual void *NewMap(const Mark &mark, const std::string &tag,
44  void *pParentNode) = 0;
45 
46  // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
47  // were created with one of the NewXxx() methods and pMap with NewMap().
48  virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
49 
50  // Note that no more assignments will be made in pMap
51  virtual void MapComplete(void *pMap) { (void)pMap; }
52 
53  // Return the node that should be used in place of an alias referencing
54  // pNode (pNode by default)
55  virtual void *AnchorReference(const Mark &mark, void *pNode) {
56  (void)mark;
57  return pNode;
58  }
59 };
60 
61 // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
62 // Node, Sequence, and Map types. Sequence and Map must derive from Node
63 // (unless Node is defined as void). Impl must also implement function with
64 // all of the same names as the virtual functions in GraphBuilderInterface
65 // -- including the ones with default implementations -- but with the
66 // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
67 // appropriate.
68 template <class Impl>
69 class GraphBuilder : public GraphBuilderInterface {
70  public:
71  typedef typename Impl::Node Node;
72  typedef typename Impl::Sequence Sequence;
73  typedef typename Impl::Map Map;
74 
75  GraphBuilder(Impl &impl) : m_impl(impl) {
76  Map *pMap = nullptr;
77  Sequence *pSeq = nullptr;
78  Node *pNode = nullptr;
79 
80  // Type consistency checks
81  pNode = pMap;
82  pNode = pSeq;
83  }
84 
85  GraphBuilderInterface &AsBuilderInterface() { return *this; }
86 
87  virtual void *NewNull(const Mark &mark, void *pParentNode) {
88  return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
89  }
90 
91  virtual void *NewScalar(const Mark &mark, const std::string &tag,
92  void *pParentNode, const std::string &value) {
93  return CheckType<Node>(
94  m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
95  }
96 
97  virtual void *NewSequence(const Mark &mark, const std::string &tag,
98  void *pParentNode) {
99  return CheckType<Sequence>(
100  m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
101  }
102  virtual void AppendToSequence(void *pSequence, void *pNode) {
103  m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
104  }
105  virtual void SequenceComplete(void *pSequence) {
106  m_impl.SequenceComplete(AsSequence(pSequence));
107  }
108 
109  virtual void *NewMap(const Mark &mark, const std::string &tag,
110  void *pParentNode) {
111  return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
112  }
113  virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
114  m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
115  }
116  virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
117 
118  virtual void *AnchorReference(const Mark &mark, void *pNode) {
119  return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
120  }
121 
122  private:
123  Impl &m_impl;
124 
125  // Static check for pointer to T
126  template <class T, class U>
127  static T *CheckType(U *p) {
128  return p;
129  }
130 
131  static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
132  static Sequence *AsSequence(void *pSeq) {
133  return static_cast<Sequence *>(pSeq);
134  }
135  static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
136 };
137 
138 void *BuildGraphOfNextDocument(Parser &parser,
139  GraphBuilderInterface &graphBuilder);
140 
141 template <class Impl>
142 typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
143  GraphBuilder<Impl> graphBuilder(impl);
144  return static_cast<typename Impl::Node *>(
145  BuildGraphOfNextDocument(parser, graphBuilder));
146 }
147 }
148 
149 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
Definition: anchor.h:12