DGtal  0.9.2
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 /**
329  * set union to left.
330  * @param aSet any other set.
331  */
332 template <typename Domain, typename Container>
333 inline
334 DGtal::DigitalSetByAssociativeContainer<Domain, Container> &
335 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::operator+=( const DigitalSetByAssociativeContainer<Domain, Container> & aSet )
336 {
337  if ( this != &aSet )
338  {
339  Iterator it_dst = end();
340  for ( ConstIterator it_src = aSet.begin();
341  it_src != aSet.end();
342  ++it_src )
343  {
344  // Use hint it_dst to go faster.
345  it_dst = mySet.insert( it_dst, *it_src );
346  }
347  }
348  return *this;
349 }
350 
351 //-----------------------------------------------------------------------------
352 template <typename Domain, typename Container>
353 inline
354 bool
355 DGtal::DigitalSetByAssociativeContainer<Domain, Container>
356 ::operator()( const Point & p ) const
357 {
358  return find( p ) != end();
359 }
360 
361 ///////////////////////////////////////////////////////////////////////////////
362 // ----------------------- Other Set services -----------------------------
363 
364 
365 template <typename Domain, typename Container>
366 template <typename TOutputIterator>
367 inline
368 void
369 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::computeComplement(TOutputIterator& ito) const
370 {
371  typename Domain::ConstIterator itPoint = domain().begin();
372  typename Domain::ConstIterator itEnd = domain().end();
373  while ( itPoint != itEnd )
374  {
375  if ( find( *itPoint ) == end() )
376  {
377  *ito++ = *itPoint;
378  }
379  ++itPoint;
380  }
381 }
382 
383 /**
384  * Builds the complement in the domain of the set [other_set] in
385  * this.
386  *
387  * @param other_set defines the set whose complement is assigned to 'this'.
388  */
389 template <typename Domain, typename Container>
390 inline
391 void
392 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::assignFromComplement
393 ( const DigitalSetByAssociativeContainer<Domain, Container> & other_set )
394 {
395  clear();
396  typename Domain::ConstIterator itPoint = domain().begin();
397  typename Domain::ConstIterator itEnd = domain().end();
398  while ( itPoint != itEnd )
399  {
400  if ( other_set.find( *itPoint ) == other_set.end() )
401  {
402  insert( *itPoint );
403  }
404  ++itPoint;
405  }
406 }
407 
408 /**
409  * Computes the bounding box of this set.
410  *
411  * @param lower the first point of the bounding box (lowest in all
412  * directions).
413  * @param upper the last point of the bounding box (highest in all
414  * directions).
415  */
416 template <typename Domain, typename Container>
417 inline
418 void
419 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::computeBoundingBox
420 ( Point & lower, Point & upper ) const
421 {
422  lower = domain().upperBound();
423  upper = domain().lowerBound();
424  ConstIterator it = begin();
425  ConstIterator itEnd = end();
426  while ( it != itEnd )
427  {
428  lower = lower.inf( *it );
429  upper = upper.sup( *it );
430  ++it;
431  }
432 }
433 
434 ///////////////////////////////////////////////////////////////////////////////
435 // Interface - public :
436 
437 /**
438  * Writes/Displays the object on an output stream.
439  * @param out the output stream where the object is written.
440  */
441 template <typename Domain, typename Container>
442 inline
443 void
444 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::selfDisplay ( std::ostream & out ) const
445 {
446  out << "[DigitalSetByAssociativeContainer]" << " size=" << size();
447 }
448 
449 /**
450  * Checks the validity/consistency of the object.
451  * @return 'true' if the object is valid, 'false' otherwise.
452  */
453 template <typename Domain, typename Container>
454 inline
455 bool
456 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::isValid() const
457 {
458  return true;
459 }
460 
461 
462 // --------------- CDrawableWithBoard2D realization -------------------------
463 
464 /**
465  * Default drawing style object.
466  * @return the dyn. alloc. default style for this object.
467  */
468 
469 /**
470  * @return the style name used for drawing this object.
471  */
472 template<typename Domain, typename Container>
473 inline
474 std::string
475 DGtal::DigitalSetByAssociativeContainer<Domain, Container>::className() const
476 {
477  return "DigitalSetByAssociativeContainer";
478 }
479 
480 ///////////////////////////////////////////////////////////////////////////////
481 // Implementation of inline function //
482 
483 template <typename Domain, typename Container>
484 inline
485 std::ostream &
486 DGtal::operator<< ( std::ostream & out, const DGtal::DigitalSetByAssociativeContainer<Domain, Container> & object )
487 {
488  object.selfDisplay( out );
489  return out;
490 }
491 
492 // //
493 ///////////////////////////////////////////////////////////////////////////////
494 
495