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/>.
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in Labels.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
34 #include "DGtal/base/Bits.h"
35 //////////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////////
38 // IMPLEMENTATION of inline methods.
39 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 // class DGtal::Labels<L, TWord>::ConstEnumerator
44 ///////////////////////////////////////////////////////////////////////////////
45 // ----------------------- Standard services ------------------------------
46 //-----------------------------------------------------------------------------
47 template <unsigned int L, typename TWord>
49 DGtal::Labels<L, TWord>::ConstEnumerator::
52 //-----------------------------------------------------------------------------
53 template <unsigned int L, typename TWord>
55 DGtal::Labels<L, TWord>::ConstEnumerator::
57 : myWordAddress( 0 ), myLabel( 0 )
59 //-----------------------------------------------------------------------------
60 template <unsigned int L, typename TWord>
62 DGtal::Labels<L, TWord>::ConstEnumerator::
63 ConstEnumerator( const Word* address, SizeType firstWord )
64 : myWordAddress( address + firstWord ),
65 myWordLabel( firstWord * __DGTAL_WORD_NBDIGITS )
67 ASSERT( firstWord <= __DGTAL_LABELS_NBWORDS );
68 if ( firstWord != __DGTAL_LABELS_NBWORDS )
70 myWord = *myWordAddress++;
71 this->operator++(); // find first bit
76 myLabel = std::numeric_limits<Label>::max();
79 //-----------------------------------------------------------------------------
80 template <unsigned int L, typename TWord>
82 DGtal::Labels<L, TWord>::ConstEnumerator::
83 ConstEnumerator( const ConstEnumerator & other )
84 : myWordAddress( other.myWordAddress ), myWordLabel( other.myWordLabel ),
85 myLabel( other.myLabel ), myWord( other.myWord )
87 //-----------------------------------------------------------------------------
88 template <unsigned int L, typename TWord>
90 typename DGtal::Labels<L, TWord>::ConstEnumerator::Self &
91 DGtal::Labels<L, TWord>::ConstEnumerator::
92 operator= ( const Self & other )
96 myWordAddress = other.myWordAddress;
97 myWordLabel = other.myWordLabel;
98 myLabel = other.myLabel;
99 myWord = other.myWord;
103 //-----------------------------------------------------------------------------
104 template <unsigned int L, typename TWord>
106 typename DGtal::Labels<L, TWord>::ConstEnumerator::Reference
107 DGtal::Labels<L, TWord>::ConstEnumerator::
112 //-----------------------------------------------------------------------------
113 template <unsigned int L, typename TWord>
115 typename DGtal::Labels<L, TWord>::ConstEnumerator::Pointer
116 DGtal::Labels<L, TWord>::ConstEnumerator::
121 //-----------------------------------------------------------------------------
122 template <unsigned int L, typename TWord>
124 typename DGtal::Labels<L, TWord>::ConstEnumerator::Self&
125 DGtal::Labels<L, TWord>::ConstEnumerator::
128 ASSERT( ( myWordLabel < ( __DGTAL_LABELS_NBWORDS
129 * __DGTAL_WORD_NBDIGITS ) ) );
130 while ( myWord == 0 )
132 myWordLabel += __DGTAL_WORD_NBDIGITS;
133 if ( myWordLabel == ( __DGTAL_LABELS_NBWORDS
134 * __DGTAL_WORD_NBDIGITS ) )
136 myLabel = std::numeric_limits<Label>::max();
139 myWord = *myWordAddress++;
141 ASSERT( myWord != 0 );
142 Word fsb = Bits::firstSetBit( myWord );
143 myLabel = myWordLabel + Bits::leastSignificantBit( fsb );
147 //-----------------------------------------------------------------------------
148 template <unsigned int L, typename TWord>
150 typename DGtal::Labels<L, TWord>::ConstEnumerator::Self
151 DGtal::Labels<L, TWord>::ConstEnumerator::
154 ConstEnumerator tmp( *this );
158 //-----------------------------------------------------------------------------
159 template <unsigned int L, typename TWord>
162 DGtal::Labels<L, TWord>::ConstEnumerator::
163 operator==( const Self & other ) const
165 return ( myWordAddress == other.myWordAddress )
166 && ( myLabel == other.myLabel );
168 //-----------------------------------------------------------------------------
169 template <unsigned int L, typename TWord>
172 DGtal::Labels<L, TWord>::ConstEnumerator::
173 operator!=( const Self & other ) const
175 return ( myWordAddress != other.myWordAddress )
176 || ( myLabel != other.myLabel );
181 //-----------------------------------------------------------------------------
182 template <unsigned int L, typename TWord>
184 typename DGtal::Labels<L, TWord>::SizeType
185 DGtal::Labels<L, TWord>::_word( Label l )
187 return __DGTAL_LABEL_WORD_INDEX( l );
189 //-----------------------------------------------------------------------------
190 template <unsigned int L, typename TWord>
192 typename DGtal::Labels<L, TWord>::SizeType
193 DGtal::Labels<L, TWord>::_digit( Label l )
195 return __DGTAL_LABEL_DIGIT_INDEX( l );
197 //-----------------------------------------------------------------------------
198 template <unsigned int L, typename TWord>
200 typename DGtal::Labels<L, TWord>::Word
201 DGtal::Labels<L, TWord>::_mask( Label l )
203 return ( (Word) 1 ) << _digit( l );
205 //-----------------------------------------------------------------------------
206 template <unsigned int L, typename TWord>
208 DGtal::Labels<L, TWord>::~Labels()
211 //-----------------------------------------------------------------------------
212 template <unsigned int L, typename TWord>
214 DGtal::Labels<L, TWord>::Labels()
218 //-----------------------------------------------------------------------------
219 template <unsigned int L, typename TWord>
221 DGtal::Labels<L, TWord>::Labels( const Self & other )
223 std::copy( other.myLabels, other.myLabels + __DGTAL_LABELS_NBWORDS,
226 //-----------------------------------------------------------------------------
227 template <unsigned int L, typename TWord>
229 typename DGtal::Labels<L, TWord>::Self &
230 DGtal::Labels<L, TWord>::operator=( const Self & other )
232 if ( this != &other )
233 std::copy( other.myLabels, other.myLabels + __DGTAL_LABELS_NBWORDS,
237 //-----------------------------------------------------------------------------
238 template <unsigned int L, typename TWord>
240 typename DGtal::Labels<L, TWord>::Self &
241 DGtal::Labels<L, TWord>::reset()
244 Word* p2 = myLabels + __DGTAL_LABELS_NBWORDS;
249 //-----------------------------------------------------------------------------
250 template <unsigned int L, typename TWord>
253 DGtal::Labels<L, TWord>::test( Label l ) const
255 return _mask( l ) & myLabels[ _word( l ) ];
257 //-----------------------------------------------------------------------------
258 template <unsigned int L, typename TWord>
260 typename DGtal::Labels<L, TWord>::Self &
261 DGtal::Labels<L, TWord>::set( Label l, bool val )
264 myLabels[ _word( l ) ] |= _mask( l );
266 myLabels[ _word( l ) ] &= ~_mask( l );
269 //-----------------------------------------------------------------------------
270 template <unsigned int L, typename TWord>
272 typename DGtal::Labels<L, TWord>::Self &
273 DGtal::Labels<L, TWord>::reset( Label l )
275 myLabels[ _word( l ) ] &= ~_mask( l );
278 //-----------------------------------------------------------------------------
279 template <unsigned int L, typename TWord>
281 typename DGtal::Labels<L, TWord>::Self &
282 DGtal::Labels<L, TWord>::flip( Label l )
284 myLabels[ _word( l ) ] ^= _mask( l );
287 //-----------------------------------------------------------------------------
288 template <unsigned int L, typename TWord>
290 typename DGtal::Labels<L, TWord>::SizeType
291 DGtal::Labels<L, TWord>::
295 const Word* p1 = myLabels;
296 const Word* p2 = myLabels + __DGTAL_LABELS_NBWORDS;
298 n += Bits::nbSetBits( *p1++ );
301 //-----------------------------------------------------------------------------
302 template <unsigned int L, typename TWord>
304 typename DGtal::Labels<L, TWord>::SizeType
305 DGtal::Labels<L, TWord>::
310 //-----------------------------------------------------------------------------
311 template <unsigned int L, typename TWord>
314 DGtal::Labels<L, TWord>::
315 getLabels( std::vector<Label> & labels ) const
320 const Word* p1 = myLabels;
321 const Word* p2 = myLabels + __DGTAL_LABELS_NBWORDS;
326 while ( w ) // extract labels within word
328 fsb = Bits::firstSetBit( w );
329 labels.push_back( l + Bits::leastSignificantBit( fsb ) );
331 ASSERT( index( labels.back() ) == ( labels.size() - 1 ) );
333 l += __DGTAL_WORD_NBDIGITS;
336 //-----------------------------------------------------------------------------
337 template <unsigned int L, typename TWord>
339 typename DGtal::Labels<L, TWord>::SizeType
340 DGtal::Labels<L, TWord>::
341 index( Label l ) const
344 const Word* p1 = myLabels;
345 const Word* p2 = myLabels + _word( l );
348 i += Bits::nbSetBits( *p1++ );
349 return ( _mask( l ) & *p1 )
350 ? i + Bits::indexInSetBits( *p1, _digit( l ) ) - 1
353 //-----------------------------------------------------------------------------
354 template <unsigned int L, typename TWord>
356 typename DGtal::Labels<L, TWord>::ConstIterator
357 DGtal::Labels<L, TWord>::
360 return ConstIterator( myLabels, 0 );
362 //-----------------------------------------------------------------------------
363 template <unsigned int L, typename TWord>
365 typename DGtal::Labels<L, TWord>::ConstIterator
366 DGtal::Labels<L, TWord>::
369 return ConstIterator( myLabels, __DGTAL_LABELS_NBWORDS );
373 ///////////////////////////////////////////////////////////////////////////////
374 // Interface - public :
377 * Writes/Displays the object on an output stream.
378 * @param out the output stream where the object is written.
380 template <unsigned int L, typename TWord>
383 DGtal::Labels<L, TWord>::selfDisplay ( std::ostream & out ) const
385 std::vector<Label> v;
386 this->getLabels( v );
391 out << "(" << v[ 0 ];
392 for ( SizeType i = 1; i < v.size(); ++i )
393 out << "," << v[ i ];
399 * Checks the validity/consistency of the object.
400 * @return 'true' if the object is valid, 'false' otherwise.
402 template <unsigned int L, typename TWord>
405 DGtal::Labels<L, TWord>::isValid() const
412 ///////////////////////////////////////////////////////////////////////////////
413 // Implementation of inline functions //
415 template <unsigned int L, typename TWord>
418 DGtal::operator<< ( std::ostream & out,
419 const Labels<L, TWord> & object )
421 object.selfDisplay( out );
426 ///////////////////////////////////////////////////////////////////////////////