MorphoGraphX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Vertex.hpp
Go to the documentation of this file.
1 #ifndef VERTEX_HPP
2 #define VERTEX_HPP
3 
12 #include <Config.hpp>
13 
14 #include <Mangling.hpp>
15 #include <Thrust.hpp>
16 #include <UnorderedMap.hpp>
17 
18 #include <iostream>
19 #include <map>
20 #include <memory>
21 #ifndef _MSC_VER
22 # include <stdint.h>
23 #endif
24 #include <typeinfo>
25 #include <utility>
26 
27 namespace mgx {
28 namespace graph {
32 typedef intptr_t vertex_identity_t;
33 
37 extern mgx_EXPORT size_t vertex_counter;
38 
39 template <typename VertexContent, typename Alloc> class WeakVertex;
40 
57 template <typename VertexContent, typename Alloc> class Vertex {
58  friend class WeakVertex<VertexContent, Alloc>;
59 
60 protected:
64  struct CountedContent : public VertexContent {
65 private:
67  : VertexContent()
68  , num(vertex_counter++)
69  {
70  count = 1u; // To be used with tbb::atomic
71  }
72 
73  CountedContent(const CountedContent& copy)
74  : VertexContent(copy)
75  , count(copy.count)
76  , num(vertex_counter++)
77  {
78  }
79 
80  CountedContent(const VertexContent& copy)
81  : VertexContent(copy)
82  , num(vertex_counter++)
83  {
84  count = 1u; // To be used with tbb::atomic
85  }
86 
87 public:
88  typedef typename Alloc::template rebind<CountedContent>::other alloc_t;
89  static alloc_t alloc;
90 
91  static CountedContent* New()
92  {
93  CountedContent* cc = alloc.allocate(1);
94  ::new (cc) CountedContent();
95  return cc;
96  }
97 
98  static CountedContent* New(const VertexContent& copy)
99  {
100  CountedContent* cc = alloc.allocate(1);
101  ::new (cc) CountedContent(copy);
102  return cc;
103  }
104 
105  static void Delete(CountedContent* cc)
106  {
107  cc->~CountedContent();
108  alloc.deallocate(cc, 1);
109  }
110 
114  unsigned int count;
115 
116  size_t num;
117  };
118 
119 public:
123  typedef vertex_identity_t identity_t;
124 
128  typedef VertexContent content_t;
129 
131 
135  typedef VertexContent* pointer;
136 
148  Vertex();
149 
168  explicit Vertex(identity_t id);
169 
176  Vertex(const Vertex& copy);
177 
181  explicit Vertex(const weak_ref_t& w);
182 
186  ~Vertex();
187 
193  VertexContent* operator->() const {
194  return content;
195  }
201  VertexContent& operator*() const {
202  return *content;
203  }
204 
214  Vertex& operator=(const Vertex& other);
215 
216  Vertex& operator=(const identity_t& id);
217 
218  Vertex& operator=(const weak_ref_t& other);
219 
220  Vertex& operator=(const VertexContent* value);
221 
227  bool operator==(const Vertex& other) const {
228  return id() == other.id();
229  }
235  bool operator!=(const Vertex& other) const {
236  return id() != other.id();
237  }
243  bool operator>(const Vertex& other) const {
244  return id() > other.id();
245  }
251  bool operator<(const Vertex& other) const {
252  return id() < other.id();
253  }
259  bool operator>=(const Vertex& other) const {
260  return id() >= other.id();
261  }
267  bool operator<=(const Vertex& other) const {
268  return id() <= other.id();
269  }
270 
274  bool isNull() const {
275  return content == 0;
276  }
277 
281  identity_t id() const {
282  return (identity_t)content;
283  }
284 
288  size_t num() const {
289  return content->num;
290  }
291 
295  operator bool() const { return content; }
296 
300  bool isWeakRef() const {
301  return false;
302  }
303 
307  weak_ref_t weakRef() const;
308 
325  static Vertex null;
326 
333  // bool serialize(storage::VVEStorage&);
334 
335  unsigned int count() const
336  {
337  if(content)
338  return content->count;
339  return 0;
340  }
341 
342 protected:
350  mutable CountedContent* content;
351 
355  void release();
356 
360  void acquire();
361 };
362 
363 template <typename VertexContent, typename Alloc>
364 typename Vertex<VertexContent, Alloc>::CountedContent::alloc_t Vertex<VertexContent, Alloc>::CountedContent::alloc;
365 
366 template <typename VertexContent, typename Alloc> Vertex<VertexContent, Alloc> Vertex<VertexContent, Alloc>::null(0);
367 
368 template <typename VertexContent, typename Alloc> class WeakVertex : public Vertex<VertexContent, Alloc> {
369  typedef typename Vertex<VertexContent, Alloc>::CountedContent CountedContent;
370 
371 public:
375  typedef vertex_identity_t identity_t;
376 
380  typedef VertexContent content_t;
381 
386 
390  typedef VertexContent* pointer;
391 
399  : Vertex<VertexContent, Alloc>(0)
400  {
401  }
402 
407  : Vertex<VertexContent, Alloc>(0)
408  {
409  this->content = v.content;
410  }
411 
415  WeakVertex(const WeakVertex& copy)
416  : Vertex<VertexContent, Alloc>(0)
417  {
418  this->content = copy.content;
419  }
420 
424  explicit WeakVertex(const identity_t& id)
425  : Vertex<VertexContent, Alloc>(0)
426  {
427  this->content = reinterpret_cast<CountedContent*>(id);
428  if(this->content and this->content->count == 0)
429  this->content = 0;
430  }
431 
436  {
437  this->content = other.content;
438  return *this;
439  }
440 
441  WeakVertex& operator=(const identity_t& id)
442  {
443  this->content = reinterpret_cast<CountedContent*>(id);
444  return *this;
445  }
446 
447  WeakVertex& operator=(const strong_ref& other)
448  {
449  this->content = other.content;
450  return *this;
451  }
452 
453  ~WeakVertex() {
454  this->content = 0;
455  }
456 
457  bool isNull() const {
458  return this->content == 0 or this->content->count == 0;
459  }
460 
461 protected:
462 };
463 
464 template <typename VertexContent, typename Alloc> Vertex<VertexContent, Alloc>::~Vertex() {
465  this->release();
466 }
467 
468 template <typename VertexContent, typename Alloc>
470  : content(0)
471 {
472  content = CountedContent::New();
473 }
474 
475 template <typename VertexContent, typename Alloc>
477  : content(reinterpret_cast<CountedContent*>(id))
478 {
479  acquire();
480 }
481 
482 // template <typename VertexContent, typename Alloc>
483 // Vertex<VertexContent,Alloc>::Vertex( VertexContent* data )
484 // : content(0)
485 // {
486 // CountedContent *cdata = dynamic_cast<CountedContent*>(data);
487 // if(cdata != 0)
488 // {
489 // content = cdata;
490 // ++(content->count);
491 // }
492 // else
493 // {
494 // content = CountedContent::New();
495 // *(VertexContent*)content = *data;
496 // }
497 // }
498 
499 template <typename VertexContent, typename Alloc>
501  : content(copy.content)
502 {
503  acquire();
504 }
505 
506 template <typename VertexContent, typename Alloc>
508  : content(copy.content)
509 {
510  acquire();
511 }
512 
513 template <typename VertexContent, typename Alloc>
515 {
516  if((identity_t)content == id)
517  return *this;
518  this->release();
519  content = reinterpret_cast<CountedContent*>(id);
520  acquire();
521  return *this;
522 }
523 
524 template <typename VertexContent, typename Alloc>
525 Vertex<VertexContent, Alloc>& Vertex<VertexContent, Alloc>::operator=(const VertexContent* id)
526 {
527  const CountedContent* cid = dynamic_cast<const CountedContent*>(id);
528  if(cid != 0)
529  return *this = (const identity_t&)cid;
530  else {
531  return *this = (const identity_t&)(*(CountedContent::New(*id)));
532  }
533 }
534 
535 template <typename VertexContent, typename Alloc>
536 Vertex<VertexContent, Alloc>& Vertex<VertexContent, Alloc>::operator=(const weak_ref_t& copy)
537 {
538  if(content == copy.content)
539  return *this;
540  this->release();
541  content = copy.content;
542  acquire();
543  return *this;
544 }
545 
546 template <typename VertexContent, typename Alloc> void Vertex<VertexContent, Alloc>::acquire()
547 {
548  if(content) {
549  if(content->count == 0)
550  content = 0;
551  else
552 #pragma omp atomic
553  ++(content->count);
554  }
555 }
556 
557 template <typename VertexContent, typename Alloc> void Vertex<VertexContent, Alloc>::release()
558 {
559  if(content) {
560 #pragma omp atomic
561  --(content->count);
562  if(content->count == 0) {
563  CountedContent::Delete(content);
564  }
565  }
566 }
567 
568 template <typename VertexContent, typename Alloc>
570 {
571  return weak_ref_t(*this);
572 }
573 
574 template <typename VertexContent, typename Alloc>
576 {
577  if(content == other.content) {
578  return *this;
579  } else
580  this->release();
581  content = other.content;
582  acquire();
583  return *this;
584 }
585 
586 template <typename VertexContent, typename Alloc, typename charT>
587 std::basic_ostream<charT>& operator<<(std::basic_ostream<charT>& ss, const Vertex<VertexContent, Alloc>& v)
588 {
589  ss << "Vertex<" << util::demangle(typeid(VertexContent).name()) << ">(" << v.id() << ")";
590  return ss;
591 }
592 } // namespace graph
593 } // namespace mgx
594 
595 namespace std {
596 #ifdef HASH_NEED_TR1
597 namespace tr1 {
598 #endif
599 template <typename VertexContent, typename Alloc>
600 struct hash<mgx::graph::Vertex<VertexContent, Alloc> > {
601  size_t operator()(const mgx::graph::Vertex<VertexContent, Alloc>& v) const
602  {
603  return ((size_t)v.id()) >> 2; // Shift to consider memory alignment!
604  }
605 };
606 
607 template <typename VertexContent, typename Alloc>
608 struct hash<mgx::graph::WeakVertex<VertexContent, Alloc> > {
609  size_t operator()(const mgx::graph::WeakVertex<VertexContent, Alloc>& v) const
610  {
611  return ((size_t)v.id()) >> 2; // Shift to consider memory alignment!
612  }
613 };
614 #ifdef HASH_NEED_TR1
615 } // namespace tr1
616 #endif
617 } // namespace std
618 
619 #endif // VERTEX_HPP
identity_t id() const
Return the identifier of a vertex.
Definition: Vertex.hpp:281
void release()
Release the current pointer.
Definition: Vertex.hpp:557
bool operator!=(const Vertex &other) const
Comparison operators.
Definition: Vertex.hpp:235
unsigned int count
Reference count on the vertex.
Definition: Vertex.hpp:114
bool operator==(const Vertex &other) const
Comparison operators.
Definition: Vertex.hpp:227
bool operator<(const Vertex &other) const
Comparison operators.
Definition: Vertex.hpp:251
AttribBase(const QString &name) const QString & name()
Default constructor of named attribute.
Definition: Attributes.hpp:54
Vertex< VertexContent, Alloc > strong_ref
Strong reference corresponding to the weak one.
Definition: Vertex.hpp:385
WeakVertex(const identity_t &id)
Construct a weak reference from an id.
Definition: Vertex.hpp:424
VertexContent * pointer
Type of the equivalent pointer.
Definition: Vertex.hpp:135
WeakVertex()
Construct an empty weak vertex.
Definition: Vertex.hpp:398
weak_ref_t weakRef() const
Construct a weak reference on the current vertex.
Definition: Vertex.hpp:569
Vertex()
Creates a new vertex with a new content.
Definition: Vertex.hpp:469
Type of the reference counted content.
Definition: Vertex.hpp:64
VertexContent content_t
Type of the content of the vertex.
Definition: Vertex.hpp:128
size_t num() const
Return a number unique to each vertex, globally.
Definition: Vertex.hpp:288
Definition: Vertex.hpp:39
vertex_identity_t identity_t
Type of the identifier of the vertex.
Definition: Vertex.hpp:123
vertex_identity_t identity_t
Type of the identifier of the vertex.
Definition: Vertex.hpp:375
CountedContent * content
Content of the vertex.
Definition: Vertex.hpp:350
VertexContent & operator*() const
Access to the data.
Definition: Vertex.hpp:201
VertexContent * operator->() const
Access to the data.
Definition: Vertex.hpp:193
Vertex & operator=(const Vertex &other)
Change the vertex held by the current object.
Definition: Vertex.hpp:575
void acquire()
Acquire the current pointer.
Definition: Vertex.hpp:546
bool operator<=(const Vertex &other) const
Comparison operators.
Definition: Vertex.hpp:267
Vertex of a vv graph.
Definition: Vertex.hpp:57
WeakVertex(const strong_ref &v)
Construct a weak reference from a strong one.
Definition: Vertex.hpp:406
bool isWeakRef() const
Return true if the current object hold a weak reference on a vertex.
Definition: Vertex.hpp:300
unsigned int count() const
Serialization method.
Definition: Vertex.hpp:335
VertexContent * pointer
Type of the equivalent pointer.
Definition: Vertex.hpp:390
bool operator>=(const Vertex &other) const
Comparison operators.
Definition: Vertex.hpp:259
WeakVertex & operator=(const WeakVertex &other)
Set the content of the weak reference.
Definition: Vertex.hpp:435
WeakVertex(const WeakVertex &copy)
Copy constructor.
Definition: Vertex.hpp:415
bool isNull() const
Test if a vertex is a null vertex.
Definition: Vertex.hpp:274
VertexContent content_t
Type of the content of the vertex.
Definition: Vertex.hpp:380
bool operator>(const Vertex &other) const
Comparison operators.
Definition: Vertex.hpp:243
static Vertex null
Null vertex.
Definition: Vertex.hpp:325
~Vertex()
Desctructor.
Definition: Vertex.hpp:464