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 //-----------------------------------------------------------------------------
44 template <typename TValue, unsigned int N, unsigned int M>
45 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
48 //-----------------------------------------------------------------------------
49 template <typename TValue, unsigned int N, unsigned int M>
50 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
52 : myIdx( 0 ), myValues( 0 )
54 //-----------------------------------------------------------------------------
55 template <typename TValue, unsigned int N, unsigned int M>
56 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
57 Iterator( const Self & other)
58 : myIdx( other.myIdx ), myNbValues( other.myNbValues ),
59 myValues( other.myValues ), myNext( other.myNext )
61 //-----------------------------------------------------------------------------
62 template <typename TValue, unsigned int N, unsigned int M>
63 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
64 Iterator( 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 //-----------------------------------------------------------------------------
118 template <typename TValue, unsigned int N, unsigned int M>
120 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self &
121 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
122 operator=( const Self & other )
124 if ( this != &other )
127 myNbValues = other.myNbValues;
128 myValues = other.myValues;
129 myNext = other.myNext;
133 //-----------------------------------------------------------------------------
134 template <typename TValue, unsigned int N, unsigned int M>
136 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Reference
137 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
140 ASSERT( myValues != 0 );
141 return myValues[ myIdx ];
143 //-----------------------------------------------------------------------------
144 template <typename TValue, unsigned int N, unsigned int M>
146 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Pointer
147 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
150 ASSERT( myValues != 0 );
151 return myValues + myIdx;
153 //-----------------------------------------------------------------------------
154 template <typename TValue, unsigned int N, unsigned int M>
156 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self &
157 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
160 return this->operator+=( 1 );
162 //-----------------------------------------------------------------------------
163 template <typename TValue, unsigned int N, unsigned int M>
165 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self
166 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
173 //-----------------------------------------------------------------------------
174 template <typename TValue, unsigned int N, unsigned int M>
177 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
178 operator==( const Self & other ) const
180 return ( myValues == other.myValues ) && ( myIdx == other.myIdx );
182 //-----------------------------------------------------------------------------
183 template <typename TValue, unsigned int N, unsigned int M>
186 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
187 operator!=( const Self & other ) const
189 return ( myValues != other.myValues ) || ( myIdx != other.myIdx );
191 //-----------------------------------------------------------------------------
192 template <typename TValue, unsigned int N, unsigned int M>
194 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Self &
195 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
196 operator+=( DifferenceType n )
199 while ( myIdx >= myNbValues )
208 myValues = myNext->values;
210 myNext = myNext->next;
214 //-----------------------------------------------------------------------------
215 template <typename TValue, unsigned int N, unsigned int M>
217 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::Reference
218 DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator::
219 operator[]( DifferenceType n ) const
226 ///////////////////////////////////////////////////////////////////////////////
227 // class IndexedListWithBlocks::ConstIterator
228 //-----------------------------------------------------------------------------
229 template <typename TValue, unsigned int N, unsigned int M>
230 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
233 //-----------------------------------------------------------------------------
234 template <typename TValue, unsigned int N, unsigned int M>
235 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
237 : myIdx( 0 ), myValues( 0 )
239 //-----------------------------------------------------------------------------
240 template <typename TValue, unsigned int N, unsigned int M>
241 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
242 ConstIterator( const Self & other)
243 : myIdx( other.myIdx ), myNbValues( other.myNbValues ),
244 myValues( other.myValues ), myNext( other.myNext )
246 //-----------------------------------------------------------------------------
247 template <typename TValue, unsigned int N, unsigned int M>
248 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
249 ConstIterator( 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 //-----------------------------------------------------------------------------
303 template <typename TValue, unsigned int N, unsigned int M>
305 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self &
306 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
307 operator=( const Self & other )
309 if ( this != &other )
312 myNbValues = other.myNbValues;
313 myValues = other.myValues;
314 myNext = other.myNext;
318 //-----------------------------------------------------------------------------
319 template <typename TValue, unsigned int N, unsigned int M>
321 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Reference
322 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
325 ASSERT( myValues != 0 );
326 return myValues[ myIdx ];
328 //-----------------------------------------------------------------------------
329 template <typename TValue, unsigned int N, unsigned int M>
331 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Pointer
332 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
335 ASSERT( myValues != 0 );
336 return myValues + myIdx;
338 //-----------------------------------------------------------------------------
339 template <typename TValue, unsigned int N, unsigned int M>
341 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self &
342 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
345 return this->operator+=( 1 );
347 //-----------------------------------------------------------------------------
348 template <typename TValue, unsigned int N, unsigned int M>
350 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self
351 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
358 //-----------------------------------------------------------------------------
359 template <typename TValue, unsigned int N, unsigned int M>
362 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
363 operator==( const Self & other ) const
365 return ( myValues == other.myValues ) && ( myIdx == other.myIdx );
367 //-----------------------------------------------------------------------------
368 template <typename TValue, unsigned int N, unsigned int M>
371 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
372 operator!=( const Self & other ) const
374 return ( myValues != other.myValues ) || ( myIdx != other.myIdx );
376 //-----------------------------------------------------------------------------
377 template <typename TValue, unsigned int N, unsigned int M>
379 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Self &
380 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
381 operator+=( DifferenceType n )
384 while ( myIdx >= myNbValues )
393 myValues = myNext->values;
395 myNext = myNext->next;
399 //-----------------------------------------------------------------------------
400 template <typename TValue, unsigned int N, unsigned int M>
402 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::Reference
403 DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator::
404 operator[]( DifferenceType n ) const
412 //-----------------------------------------------------------------------------
413 template <typename TValue, unsigned int N, unsigned int M>
415 DGtal::IndexedListWithBlocks<TValue, N, M>::
416 IndexedListWithBlocks()
417 { // default constructor of myFirstBlock is automatically called.
419 //-----------------------------------------------------------------------------
420 template <typename TValue, unsigned int N, unsigned int M>
422 DGtal::IndexedListWithBlocks<TValue, N, M>::
423 ~IndexedListWithBlocks()
427 //-----------------------------------------------------------------------------
428 template <typename TValue, unsigned int N, unsigned int M>
430 DGtal::IndexedListWithBlocks<TValue, N, M>::
431 IndexedListWithBlocks( 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 //-----------------------------------------------------------------------------
445 template <typename TValue, unsigned int N, unsigned int M>
447 DGtal::IndexedListWithBlocks<TValue, N, M> &
448 DGtal::IndexedListWithBlocks<TValue, N, M>::
449 operator=( 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 //-----------------------------------------------------------------------------
469 template <typename TValue, unsigned int N, unsigned int M>
472 DGtal::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 //-----------------------------------------------------------------------------
486 template <typename TValue, unsigned int N, unsigned int M>
488 typename DGtal::IndexedListWithBlocks<TValue, N, M>::SizeType
489 DGtal::IndexedListWithBlocks<TValue, N, M>::
492 return myFirstBlock.size;
494 //-----------------------------------------------------------------------------
495 template <typename TValue, unsigned int N, unsigned int M>
498 DGtal::IndexedListWithBlocks<TValue, N, M>::
503 //-----------------------------------------------------------------------------
504 template <typename TValue, unsigned int N, unsigned int M>
506 typename DGtal::IndexedListWithBlocks<TValue, N, M>::SizeType
507 DGtal::IndexedListWithBlocks<TValue, N, M>::
510 return SizeType( -1 ) / (2*sizeof( Value ));
512 //-----------------------------------------------------------------------------
513 template <typename TValue, unsigned int N, unsigned int M>
515 typename DGtal::IndexedListWithBlocks<TValue, N, M>::SizeType
516 DGtal::IndexedListWithBlocks<TValue, N, M>::
519 return ( size() <= (N+1) )
521 : ( 1 + ( size() - 1 - N ) / M ) * M + N;
523 //-----------------------------------------------------------------------------
524 template <typename TValue, unsigned int N, unsigned int M>
526 const typename DGtal::IndexedListWithBlocks<TValue, N, M>::Value &
527 DGtal::IndexedListWithBlocks<TValue, N, M>::
528 operator[]( 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 //-----------------------------------------------------------------------------
546 template <typename TValue, unsigned int N, unsigned int M>
548 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Value &
549 DGtal::IndexedListWithBlocks<TValue, N, M>::
550 operator[]( 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 //-----------------------------------------------------------------------------
568 template <typename TValue, unsigned int N, unsigned int M>
571 DGtal::IndexedListWithBlocks<TValue, N, M>::
572 insert( unsigned int idx, const Value & value )
574 ASSERT( idx <= size() ); // end is ok.
575 myFirstBlock.insert( idx, value );
577 //-----------------------------------------------------------------------------
578 template <typename TValue, unsigned int N, unsigned int M>
581 DGtal::IndexedListWithBlocks<TValue, N, M>::
582 erase( unsigned int idx )
584 ASSERT( idx < size() ); // end is not ok.
585 myFirstBlock.erase( idx );
589 //-----------------------------------------------------------------------------
590 template <typename TValue, unsigned int N, unsigned int M>
592 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator
593 DGtal::IndexedListWithBlocks<TValue, N, M>::
596 return Iterator( myFirstBlock, 0 );
598 //-----------------------------------------------------------------------------
599 template <typename TValue, unsigned int N, unsigned int M>
601 typename DGtal::IndexedListWithBlocks<TValue, N, M>::Iterator
602 DGtal::IndexedListWithBlocks<TValue, N, M>::
605 return Iterator( myFirstBlock, size() );
607 //-----------------------------------------------------------------------------
608 template <typename TValue, unsigned int N, unsigned int M>
610 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator
611 DGtal::IndexedListWithBlocks<TValue, N, M>::
614 return ConstIterator( myFirstBlock, 0 );
616 //-----------------------------------------------------------------------------
617 template <typename TValue, unsigned int N, unsigned int M>
619 typename DGtal::IndexedListWithBlocks<TValue, N, M>::ConstIterator
620 DGtal::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.
633 template <typename TValue, unsigned int N, unsigned int M>
636 DGtal::IndexedListWithBlocks<TValue, N, M>::
637 selfDisplay( 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.
662 template <typename TValue, unsigned int N, unsigned int M>
665 DGtal::IndexedListWithBlocks<TValue, N, M>::isValid() const
672 ///////////////////////////////////////////////////////////////////////////////
673 // Implementation of inline functions //
675 template <typename TValue, unsigned int N, unsigned int M>
678 DGtal::operator<< ( std::ostream & out,
679 const IndexedListWithBlocks<TValue, N, M> & object )
681 object.selfDisplay( out );
686 ///////////////////////////////////////////////////////////////////////////////