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     //typedef std::allocator<VERTEX_ARGS> Alloc;
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     //Vertex& operator=(const VertexContent* value);
00306 
00312     bool operator==(const Vertex& other) const { return id() == other.id(); }
00313 
00317     template <typename T1>
00318       bool operator==(const Vertex<T1>& /*other*/) 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 //  template <TEMPLATE_VERTEX>
00688 //    Vertex<VERTEX_ARGS>::Vertex( VertexContent* data )
00689 //    : _content(0)
00690 //    , cache_source(0)
00691 //    , cache(0)
00692 //  {
00693 //    counted_content_t *cdata = dynamic_cast<real_pointer>(data);
00694 //    if(cdata != 0)
00695 //    {
00696 //      _content = cdata;
00697 //      ++(_content->count);
00698 //    }
00699 //    else
00700 //    {
00701 //      _content = new counted_content_t();
00702 //      *(VertexContent*)_content = *data;
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 //  template <TEMPLATE_VERTEX>
00768 //  Vertex<VERTEX_ARGS>& Vertex<VERTEX_ARGS>::operator=(const VertexContent* id)
00769 //  {
00770 //    const counted_content_t* cid = dynamic_cast<const counted_content_t*>(&id);
00771 //    if(cid != 0)
00772 //      return *this = (const identity_t&)cid;
00773 //    else
00774 //    {
00775 //      return *this = (const identity_t&)(new counted_content_t(id));
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; // Shift to consider memory alignment on 64bit!
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; // Shift to consider memory alignment on 64bit!
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:50 2013 for VVE by  doxygen 1.6.3