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.
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.
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/>.
18 * @file DigitalSetBySTLVector.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in DigitalSetBySTLVector.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////
35 ///////////////////////////////////////////////////////////////////////////////
36 // IMPLEMENTATION of inline methods.
37 ///////////////////////////////////////////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////////
40 // ----------------------- Standard services ------------------------------
45 template <typename Domain>
47 DGtal::DigitalSetBySTLVector<Domain>::~DigitalSetBySTLVector()
53 * Creates the empty set in the domain [d].
55 * @param d any domain.
57 template <typename Domain>
59 DGtal::DigitalSetBySTLVector<Domain>::DigitalSetBySTLVector
61 : myDomain( d ), myVector()
67 * @param other the object to clone.
69 template <typename Domain>
71 DGtal::DigitalSetBySTLVector<Domain>::DigitalSetBySTLVector
72 ( const DigitalSetBySTLVector & other )
73 : myDomain( other.myDomain ), myVector( other.myVector )
79 * @param other the object to copy.
80 * @return a reference on 'this'.
82 template <typename Domain>
84 DGtal::DigitalSetBySTLVector<Domain> &
85 DGtal::DigitalSetBySTLVector<Domain>::operator=
86 ( const DigitalSetBySTLVector & other )
88 ASSERT( ( domain().lowerBound() <= other.domain().lowerBound() )
89 && ( domain().upperBound() >= other.domain().upperBound() )
90 && "This domain should include the domain of the other set in case of assignment." );
91 myVector = other.myVector;
97 * @return the embedding domain.
99 template <typename Domain>
102 DGtal::DigitalSetBySTLVector<Domain>::domain() const
107 template <typename Domain>
109 DGtal::CowPtr<Domain>
110 DGtal::DigitalSetBySTLVector<Domain>::domainPointer() const
117 // ----------------------- Standard Set services --------------------------
120 * @return the number of elements in the set.
122 template <typename Domain>
124 typename DGtal::DigitalSetBySTLVector<Domain>::Size
125 DGtal::DigitalSetBySTLVector<Domain>::size() const
127 return (unsigned int)myVector.size();
131 * @return 'true' iff the set is empty (no element).
133 template <typename Domain>
136 DGtal::DigitalSetBySTLVector<Domain>::empty() const
138 return myVector.empty();
142 * Adds point [p] to this set.
144 * @param p any digital point.
145 * @pre p should belong to the associated domain.
147 template <typename Domain>
150 DGtal::DigitalSetBySTLVector<Domain>::insert( const Point & p )
152 // ASSERT( domain().isInside( p ) );
153 Iterator it = find( p );
155 myVector.push_back( p );
159 * Adds the collection of points specified by the two iterators to
162 * @param first the start point in the collection of Point.
163 * @param last the last point in the collection of Point.
164 * @pre all points should belong to the associated domain.
166 template <typename Domain>
167 template <typename PointInputIterator>
170 DGtal::DigitalSetBySTLVector<Domain>::insert
171 ( PointInputIterator first, PointInputIterator last )
173 for ( ; first != last; ++first )
178 * Adds point [p] to this set if the point is not already in the
179 * set. There is no defined behavior if the point is already in
180 * the set (for instance, may be present twice).
182 * @param p any digital point.
184 * @pre p should belong to the associated domain.
185 * @pre p should not belong to this.
187 template <typename Domain>
190 DGtal::DigitalSetBySTLVector<Domain>::insertNew( const Point & p )
192 // ASSERT( domain().isInside( p ) );
193 ASSERT( find( p ) == end() );
194 myVector.push_back( p );
198 * Adds the collection of points specified by the two iterators to
199 * this set. The collection should contain distinct points. Each
200 * of these points should also not belong already to the set.
201 * set. There is no defined behavior if the preceding requisites
202 * are not satisfied (for instance, points may be present several
205 * @param first the start point in the collection of Point.
206 * @param last the last point in the collection of Point.
208 * @pre all points should belong to the associated domain.
209 * @pre each point should not belong to this.
211 template <typename Domain>
212 template <typename PointInputIterator>
215 DGtal::DigitalSetBySTLVector<Domain>::insertNew
216 ( PointInputIterator first, PointInputIterator last )
218 while ( first != last )
219 myVector.push_back( *first++ );
220 // std::copy( first, last, myVector.end() );
225 * Removes point [p] from the set.
227 * @param p the point to remove.
228 * @return the number of removed elements (0 or 1).
230 template <typename Domain>
232 typename DGtal::DigitalSetBySTLVector<Domain>::Size
233 DGtal::DigitalSetBySTLVector<Domain>::erase( const Point & p )
235 Iterator it = find( p );
245 * Removes the point pointed by [it] from the set.
247 * @param it an iterator on this set.
248 * @pre it should point on a valid element ( it != end() ).
249 * Note: generally faster than giving just the point.
251 template <typename Domain>
254 DGtal::DigitalSetBySTLVector<Domain>::erase( Iterator it )
256 //take a mutable iterator
257 typename std::iterator_traits<Iterator>::difference_type d = it - this->begin();
258 typename std::vector<Point>::iterator it2 = myVector.begin() + d;
260 *it2 = myVector.back();
265 * Removes the collection of points specified by the two iterators from
268 * @param first the start point in this set.
269 * @param last the last point in this set.
271 template <typename Domain>
274 DGtal::DigitalSetBySTLVector<Domain>::erase( Iterator first, Iterator last )
276 while ( ( last != end() )
277 && ( first != last ) )
279 //take a mutable iterator
280 typename std::iterator_traits<Iterator>::difference_type d = first - this->begin();
281 typename std::vector<Point>::iterator first2 = myVector.begin() + d;
283 *first2 = myVector.back();
289 while ( first != end() )
295 * @post this set is empty.
297 template <typename Domain>
300 DGtal::DigitalSetBySTLVector<Domain>::clear()
306 * @param p any digital point.
307 * @return a const iterator pointing on [p] if found, otherwise end().
309 template <typename Domain>
311 typename DGtal::DigitalSetBySTLVector<Domain>::ConstIterator
312 DGtal::DigitalSetBySTLVector<Domain>::find( const Point & p ) const
314 const ConstIterator it_end = end();
315 for ( ConstIterator it = begin(); it != it_end; ++it )
316 if ( p == *it ) return it;
321 * @param p any digital point.
322 * @return an iterator pointing on [p] if found, otherwise end().
324 template <typename Domain>
326 typename DGtal::DigitalSetBySTLVector<Domain>::Iterator
327 DGtal::DigitalSetBySTLVector<Domain>::find( const Point & p )
329 const Iterator it_end = end();
330 for ( Iterator it = begin(); it != it_end; ++it )
331 if ( p == *it ) return it;
337 * @return a const iterator on the first element in this set.
339 template <typename Domain>
341 typename DGtal::DigitalSetBySTLVector<Domain>::ConstIterator
342 DGtal::DigitalSetBySTLVector<Domain>::begin() const
344 return myVector.begin();
348 * @return a const iterator on the element after the last in this set.
350 template <typename Domain>
352 typename DGtal::DigitalSetBySTLVector<Domain>::ConstIterator
353 DGtal::DigitalSetBySTLVector<Domain>::end() const
355 return myVector.end();
360 * @return an iterator on the first element in this set.
362 template <typename Domain>
364 typename DGtal::DigitalSetBySTLVector<Domain>::Iterator
365 DGtal::DigitalSetBySTLVector<Domain>::begin()
367 return myVector.begin();
372 * @return a iterator on the element after the last in this set.
374 template <typename Domain>
376 typename DGtal::DigitalSetBySTLVector<Domain>::Iterator
377 DGtal::DigitalSetBySTLVector<Domain>::end()
379 return myVector.end();
382 template <typename Domain>
384 const typename DGtal::DigitalSetBySTLVector<Domain>::Container &
385 DGtal::DigitalSetBySTLVector<Domain>::container() const
390 template <typename Domain>
392 typename DGtal::DigitalSetBySTLVector<Domain>::Container &
393 DGtal::DigitalSetBySTLVector<Domain>::container()
400 * @param aSet any other set.
402 template <typename Domain>
404 DGtal::DigitalSetBySTLVector<Domain> &
405 DGtal::DigitalSetBySTLVector<Domain>
406 ::operator+=( const DigitalSetBySTLVector<Domain> & aSet )
410 std::vector<Point> other( aSet.myVector );
411 std::stable_sort( other.begin(), other.end() );
412 std::stable_sort( myVector.begin(), myVector.end() );
413 std::vector<Point> new_vector;
414 new_vector.reserve( size() + other.size() );
415 std::set_union( begin(), end(), other.begin(), other.end(),
416 std::back_insert_iterator< std::vector<Point> >
418 myVector.swap( new_vector );
423 //-----------------------------------------------------------------------------
424 template <typename Domain>
427 DGtal::DigitalSetBySTLVector<Domain>
428 ::operator()( const Point & p ) const
430 return find( p ) != end();
434 ///////////////////////////////////////////////////////////////////////////////
435 // ----------------------- Other Set services -----------------------------
438 template <typename Domain>
439 template <typename TOutputIterator>
442 DGtal::DigitalSetBySTLVector<Domain>::computeComplement(TOutputIterator& ito) const
444 typename Domain::ConstIterator itPoint = domain().begin();
445 typename Domain::ConstIterator itEnd = domain().end();
446 while ( itPoint != itEnd ) {
447 if ( std::find( begin(), end(), *itPoint ) == end() ) {
455 * Builds the complement in the domain of the set [other_set] in
458 * @param other_set defines the set whose complement is assigned to 'this'.
460 template <typename Domain>
463 DGtal::DigitalSetBySTLVector<Domain>::assignFromComplement
464 ( const DigitalSetBySTLVector<Domain> & other_set )
467 typename Domain::ConstIterator itPoint = domain().begin();
468 typename Domain::ConstIterator itEnd = domain().end();
469 while ( itPoint != itEnd ) {
470 if ( std::find( other_set.begin(),
472 *itPoint ) == other_set.end() ) {
480 * Computes the bounding box of this set.
482 * @param lower the first point of the bounding box (lowest in all
484 * @param upper the last point of the bounding box (highest in all
487 template <typename Domain>
490 DGtal::DigitalSetBySTLVector<Domain>::computeBoundingBox
491 ( Point & lower, Point & upper ) const
493 if ( begin() != end() )
495 ConstIterator it = begin();
496 ConstIterator it_end = end();
498 for ( ; it != it_end; ++it )
499 if ( it->isLower( lower ) ) lower = *it;
500 else if ( it->isUpper( upper ) ) upper = *it;
504 lower = domain().upperBound();
505 upper = domain().lowerBound();
510 ///////////////////////////////////////////////////////////////////////////////
511 // Interface - public :
514 * Writes/Displays the object on an output stream.
515 * @param out the output stream where the object is written.
517 template <typename Domain>
520 DGtal::DigitalSetBySTLVector<Domain>::selfDisplay ( std::ostream & out ) const
522 out << "[DigitalSetBySTLVector]" << " size=" << size();
526 * Checks the validity/consistency of the object.
527 * @return 'true' if the object is valid, 'false' otherwise.
529 template <typename Domain>
532 DGtal::DigitalSetBySTLVector<Domain>::isValid() const
539 // --------------- CDrawableWithBoard2D realization -------------------------
543 * @return the style name used for drawing this object.
545 template<typename Domain>
548 DGtal::DigitalSetBySTLVector<Domain>::className() const
550 return "DigitalSetBySTLVector";
553 ///////////////////////////////////////////////////////////////////////////////
554 // Implementation of inline function //
556 template <typename Domain>
559 DGtal::operator<< ( std::ostream & out,
560 const DigitalSetBySTLVector<Domain> & object )
562 object.selfDisplay( out );
567 ///////////////////////////////////////////////////////////////////////////////