00001 #ifndef VVELIB_ALGORITHMS_INSERT_H 00002 #define VVELIB_ALGORITHMS_INSERT_H 00003 00009 #include <config.h> 00010 #include <utility> 00011 #include <util/static_assert.h> 00012 #include <graph/vvgraph.h> 00013 00017 namespace algorithms 00018 { 00019 00049 template <class vvgraph, bool do_checks = true> 00050 class Insert 00051 #ifdef JUST_FOR_DOXYGEN 00052 { }; 00053 #else 00054 ; 00055 #endif 00056 00057 template <class vvgraph> 00058 class Insert<vvgraph, true> 00059 { 00060 public: 00061 typedef typename vvgraph::vertex_t vertex; 00062 00063 vertex operator()(const vertex& a, const vertex& b, vvgraph& S, const vertex& x = vertex(0)) const 00064 { 00065 if (a.isNull() || b.isNull()) 00066 { 00067 return vertex(0); 00068 } 00069 00070 unsigned int check = 0; 00071 if (S.edge(a,b)) check++; 00072 if (S.edge(b,a)) check++; 00073 00074 switch (check) 00075 { 00076 case 0: 00077 std::cerr << "Warning: Attempt to insert a vertex between vertices that have no relation." << std::endl; 00078 return vertex(0); 00079 break; 00080 case 1: 00081 std::cerr << "Warning: Attempt to insert a vertex between vertices that have an assymetric relation." << std::endl; 00082 return vertex(0); 00083 break; 00084 default: 00085 break; 00086 } 00087 00088 const vertex& r = *S.insert(x?x:vertex()); 00089 00090 S.insert(r); 00091 00092 S.replace(a, b, r); 00093 S.replace(b, a, r); 00094 00095 S.insertEdge(r, a); 00096 S.insertEdge(r, b); 00097 00098 return r; 00099 } 00100 }; 00101 00102 template <class vvgraph> 00103 class Insert<vvgraph, false> 00104 { 00105 public: 00106 typedef typename vvgraph::vertex_t vertex; 00107 00108 const vertex& operator()(const vertex& a, const vertex& b, vvgraph& S, const vertex& x = vertex(0)) const 00109 { 00110 const vertex& r = *S.insert(x?x:vertex()); 00111 00112 S.replace(a, b, r); 00113 S.replace(b, a, r); 00114 00115 S.insertEdge(r, a); 00116 S.insertEdge(r, b); 00117 00118 return r; 00119 } 00120 }; 00121 00122 template <class VertexContent, class EdgeContent, bool compact> 00123 const graph::Vertex<VertexContent>& insert( const graph::Vertex<VertexContent>& a, 00124 const graph::Vertex<VertexContent>& b, 00125 graph::VVGraph<VertexContent,EdgeContent,compact>& S, 00126 const graph::Vertex<VertexContent>& x = graph::Vertex<VertexContent>(0) ) 00127 { 00128 typedef Insert<graph::VVGraph<VertexContent,EdgeContent,compact>,false> Insert; 00129 static const Insert fct = Insert(); 00130 return fct(a,b,S,x); 00131 } 00132 00137 template <class Graph> 00138 typename Graph::edge_t insertAfter(const typename Graph::vertex_t& v, 00139 const typename Graph::vertex_t& ref, 00140 const typename Graph::vertex_t& nv, 00141 Graph& S) 00142 { 00143 if(ref) 00144 return S.spliceAfter(v, ref, nv); 00145 return S.insertEdge(v, nv); 00146 } 00147 00152 template <class Graph> 00153 typename Graph::edge_t insertBefore(const typename Graph::vertex_t& v, 00154 const typename Graph::vertex_t& ref, 00155 const typename Graph::vertex_t& nv, 00156 Graph& S) 00157 { 00158 if(ref) 00159 return S.spliceBefore(v, ref, nv); 00160 return S.insertEdge(v, nv); 00161 } 00162 00163 } 00164 00165 #endif // VVELIB_ALGORITHMS_INSERT_H 00166