vertex.h
Go to the documentation of this file.00001 #ifndef __GRAPH_VERTEX_H
00002 #define __GRAPH_VERTEX_H
00003
00012 #include <QtCore/QHash>
00013 #include <config.h>
00014 #include <map>
00015 #include <utility>
00016 #include <util/unorderedmap.h>
00017 #include <util/mangling.h>
00018 #include <iostream>
00019 #include <typeinfo>
00020 #ifndef _MSC_VER
00021 # include <stdint.h>
00022 #endif
00023
00024 #include <util/assert.h>
00025
00026 #include <storage/fwd.h>
00027
00028 #ifdef USE_ALLOCATOR
00029 # include <memory>
00030 #endif // defined USE_ALLOCATOR
00031
00032 #ifndef NO_NUMBER_VERTICES
00033 # ifdef VERTEX_ORDER_BY_NUM
00034 # undef VERTEX_ORDER_BY_NUM
00035 # endif
00036 #endif
00037
00038 #define VVVERTEX_NO_CACHE
00039 #ifndef VVGRAPH_NO_CACHE
00040 # undef VVVERTEX_NO_CACHE
00041 #elif !defined(VVBIGRAPH_NO_CACHE)
00042 # undef VVVERTEX_NO_CACHE
00043 #endif
00044
00045 #ifdef USE_ALLOCATOR
00046 # define TEMPLATE_VERTEX typename VertexContent, typename Alloc
00047 # define VERTEX_ARGS VertexContent,Alloc
00048 #else // USE_ALLOCATOR
00049 # define TEMPLATE_VERTEX typename VertexContent
00050 # define VERTEX_ARGS VertexContent
00051 #endif // USE_ALLOCATOR
00052
00053 namespace graph
00054 {
00058 typedef uintptr_t vertex_identity_t;
00059
00060 #ifndef NO_NUMBER_VERTICES
00061
00067 extern size_t vertex_counter;
00068 #endif
00069
00070 template <TEMPLATE_VERTEX> class WeakVertex;
00071
00075 template <typename Content>
00076 struct CountedContent : public Content
00077 {
00078 CountedContent()
00079 : Content()
00080 , count(1)
00081 #ifndef NO_NUMBER_VERTICES
00082 , num(++vertex_counter)
00083 #endif
00084 {}
00085
00089 unsigned int count;
00090 #ifndef NO_NUMBER_VERTICES
00091 size_t num;
00092 #endif
00093 };
00094
00111 template <typename VertexContent
00112 #ifdef USE_ALLOCATOR
00113 , typename Alloc = DEFAULT_ALLOC(VertexContent)
00114 #endif
00115 >
00116 class Vertex
00117 {
00118 friend class WeakVertex<VERTEX_ARGS>;
00119
00120 public:
00126 typedef CountedContent<VertexContent> counted_content_t;
00127
00128 protected:
00129
00130 #ifdef USE_ALLOCATOR
00131
00132 typedef typename Alloc::template rebind<counted_content_t>::other RealAlloc;
00133
00134 static RealAlloc alloc;
00135 #endif
00136
00137 public:
00138
00139 #ifdef USE_ALLOCATOR
00140
00145 typedef typename RealAlloc::pointer real_pointer;
00146 #else
00147
00152 typedef counted_content_t* real_pointer;
00153 #endif // defined USE_ALLOCATOR
00154
00158 typedef vertex_identity_t identity_t;
00159
00163 typedef VertexContent content_t;
00164
00165 typedef WeakVertex<VERTEX_ARGS> weak_ref_t;
00166
00170 typedef content_t* pointer;
00171 typedef content_t& reference;
00172
00184 Vertex();
00185
00189 explicit Vertex( int i );
00190
00209 explicit Vertex( identity_t id );
00210
00217 Vertex( const Vertex& copy );
00218
00224 Vertex(real_pointer content);
00225
00226 #ifdef USE_CXX0X
00227
00233 Vertex( Vertex&& copy );
00234 #endif
00235
00239 explicit Vertex( const weak_ref_t& w );
00240
00244 ~Vertex();
00245
00251 pointer operator->() const { return _content; }
00257 reference operator*() const { return *_content; }
00258
00262 real_pointer content() const { return _content; }
00263
00267 real_pointer acquire() { real_pointer p = _content; _content = 0; return p; }
00268
00272 template <typename R>
00273 R& operator->*(R VertexContent::*ptr)
00274 {
00275 return _content->*ptr;
00276 }
00280 template <typename R>
00281 const R& operator->*(R VertexContent::*ptr) const
00282 {
00283 return _content->*ptr;
00284 }
00285
00295 Vertex& operator=(const Vertex& other);
00296
00297 #ifdef USE_CXX0X
00298 Vertex& operator=(Vertex&& other);
00299 #endif
00300
00301 Vertex& operator=(const identity_t& id);
00302
00303 Vertex& operator=(const weak_ref_t& other);
00304
00305
00306
00312 bool operator==(const Vertex& other) const { return id() == other.id(); }
00313
00317 template <typename T1>
00318 bool operator==(const Vertex<T1>& ) const { return false; }
00319
00325 bool operator!=(const Vertex& other) const { return id() != other.id(); }
00326
00330 template <typename T1>
00331 bool operator!=(const Vertex<T1>& other) const { return true; }
00332
00338 bool operator>(const Vertex& other) const
00339 {
00340 #ifdef VERTEX_ORDER_BY_NUM
00341 return num() > other.num();
00342 #else
00343 return id() > other.id();
00344 #endif
00345 }
00351 bool operator<(const Vertex& other) const
00352 {
00353 #ifdef VERTEX_ORDER_BY_NUM
00354 return num() < other.num();
00355 #else
00356 return id() < other.id();
00357 #endif
00358 }
00359
00365 bool operator>=(const Vertex& other) const
00366 {
00367 #ifdef VERTEX_ORDER_BY_NUM
00368 return num() >= other.num();
00369 #else
00370 return id() >= other.id();
00371 #endif
00372 }
00378 bool operator<=(const Vertex& other) const
00379 {
00380 #ifdef VERTEX_ORDER_BY_NUM
00381 return num() <= other.num();
00382 #else
00383 return id() <= other.id();
00384 #endif
00385 }
00386
00390 bool isNull() const { return _content == 0; }
00391
00395 identity_t id() const { return (identity_t)_content; }
00396
00397
00398 #ifndef NO_NUMBER_VERTICES
00399
00405 size_t num() const { return _content->num; }
00406 #endif
00407
00411 operator bool() const { return _content; }
00412
00416 bool isWeakRef() const { return false; }
00417
00421 weak_ref_t weakRef() const;
00422
00439 static Vertex null;
00440
00447 bool serialize(storage::VVEStorage&);
00448
00449 protected:
00457 mutable real_pointer _content;
00458
00462 void release();
00463
00464 #ifndef VVVERTEX_NO_CACHE
00465 public:
00472 mutable identity_t cache_source;
00473
00479 mutable void *cache;
00480 #endif
00481 };
00482
00483 template <TEMPLATE_VERTEX>
00484 Vertex<VERTEX_ARGS> Vertex<VERTEX_ARGS>::null(0);
00485
00486 #ifdef USE_ALLOCATOR
00487 template <TEMPLATE_VERTEX>
00488 typename Vertex<VERTEX_ARGS>::RealAlloc Vertex<VERTEX_ARGS>::alloc;
00489 #endif // defined USE_ALLOCATOR
00490
00498 template <typename VertexContent
00499 #ifdef USE_ALLOCATOR
00500 , typename Alloc = DEFAULT_ALLOC(VertexContent)
00501 #endif
00502 >
00503 class WeakVertex : public Vertex<VERTEX_ARGS>
00504 {
00505 typedef typename Vertex<VERTEX_ARGS>::counted_content_t counted_content_t;
00506 typedef typename Vertex<VERTEX_ARGS>::real_pointer real_pointer;
00507 public:
00511 typedef vertex_identity_t identity_t;
00512
00516 typedef VertexContent content_t;
00517
00521 typedef Vertex<VERTEX_ARGS> strong_ref;
00522
00526 typedef VertexContent* pointer;
00527
00534 WeakVertex()
00535 : Vertex<VERTEX_ARGS>(0)
00536 {}
00537
00541 WeakVertex(const strong_ref& v)
00542 : Vertex<VERTEX_ARGS>(0)
00543 {
00544 this->_content = v._content;
00545 }
00546
00550 WeakVertex(const WeakVertex& copy)
00551 : Vertex<VERTEX_ARGS>(0)
00552 {
00553 this->_content = copy._content;
00554 }
00555
00556 #ifdef USE_CXX0X
00557
00560 WeakVertex(WeakVertex&& ) = default;
00561 #endif
00562
00566 explicit WeakVertex(const identity_t& id)
00567 : Vertex<VERTEX_ARGS>(0)
00568 {
00569 this->_content = reinterpret_cast<real_pointer>(id);
00570 if(this->_content and this->_content->count == 0)
00571 this->_content = 0;
00572 }
00573
00577 WeakVertex& operator=(const WeakVertex& other)
00578 {
00579 this->_content = other._content;
00580 return *this;
00581 }
00582
00583 #ifdef USE_CXX0X
00584 WeakVertex& operator=(WeakVertex&& other)
00585 {
00586 this->_content = std::move(other._content);
00587 return *this;
00588 }
00589 #endif
00590
00591 WeakVertex& operator=(const identity_t& id)
00592 {
00593 this->_content = reinterpret_cast<real_pointer>(id);
00594 return *this;
00595 }
00596
00597 WeakVertex& operator=(const strong_ref& other)
00598 {
00599 this->_content = other._content;
00600 return *this;
00601 }
00602
00603 ~WeakVertex()
00604 {
00605 this->_content = 0;
00606 }
00607
00608 bool isNull() const
00609 {
00610 return this->_content == 0 or this->_content->count == 0;
00611 }
00612
00613 protected:
00614 };
00615
00616 template <TEMPLATE_VERTEX>
00617 Vertex<VERTEX_ARGS>::~Vertex()
00618 {
00619 this->release();
00620 }
00621
00622 template <TEMPLATE_VERTEX>
00623 Vertex<VERTEX_ARGS>::Vertex()
00624 : _content(0)
00625 #ifndef VVVERTEX_NO_CACHE
00626 , cache_source(0)
00627 , cache(0)
00628 #endif
00629 {
00630 #ifdef USE_ALLOCATOR
00631 _content = alloc.allocate(1);
00632 ::new(_content) counted_content_t();
00633 #elif defined(DEBUG_ALLOC) // defined USE_ALLOCATOR
00634 try
00635 {
00636 _content = new counted_content_t();
00637 }
00638 catch(std::bad_alloc& )
00639 {
00640 _content = 0;
00641 }
00642 #else
00643 _content = new counted_content_t();
00644 #endif // defined USE_ALLOCATOR
00645 }
00646
00647 template <TEMPLATE_VERTEX>
00648 Vertex<VERTEX_ARGS>::Vertex( int id )
00649 : _content(0)
00650 #ifndef VVVERTEX_NO_CACHE
00651 , cache_source(0)
00652 , cache(0)
00653 #endif
00654 {
00655 vvassert(id == 0);
00656 }
00657
00658 template <TEMPLATE_VERTEX>
00659 Vertex<VERTEX_ARGS>::Vertex( identity_t id )
00660 : _content(reinterpret_cast<real_pointer>(id))
00661 #ifndef VVVERTEX_NO_CACHE
00662 , cache_source(0)
00663 , cache(0)
00664 #endif
00665 {
00666 if(_content)
00667 {
00668 if(_content->count == 0)
00669 _content = 0;
00670 else
00671 ++(_content->count);
00672 }
00673 }
00674
00675 template <TEMPLATE_VERTEX>
00676 Vertex<VERTEX_ARGS>::Vertex( real_pointer content )
00677 : _content(content)
00678 #ifndef VVVERTEX_NO_CACHE
00679 , cache_source(0)
00680 , cache(0)
00681 #endif
00682 {
00683 if(_content)
00684 ++(_content->count);
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 template <TEMPLATE_VERTEX>
00707 Vertex<VERTEX_ARGS>::Vertex( const typename Vertex<VERTEX_ARGS>::weak_ref_t& copy )
00708 : _content(copy._content)
00709 #ifndef VVVERTEX_NO_CACHE
00710 , cache_source(0)
00711 , cache(0)
00712 #endif
00713 {
00714 if(_content)
00715 {
00716 if(_content->count == 0)
00717 _content = 0;
00718 else
00719 ++(_content->count);
00720 }
00721 }
00722
00723 template <TEMPLATE_VERTEX>
00724 Vertex<VERTEX_ARGS>::Vertex( const Vertex& copy )
00725 : _content(copy._content)
00726 #ifndef VVVERTEX_NO_CACHE
00727 , cache_source(0)
00728 , cache(0)
00729 #endif
00730 {
00731 if(_content)
00732 {
00733 ++(_content->count);
00734 }
00735 }
00736
00737 #ifdef USE_CXX0X
00738 template <TEMPLATE_VERTEX>
00739 Vertex<VERTEX_ARGS>::Vertex( Vertex&& copy )
00740 : _content(std::move(copy._content))
00741 # ifndef VVVERTEX_NO_CACHE
00742 , cache_source(0)
00743 , cache(0)
00744 # endif
00745 {
00746 copy._content = 0;
00747 }
00748 #endif
00749
00750 template <TEMPLATE_VERTEX>
00751 Vertex<VERTEX_ARGS>& Vertex<VERTEX_ARGS>::operator=(const identity_t& id)
00752 {
00753 if((identity_t)_content == id)
00754 return *this;
00755 this->release();
00756 _content = reinterpret_cast<real_pointer>(id);
00757 if(_content)
00758 {
00759 if(_content->count == 0)
00760 _content = 0;
00761 else
00762 ++(_content->count);
00763 }
00764 return *this;
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 template <TEMPLATE_VERTEX>
00780 Vertex<VERTEX_ARGS>& Vertex<VERTEX_ARGS>::operator=(const weak_ref_t& copy)
00781 {
00782 if(_content == copy._content)
00783 return *this;
00784 this->release();
00785 _content = copy._content;
00786 if(_content)
00787 {
00788 if(_content->count == 0)
00789 _content = 0;
00790 else
00791 ++(_content->count);
00792 }
00793 return *this;
00794 }
00795
00796 template <TEMPLATE_VERTEX>
00797 void Vertex<VERTEX_ARGS>::release()
00798 {
00799 if( _content )
00800 {
00801 --(_content->count);
00802 if(_content->count == 0)
00803 {
00804 #ifdef USE_ALLOCATOR
00805 _content->~counted_content_t();
00806 alloc.deallocate(_content, 1);
00807 #else // defined USE_ALLOCATOR
00808 delete _content;
00809 #endif
00810 }
00811 }
00812 }
00813
00814 template <TEMPLATE_VERTEX>
00815 typename Vertex<VERTEX_ARGS>::weak_ref_t Vertex<VERTEX_ARGS>::weakRef() const
00816 {
00817 return weak_ref_t(*this);
00818 }
00819
00820 template <TEMPLATE_VERTEX>
00821 Vertex<VERTEX_ARGS>& Vertex<VERTEX_ARGS>::operator=(const Vertex& other)
00822 {
00823 if(_content == other._content)
00824 {
00825 return *this;
00826 }
00827 else
00828 this->release();
00829 _content = other._content;
00830 if(_content)
00831 {
00832 ++(_content->count);
00833 }
00834 return *this;
00835 }
00836
00837 #ifdef USE_CXX0X
00838
00839 template <TEMPLATE_VERTEX>
00840 Vertex<VERTEX_ARGS>& Vertex<VERTEX_ARGS>::operator=(Vertex&& other)
00841 {
00842 if(_content == other._content)
00843 {
00844 return *this;
00845 }
00846 else
00847 this->release();
00848 _content = other._content;
00849 other._content = 0;
00850 return *this;
00851 }
00852 #endif
00853
00854 template <TEMPLATE_VERTEX, typename charT>
00855 std::basic_ostream<charT>& operator<<(std::basic_ostream<charT>& ss, const Vertex<VERTEX_ARGS>& v)
00856 {
00857 ss << "Vertex<" << util::demangle(typeid(VertexContent).name()) << ">(" << v.id() << ")";
00858 return ss;
00859 }
00860
00861
00862 }
00863
00864 #ifdef USE_HASH
00865 namespace std
00866 {
00867 #ifdef CXX_NEEDS_TR1
00868 namespace tr1
00869 {
00870 #endif
00871 template <TEMPLATE_VERTEX>
00872 struct hash<graph::Vertex<VERTEX_ARGS> >
00873 {
00874 size_t operator()(const graph::Vertex<VERTEX_ARGS>& v) const
00875 {
00876 return ((size_t)v.id())>>4;
00877 }
00878 };
00879
00880 template <TEMPLATE_VERTEX>
00881 struct hash<graph::WeakVertex<VERTEX_ARGS> >
00882 {
00883 size_t operator()(const graph::WeakVertex<VERTEX_ARGS>& v) const
00884 {
00885 return ((size_t)v.id())>>4;
00886 }
00887 };
00888 #ifdef CXX_NEEDS_TR1
00889 }
00890 #endif
00891 }
00892 #endif
00893
00894 template <TEMPLATE_VERTEX>
00895 uint qHash(const graph::Vertex<VERTEX_ARGS>& v)
00896 {
00897 return qHash(uint(v.id() >> 4));
00898 }
00899
00900 #undef TEMPLATE_VERTEX
00901 #undef VERTEX
00902
00903 #endif // __GRAPH_VERTEX_H
00904