123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #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 <string>
- 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:
- virtual ~GraphBuilderInterface() = 0;
- // 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 Impl>
- 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<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
- }
- virtual void *NewScalar(const Mark &mark, const std::string &tag,
- void *pParentNode, const std::string &value) {
- return CheckType<Node>(
- m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
- }
- virtual void *NewSequence(const Mark &mark, const std::string &tag,
- void *pParentNode) {
- return CheckType<Sequence>(
- 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<Map>(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<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
- }
- private:
- Impl &m_impl;
- // Static check for pointer to T
- template <class T, class U>
- static T *CheckType(U *p) {
- return p;
- }
- static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
- static Sequence *AsSequence(void *pSeq) {
- return static_cast<Sequence *>(pSeq);
- }
- static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
- };
- void *BuildGraphOfNextDocument(Parser &parser,
- GraphBuilderInterface &graphBuilder);
- template <class Impl>
- typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
- GraphBuilder<Impl> graphBuilder(impl);
- return static_cast<typename Impl::Node *>(
- BuildGraphOfNextDocument(parser, graphBuilder));
- }
- }
- #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|