graphbuilder.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  2. #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
  3. #if defined(_MSC_VER) || \
  4. (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
  5. (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
  6. #pragma once
  7. #endif
  8. #include "yaml-cpp/mark.h"
  9. #include <string>
  10. namespace YAML {
  11. class Parser;
  12. // GraphBuilderInterface
  13. // . Abstraction of node creation
  14. // . pParentNode is always NULL or the return value of one of the NewXXX()
  15. // functions.
  16. class GraphBuilderInterface {
  17. public:
  18. virtual ~GraphBuilderInterface() = 0;
  19. // Create and return a new node with a null value.
  20. virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
  21. // Create and return a new node with the given tag and value.
  22. virtual void *NewScalar(const Mark &mark, const std::string &tag,
  23. void *pParentNode, const std::string &value) = 0;
  24. // Create and return a new sequence node
  25. virtual void *NewSequence(const Mark &mark, const std::string &tag,
  26. void *pParentNode) = 0;
  27. // Add pNode to pSequence. pNode was created with one of the NewXxx()
  28. // functions and pSequence with NewSequence().
  29. virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
  30. // Note that no moew entries will be added to pSequence
  31. virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
  32. // Create and return a new map node
  33. virtual void *NewMap(const Mark &mark, const std::string &tag,
  34. void *pParentNode) = 0;
  35. // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
  36. // were created with one of the NewXxx() methods and pMap with NewMap().
  37. virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
  38. // Note that no more assignments will be made in pMap
  39. virtual void MapComplete(void *pMap) { (void)pMap; }
  40. // Return the node that should be used in place of an alias referencing
  41. // pNode (pNode by default)
  42. virtual void *AnchorReference(const Mark &mark, void *pNode) {
  43. (void)mark;
  44. return pNode;
  45. }
  46. };
  47. // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
  48. // Node, Sequence, and Map types. Sequence and Map must derive from Node
  49. // (unless Node is defined as void). Impl must also implement function with
  50. // all of the same names as the virtual functions in GraphBuilderInterface
  51. // -- including the ones with default implementations -- but with the
  52. // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
  53. // appropriate.
  54. template <class Impl>
  55. class GraphBuilder : public GraphBuilderInterface {
  56. public:
  57. typedef typename Impl::Node Node;
  58. typedef typename Impl::Sequence Sequence;
  59. typedef typename Impl::Map Map;
  60. GraphBuilder(Impl &impl) : m_impl(impl) {
  61. Map *pMap = NULL;
  62. Sequence *pSeq = NULL;
  63. Node *pNode = NULL;
  64. // Type consistency checks
  65. pNode = pMap;
  66. pNode = pSeq;
  67. }
  68. GraphBuilderInterface &AsBuilderInterface() { return *this; }
  69. virtual void *NewNull(const Mark &mark, void *pParentNode) {
  70. return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
  71. }
  72. virtual void *NewScalar(const Mark &mark, const std::string &tag,
  73. void *pParentNode, const std::string &value) {
  74. return CheckType<Node>(
  75. m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
  76. }
  77. virtual void *NewSequence(const Mark &mark, const std::string &tag,
  78. void *pParentNode) {
  79. return CheckType<Sequence>(
  80. m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
  81. }
  82. virtual void AppendToSequence(void *pSequence, void *pNode) {
  83. m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
  84. }
  85. virtual void SequenceComplete(void *pSequence) {
  86. m_impl.SequenceComplete(AsSequence(pSequence));
  87. }
  88. virtual void *NewMap(const Mark &mark, const std::string &tag,
  89. void *pParentNode) {
  90. return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
  91. }
  92. virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
  93. m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
  94. }
  95. virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
  96. virtual void *AnchorReference(const Mark &mark, void *pNode) {
  97. return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
  98. }
  99. private:
  100. Impl &m_impl;
  101. // Static check for pointer to T
  102. template <class T, class U>
  103. static T *CheckType(U *p) {
  104. return p;
  105. }
  106. static Node *AsNode(void *pNode) { return static_cast<Node *>(pNode); }
  107. static Sequence *AsSequence(void *pSeq) {
  108. return static_cast<Sequence *>(pSeq);
  109. }
  110. static Map *AsMap(void *pMap) { return static_cast<Map *>(pMap); }
  111. };
  112. void *BuildGraphOfNextDocument(Parser &parser,
  113. GraphBuilderInterface &graphBuilder);
  114. template <class Impl>
  115. typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
  116. GraphBuilder<Impl> graphBuilder(impl);
  117. return static_cast<typename Impl::Node *>(
  118. BuildGraphOfNextDocument(parser, graphBuilder));
  119. }
  120. }
  121. #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66