aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
nodeGraphPart_inl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /** @file
23  * @brief Inline implementation of the base node set class for graphs
24  *
25  * @author Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
26  *
27  */
28 
29 // to ease parsing by IDE
30 #include <agrum/tools/graphs/parts/nodeGraphPart.h>
31 
32 namespace gum {
33 
34  //=================NODEGRAPHPARTITERATOR============================
35 
36  /// ensure that the nodeId is either end() either a valid NodeId
38  valid_ = false;
39 
40  if (pos_ > nodes_->bound()) { pos_ = nodes_->bound(); }
41 
42  while (pos_ < nodes_->bound()) {
43  if (!nodes_->inHoles__(pos_)) {
44  valid_ = true;
45  return;
46  }
47 
48  ++pos_;
49  }
50  }
51 
52  /// default constructor
53  INLINE
55  :
56  nodes_(&nodes) {
58  }
59 
60  /// copy constructor
61  INLINE
63  const NodeGraphPartIterator& it) noexcept :
64  nodes_(it.nodes_),
65  pos_(it.pos_), valid_(it.valid_) {
67  }
68 
69  /// move constructor
70  INLINE
72  :
73  nodes_(it.nodes_),
74  pos_(it.pos_), valid_(it.valid_) {
76  }
77 
78  /// destructor
81  }
82 
83  /// copy assignment operator
84  INLINE NodeGraphPartIterator&
86  nodes_ = it.nodes_;
87  pos_ = it.pos_;
88  valid_ = it.valid_;
90 
91  return *this;
92  }
93 
94  /// move assignment operator
97  nodes_ = it.nodes_;
98  pos_ = it.pos_;
99  valid_ = it.valid_;
101 
102  return *this;
103  }
104 
105  /// checks whether two iterators point toward the same node
106  INLINE
108  const NodeGraphPartIterator& it) const noexcept {
109  return ((pos_ == it.pos_) && (valid_ == it.valid_) && (nodes_ == it.nodes_));
110  }
111 
112  /// checks whether two iterators point toward different nodes
113  INLINE
115  const NodeGraphPartIterator& it) const noexcept {
116  return !(operator==(it));
117  }
118 
119  /// increment the iterator
121  ++pos_;
122  validate_();
123  return *this;
124  }
125 
126  /// dereferencing operator
128  if (!valid_) {
129  GUM_ERROR(UndefinedIteratorValue, "This iterator is not valid !");
130  }
131 
132  return pos_;
133  }
134 
135  // unsafe private method
137  pos_ = id;
138 
139  if (pos_ >= nodes_->bound()) {
140  pos_ = nodes_->bound();
141  valid_ = false;
142  } else {
143  valid_ = nodes_->exists(pos_);
144  }
145  }
146 
147  //=================NODEGRAPHPARTITERATORSAFE============================
148 
149  /// default constructor
150  INLINE
152  const NodeGraphPart& nodes) :
154  GUM_CONNECT(*const_cast< NodeGraphPart* >(&nodes),
156  *this,
159  }
160 
161  /// copy constructor
162  INLINE
164  const NodeGraphPartIteratorSafe& it) :
166  GUM_CONNECT(*const_cast< NodeGraphPart* >(nodes_),
168  *this,
171  }
172 
173  /// move constructor
174  INLINE
178  GUM_CONNECT(*const_cast< NodeGraphPart* >(nodes_),
180  *this,
183  }
184 
185  /// destructor
188  }
189 
190  /// copy assignment operator
193  // avoid self assignment
194  if (&it != this) {
196  Listener:: operator=(it);
198  }
199 
200  return *this;
201  }
202 
203  /// move assignment operator
206  // avoid self assignment
207  if (&it != this) {
209  Listener:: operator=(std::move(it));
211  }
212 
213  return *this;
214  }
215 
216  //=================NODEGRAPHPART============================
217 
219  // avoid self assignment
220  if (this != &p) { populateNodes(p); }
221 
222  return *this;
223  }
224 
226  NodeId next = 0;
227 
228  // return the first hole if holes exist
229  if (holes__ && (!holes__->empty()))
230  next = *(holes__->begin());
231  else // in other case
232  next = boundVal__;
233 
234  return next;
235  }
236 
237  // holes__ is assumed to be not nullptr and id is assumed to be in holes__
239  holes__->erase(id);
240 
241  if (holes__->empty()) {
242  delete holes__;
243  holes__ = nullptr;
244  }
245  }
246 
247  // warning: do not try to use function addNodeWithId ( const NodeId id ) within
248  // function addNodeWithId(): as both functions are virtual, this may create
249  // bugs within the graphs hierarchy (i.e., virtual functions calling
250  // recursively
251  // each other along the hierarchy) that are not easy to debug.
253  NodeId newNode;
254 
255  // fill the first hole if holes exist
256  if (holes__ && (!holes__->empty())) {
257  newNode = *(holes__->begin());
259  } else {
261  ++boundVal__;
263  }
264 
266 
267  return newNode;
268  }
269 
271  std::vector< NodeId > v;
272  v.reserve(N);
273  for (Idx i = 0; i < N; i++)
274  v.push_back(this->addNode());
275  return v;
276  }
277 
278 
280  return (holes__) ? (boundVal__ - holes__->size()) : boundVal__;
281  }
282 
283  INLINE Size NodeGraphPart::size() const { return sizeNodes(); }
284 
286  if (node >= boundVal__) return false;
287 
288  return (!inHoles__(node));
289  }
290 
291  INLINE bool NodeGraphPart::exists(const NodeId node) const {
292  return existsNode(node);
293  }
294 
296  if (!existsNode(node)) return;
297 
298  addHole__(node);
299 
301  }
302 
303  INLINE bool NodeGraphPart::emptyNodes() const { return (sizeNodes() == 0); }
304 
305  INLINE bool NodeGraphPart::empty() const { return emptyNodes(); }
306 
308 
310 
311  // warning: clear is an alias for clearNodes but it should never be the case
312  // that the code of clear is just a call to clearNodes: as both methods are
313  // virtual, this could induce bugs within the graphs hierarchy (i.e., virtual
314  // functions calling recursively each other along the hierarchy) that are not
315  // easy to debug. Hence, the code of clearNodes should be duplicated here.
317 
320  it.validate_(); // stop the iterator at the first not-in-holes
321  return it;
322  }
323 
326  }
327 
329  return endIteratorSafe__;
330  }
331 
333  NodeGraphPartIterator it(*this);
334  it.validate_(); // stop the iterator at the first not-in-holes
335  return it;
336  }
337 
338  INLINE const NodeGraphPartIterator& NodeGraphPart::end() const noexcept {
339  return endIteratorSafe__;
340  }
341 
342  INLINE bool NodeGraphPart::operator==(const NodeGraphPart& p) const {
343  if (boundVal__ != p.boundVal__) return false;
344 
345  if (holes__)
346  if (p.holes__)
347  return (*holes__ == *p.holes__);
348  else
349  return false;
350  else if (p.holes__)
351  return false;
352 
353  return true;
354  }
355 
356  INLINE bool NodeGraphPart::operator!=(const NodeGraphPart& p) const {
357  return !operator==(p);
358  }
359 
361  NodeSet son(sizeNodes());
362 
363  if (!empty()) {
364  for (NodeId n = 0; n < boundVal__; ++n) {
365  if (!inHoles__(n)) son.insert(n);
366  }
367  }
368 
369  return son;
370  }
371 
373  return *(static_cast< const NodeGraphPart* >(this));
374  }
375 
377  return holes__ && holes__->contains(id);
378  }
379 
380  /// @return the size of holes__
382  return holes__ ? holes__->size() : (Size)0;
383  }
384 
385 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:669