#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #pragma once #endif #include "yaml-cpp/mark.h" #include namespace YAML { class Parser; // GraphBuilderInterface // . Abstraction of node creation // . pParentNode is always NULL or the return value of one of the NewXXX() // functions. class GraphBuilderInterface { public: // Create and return a new node with a null value. virtual void *NewNull(const Mark& mark, void *pParentNode) = 0; // Create and return a new node with the given tag and value. virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) = 0; // Create and return a new sequence node virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0; // Add pNode to pSequence. pNode was created with one of the NewXxx() // functions and pSequence with NewSequence(). virtual void AppendToSequence(void *pSequence, void *pNode) = 0; // Note that no moew entries will be added to pSequence virtual void SequenceComplete(void *pSequence) {(void)pSequence;} // Create and return a new map node virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0; // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode // were created with one of the NewXxx() methods and pMap with NewMap(). virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; // Note that no more assignments will be made in pMap virtual void MapComplete(void *pMap) {(void)pMap;} // Return the node that should be used in place of an alias referencing // pNode (pNode by default) virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;} }; // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines // Node, Sequence, and Map types. Sequence and Map must derive from Node // (unless Node is defined as void). Impl must also implement function with // all of the same names as the virtual functions in GraphBuilderInterface // -- including the ones with default implementations -- but with the // prototypes changed to accept an explicit Node*, Sequence*, or Map* where // appropriate. template class GraphBuilder : public GraphBuilderInterface { public: typedef typename Impl::Node Node; typedef typename Impl::Sequence Sequence; typedef typename Impl::Map Map; GraphBuilder(Impl& impl) : m_impl(impl) { Map* pMap = NULL; Sequence* pSeq = NULL; Node* pNode = NULL; // Type consistency checks pNode = pMap; pNode = pSeq; } GraphBuilderInterface& AsBuilderInterface() {return *this;} virtual void *NewNull(const Mark& mark, void* pParentNode) { return CheckType(m_impl.NewNull(mark, AsNode(pParentNode))); } virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) { return CheckType(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); } virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) { return CheckType(m_impl.NewSequence(mark, tag, AsNode(pParentNode))); } virtual void AppendToSequence(void *pSequence, void *pNode) { m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); } virtual void SequenceComplete(void *pSequence) { m_impl.SequenceComplete(AsSequence(pSequence)); } virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) { return CheckType(m_impl.NewMap(mark, tag, AsNode(pParentNode))); } virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); } virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); } virtual void *AnchorReference(const Mark& mark, void *pNode) { return CheckType(m_impl.AnchorReference(mark, AsNode(pNode))); } private: Impl& m_impl; // Static check for pointer to T template static T* CheckType(U* p) {return p;} static Node *AsNode(void *pNode) {return static_cast(pNode);} static Sequence *AsSequence(void *pSeq) {return static_cast(pSeq);} static Map *AsMap(void *pMap) {return static_cast(pMap);} }; void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder); template typename Impl::Node *BuildGraphOfNextDocument(Parser& parser, Impl& impl) { GraphBuilder graphBuilder(impl); return static_cast(BuildGraphOfNextDocument( parser, graphBuilder )); } } #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66