DGtal  1.2.0
DigitalSetByAssociativeContainer.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file DigitalSetByAssociativeContainer.ih
19  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20  * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
21  *
22  * @author Sebastien Fourey (\c Sebastien.Fourey@greyc.ensicaen.fr )
23  * Groupe de Recherche en Informatique, Image, Automatique et
24  * Instrumentation de Caen - GREYC (CNRS, UMR 6072), ENSICAEN, France
25  *
26  * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
27  * Laboratoire LIRIS (CNRS, UMR 5205), Université de Lyon, France
28  *
29  *
30  * @date 2010/07/01
31  *
32  * Implementation of inline methods defined in DigitalSetByAssociativeContainer.h
33  *
34  * This file is part of the DGtal library.
35  */
36 
37 
38 //////////////////////////////////////////////////////////////////////////////
39 #include <cstdlib>
40 //////////////////////////////////////////////////////////////////////////////
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 // IMPLEMENTATION of inline methods.
44 ///////////////////////////////////////////////////////////////////////////////
45 
46 ///////////////////////////////////////////////////////////////////////////////
47 // ----------------------- Standard services ------------------------------
48 
49 /**
50  * Destructor.
51  */
52 template <typename Domain, typename Container>
53 inline
54 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::~DigitalSetByAssociativeContainer()
55 {
56 }
57 
58 /**
59  * Constructor.
60  * Creates the empty set in the domain [d].
61  *
62  * @param d any counted pointer on domain.
63  */
64 template <typename Domain, typename Container>
65 inline
66 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::DigitalSetByAssociativeContainer
67 ( Clone<Domain> d)
68 : myDomain( d )
69 {
70 }
71 
72 /**
73  * Copy constructor.
74  * @param other the object to clone.
75  */
76 template <typename Domain, typename Container>
77 inline
78 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::DigitalSetByAssociativeContainer( const DigitalSetByAssociativeContainer<Domain, Container> & other )
79 : myDomain( other.myDomain ), mySet( other.mySet )
80 {
81 }
82 
83 /**
84  * Assignment.
85  * @param other the object to copy.
86  * @return a reference on 'this'.
87  */
88 template <typename Domain, typename Container>
89 inline
90 DGtal::DigitalSetByAssociativeContainer<Domain, Container> &
91 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::operator= ( const DigitalSetByAssociativeContainer<Domain, Container> & other )
92 {
93  ASSERT( ( domain().lowerBound() <= other.domain().lowerBound() )
94  && ( domain().upperBound() >= other.domain().upperBound() )
95  && "This domain should include the domain of the other set in case of assignment." );
96  mySet = other.mySet;
97  return *this;
98 }
99 
100 
101 /**
102  * @return the embedding domain.
103  */
104 template <typename Domain, typename Container>
105 inline
106 const Domain &
107 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::domain() const
108 {
109  return *myDomain;
110 }
111 
112 template <typename Domain, typename Container>
113 inline
114 DGtal::CowPtr<Domain>
115 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::domainPointer() const
116 {
117  return myDomain;
118 }
119 
120 
121 
122 ///////////////////////////////////////////////////////////////////////////////
123 // Interface - public :
124 
125 
126 /**
127  * @return the number of elements in the set.
128  */
129 template <typename Domain, typename Container>
130 inline
131 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Size
132 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::size() const
133 {
134  return mySet.size();
135 }
136 
137 /**
138  * @return 'true' iff the set is empty (no element).
139  */
140 template <typename Domain, typename Container>
141 inline
142 bool
143 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::empty() const
144 {
145  return mySet.empty();
146 }
147 
148 
149 /**
150  * Adds point [p] to this set.
151  *
152  * @param p any digital point.
153  * @pre p should belong to the associated domain.
154  */
155 template <typename Domain, typename Container>
156 inline
157 void
158 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::insert( const Point & p )
159 {
160  ASSERT( domain().isInside( p ) );
161  mySet.insert( p );
162 }
163 
164 
165 /**
166  * Adds the collection of points specified by the two iterators to
167  * this set.
168  *
169  * @param first the start point in the collection of Point.
170  * @param last the last point in the collection of Point.
171  * @pre all points should belong to the associated domain.
172  */
173 template <typename Domain, typename Container>
174 template <typename PointInputIterator>
175 void
176 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::insert( PointInputIterator first,
177  PointInputIterator last )
178 {
179  mySet.insert( first, last );
180 }
181 
182 
183 /**
184  * Adds point [p] to this set if the point is not already in the
185  * set.
186  *
187  * @param p any digital point.
188  *
189  * @pre p should belong to the associated domain.
190  * @pre p should not belong to this.
191  */
192 template <typename Domain, typename Container>
193 inline
194 void
195 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::insertNew( const Point & p )
196 {
197  ASSERT( domain().isInside( p ) );
198  mySet.insert( p );
199 }
200 
201 /**
202  * Adds the collection of points specified by the two iterators to
203  * this set.
204  *
205  * @param first the start point in the collection of Point.
206  * @param last the last point in the collection of Point.
207  *
208  * @pre all points should belong to the associated domain.
209  * @pre each point should not belong to this.
210  */
211 template <typename Domain, typename Container>
212 template <typename PointInputIterator>
213 inline
214 void
215 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::insertNew
216 ( PointInputIterator first, PointInputIterator last )
217 {
218  mySet.insert( first, last );
219 }
220 
221 /**
222  * Removes point [p] from the set.
223  *
224  * @param p the point to remove.
225  * @return the number of removed elements (0 or 1).
226  */
227 template <typename Domain, typename Container>
228 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Size
229 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::erase( const Point & p )
230 {
231  return mySet.erase( p );
232 }
233 
234 /**
235  * Removes the point pointed by [it] from the set.
236  *
237  * @param it an iterator on this set.
238  * Note: generally faster than giving just the point.
239  */
240 template <typename Domain, typename Container>
241 inline
242 void
243 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::erase( Iterator it )
244 {
245  mySet.erase( it );
246 }
247 
248 /**
249  * Clears the set.
250  * @post this set is empty.
251  */
252 template <typename Domain, typename Container>
253 inline
254 void
255 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::clear()
256 {
257  mySet.clear();
258 }
259 
260 /**
261  * @param p any digital point.
262  * @return a const iterator pointing on [p] if found, otherwise end().
263  */
264 template <typename Domain, typename Container>
265 inline
266 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::ConstIterator
267 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::find( const Point & p ) const
268 {
269  return mySet.find( p );
270 }
271 
272 /**
273  * @param p any digital point.
274  * @return an iterator pointing on [p] if found, otherwise end().
275  */
276 template <typename Domain, typename Container>
277 inline
278 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Iterator
279 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::find( const Point & p )
280 {
281  return mySet.find( p );
282 }
283 
284 /**
285  * @return a const iterator on the first element in this set.
286  */
287 template <typename Domain, typename Container>
288 inline
289 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::ConstIterator
290 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::begin() const
291 {
292  return mySet.begin();
293 }
294 
295 /**
296  * @return a const iterator on the element after the last in this set.
297  */
298 template <typename Domain, typename Container>
299 inline
300 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::ConstIterator
301 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::end() const
302 {
303  return mySet.end();
304 }
305 
306 /**
307  * @return an iterator on the first element in this set.
308  */
309 template <typename Domain, typename Container>
310 inline
311 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Iterator
312 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::begin()
313 {
314  return mySet.begin();
315 }
316 
317 /**
318  * @return a iterator on the element after the last in this set.
319  */
320 template <typename Domain, typename Container>
321 inline
322 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Iterator
323 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::end()
324 {
325  return mySet.end();
326 }
327 
328 template <typename Domain, typename Container>
329 inline
330 const typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Container &
331 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::container() const
332 {
333  return mySet;
334 }
335 
336 template <typename Domain, typename Container>
337 inline
338 typename DGtal::DigitalSetByAssociativeContainer<Domain, Container>::Container &
339 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::container()
340 {
341  return mySet;
342 }
343 
344 /**
345  * set union to left.
346  * @param aSet any other set.
347  */
348 template <typename Domain, typename Container>
349 inline
350 DGtal::DigitalSetByAssociativeContainer<Domain, Container> &
351 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::operator+=( const DigitalSetByAssociativeContainer<Domain, Container> & aSet )
352 {
353  if ( this != &aSet )
354  {
355  Iterator it_dst = end();
356  for ( ConstIterator it_src = aSet.begin();
357  it_src != aSet.end();
358  ++it_src )
359  {
360  // Use hint it_dst to go faster.
361  it_dst = mySet.insert( it_dst, *it_src );
362  }
363  }
364  return *this;
365 }
366 
367 //-----------------------------------------------------------------------------
368 template <typename Domain, typename Container>
369 inline
370 bool
371 DGtal::DigitalSetByAssociativeContainer<Domain, Container>
372 ::operator()( const Point & p ) const
373 {
374  return find( p ) != end();
375 }
376 
377 ///////////////////////////////////////////////////////////////////////////////
378 // ----------------------- Other Set services -----------------------------
379 
380 
381 template <typename Domain, typename Container>
382 template <typename TOutputIterator>
383 inline
384 void
385 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::computeComplement(TOutputIterator& ito) const
386 {
387  typename Domain::ConstIterator itPoint = domain().begin();
388  typename Domain::ConstIterator itEnd = domain().end();
389  while ( itPoint != itEnd )
390  {
391  if ( find( *itPoint ) == end() )
392  {
393  *ito++ = *itPoint;
394  }
395  ++itPoint;
396  }
397 }
398 
399 /**
400  * Builds the complement in the domain of the set [other_set] in
401  * this.
402  *
403  * @param other_set defines the set whose complement is assigned to 'this'.
404  */
405 template <typename Domain, typename Container>
406 inline
407 void
408 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::assignFromComplement
409 ( const DigitalSetByAssociativeContainer<Domain, Container> & other_set )
410 {
411  clear();
412  typename Domain::ConstIterator itPoint = domain().begin();
413  typename Domain::ConstIterator itEnd = domain().end();
414  while ( itPoint != itEnd )
415  {
416  if ( other_set.find( *itPoint ) == other_set.end() )
417  {
418  insert( *itPoint );
419  }
420  ++itPoint;
421  }
422 }
423 
424 /**
425  * Computes the bounding box of this set.
426  *
427  * @param lower the first point of the bounding box (lowest in all
428  * directions).
429  * @param upper the last point of the bounding box (highest in all
430  * directions).
431  */
432 template <typename Domain, typename Container>
433 inline
434 void
435 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::computeBoundingBox
436 ( Point & lower, Point & upper ) const
437 {
438  lower = domain().upperBound();
439  upper = domain().lowerBound();
440  ConstIterator it = begin();
441  ConstIterator itEnd = end();
442  while ( it != itEnd )
443  {
444  lower = lower.inf( *it );
445  upper = upper.sup( *it );
446  ++it;
447  }
448 }
449 
450 ///////////////////////////////////////////////////////////////////////////////
451 // Interface - public :
452 
453 /**
454  * Writes/Displays the object on an output stream.
455  * @param out the output stream where the object is written.
456  */
457 template <typename Domain, typename Container>
458 inline
459 void
460 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::selfDisplay ( std::ostream & out ) const
461 {
462  out << "[DigitalSetByAssociativeContainer]" << " size=" << size();
463 }
464 
465 /**
466  * Checks the validity/consistency of the object.
467  * @return 'true' if the object is valid, 'false' otherwise.
468  */
469 template <typename Domain, typename Container>
470 inline
471 bool
472 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::isValid() const
473 {
474  return true;
475 }
476 
477 
478 // --------------- CDrawableWithBoard2D realization -------------------------
479 
480 /**
481  * Default drawing style object.
482  * @return the dyn. alloc. default style for this object.
483  */
484 
485 /**
486  * @return the style name used for drawing this object.
487  */
488 template<typename Domain, typename Container>
489 inline
490 std::string
491 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::className() const
492 {
493  return "DigitalSetByAssociativeContainer";
494 }
495 
496 ///////////////////////////////////////////////////////////////////////////////
497 // Implementation of inline function //
498 
499 template <typename Domain, typename Container>
500 inline
501 std::ostream &
502 DGtal::operator<< ( std::ostream & out, const DGtal::DigitalSetByAssociativeContainer<Domain, Container> & object )
503 {
504  object.selfDisplay( out );
505  return out;
506 }
507 
508 // //
509 ///////////////////////////////////////////////////////////////////////////////
510 
511