|
Video Processing Framework
|
00001 #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 00002 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 00003 00004 #if !defined(__GNUC__) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4) // GCC supports "pragma once" correctly since 3.4 00005 #pragma once 00006 #endif 00007 00008 #include "yaml-cpp/mark.h" 00009 #include <string> 00010 00011 namespace YAML 00012 { 00013 class Parser; 00014 00015 // GraphBuilderInterface 00016 // . Abstraction of node creation 00017 // . pParentNode is always NULL or the return value of one of the NewXXX() 00018 // functions. 00019 class GraphBuilderInterface 00020 { 00021 public: 00022 // Create and return a new node with a null value. 00023 virtual void *NewNull(const Mark& mark, void *pParentNode) = 0; 00024 00025 // Create and return a new node with the given tag and value. 00026 virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) = 0; 00027 00028 // Create and return a new sequence node 00029 virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0; 00030 // Add pNode to pSequence. pNode was created with one of the NewXxx() 00031 // functions and pSequence with NewSequence(). 00032 virtual void AppendToSequence(void *pSequence, void *pNode) = 0; 00033 // Note that no moew entries will be added to pSequence 00034 virtual void SequenceComplete(void *pSequence) {(void)pSequence;} 00035 00036 // Create and return a new map node 00037 virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0; 00038 // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode 00039 // were created with one of the NewXxx() methods and pMap with NewMap(). 00040 virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; 00041 // Note that no more assignments will be made in pMap 00042 virtual void MapComplete(void *pMap) {(void)pMap;} 00043 00044 // Return the node that should be used in place of an alias referencing 00045 // pNode (pNode by default) 00046 virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;} 00047 }; 00048 00049 // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines 00050 // Node, Sequence, and Map types. Sequence and Map must derive from Node 00051 // (unless Node is defined as void). Impl must also implement function with 00052 // all of the same names as the virtual functions in GraphBuilderInterface 00053 // -- including the ones with default implementations -- but with the 00054 // prototypes changed to accept an explicit Node*, Sequence*, or Map* where 00055 // appropriate. 00056 template <class Impl> 00057 class GraphBuilder : public GraphBuilderInterface 00058 { 00059 public: 00060 typedef typename Impl::Node Node; 00061 typedef typename Impl::Sequence Sequence; 00062 typedef typename Impl::Map Map; 00063 00064 GraphBuilder(Impl& impl) : m_impl(impl) 00065 { 00066 Map* pMap = NULL; 00067 Sequence* pSeq = NULL; 00068 Node* pNode = NULL; 00069 00070 // Type consistency checks 00071 pNode = pMap; 00072 pNode = pSeq; 00073 } 00074 00075 GraphBuilderInterface& AsBuilderInterface() {return *this;} 00076 00077 virtual void *NewNull(const Mark& mark, void* pParentNode) { 00078 return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode))); 00079 } 00080 00081 virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) { 00082 return CheckType<Node>(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); 00083 } 00084 00085 virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) { 00086 return CheckType<Sequence>(m_impl.NewSequence(mark, tag, AsNode(pParentNode))); 00087 } 00088 virtual void AppendToSequence(void *pSequence, void *pNode) { 00089 m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); 00090 } 00091 virtual void SequenceComplete(void *pSequence) { 00092 m_impl.SequenceComplete(AsSequence(pSequence)); 00093 } 00094 00095 virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) { 00096 return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode))); 00097 } 00098 virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { 00099 m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); 00100 } 00101 virtual void MapComplete(void *pMap) { 00102 m_impl.MapComplete(AsMap(pMap)); 00103 } 00104 00105 virtual void *AnchorReference(const Mark& mark, void *pNode) { 00106 return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode))); 00107 } 00108 00109 private: 00110 Impl& m_impl; 00111 00112 // Static check for pointer to T 00113 template <class T, class U> 00114 static T* CheckType(U* p) {return p;} 00115 00116 static Node *AsNode(void *pNode) {return static_cast<Node*>(pNode);} 00117 static Sequence *AsSequence(void *pSeq) {return static_cast<Sequence*>(pSeq);} 00118 static Map *AsMap(void *pMap) {return static_cast<Map*>(pMap);} 00119 }; 00120 00121 void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder); 00122 00123 template <class Impl> 00124 typename Impl::Node *BuildGraphOfNextDocument(Parser& parser, Impl& impl) 00125 { 00126 GraphBuilder<Impl> graphBuilder(impl); 00127 return static_cast<typename Impl::Node *>(BuildGraphOfNextDocument( 00128 parser, graphBuilder 00129 )); 00130 } 00131 } 00132 00133 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66