aGrUM  0.16.0
nodeGraphPart_inl.h
Go to the documentation of this file.
1 
30 // to ease parsing by IDE
32 
33 namespace gum {
34 
35  //=================NODEGRAPHPARTITERATOR============================
36 
38  INLINE void NodeGraphPartIterator::_validate() noexcept {
39  _valid = false;
40 
41  if (_pos > _nodes->bound()) { _pos = _nodes->bound(); }
42 
43  while (_pos < _nodes->bound()) {
44  if (!_nodes->__inHoles(_pos)) {
45  _valid = true;
46  return;
47  }
48 
49  ++_pos;
50  }
51  }
52 
54  INLINE
56  const NodeGraphPart& nodes) noexcept :
57  _nodes(&nodes) {
58  GUM_CONSTRUCTOR(NodeGraphPartIterator);
59  }
60 
62  INLINE
64  const NodeGraphPartIterator& it) noexcept :
65  _nodes(it._nodes),
66  _pos(it._pos), _valid(it._valid) {
67  GUM_CONS_CPY(NodeGraphPartIterator);
68  }
69 
71  INLINE
73  NodeGraphPartIterator&& it) noexcept :
74  _nodes(it._nodes),
75  _pos(it._pos), _valid(it._valid) {
76  GUM_CONS_MOV(NodeGraphPartIterator);
77  }
78 
81  GUM_DESTRUCTOR(NodeGraphPartIterator);
82  }
83 
86  operator=(const NodeGraphPartIterator& it) noexcept {
87  _nodes = it._nodes;
88  _pos = it._pos;
89  _valid = it._valid;
90  GUM_OP_CPY(NodeGraphPartIterator);
91 
92  return *this;
93  }
94 
98  _nodes = it._nodes;
99  _pos = it._pos;
100  _valid = it._valid;
101  GUM_OP_MOV(NodeGraphPartIterator);
102 
103  return *this;
104  }
105 
107  INLINE
109  noexcept {
110  return ((_pos == it._pos) && (_valid == it._valid) && (_nodes == it._nodes));
111  }
112 
114  INLINE
116  noexcept {
117  return !(operator==(it));
118  }
119 
122  ++_pos;
123  _validate();
124  return *this;
125  }
126 
129  if (!_valid) {
130  GUM_ERROR(UndefinedIteratorValue, "This iterator is not valid !");
131  }
132 
133  return _pos;
134  }
135 
136  // unsafe private method
137  INLINE void NodeGraphPartIterator::_setPos(NodeId id) noexcept {
138  _pos = id;
139 
140  if (_pos >= _nodes->bound()) {
141  _pos = _nodes->bound();
142  _valid = false;
143  } else {
144  _valid = _nodes->exists(_pos);
145  }
146  }
147 
148  //=================NODEGRAPHPARTITERATORSAFE============================
149 
151  INLINE
153  const NodeGraphPart& nodes) :
154  NodeGraphPartIterator(nodes) {
155  GUM_CONNECT(*const_cast< NodeGraphPart* >(&nodes),
156  onNodeDeleted,
157  *this,
159  GUM_CONSTRUCTOR(NodeGraphPartIteratorSafe);
160  }
161 
163  INLINE
165  const NodeGraphPartIteratorSafe& it) :
167  GUM_CONNECT(*const_cast< NodeGraphPart* >(_nodes),
168  onNodeDeleted,
169  *this,
171  GUM_CONS_CPY(NodeGraphPartIteratorSafe);
172  }
173 
175  INLINE
178  NodeGraphPartIterator(std::move(it)) {
179  GUM_CONNECT(*const_cast< NodeGraphPart* >(_nodes),
180  onNodeDeleted,
181  *this,
183  GUM_CONS_MOV(NodeGraphPartIteratorSafe);
184  }
185 
188  GUM_DESTRUCTOR(NodeGraphPartIteratorSafe);
189  }
190 
194  // avoid self assignment
195  if (&it != this) {
197  Listener:: operator=(it);
198  GUM_OP_CPY(NodeGraphPartIteratorSafe);
199  }
200 
201  return *this;
202  }
203 
207  // avoid self assignment
208  if (&it != this) {
209  NodeGraphPartIterator::operator=(std::move(it));
210  Listener:: operator=(std::move(it));
211  GUM_OP_MOV(NodeGraphPartIteratorSafe);
212  }
213 
214  return *this;
215  }
216 
217  //=================NODEGRAPHPART============================
218 
220  // avoid self assignment
221  if (this != &p) { populateNodes(p); }
222 
223  return *this;
224  }
225 
227  NodeId next = 0;
228 
229  // return the first hole if holes exist
230  if (__holes && (!__holes->empty()))
231  next = *(__holes->begin());
232  else // in other case
233  next = __boundVal;
234 
235  return next;
236  }
237 
238  // __holes is assumed to be not nullptr and id is assumed to be in __holes
240  __holes->erase(id);
241 
242  if (__holes->empty()) {
243  delete __holes;
244  __holes = nullptr;
245  }
246  }
247 
248  // warning: do not try to use function addNodeWithId ( const NodeId id ) within
249  // function addNodeWithId(): as both functions are virtual, this may create
250  // bugs within the graphs hierarchy (i.e., virtual functions calling
251  // recursively
252  // each other along the hierarchy) that are not easy to debug.
254  NodeId newNode;
255 
256  // fill the first hole if holes exist
257  if (__holes && (!__holes->empty())) {
258  newNode = *(__holes->begin());
259  __eraseHole(newNode);
260  } else {
261  newNode = __boundVal;
262  ++__boundVal;
263  __updateEndIteratorSafe();
264  }
265 
266  GUM_EMIT1(onNodeAdded, newNode);
267 
268  return newNode;
269  }
270 
271  INLINE std::vector< NodeId > NodeGraphPart::addNodes(Size N) {
272  std::vector< NodeId > v;
273  v.reserve(N);
274  for (Idx i = 0; i < N; i++)
275  v.push_back(this->addNode());
276  return v;
277  }
278 
279 
281  return (__holes) ? (__boundVal - __holes->size()) : __boundVal;
282  }
283 
284  INLINE Size NodeGraphPart::size() const { return sizeNodes(); }
285 
286  INLINE bool NodeGraphPart::existsNode(const NodeId node) const {
287  if (node >= __boundVal) return false;
288 
289  return (!__inHoles(node));
290  }
291 
292  INLINE bool NodeGraphPart::exists(const NodeId node) const {
293  return existsNode(node);
294  }
295 
296  INLINE void NodeGraphPart::eraseNode(const NodeId node) {
297  if (!existsNode(node)) return;
298 
299  __addHole(node);
300 
301  GUM_EMIT1(onNodeDeleted, node);
302  }
303 
304  INLINE bool NodeGraphPart::emptyNodes() const { return (sizeNodes() == 0); }
305 
306  INLINE bool NodeGraphPart::empty() const { return emptyNodes(); }
307 
308  INLINE NodeId NodeGraphPart::bound() const { return __boundVal; }
309 
310  INLINE void NodeGraphPart::clearNodes() { __clearNodes(); }
311 
312  // warning: clear is an alias for clearNodes but it should never be the case
313  // that the code of clear is just a call to clearNodes: as both methods are
314  // virtual, this could induce bugs within the graphs hierarchy (i.e., virtual
315  // functions calling recursively each other along the hierarchy) that are not
316  // easy to debug. Hence, the code of clearNodes should be duplicated here.
317  INLINE void NodeGraphPart::clear() { __clearNodes(); }
318 
320  NodeGraphPartIteratorSafe it(*this);
321  it._validate(); // stop the iterator at the first not-in-holes
322  return it;
323  }
324 
326  __endIteratorSafe._setPos(__boundVal);
327  }
328 
329  INLINE const NodeGraphPartIteratorSafe& NodeGraphPart::endSafe() const noexcept {
330  return __endIteratorSafe;
331  }
332 
333  INLINE NodeGraphPartIterator NodeGraphPart::begin() const noexcept {
334  NodeGraphPartIterator it(*this);
335  it._validate(); // stop the iterator at the first not-in-holes
336  return it;
337  }
338 
339  INLINE const NodeGraphPartIterator& NodeGraphPart::end() const noexcept {
340  return __endIteratorSafe;
341  }
342 
343  INLINE bool NodeGraphPart::operator==(const NodeGraphPart& p) const {
344  if (__boundVal != p.__boundVal) return false;
345 
346  if (__holes)
347  if (p.__holes)
348  return (*__holes == *p.__holes);
349  else
350  return false;
351  else if (p.__holes)
352  return false;
353 
354  return true;
355  }
356 
357  INLINE bool NodeGraphPart::operator!=(const NodeGraphPart& p) const {
358  return !operator==(p);
359  }
360 
362  NodeSet son(sizeNodes());
363 
364  if (!empty()) {
365  for (NodeId n = 0; n < __boundVal; ++n) {
366  if (!__inHoles(n)) son.insert(n);
367  }
368  }
369 
370  return son;
371  }
372 
373  INLINE const NodeGraphPart& NodeGraphPart::nodes() const {
374  return *(static_cast< const NodeGraphPart* >(this));
375  }
376 
377  INLINE bool NodeGraphPart::__inHoles(NodeId id) const {
378  return __holes && __holes->contains(id);
379  }
380 
383  return __holes ? __holes->size() : (Size)0;
384  }
385 
386 } /* namespace gum */
NodeGraphPart & operator=(const NodeGraphPart &p)
copy operator
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
node_iterator_safe beginSafe() const
a begin iterator to parse the set of nodes contained in the NodeGraphPart
Size __sizeHoles() const
NodeSet * __holes
the set of nodes not contained in the NodeGraphPart in the interval 1..__max
#define GUM_EMIT1(signal, arg1)
Definition: signaler1.h:42
NodeGraphPartIterator & operator=(const NodeGraphPartIterator &it) noexcept
copy assignment operator
NodeGraphPartIteratorSafe & operator=(const NodeGraphPartIteratorSafe &it)
copy assignment operator
Size size() const
alias for sizeNodes
STL namespace.
void _validate() noexcept
ensure that the nodeId is either end() either a valid NodeId
void _setPos(NodeId id) noexcept
this function is used by NodeGraphPart to update
bool exists(const NodeId id) const
alias for existsNode
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
Definition: agrum.h:25
bool __inHoles(NodeId id) const
const NodeGraphPart * _nodes
the nodegraphpart on which points the iterator
virtual NodeId addNode()
insert a new node and return its id
bool operator!=(const NodeGraphPartIterator &it) const noexcept
checks whether two iterators point toward different nodes
bool operator==(const NodeGraphPart &p) const
check whether two NodeGraphParts contain the same nodes
NodeId __boundVal
the id below which NodeIds may belong to the NodeGraphPart
bool empty() const
alias for emptyNodes
bool emptyNodes() const
indicates whether there exists nodes in the NodeGraphPart
node_iterator begin() const noexcept
a begin iterator to parse the set of nodes contained in the NodeGraphPart
Unsafe iterator on the node set of a graph.
Definition: nodeGraphPart.h:58
void __updateEndIteratorSafe()
updating endIterator (always at __max+1)
NodeGraphPartIteratorSafe(const NodeGraphPart &nodes)
default constructor
value_type operator*() const
dereferencing operator
NodeSet asNodeSet() const
returns a copy of the set of nodes represented by the NodeGraphPart
NodeGraphPartIterator & operator++() noexcept
increment the iterator
const NodeGraphPart & nodes() const
return *this as a NodeGraphPart
std::vector< NodeId > addNodes(Size n)
insert n nodes
Class for node sets in graph.
virtual void clear()
alias for clearNodes
bool existsNode(const NodeId id) const
returns true iff the NodeGraphPart contains the given nodeId
Size sizeNodes() const
returns the number of nodes in the NodeGraphPart
#define GUM_CONNECT(sender, signal, receiver, target)
Definition: listener.h:98
bool operator==(const NodeGraphPartIterator &it) const noexcept
checks whether two iterators point toward the same node
NodeId bound() const
returns a number n such that all node ids are strictly lower than n
NodeId _pos
the nodeid on which the iterator points currently
virtual void clearNodes()
remove all the nodes from the NodeGraphPart
Size Idx
Type for indexes.
Definition: types.h:53
const node_iterator_safe & endSafe() const noexcept
the end iterator to parse the set of nodes contained in the NodeGraphPart
NodeId nextNodeId() const
returns a new node id, not yet used by any node
bool operator!=(const NodeGraphPart &p) const
check whether two NodeGraphParts contain different nodes
void __eraseHole(NodeId id)
to delete hole.
virtual ~NodeGraphPartIterator() noexcept
destructor
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:48
NodeGraphPartIterator(const NodeGraphPart &nodes) noexcept
Default constructor.
Safe iterator on the node set of a graph.
const node_iterator & end() const noexcept
the end iterator to parse the set of nodes contained in the NodeGraphPart
void whenNodeDeleted(const void *src, NodeId id)
called when a node is deleted in the iterated NodeGraphPart
Size NodeId
Type for node ids.
Definition: graphElements.h:98
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:613
#define GUM_ERROR(type, msg)
Definition: exceptions.h:55
virtual void eraseNode(const NodeId id)
erase the node with the given id