aGrUM  0.14.2
nodeGraphPart_inl.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
27 // to ease parsing by IDE
29 
30 namespace gum {
31 
32  //=================NODEGRAPHPARTITERATOR============================
33 
35  INLINE void NodeGraphPartIterator::_validate() noexcept {
36  _valid = false;
37 
38  if (_pos > _nodes->bound()) { _pos = _nodes->bound(); }
39 
40  while (_pos < _nodes->bound()) {
41  if (!_nodes->__inHoles(_pos)) {
42  _valid = true;
43  return;
44  }
45 
46  ++_pos;
47  }
48  }
49 
51  INLINE
53  const NodeGraphPart& nodes) noexcept :
54  _nodes(&nodes) {
55  GUM_CONSTRUCTOR(NodeGraphPartIterator);
56  }
57 
59  INLINE
61  const NodeGraphPartIterator& it) noexcept :
62  _nodes(it._nodes),
63  _pos(it._pos), _valid(it._valid) {
64  GUM_CONS_CPY(NodeGraphPartIterator);
65  }
66 
68  INLINE
70  NodeGraphPartIterator&& it) noexcept :
71  _nodes(it._nodes),
72  _pos(it._pos), _valid(it._valid) {
73  GUM_CONS_MOV(NodeGraphPartIterator);
74  }
75 
78  GUM_DESTRUCTOR(NodeGraphPartIterator);
79  }
80 
83  operator=(const NodeGraphPartIterator& it) noexcept {
84  _nodes = it._nodes;
85  _pos = it._pos;
86  _valid = it._valid;
87  GUM_OP_CPY(NodeGraphPartIterator);
88 
89  return *this;
90  }
91 
95  _nodes = it._nodes;
96  _pos = it._pos;
97  _valid = it._valid;
98  GUM_OP_MOV(NodeGraphPartIterator);
99 
100  return *this;
101  }
102 
104  INLINE
106  noexcept {
107  return ((_pos == it._pos) && (_valid == it._valid) && (_nodes == it._nodes));
108  }
109 
111  INLINE
113  noexcept {
114  return !(operator==(it));
115  }
116 
119  ++_pos;
120  _validate();
121  return *this;
122  }
123 
126  if (!_valid) {
127  GUM_ERROR(UndefinedIteratorValue, "This iterator is not valid !");
128  }
129 
130  return _pos;
131  }
132 
133  // unsafe private method
134  INLINE void NodeGraphPartIterator::_setPos(NodeId id) noexcept {
135  _pos = id;
136 
137  if (_pos >= _nodes->bound()) {
138  _pos = _nodes->bound();
139  _valid = false;
140  } else {
141  _valid = _nodes->exists(_pos);
142  }
143  }
144 
145  //=================NODEGRAPHPARTITERATORSAFE============================
146 
148  INLINE
150  const NodeGraphPart& nodes) :
151  NodeGraphPartIterator(nodes) {
152  GUM_CONNECT(*const_cast< NodeGraphPart* >(&nodes),
153  onNodeDeleted,
154  *this,
156  GUM_CONSTRUCTOR(NodeGraphPartIteratorSafe);
157  }
158 
160  INLINE
162  const NodeGraphPartIteratorSafe& it) :
164  GUM_CONNECT(*const_cast< NodeGraphPart* >(_nodes),
165  onNodeDeleted,
166  *this,
168  GUM_CONS_CPY(NodeGraphPartIteratorSafe);
169  }
170 
172  INLINE
175  NodeGraphPartIterator(std::move(it)) {
176  GUM_CONNECT(*const_cast< NodeGraphPart* >(_nodes),
177  onNodeDeleted,
178  *this,
180  GUM_CONS_MOV(NodeGraphPartIteratorSafe);
181  }
182 
185  GUM_DESTRUCTOR(NodeGraphPartIteratorSafe);
186  }
187 
191  // avoid self assignment
192  if (&it != this) {
194  Listener:: operator=(it);
195  GUM_OP_CPY(NodeGraphPartIteratorSafe);
196  }
197 
198  return *this;
199  }
200 
204  // avoid self assignment
205  if (&it != this) {
206  NodeGraphPartIterator::operator=(std::move(it));
207  Listener:: operator=(std::move(it));
208  GUM_OP_MOV(NodeGraphPartIteratorSafe);
209  }
210 
211  return *this;
212  }
213 
214  //=================NODEGRAPHPART============================
215 
217  // avoid self assignment
218  if (this != &p) { populateNodes(p); }
219 
220  return *this;
221  }
222 
224  NodeId next = 0;
225 
226  // return the first hole if holes exist
227  if (__holes && (!__holes->empty()))
228  next = *(__holes->begin());
229  else // in other case
230  next = __boundVal;
231 
232  return next;
233  }
234 
235  // __holes is assumed to be not nullptr and id is assumed to be in __holes
237  __holes->erase(id);
238 
239  if (__holes->empty()) {
240  delete __holes;
241  __holes = nullptr;
242  }
243  }
244 
245  // warning: do not try to use function addNodeWithId ( const NodeId id ) within
246  // function addNodeWithId(): as both functions are virtual, this may create
247  // bugs within the graphs hierarchy (i.e., virtual functions calling
248  // recursively
249  // each other along the hierarchy) that are not easy to debug.
251  NodeId newNode;
252 
253  // fill the first hole if holes exist
254  if (__holes && (!__holes->empty())) {
255  newNode = *(__holes->begin());
256  __eraseHole(newNode);
257  } else {
258  newNode = __boundVal;
259  ++__boundVal;
260  __updateEndIteratorSafe();
261  }
262 
263  GUM_EMIT1(onNodeAdded, newNode);
264 
265  return newNode;
266  }
267 
268  INLINE std::vector< NodeId > NodeGraphPart::addNodes(Size N) {
269  std::vector< NodeId > v;
270  v.reserve(N);
271  for (Idx i = 0; i < N; i++)
272  v.push_back(this->addNode());
273  return v;
274  }
275 
276 
278  return (__holes) ? (__boundVal - __holes->size()) : __boundVal;
279  }
280 
281  INLINE Size NodeGraphPart::size() const { return sizeNodes(); }
282 
283  INLINE bool NodeGraphPart::existsNode(const NodeId node) const {
284  if (node >= __boundVal) return false;
285 
286  return (!__inHoles(node));
287  }
288 
289  INLINE bool NodeGraphPart::exists(const NodeId node) const {
290  return existsNode(node);
291  }
292 
293  INLINE void NodeGraphPart::eraseNode(const NodeId node) {
294  if (!existsNode(node)) return;
295 
296  __addHole(node);
297 
298  GUM_EMIT1(onNodeDeleted, node);
299  }
300 
301  INLINE bool NodeGraphPart::emptyNodes() const { return (sizeNodes() == 0); }
302 
303  INLINE bool NodeGraphPart::empty() const { return emptyNodes(); }
304 
305  INLINE NodeId NodeGraphPart::bound() const { return __boundVal; }
306 
307  INLINE void NodeGraphPart::clearNodes() { __clearNodes(); }
308 
309  // warning: clear is an alias for clearNodes but it should never be the case
310  // that the code of clear is just a call to clearNodes: as both methods are
311  // virtual, this could induce bugs within the graphs hierarchy (i.e., virtual
312  // functions calling recursively each other along the hierarchy) that are not
313  // easy to debug. Hence, the code of clearNodes should be duplicated here.
314  INLINE void NodeGraphPart::clear() { __clearNodes(); }
315 
317  NodeGraphPartIteratorSafe it(*this);
318  it._validate(); // stop the iterator at the first not-in-holes
319  return it;
320  }
321 
323  __endIteratorSafe._setPos(__boundVal);
324  }
325 
326  INLINE const NodeGraphPartIteratorSafe& NodeGraphPart::endSafe() const noexcept {
327  return __endIteratorSafe;
328  }
329 
330  INLINE NodeGraphPartIterator NodeGraphPart::begin() const noexcept {
331  NodeGraphPartIterator it(*this);
332  it._validate(); // stop the iterator at the first not-in-holes
333  return it;
334  }
335 
336  INLINE const NodeGraphPartIterator& NodeGraphPart::end() const noexcept {
337  return __endIteratorSafe;
338  }
339 
340  INLINE bool NodeGraphPart::operator==(const NodeGraphPart& p) const {
341  if (__boundVal != p.__boundVal) return false;
342 
343  if (__holes)
344  if (p.__holes)
345  return (*__holes == *p.__holes);
346  else
347  return false;
348  else if (p.__holes)
349  return false;
350 
351  return true;
352  }
353 
354  INLINE bool NodeGraphPart::operator!=(const NodeGraphPart& p) const {
355  return !operator==(p);
356  }
357 
359  NodeSet son(sizeNodes());
360 
361  if (!empty()) {
362  for (NodeId n = 0; n < __boundVal; ++n) {
363  if (!__inHoles(n)) son.insert(n);
364  }
365  }
366 
367  return son;
368  }
369 
370  INLINE const NodeGraphPart& NodeGraphPart::nodes() const {
371  return *(static_cast< const NodeGraphPart* >(this));
372  }
373 
374  INLINE bool NodeGraphPart::__inHoles(NodeId id) const {
375  return __holes && __holes->contains(id);
376  }
377 
380  return __holes ? __holes->size() : (Size)0;
381  }
382 
383 } /* namespace gum */
NodeGraphPart & operator=(const NodeGraphPart &p)
copy operator
Base node set class for graphs.
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:40
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
gum is the global namespace for all aGrUM entities
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:55
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:96
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:50
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:45
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:97
void insert(const Key &k)
Inserts a new element into the set.
Definition: set_tpl.h:610
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52
virtual void eraseNode(const NodeId id)
erase the node with the given id