OSDN Git Service

First version
[st-ro/stro.git] / 3rdparty / yaml-cpp / include / yaml-cpp / contrib / 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.
20 class GraphBuilderInterface {
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>
67 class GraphBuilder : public GraphBuilderInterface {
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