aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
nodeGraphPart_inl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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  nodes_(&nodes) {
57  }
58 
59  /// copy constructor
63  }
64 
65  /// move constructor
69  }
70 
71  /// destructor
74  }
75 
76  /// copy assignment operator
77  INLINE NodeGraphPartIterator&
79  nodes_ = it.nodes_;
80  pos_ = it.pos_;
81  valid_ = it.valid_;
83 
84  return *this;
85  }
86 
87  /// move assignment operator
90  nodes_ = it.nodes_;
91  pos_ = it.pos_;
92  valid_ = it.valid_;
94 
95  return *this;
96  }
97 
98  /// checks whether two iterators point toward the same node
99  INLINE
100  bool NodeGraphPartIterator::operator==(const NodeGraphPartIterator& it) const noexcept {
101  return ((pos_ == it.pos_) && (valid_ == it.valid_) && (nodes_ == it.nodes_));
102  }
103 
104  /// checks whether two iterators point toward different nodes
105  INLINE
106  bool NodeGraphPartIterator::operator!=(const NodeGraphPartIterator& it) const noexcept {
107  return !(operator==(it));
108  }
109 
110  /// increment the iterator
112  ++pos_;
113  validate_();
114  return *this;
115  }
116 
117  /// dereferencing operator
119  if (!valid_) { GUM_ERROR(UndefinedIteratorValue, "This iterator is not valid !") }
120 
121  return pos_;
122  }
123 
124  // unsafe private method
126  pos_ = id;
127 
128  if (pos_ >= nodes_->bound()) {
129  pos_ = nodes_->bound();
130  valid_ = false;
131  } else {
132  valid_ = nodes_->exists(pos_);
133  }
134  }
135 
136  //=================NODEGRAPHPARTITERATORSAFE============================
137 
138  /// default constructor
139  INLINE
142  GUM_CONNECT(*const_cast< NodeGraphPart* >(&nodes),
144  *this,
147  }
148 
149  /// copy constructor
150  INLINE
153  GUM_CONNECT(*const_cast< NodeGraphPart* >(nodes_),
155  *this,
158  }
159 
160  /// move constructor
161  INLINE
164  GUM_CONNECT(*const_cast< NodeGraphPart* >(nodes_),
166  *this,
169  }
170 
171  /// destructor
174  }
175 
176  /// copy assignment operator
179  // avoid self assignment
180  if (&it != this) {
182  Listener:: operator=(it);
184  }
185 
186  return *this;
187  }
188 
189  /// move assignment operator
192  // avoid self assignment
193  if (&it != this) {
195  Listener:: operator=(std::move(it));
197  }
198 
199  return *this;
200  }
201 
202  //=================NODEGRAPHPART============================
203 
205  // avoid self assignment
206  if (this != &p) { populateNodes(p); }
207 
208  return *this;
209  }
210 
212  NodeId next = 0;
213 
214  // return the first hole if holes exist
215  if (_holes_ && (!_holes_->empty()))
216  next = *(_holes_->begin());
217  else // in other case
218  next = _boundVal_;
219 
220  return next;
221  }
222 
223  // _holes_ is assumed to be not nullptr and id is assumed to be in _holes_
225  _holes_->erase(id);
226 
227  if (_holes_->empty()) {
228  delete _holes_;
229  _holes_ = nullptr;
230  }
231  }
232 
233  // warning: do not try to use function addNodeWithId ( const NodeId id ) within
234  // function addNodeWithId(): as both functions are virtual, this may create
235  // bugs within the graphs hierarchy (i.e., virtual functions calling
236  // recursively
237  // each other along the hierarchy) that are not easy to debug.
239  NodeId newNode;
240 
241  // fill the first hole if holes exist
242  if (_holes_ && (!_holes_->empty())) {
243  newNode = *(_holes_->begin());
245  } else {
247  ++_boundVal_;
249  }
250 
252 
253  return newNode;
254  }
255 
257  std::vector< NodeId > v;
258  v.reserve(N);
259  for (Idx i = 0; i < N; i++)
260  v.push_back(this->addNode());
261  return v;
262  }
263 
264 
266  return (_holes_) ? (_boundVal_ - _holes_->size()) : _boundVal_;
267  }
268 
269  INLINE Size NodeGraphPart::size() const { return sizeNodes(); }
270 
272  if (node >= _boundVal_) return false;
273 
274  return (!_inHoles_(node));
275  }
276 
277  INLINE bool NodeGraphPart::exists(const NodeId node) const { return existsNode(node); }
278 
280  if (!existsNode(node)) return;
281 
282  _addHole_(node);
283 
285  }
286 
287  INLINE bool NodeGraphPart::emptyNodes() const { return (sizeNodes() == 0); }
288 
289  INLINE bool NodeGraphPart::empty() const { return emptyNodes(); }
290 
292 
294 
295  // warning: clear is an alias for clearNodes but it should never be the case
296  // that the code of clear is just a call to clearNodes: as both methods are
297  // virtual, this could induce bugs within the graphs hierarchy (i.e., virtual
298  // functions calling recursively each other along the hierarchy) that are not
299  // easy to debug. Hence, the code of clearNodes should be duplicated here.
301 
304  it.validate_(); // stop the iterator at the first not-in-holes
305  return it;
306  }
307 
309 
311  return _endIteratorSafe_;
312  }
313 
315  NodeGraphPartIterator it(*this);
316  it.validate_(); // stop the iterator at the first not-in-holes
317  return it;
318  }
319 
320  INLINE const NodeGraphPartIterator& NodeGraphPart::end() const noexcept {
321  return _endIteratorSafe_;
322  }
323 
324  INLINE bool NodeGraphPart::operator==(const NodeGraphPart& p) const {
325  if (_boundVal_ != p._boundVal_) return false;
326 
327  if (_holes_)
328  if (p._holes_)
329  return (*_holes_ == *p._holes_);
330  else
331  return false;
332  else if (p._holes_)
333  return false;
334 
335  return true;
336  }
337 
338  INLINE bool NodeGraphPart::operator!=(const NodeGraphPart& p) const { return !operator==(p); }
339 
341  NodeSet son(sizeNodes());
342 
343  if (!empty()) {
344  for (NodeId n = 0; n < _boundVal_; ++n) {
345  if (!_inHoles_(n)) son.insert(n);
346  }
347  }
348 
349  return son;
350  }
351 
353  return *(static_cast< const NodeGraphPart* >(this));
354  }
355 
357 
358  /// @return the size of _holes_
359  INLINE Size NodeGraphPart::_sizeHoles_() const { return _holes_ ? _holes_->size() : (Size)0; }
360 
361 } /* namespace gum */
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643