edge.h
Go to the documentation of this file.00001 #ifndef EDGE_H
00002 #define EDGE_H
00003
00010 #include <config.h>
00011 #include <util/unorderedmap.h>
00012
00013 #include <storage/fwd.h>
00014 #include <QtCore/QHash>
00015
00016 namespace graph
00017 {
00018
00022 typedef uintptr_t edge_identity_t;
00023
00032 template <typename EdgeContent>
00033 class Edge
00034 {
00035 public:
00039 typedef edge_identity_t identity_t;
00040
00044 typedef EdgeContent content_t;
00045
00049 typedef EdgeContent* pointer;
00050
00054 Edge();
00055
00065 Edge(identity_t src, identity_t tgt, EdgeContent* content);
00066
00070 Edge(const Edge& copy);
00071
00072 #ifdef USE_CXX0X
00073 Edge(Edge&& ) = default;
00074 #endif
00075
00082 EdgeContent* operator->() const { return _content; }
00083
00090 EdgeContent& operator*() const { return *_content; }
00091
00095 template <typename R>
00096 R& operator->*(R EdgeContent::*ptr)
00097 {
00098 return _content->*ptr;
00099 }
00103 template <typename R>
00104 const R& operator->*(R EdgeContent::*ptr) const
00105 {
00106 return _content->*ptr;
00107 }
00108
00109
00113 Edge& operator=(const Edge& other);
00114
00115 #ifdef USE_CXX0X
00116 Edge& operator=(Edge&& ) = default;
00117 #endif
00118
00124 bool operator==(const Edge& other) const { return _content == other._content; }
00130 bool operator!=(const Edge& other) const { return _content != other._content; }
00136 bool operator>(const Edge& other) const { return _content > other._content; }
00142 bool operator<(const Edge& other) const { return _content < other._content; }
00143
00149 bool operator>=(const Edge& other) const { return _content >= other._content; }
00155 bool operator<=(const Edge& other) const { return _content <= other._content; }
00156
00160 bool isNull() const { return _content == 0; }
00161
00165 operator bool() const { return _content != 0; }
00166
00173 identity_t source() const { return _source; }
00180 identity_t target() const { return _target; }
00181
00185 void clear()
00186 {
00187 _source = 0;
00188 _target = 0;
00189 _content = 0;
00190 }
00191
00192 static Edge null;
00193
00200 bool serialize(storage::VVEStorage&);
00201
00202 protected:
00206 identity_t _source;
00210 identity_t _target;
00214 EdgeContent* _content;
00215 };
00216
00217 template <typename EdgeContent>
00218 Edge<EdgeContent> Edge<EdgeContent>::null;
00219
00220
00221 template <typename EdgeContent>
00222 Edge<EdgeContent>::Edge()
00223 : _source(0)
00224 , _target(0)
00225 , _content(0)
00226 { }
00227
00228 template <typename EdgeContent>
00229 Edge<EdgeContent>::Edge( const Edge& copy )
00230 : _source(copy._source)
00231 , _target(copy._target)
00232 , _content(copy._content)
00233 { }
00234
00235 template <typename EdgeContent>
00236 Edge<EdgeContent>::Edge( identity_t src, identity_t tgt, EdgeContent* content )
00237 : _source(src)
00238 , _target(tgt)
00239 , _content(content)
00240 { }
00241
00242 template <typename EdgeContent>
00243 Edge<EdgeContent>& Edge<EdgeContent>::operator=(const Edge<EdgeContent>& other)
00244 {
00245 _source = other._source;
00246 _target = other._target;
00247 _content = other._content;
00248 return *this;
00249 }
00250
00255 template <typename T>
00256 void copy_symmetric(T& e2, const T& e1)
00257 {
00258 e2 = e1;
00259 }
00260
00270 template <typename EdgeContent>
00271 struct Arc
00272 {
00276 typedef edge_identity_t identity_t;
00277
00278 typedef EdgeContent content_t;
00279
00280 typedef Edge<EdgeContent> edge_t;
00281
00285 Arc();
00286
00290 Arc(const Arc& copy);
00291
00292 #ifdef USE_CXX0X
00293 Arc(Arc&& ) = default;
00294 #endif
00295
00299 Arc(identity_t src, identity_t tgt, EdgeContent *c1, EdgeContent *c2);
00300
00304 operator edge_t() const
00305 {
00306 return edge_t(_source, _target, main);
00307 }
00308
00314 Arc inv() const;
00315
00319 Arc operator-() const { return inv(); }
00320
00324 ~Arc() { sync(); }
00325
00329 bool isNull() const { return main == 0; }
00330
00334 operator bool() const { return main != 0; }
00335
00339 EdgeContent& operator*() const { return *main; }
00343 EdgeContent* operator->() const { return main; }
00344
00351 identity_t source() const { return _source; }
00358 identity_t target() const { return _target; }
00359
00363 void sync() const { if(main) copy_symmetric(*other, *main); }
00364
00365 protected:
00366 identity_t _source, _target;
00367 mutable EdgeContent *main, *other;
00368 };
00369
00370 template <typename EdgeContent>
00371 Arc<EdgeContent>::Arc()
00372 : _source(0)
00373 , _target(0)
00374 , main(0)
00375 , other(0)
00376 {}
00377
00378 template <typename EdgeContent>
00379 Arc<EdgeContent>::Arc(identity_t src, identity_t tgt, EdgeContent *e1, EdgeContent *e2)
00380 : _source(src)
00381 , _target(tgt)
00382 , main(e1)
00383 , other(e2)
00384 {}
00385
00386 template <typename EdgeContent>
00387 Arc<EdgeContent>::Arc(const Arc& copy)
00388 : _source(copy._source)
00389 , _target(copy._target)
00390 , main(copy.main)
00391 , other(copy.other)
00392 {}
00393
00394
00395 template <typename EdgeContent>
00396 Arc<EdgeContent> Arc<EdgeContent>::inv() const
00397 {
00398 return Arc(_target, _source, other, main);
00399 }
00400
00401 }
00402
00403 #ifdef USE_HASH
00404 namespace std
00405 {
00406 #ifdef CXX_NEEDS_TR1
00407 namespace tr1
00408 {
00409 #endif
00410 template <typename EdgeContent>
00411 struct hash<graph::Edge<EdgeContent> >
00412 {
00413 size_t operator()(const graph::Edge<EdgeContent>& e) const
00414 {
00415 return e.source() + e.target();
00416 }
00417 };
00418 #ifdef CXX_NEEDS_TR1
00419 }
00420 #endif
00421 }
00422 #endif
00423
00424 template <typename EdgeContent>
00425 uint qHash(const graph::Edge<EdgeContent>& e)
00426 {
00427 return qHash(uint(e.source() >> 4)) ^ qHash(uint(e.target() >> 4));
00428 }
00429
00430 #endif // EDGE_H
00431