mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
134 lines
5.1 KiB
C++
134 lines
5.1 KiB
C++
#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:
|
|
// 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
|