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//-----------------------------------------------------------------------------
47template <unsigned int L, typename TWord>
49DGtal::Labels<L, TWord>::ConstEnumerator::
52//-----------------------------------------------------------------------------
53template <unsigned int L, typename TWord>
55DGtal::Labels<L, TWord>::ConstEnumerator::
57 : myWordAddress( 0 ), myLabel( 0 )
59//-----------------------------------------------------------------------------
60template <unsigned int L, typename TWord>
62DGtal::Labels<L, TWord>::ConstEnumerator::
63ConstEnumerator( 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//-----------------------------------------------------------------------------
80template <unsigned int L, typename TWord>
82DGtal::Labels<L, TWord>::ConstEnumerator::
83ConstEnumerator( const ConstEnumerator & other )
84 : myWordAddress( other.myWordAddress ), myWordLabel( other.myWordLabel ),
85 myLabel( other.myLabel ), myWord( other.myWord )
87//-----------------------------------------------------------------------------
88template <unsigned int L, typename TWord>
90typename DGtal::Labels<L, TWord>::ConstEnumerator::Self &
91DGtal::Labels<L, TWord>::ConstEnumerator::
92operator= ( const Self & other )
96 myWordAddress = other.myWordAddress;
97 myWordLabel = other.myWordLabel;
98 myLabel = other.myLabel;
99 myWord = other.myWord;
103//-----------------------------------------------------------------------------
104template <unsigned int L, typename TWord>
106typename DGtal::Labels<L, TWord>::ConstEnumerator::Reference
107DGtal::Labels<L, TWord>::ConstEnumerator::
112//-----------------------------------------------------------------------------
113template <unsigned int L, typename TWord>
115typename DGtal::Labels<L, TWord>::ConstEnumerator::Pointer
116DGtal::Labels<L, TWord>::ConstEnumerator::
121//-----------------------------------------------------------------------------
122template <unsigned int L, typename TWord>
124typename DGtal::Labels<L, TWord>::ConstEnumerator::Self&
125DGtal::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//-----------------------------------------------------------------------------
148template <unsigned int L, typename TWord>
150typename DGtal::Labels<L, TWord>::ConstEnumerator::Self
151DGtal::Labels<L, TWord>::ConstEnumerator::
154 ConstEnumerator tmp( *this );
158//-----------------------------------------------------------------------------
159template <unsigned int L, typename TWord>
162DGtal::Labels<L, TWord>::ConstEnumerator::
163operator==( const Self & other ) const
165 return ( myWordAddress == other.myWordAddress )
166 && ( myLabel == other.myLabel );
168//-----------------------------------------------------------------------------
169template <unsigned int L, typename TWord>
172DGtal::Labels<L, TWord>::ConstEnumerator::
173operator!=( const Self & other ) const
175 return ( myWordAddress != other.myWordAddress )
176 || ( myLabel != other.myLabel );
181//-----------------------------------------------------------------------------
182template <unsigned int L, typename TWord>
184typename DGtal::Labels<L, TWord>::SizeType
185DGtal::Labels<L, TWord>::_word( Label l )
187 return __DGTAL_LABEL_WORD_INDEX( l );
189//-----------------------------------------------------------------------------
190template <unsigned int L, typename TWord>
192typename DGtal::Labels<L, TWord>::SizeType
193DGtal::Labels<L, TWord>::_digit( Label l )
195 return __DGTAL_LABEL_DIGIT_INDEX( l );
197//-----------------------------------------------------------------------------
198template <unsigned int L, typename TWord>
200typename DGtal::Labels<L, TWord>::Word
201DGtal::Labels<L, TWord>::_mask( Label l )
203 return ( (Word) 1 ) << _digit( l );
205//-----------------------------------------------------------------------------
206template <unsigned int L, typename TWord>
208DGtal::Labels<L, TWord>::~Labels()
211//-----------------------------------------------------------------------------
212template <unsigned int L, typename TWord>
214DGtal::Labels<L, TWord>::Labels()
218//-----------------------------------------------------------------------------
219template <unsigned int L, typename TWord>
221DGtal::Labels<L, TWord>::Labels( const Self & other )
223 std::copy( other.myLabels, other.myLabels + __DGTAL_LABELS_NBWORDS,
226//-----------------------------------------------------------------------------
227template <unsigned int L, typename TWord>
229typename DGtal::Labels<L, TWord>::Self &
230DGtal::Labels<L, TWord>::operator=( const Self & other )
232 if ( this != &other )
233 std::copy( other.myLabels, other.myLabels + __DGTAL_LABELS_NBWORDS,
237//-----------------------------------------------------------------------------
238template <unsigned int L, typename TWord>
240typename DGtal::Labels<L, TWord>::Self &
241DGtal::Labels<L, TWord>::reset()
244 Word* p2 = myLabels + __DGTAL_LABELS_NBWORDS;
249//-----------------------------------------------------------------------------
250template <unsigned int L, typename TWord>
253DGtal::Labels<L, TWord>::test( Label l ) const
255 return _mask( l ) & myLabels[ _word( l ) ];
257//-----------------------------------------------------------------------------
258template <unsigned int L, typename TWord>
260typename DGtal::Labels<L, TWord>::Self &
261DGtal::Labels<L, TWord>::set( Label l, bool val )
264 myLabels[ _word( l ) ] |= _mask( l );
266 myLabels[ _word( l ) ] &= ~_mask( l );
269//-----------------------------------------------------------------------------
270template <unsigned int L, typename TWord>
272typename DGtal::Labels<L, TWord>::Self &
273DGtal::Labels<L, TWord>::reset( Label l )
275 myLabels[ _word( l ) ] &= ~_mask( l );
278//-----------------------------------------------------------------------------
279template <unsigned int L, typename TWord>
281typename DGtal::Labels<L, TWord>::Self &
282DGtal::Labels<L, TWord>::flip( Label l )
284 myLabels[ _word( l ) ] ^= _mask( l );
287//-----------------------------------------------------------------------------
288template <unsigned int L, typename TWord>
290typename DGtal::Labels<L, TWord>::SizeType
291DGtal::Labels<L, TWord>::
295 const Word* p1 = myLabels;
296 const Word* p2 = myLabels + __DGTAL_LABELS_NBWORDS;
298 n += Bits::nbSetBits( *p1++ );
301//-----------------------------------------------------------------------------
302template <unsigned int L, typename TWord>
304typename DGtal::Labels<L, TWord>::SizeType
305DGtal::Labels<L, TWord>::
310//-----------------------------------------------------------------------------
311template <unsigned int L, typename TWord>
314DGtal::Labels<L, TWord>::
315getLabels( 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//-----------------------------------------------------------------------------
337template <unsigned int L, typename TWord>
339typename DGtal::Labels<L, TWord>::SizeType
340DGtal::Labels<L, TWord>::
341index( 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//-----------------------------------------------------------------------------
354template <unsigned int L, typename TWord>
356typename DGtal::Labels<L, TWord>::ConstIterator
357DGtal::Labels<L, TWord>::
360 return ConstIterator( myLabels, 0 );
362//-----------------------------------------------------------------------------
363template <unsigned int L, typename TWord>
365typename DGtal::Labels<L, TWord>::ConstIterator
366DGtal::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.
380template <unsigned int L, typename TWord>
383DGtal::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.
402template <unsigned int L, typename TWord>
405DGtal::Labels<L, TWord>::isValid() const
412///////////////////////////////////////////////////////////////////////////////
413// Implementation of inline functions //
415template <unsigned int L, typename TWord>
418DGtal::operator<< ( std::ostream & out,
419 const Labels<L, TWord> & object )
421 object.selfDisplay( out );
426///////////////////////////////////////////////////////////////////////////////