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 IndexedListWithBlocks.ih
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 IndexedListWithBlocks.h
26 * This file is part of the DGtal library.
30//////////////////////////////////////////////////////////////////////////////
32//////////////////////////////////////////////////////////////////////////////
34///////////////////////////////////////////////////////////////////////////////
35// IMPLEMENTATION of inline methods.
36///////////////////////////////////////////////////////////////////////////////
38///////////////////////////////////////////////////////////////////////////////
39// ----------------------- Standard services ------------------------------
41///////////////////////////////////////////////////////////////////////////////
42// class IndexedListWithBlocks::Iterator
43//-----------------------------------------------------------------------------
44template <typename TValue, unsigned int N, unsigned int M>
45DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
48//-----------------------------------------------------------------------------
49template <typename TValue, unsigned int N, unsigned int M>
50DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
52 : myIdx( 0 ), myValues( 0 )
54//-----------------------------------------------------------------------------
55template <typename TValue, unsigned int N, unsigned int M>
56DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
57Iterator( const Self & other)
58 : myIdx( other.myIdx ), myNbValues( other.myNbValues ),
59 myValues( other.myValues ), myNext( other.myNext )
61//-----------------------------------------------------------------------------
62template <typename TValue, unsigned int N, unsigned int M>
63DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
64Iterator( FirstBlock & block, unsigned int idx )
66 ASSERT( idx <= block.size );
67 if ( block.size <= N+1 )
73 myValues = block.values;
86 ASSERT( block.data.nextBlock != 0 );
87 myNext = block.data.nextBlock;
92 myValues = block.values;
100 myNext = ( myNext != 0 ) ? myNext->next : 0;
112 myValues = myNext->values;
117//-----------------------------------------------------------------------------
118template <typename TValue, unsigned int N, unsigned int M>
120typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self &
121DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
122operator=( const Self & other )
124 if ( this != &other )
127 myNbValues = other.myNbValues;
128 myValues = other.myValues;
129 myNext = other.myNext;
133//-----------------------------------------------------------------------------
134template <typename TValue, unsigned int N, unsigned int M>
136typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Reference
137DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
140 ASSERT( myValues != 0 );
141 return myValues[ myIdx ];
143//-----------------------------------------------------------------------------
144template <typename TValue, unsigned int N, unsigned int M>
146typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Pointer
147DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
150 ASSERT( myValues != 0 );
151 return myValues + myIdx;
153//-----------------------------------------------------------------------------
154template <typename TValue, unsigned int N, unsigned int M>
156typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self &
157DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
160 return this->operator+=( 1 );
162//-----------------------------------------------------------------------------
163template <typename TValue, unsigned int N, unsigned int M>
165typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self
166DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
173//-----------------------------------------------------------------------------
174template <typename TValue, unsigned int N, unsigned int M>
177DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
178operator==( const Self & other ) const
180 return ( myValues == other.myValues ) && ( myIdx == other.myIdx );
182//-----------------------------------------------------------------------------
183template <typename TValue, unsigned int N, unsigned int M>
186DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
187operator!=( const Self & other ) const
189 return ( myValues != other.myValues ) || ( myIdx != other.myIdx );
191//-----------------------------------------------------------------------------
192template <typename TValue, unsigned int N, unsigned int M>
194typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self &
195DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
196operator+=( DifferenceType n )
199 while ( myIdx >= myNbValues )
208 myValues = myNext->values;
210 myNext = myNext->next;
214//-----------------------------------------------------------------------------
215template <typename TValue, unsigned int N, unsigned int M>
217typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Reference
218DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
219operator[]( DifferenceType n ) const
226///////////////////////////////////////////////////////////////////////////////
227// class IndexedListWithBlocks::ConstIterator
228//-----------------------------------------------------------------------------
229template <typename TValue, unsigned int N, unsigned int M>
230DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
233//-----------------------------------------------------------------------------
234template <typename TValue, unsigned int N, unsigned int M>
235DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
237 : myIdx( 0 ), myValues( 0 )
239//-----------------------------------------------------------------------------
240template <typename TValue, unsigned int N, unsigned int M>
241DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
242ConstIterator( const Self & other)
243 : myIdx( other.myIdx ), myNbValues( other.myNbValues ),
244 myValues( other.myValues ), myNext( other.myNext )
246//-----------------------------------------------------------------------------
247template <typename TValue, unsigned int N, unsigned int M>
248DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
249ConstIterator( const FirstBlock & block, unsigned int idx )
251 ASSERT( idx <= block.size );
252 if ( block.size <= N+1 )
258 myValues = block.values;
271 ASSERT( block.data.nextBlock != 0 );
272 myNext = block.data.nextBlock;
277 myValues = block.values;
285 myNext = ( myNext != 0 ) ? myNext->next : 0;
297 myValues = myNext->values;
302//-----------------------------------------------------------------------------
303template <typename TValue, unsigned int N, unsigned int M>
305typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self &
306DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
307operator=( const Self & other )
309 if ( this != &other )
312 myNbValues = other.myNbValues;
313 myValues = other.myValues;
314 myNext = other.myNext;
318//-----------------------------------------------------------------------------
319template <typename TValue, unsigned int N, unsigned int M>
321typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Reference
322DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
325 ASSERT( myValues != 0 );
326 return myValues[ myIdx ];
328//-----------------------------------------------------------------------------
329template <typename TValue, unsigned int N, unsigned int M>
331typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Pointer
332DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
335 ASSERT( myValues != 0 );
336 return myValues + myIdx;
338//-----------------------------------------------------------------------------
339template <typename TValue, unsigned int N, unsigned int M>
341typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self &
342DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
345 return this->operator+=( 1 );
347//-----------------------------------------------------------------------------
348template <typename TValue, unsigned int N, unsigned int M>
350typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self
351DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
358//-----------------------------------------------------------------------------
359template <typename TValue, unsigned int N, unsigned int M>
362DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
363operator==( const Self & other ) const
365 return ( myValues == other.myValues ) && ( myIdx == other.myIdx );
367//-----------------------------------------------------------------------------
368template <typename TValue, unsigned int N, unsigned int M>
371DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
372operator!=( const Self & other ) const
374 return ( myValues != other.myValues ) || ( myIdx != other.myIdx );
376//-----------------------------------------------------------------------------
377template <typename TValue, unsigned int N, unsigned int M>
379typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self &
380DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
381operator+=( DifferenceType n )
384 while ( myIdx >= myNbValues )
393 myValues = myNext->values;
395 myNext = myNext->next;
399//-----------------------------------------------------------------------------
400template <typename TValue, unsigned int N, unsigned int M>
402typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Reference
403DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
404operator[]( DifferenceType n ) const
412//-----------------------------------------------------------------------------
413template <typename TValue, unsigned int N, unsigned int M>
415DGtal::IndexedListWithBlocks<TValue, N, M>::
416IndexedListWithBlocks()
417{ // default constructor of myFirstBlock is automatically called.
419//-----------------------------------------------------------------------------
420template <typename TValue, unsigned int N, unsigned int M>
422DGtal::IndexedListWithBlocks<TValue, N, M>::
423~IndexedListWithBlocks()
427//-----------------------------------------------------------------------------
428template <typename TValue, unsigned int N, unsigned int M>
430DGtal::IndexedListWithBlocks<TValue, N, M>::
431IndexedListWithBlocks( const IndexedListWithBlocks & other )
432 : myFirstBlock( other.myFirstBlock )
434 unsigned int s = N + 1; // there is one more stored value in the last block.
435 const AnyBlock* nextBlock = other.myFirstBlock.data.nextBlock;
436 AnyBlock** currentPointer = & myFirstBlock.data.nextBlock;
437 while ( s < myFirstBlock.size )
439 *currentPointer = new AnyBlock( *nextBlock );
441 currentPointer = & ( currentPointer->data.nextBlock );
444//-----------------------------------------------------------------------------
445template <typename TValue, unsigned int N, unsigned int M>
447DGtal::IndexedListWithBlocks<TValue, N, M> &
448DGtal::IndexedListWithBlocks<TValue, N, M>::
449operator=( const IndexedListWithBlocks & other )
451 if ( this != &other )
454 myFirstBlock = other.myFirstBlock;
455 // there is one more stored value in the last block.
456 unsigned int s = N + 1;
457 const AnyBlock* nextBlock = other.myFirstBlock.data.nextBlock;
458 AnyBlock** currentPointer = & myFirstBlock.data.nextBlock;
459 while ( s < myFirstBlock.size )
461 *currentPointer = new AnyBlock( *nextBlock );
463 currentPointer = & ( (*currentPointer)->next );
468//-----------------------------------------------------------------------------
469template <typename TValue, unsigned int N, unsigned int M>
472DGtal::IndexedListWithBlocks<TValue, N, M>::
475 AnyBlock* nextBlock = myFirstBlock.data.nextBlock;
476 while ( nextBlock != 0 )
478 AnyBlock* ptr = nextBlock;
479 nextBlock = nextBlock->next;
482 myFirstBlock.size = 0;
483 myFirstBlock.data.nextBlock = 0;
485//-----------------------------------------------------------------------------
486template <typename TValue, unsigned int N, unsigned int M>
488typename DGtal::IndexedListWithBlocks<TValue, N, M>::SizeType
489DGtal::IndexedListWithBlocks<TValue, N, M>::
492 return myFirstBlock.size;
494//-----------------------------------------------------------------------------
495template <typename TValue, unsigned int N, unsigned int M>
498DGtal::IndexedListWithBlocks<TValue, N, M>::
503//-----------------------------------------------------------------------------
504template <typename TValue, unsigned int N, unsigned int M>
506typename DGtal::IndexedListWithBlocks<TValue, N, M>::SizeType
507DGtal::IndexedListWithBlocks<TValue, N, M>::
510 return SizeType( -1 ) / (2*sizeof( Value ));
512//-----------------------------------------------------------------------------
513template <typename TValue, unsigned int N, unsigned int M>
515typename DGtal::IndexedListWithBlocks<TValue, N, M>::SizeType
516DGtal::IndexedListWithBlocks<TValue, N, M>::
519 return ( size() <= (N+1) )
521 : ( 1 + ( size() - 1 - N ) / M ) * M + N;
523//-----------------------------------------------------------------------------
524template <typename TValue, unsigned int N, unsigned int M>
526const typename DGtal::IndexedListWithBlocks<TValue, N, M>::Value &
527DGtal::IndexedListWithBlocks<TValue, N, M>::
528operator[]( unsigned int idx ) const
530 ASSERT( idx < size() );
532 return myFirstBlock.values[ idx ];
533 else if ( ( idx == N ) && ( size() == N+1 ) )
534 return myFirstBlock.data.lastValue;
535 const AnyBlock* ptr = myFirstBlock.data.nextBlock;
543 return ptr->values[ idx ];
545//-----------------------------------------------------------------------------
546template <typename TValue, unsigned int N, unsigned int M>
548typename DGtal::IndexedListWithBlocks<TValue, N, M>::Value &
549DGtal::IndexedListWithBlocks<TValue, N, M>::
550operator[]( unsigned int idx )
552 ASSERT( idx < size() );
554 return myFirstBlock.values[ idx ];
555 else if ( ( idx == N ) && ( size() == N+1 ) )
556 return myFirstBlock.data.lastValue;
557 AnyBlock* ptr = myFirstBlock.data.nextBlock;
565 return ptr->values[ idx ];
567//-----------------------------------------------------------------------------
568template <typename TValue, unsigned int N, unsigned int M>
571DGtal::IndexedListWithBlocks<TValue, N, M>::
572insert( unsigned int idx, const Value & value )
574 ASSERT( idx <= size() ); // end is ok.
575 myFirstBlock.insert( idx, value );
577//-----------------------------------------------------------------------------
578template <typename TValue, unsigned int N, unsigned int M>
581DGtal::IndexedListWithBlocks<TValue, N, M>::
582erase( unsigned int idx )
584 ASSERT( idx < size() ); // end is not ok.
585 myFirstBlock.erase( idx );
589//-----------------------------------------------------------------------------
590template <typename TValue, unsigned int N, unsigned int M>
592typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator
593DGtal::IndexedListWithBlocks<TValue, N, M>::
596 return Iterator( myFirstBlock, 0 );
598//-----------------------------------------------------------------------------
599template <typename TValue, unsigned int N, unsigned int M>
601typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator
602DGtal::IndexedListWithBlocks<TValue, N, M>::
605 return Iterator( myFirstBlock, size() );
607//-----------------------------------------------------------------------------
608template <typename TValue, unsigned int N, unsigned int M>
610typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator
611DGtal::IndexedListWithBlocks<TValue, N, M>::
614 return ConstIterator( myFirstBlock, 0 );
616//-----------------------------------------------------------------------------
617template <typename TValue, unsigned int N, unsigned int M>
619typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator
620DGtal::IndexedListWithBlocks<TValue, N, M>::
623 return ConstIterator( myFirstBlock, size() );
626///////////////////////////////////////////////////////////////////////////////
627// Interface - public :
630 * Writes/Displays the object on an output stream.
631 * @param out the output stream where the object is written.
633template <typename TValue, unsigned int N, unsigned int M>
636DGtal::IndexedListWithBlocks<TValue, N, M>::
637selfDisplay( std::ostream & out ) const
639 if ( size() == 0 ) out << "()";
642 ConstIterator it = begin();
643 ConstIterator it_end = end();
644 ConstIterator it_last = it;
648 for ( ; it != it_end; ++it )
650 out << ( ( it_last.myValues == it.myValues ) ? ',' : ';' );
659 * Checks the validity/consistency of the object.
660 * @return 'true' if the object is valid, 'false' otherwise.
662template <typename TValue, unsigned int N, unsigned int M>
665DGtal::IndexedListWithBlocks<TValue, N, M>::isValid() const
672///////////////////////////////////////////////////////////////////////////////
673// Implementation of inline functions //
675template <typename TValue, unsigned int N, unsigned int M>
678DGtal::operator<< ( std::ostream & out,
679 const IndexedListWithBlocks<TValue, N, M> & object )
681 object.selfDisplay( out );
686///////////////////////////////////////////////////////////////////////////////