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 LabelledMap.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 LabelledMap.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 LabelledMap::BlockIterator
43 //-----------------------------------------------------------------------------
44 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
45 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
48 //-----------------------------------------------------------------------------
49 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
50 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
52 : myIdx( 0 ), myDatas( 0 )
54 //-----------------------------------------------------------------------------
55 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
56 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
57 BlockIterator( const Self & other)
58 : myIdx( other.myIdx ), myNbDatas( other.myNbDatas ),
59 myDatas( other.myDatas ), myNext( other.myNext )
61 //-----------------------------------------------------------------------------
62 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
63 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
64 BlockIterator( __FirstBlock & block, unsigned int idx, unsigned int size )
66 ASSERT( idx <= size );
73 myDatas = block.datas;
86 ASSERT( block.data.nextBlock != 0 );
87 myNext = block.data.nextBlock;
92 myDatas = block.datas;
100 myNext = ( myNext != 0 ) ? myNext->next : 0;
112 myDatas = myNext->datas;
117 //-----------------------------------------------------------------------------
118 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
120 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self &
121 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
122 operator=( const Self & other )
124 if ( this != &other )
127 myNbDatas = other.myNbDatas;
128 myDatas = other.myDatas;
129 myNext = other.myNext;
133 //-----------------------------------------------------------------------------
134 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
136 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Reference
137 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
140 ASSERT( myDatas != 0 );
141 return myDatas[ myIdx ];
143 //-----------------------------------------------------------------------------
144 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
146 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Pointer
147 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
150 ASSERT( myDatas != 0 );
151 return myDatas + myIdx;
153 //-----------------------------------------------------------------------------
154 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
156 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self &
157 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
160 return this->operator+=( 1 );
162 //-----------------------------------------------------------------------------
163 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
165 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self
166 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
173 //-----------------------------------------------------------------------------
174 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
177 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
178 operator==( const Self & other ) const
180 return ( myDatas == other.myDatas ) && ( myIdx == other.myIdx );
182 //-----------------------------------------------------------------------------
183 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
186 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
187 operator!=( const Self & other ) const
189 return ( myDatas != other.myDatas ) || ( myIdx != other.myIdx );
191 //-----------------------------------------------------------------------------
192 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
194 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self &
195 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
196 operator+=( DifferenceType n )
199 while ( myIdx >= myNbDatas )
208 myDatas = myNext->datas;
210 myNext = myNext->next;
214 //-----------------------------------------------------------------------------
215 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
217 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Reference
218 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
219 operator[]( DifferenceType n ) const
226 ///////////////////////////////////////////////////////////////////////////////
227 // class LabelledMap::BlockConstIterator
228 //-----------------------------------------------------------------------------
229 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
230 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
231 ~BlockConstIterator()
233 //-----------------------------------------------------------------------------
234 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
235 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
237 : myIdx( 0 ), myDatas( 0 )
239 //-----------------------------------------------------------------------------
240 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
241 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
242 BlockConstIterator( const Self & other)
243 : myIdx( other.myIdx ), myNbDatas( other.myNbDatas ),
244 myDatas( other.myDatas ), myNext( other.myNext )
246 //-----------------------------------------------------------------------------
247 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
248 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
249 BlockConstIterator( const __FirstBlock & block, unsigned int idx, unsigned int size )
251 ASSERT( idx <= size );
258 myDatas = block.datas;
271 ASSERT( block.data.nextBlock != 0 );
272 myNext = block.data.nextBlock;
277 myDatas = block.datas;
285 myNext = ( myNext != 0 ) ? myNext->next : 0;
297 myDatas = myNext->datas;
302 //-----------------------------------------------------------------------------
303 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
305 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self &
306 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
307 operator=( const Self & other )
309 if ( this != &other )
312 myNbDatas = other.myNbDatas;
313 myDatas = other.myDatas;
314 myNext = other.myNext;
318 //-----------------------------------------------------------------------------
319 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
321 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Reference
322 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
325 ASSERT( myDatas != 0 );
326 return myDatas[ myIdx ];
328 //-----------------------------------------------------------------------------
329 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
331 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Pointer
332 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
335 ASSERT( myDatas != 0 );
336 return myDatas + myIdx;
338 //-----------------------------------------------------------------------------
339 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
341 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self &
342 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
345 return this->operator+=( 1 );
347 //-----------------------------------------------------------------------------
348 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
350 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self
351 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
358 //-----------------------------------------------------------------------------
359 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
362 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
363 operator==( const Self & other ) const
365 return ( myDatas == other.myDatas ) && ( myIdx == other.myIdx );
367 //-----------------------------------------------------------------------------
368 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
371 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
372 operator!=( const Self & other ) const
374 return ( myDatas != other.myDatas ) || ( myIdx != other.myIdx );
376 //-----------------------------------------------------------------------------
377 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
379 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self &
380 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
381 operator+=( DifferenceType n )
384 while ( myIdx >= myNbDatas )
393 myDatas = myNext->datas;
395 myNext = myNext->next;
399 //-----------------------------------------------------------------------------
400 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
402 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Reference
403 DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
404 operator[]( DifferenceType n ) const
411 ///////////////////////////////////////////////////////////////////////////////
412 // class LabelledMap::ConstIterator
413 //-----------------------------------------------------------------------------
414 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
416 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
417 ConstIterator( LabelsConstIterator lIt, BlockConstIterator bIt )
418 : myLabelsIt( lIt ), myBlockIt( bIt )
420 //-----------------------------------------------------------------------------
421 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
423 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
426 //-----------------------------------------------------------------------------
427 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
429 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
432 //-----------------------------------------------------------------------------
433 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
435 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
436 ConstIterator( const ConstIterator & other )
437 : myLabelsIt( other.myLabelsIt ), myBlockIt( other.myBlockIt )
439 //-----------------------------------------------------------------------------
440 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
442 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Self &
443 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
444 operator= ( const Self & other )
446 if ( this != &other )
448 myLabelsIt = other.myLabelsIt;
449 myBlockIt = other.myBlockIt;
453 //-----------------------------------------------------------------------------
454 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
456 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Reference
457 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
460 return std::make_pair( *myLabelsIt, *myBlockIt );
462 //-----------------------------------------------------------------------------
463 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
465 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Pointer
466 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
469 // Warning: not thread-safe.
470 static Value __static_tmp;
471 __static_tmp = this->operator*();
472 return &__static_tmp;
474 //-----------------------------------------------------------------------------
475 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
477 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Self&
478 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
485 //-----------------------------------------------------------------------------
486 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
488 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Self
489 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
496 //-----------------------------------------------------------------------------
497 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
500 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
501 operator==( const Self & other ) const
503 return myLabelsIt == other.myLabelsIt;
505 //-----------------------------------------------------------------------------
506 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
509 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
510 operator!=( const Self & other ) const
512 return myLabelsIt != other.myLabelsIt;
514 //-----------------------------------------------------------------------------
515 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
517 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data&
518 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
521 return const_cast<Data&>( *myBlockIt );
523 //-----------------------------------------------------------------------------
524 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
526 const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data&
527 DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
533 ///////////////////////////////////////////////////////////////////////////////
535 //-----------------------------------------------------------------------------
536 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
538 DGtal::LabelledMap<TData, L, TWord, N, M>::
540 { // default constructor of myLabels and myFirstBlock is automatically called.
542 //-----------------------------------------------------------------------------
543 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
545 DGtal::LabelledMap<TData, L, TWord, N, M>::
548 blockClear( size() );
550 //-----------------------------------------------------------------------------
551 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
553 DGtal::LabelledMap<TData, L, TWord, N, M>::
554 LabelledMap( const LabelledMap & other )
555 : myLabels( other.myLabels ),
556 myFirstBlock( other.myFirstBlock )
558 const auto theSize = other.size();
559 if ( theSize > N + 1 )
562 const __AnyBlock* nextBlock = other.myFirstBlock.data.nextBlock;
563 __AnyBlock** currentPointer = & myFirstBlock.data.nextBlock;
564 while ( s < theSize )
566 *currentPointer = new __AnyBlock( *nextBlock );
568 currentPointer = & ( (*currentPointer)->next );
569 nextBlock = nextBlock->next;
573 //-----------------------------------------------------------------------------
574 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
575 template <typename InputIterator>
577 DGtal::LabelledMap<TData, L, TWord, N, M>::
578 LabelledMap( InputIterator first, InputIterator last )
579 { // default constructor of myLabels and myFirstBlock is automatically called.
580 BOOST_CONCEPT_ASSERT(( boost::InputIterator< InputIterator > ));
581 for ( ; first != last; ++first )
583 this->operator[]( first->first ) = first->second;
586 //-----------------------------------------------------------------------------
587 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
589 DGtal::LabelledMap<TData, L, TWord, N, M> &
590 DGtal::LabelledMap<TData, L, TWord, N, M>::
591 operator=( const LabelledMap & other )
593 if ( this != &other )
595 blockClear( size() );
596 myLabels = other.myLabels;
597 myFirstBlock = other.myFirstBlock;
599 auto theSize = other.size();
600 if ( theSize > N + 1 )
603 const __AnyBlock* nextBlock = other.myFirstBlock.data.nextBlock;
604 __AnyBlock** currentPointer = & myFirstBlock.data.nextBlock;
605 while ( s < theSize )
607 *currentPointer = new __AnyBlock( *nextBlock );
609 currentPointer = & ( (*currentPointer)->next );
610 nextBlock = nextBlock->next;
616 //-----------------------------------------------------------------------------
617 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
620 DGtal::LabelledMap<TData, L, TWord, N, M>::
623 blockClear( size() );
626 //-----------------------------------------------------------------------------
627 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
630 DGtal::LabelledMap<TData, L, TWord, N, M>::
631 blockClear( size_t theSize )
633 if ( theSize != N+1 )
635 __AnyBlock* nextBlock = myFirstBlock.data.nextBlock;
636 while ( nextBlock != 0 )
638 __AnyBlock* ptr = nextBlock;
639 nextBlock = nextBlock->next;
643 myFirstBlock.data.nextBlock = 0;
645 //-----------------------------------------------------------------------------
646 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
648 const typename DGtal::LabelledMap<TData, L, TWord, N, M>::LabelsType &
649 DGtal::LabelledMap<TData, L, TWord, N, M>::
654 //-----------------------------------------------------------------------------
655 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
657 typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
658 DGtal::LabelledMap<TData, L, TWord, N, M>::
661 return myLabels.count();
663 //-----------------------------------------------------------------------------
664 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
667 DGtal::LabelledMap<TData, L, TWord, N, M>::
672 //-----------------------------------------------------------------------------
673 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
675 typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
676 DGtal::LabelledMap<TData, L, TWord, N, M>::
679 return L; //SizeType( -1 ) / (2*sizeof( Data ));
681 //-----------------------------------------------------------------------------
682 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
684 typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
685 DGtal::LabelledMap<TData, L, TWord, N, M>::
688 return ( size() <= (N+1) )
690 : ( 1 + ( size() - 1 - N ) / M ) * M + N;
692 //-----------------------------------------------------------------------------
693 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
695 typename DGtal::LabelledMap<TData, L, TWord, N, M>::KeyCompare
696 DGtal::LabelledMap<TData, L, TWord, N, M>::
701 //-----------------------------------------------------------------------------
702 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
704 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ValueCompare
705 DGtal::LabelledMap<TData, L, TWord, N, M>::
708 return ValueCompare();
710 //-----------------------------------------------------------------------------
711 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
714 DGtal::LabelledMap<TData, L, TWord, N, M>::
717 std::swap( myLabels, other.myLabels );
718 std::swap( myFirstBlock, other.myFirstBlock );
720 //-----------------------------------------------------------------------------
721 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
723 typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
724 DGtal::LabelledMap<TData, L, TWord, N, M>::
725 count( const Key & key ) const
727 return myLabels.test( key ) ? 1 : 0;
729 //-----------------------------------------------------------------------------
730 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
732 const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
733 DGtal::LabelledMap<TData, L, TWord, N, M>::
734 blockAt( size_t idx ) const
736 ASSERT( idx < size() );
738 return myFirstBlock.datas[ idx ];
739 else if ( ( idx == N ) && ( size() == N+1 ) )
740 return myFirstBlock.data.lastData;
741 const __AnyBlock* ptr = myFirstBlock.data.nextBlock;
749 return ptr->datas[ idx ];
751 //-----------------------------------------------------------------------------
752 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
754 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
755 DGtal::LabelledMap<TData, L, TWord, N, M>::
756 blockAt( size_t idx )
758 ASSERT( idx < size() );
760 return myFirstBlock.datas[ idx ];
761 else if ( ( idx == N ) && ( size() == N+1 ) )
762 return myFirstBlock.data.lastData;
763 __AnyBlock* ptr = myFirstBlock.data.nextBlock;
771 return ptr->datas[ idx ];
773 //-----------------------------------------------------------------------------
774 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
776 const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
777 DGtal::LabelledMap<TData, L, TWord, N, M>::
778 operator[]( const Key & key ) const
781 bool exists = myLabels.test( key );
784 unsigned int block_size = size();
785 myLabels.set( key ); // must be done before so that 'index' works.
786 return blockInsert( myLabels.index( key ), block_size, Data() );
790 return blockAt( myLabels.index( key ) );
793 //-----------------------------------------------------------------------------
794 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
796 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
797 DGtal::LabelledMap<TData, L, TWord, N, M>::
798 operator[]( const Key & key )
801 bool exists = myLabels.test( key );
804 auto block_size = size();
805 myLabels.set( key ); // must be done before so that 'index' works.
806 return blockInsert( myLabels.index( key ), block_size, Data() );
810 return blockAt( myLabels.index( key ) );
813 //-----------------------------------------------------------------------------
814 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
816 const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
817 DGtal::LabelledMap<TData, L, TWord, N, M>::
818 fastAt( const Key & key ) const
821 ASSERT( myLabels.test( key ) );
822 return blockAt( myLabels.index( key ) );
824 //-----------------------------------------------------------------------------
825 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
827 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
828 DGtal::LabelledMap<TData, L, TWord, N, M>::
829 fastAt( const Key & key )
832 ASSERT( myLabels.test( key ) );
833 return blockAt( myLabels.index( key ) );
835 //-----------------------------------------------------------------------------
836 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
839 DGtal::LabelledMap<TData, L, TWord, N, M>::
840 erase( Iterator position )
842 Key key = (*position).first;
843 ASSERT( myLabels.test( key ) );
844 blockErase( myLabels.index( key ) );
845 myLabels.reset( key );
847 //-----------------------------------------------------------------------------
848 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
850 typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
851 DGtal::LabelledMap<TData, L, TWord, N, M>::
854 if ( myLabels.test( key ) )
856 blockErase( myLabels.index( key ) );
857 myLabels.reset( key );
862 //-----------------------------------------------------------------------------
863 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
866 DGtal::LabelledMap<TData, L, TWord, N, M>::
867 erase( Iterator first, Iterator last )
869 for ( ; first != last; ++first )
873 //-----------------------------------------------------------------------------
874 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
876 std::pair<typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator, bool>
877 DGtal::LabelledMap<TData, L, TWord, N, M>::
878 insert( const Value & val )
880 ASSERT( val.first < L );
881 bool exists = myLabels.test( val.first );
884 unsigned int block_size = static_cast<unsigned int>( size() );
885 myLabels.set( val.first ); // must be done before so that 'index' works.
886 blockInsert( myLabels.index( val.first ), block_size, val.second );
888 Iterator position = begin();
889 while ( (*position).first != val.first )
891 // std::cerr << "[" << (*position).first << "]" << std::endl;
894 return std::make_pair( position, exists );
896 //-----------------------------------------------------------------------------
897 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
899 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
900 DGtal::LabelledMap<TData, L, TWord, N, M>::
901 insert ( Iterator position, const Value & val )
903 ASSERT( val.first < L );
904 if ( ! myLabels.test( val.first ) )
906 unsigned int block_size = size();
907 myLabels.set( val.first ); // must be done before so that 'index' works.
908 blockInsert( myLabels.index( val.first ), block_size, val.second );
911 while ( (*position).first != val.first )
913 //std::cerr << "[" << (*position).first << "]" << std::endl;
918 //-----------------------------------------------------------------------------
919 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
920 template <typename InputIterator>
923 DGtal::LabelledMap<TData, L, TWord, N, M>::
924 insert( InputIterator first, InputIterator last )
926 BOOST_CONCEPT_ASSERT(( boost::InputIterator< InputIterator > ));
927 for ( ; first != last; ++first )
929 Key k = first->first;
930 if ( ! myLabels.test( k ) )
932 auto block_size = size();
933 myLabels.set( k ); // must be done before so that 'index' works.
934 blockInsert( myLabels.index( k ), block_size, first->second );
938 //-----------------------------------------------------------------------------
939 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
941 std::pair< typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator,
942 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator >
943 DGtal::LabelledMap<TData, L, TWord, N, M>::
944 equal_range( const Key & x )
946 Iterator it = begin(), it_end = end();
947 for ( ; it != it_end; ++it )
949 if ( (*it).first == x )
951 // JOL: g++ does not compile correctly:
952 // return std::make_pair( it, ++it );
953 it_end = it; ++it_end;
954 return std::make_pair( it, it_end );
956 else if ( (*it).first > x ) return std::make_pair( it, it );
958 return std::make_pair( it_end, it_end );
960 //-----------------------------------------------------------------------------
961 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
963 std::pair< typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator,
964 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator >
965 DGtal::LabelledMap<TData, L, TWord, N, M>::
966 equal_range( const Key & x ) const
968 ConstIterator it = begin(), it_end = end();
969 for ( ; it != it_end; ++it )
971 if ( (*it).first == x ) return std::make_pair( it, ++it );
972 else if ( (*it).first > x ) return std::make_pair( it, it );
974 return std::make_pair( it_end, it_end );
976 //-----------------------------------------------------------------------------
977 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
979 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
980 DGtal::LabelledMap<TData, L, TWord, N, M>::
981 find( const Key & x )
983 Iterator it = begin(), it_end = end();
984 for ( ; it != it_end; ++it )
986 if ( (*it).first == x ) return it;
987 else if ( (*it).first > x ) return it_end;
991 //-----------------------------------------------------------------------------
992 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
994 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
995 DGtal::LabelledMap<TData, L, TWord, N, M>::
996 find( const Key & x ) const
998 ConstIterator it = begin(), it_end = end();
999 for ( ; it != it_end; ++it )
1001 if ( (*it).first == x ) return it;
1002 else if ( (*it).first > x ) return it_end;
1006 //-----------------------------------------------------------------------------
1007 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1009 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1010 DGtal::LabelledMap<TData, L, TWord, N, M>::
1011 lower_bound( const Key & x )
1013 Iterator it = begin(), it_end = end();
1014 for ( ; it != it_end; ++it )
1016 if ( (*it).first >= x ) return it;
1020 //-----------------------------------------------------------------------------
1021 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1023 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1024 DGtal::LabelledMap<TData, L, TWord, N, M>::
1025 lower_bound( const Key & x ) const
1027 ConstIterator it = begin(), it_end = end();
1028 for ( ; it != it_end; ++it )
1030 if ( (*it).first >= x ) return it;
1034 //-----------------------------------------------------------------------------
1035 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1037 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1038 DGtal::LabelledMap<TData, L, TWord, N, M>::
1039 upper_bound( const Key & x )
1041 Iterator it = begin(), it_end = end();
1042 for ( ; it != it_end; ++it )
1044 if ( (*it).first > x ) return it;
1048 //-----------------------------------------------------------------------------
1049 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1051 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1052 DGtal::LabelledMap<TData, L, TWord, N, M>::
1053 upper_bound( const Key & x ) const
1055 ConstIterator it = begin(), it_end = end();
1056 for ( ; it != it_end; ++it )
1058 if ( (*it).first > x ) return it;
1063 //-----------------------------------------------------------------------------
1064 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1066 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
1067 DGtal::LabelledMap<TData, L, TWord, N, M>::
1068 blockInsert( size_t idx, size_t block_size, const Data & data )
1070 ASSERT( idx <= block_size ); // end is ok.
1071 return myFirstBlock.insert( idx, block_size, data );
1073 //-----------------------------------------------------------------------------
1074 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1077 DGtal::LabelledMap<TData, L, TWord, N, M>::
1078 blockErase( size_t idx )
1080 ASSERT( idx < size() ); // end is not ok.
1081 myFirstBlock.erase( idx, size() );
1083 //-----------------------------------------------------------------------------
1084 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1086 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1087 DGtal::LabelledMap<TData, L, TWord, N, M>::
1090 const Self* ptr = (const Self *) this;
1091 return Iterator( myLabels.begin(), ptr->blockBegin() );
1093 //-----------------------------------------------------------------------------
1094 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1096 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1097 DGtal::LabelledMap<TData, L, TWord, N, M>::
1100 const Self* ptr = (const Self *) this;
1101 return Iterator( myLabels.end(), ptr->blockEnd() );
1103 //-----------------------------------------------------------------------------
1104 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1106 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1107 DGtal::LabelledMap<TData, L, TWord, N, M>::
1110 return ConstIterator( myLabels.begin(), blockBegin() );
1112 //-----------------------------------------------------------------------------
1113 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1115 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1116 DGtal::LabelledMap<TData, L, TWord, N, M>::
1119 return ConstIterator( myLabels.end(), blockEnd() );
1121 //-----------------------------------------------------------------------------
1122 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1124 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator
1125 DGtal::LabelledMap<TData, L, TWord, N, M>::
1128 return BlockIterator( myFirstBlock, 0, size() );
1130 //-----------------------------------------------------------------------------
1131 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1133 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator
1134 DGtal::LabelledMap<TData, L, TWord, N, M>::
1137 SizeType s = size();
1138 return BlockIterator( myFirstBlock, s, s );
1140 //-----------------------------------------------------------------------------
1141 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1143 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator
1144 DGtal::LabelledMap<TData, L, TWord, N, M>::
1147 return BlockConstIterator( myFirstBlock, 0, size() );
1149 //-----------------------------------------------------------------------------
1150 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1152 typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator
1153 DGtal::LabelledMap<TData, L, TWord, N, M>::
1156 SizeType s = size();
1157 return BlockConstIterator( myFirstBlock, s, s );
1160 ///////////////////////////////////////////////////////////////////////////////
1161 // Interface - public :
1164 * Writes/Displays the object on an output stream.
1165 * @param out the output stream where the object is written.
1167 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1170 DGtal::LabelledMap<TData, L, TWord, N, M>::
1171 selfDisplay( std::ostream & out ) const
1173 if ( size() == 0 ) out << "()";
1176 ConstIterator it = begin();
1177 ConstIterator it_end = end();
1179 out << "(" << (*it).first << "," << (*it).second << ")";
1181 for ( ; it != it_end; ++it )
1183 out << ",(" << (*it).first << "," << (*it).second << ")";
1188 // BlockConstIterator it = blockBegin();
1189 // BlockConstIterator it_end = blockEnd();
1190 // BlockConstIterator it_last = it;
1194 // for ( ; it != it_end; ++it )
1196 // out << ( ( it_last.myDatas == it.myDatas ) ? ',' : ';' );
1205 * Checks the validity/consistency of the object.
1206 * @return 'true' if the object is valid, 'false' otherwise.
1208 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1211 DGtal::LabelledMap<TData, L, TWord, N, M>::isValid() const
1218 ///////////////////////////////////////////////////////////////////////////////
1219 // Implementation of inline functions //
1221 template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1224 DGtal::operator<< ( std::ostream & out,
1225 const LabelledMap<TData, L, TWord, N, M> & object )
1227 object.selfDisplay( out );
1231 template <typename TData>
1232 std::pair< unsigned int, unsigned int >
1233 DGtal::detail::argminLabelledMapMemoryUsageForGeometricDistribution
1234 ( unsigned int L, double prob_no_data, double prob_one_data )
1236 unsigned int sL = 2 * ( ( ( L - 1 ) / 16 ) + 1 ); // word of 16bits
1237 // std::cerr << "L=" << L << " sL=" << sL << std::endl;
1238 LabelledMapMemFunctor F( prob_one_data, prob_no_data, sL, sizeof( TData ),
1239 sizeof( TData* ), 2 );
1241 unsigned int Nopt = 0;
1242 unsigned int Mopt = 0;
1243 for ( unsigned int N = 1; N < L; ++N )
1244 for ( unsigned int M = 2; M < (L-N); ++M )
1246 // std::cerr << "Fmem(" << N << "," << M << ")="
1247 // << F.fctNM( N, M ) << std::endl;
1248 if ( ( m < 0.0 ) || ( F.fctNM( N, M ) < m ) )
1251 m = F.fctNM( Nopt, Mopt );
1254 return std::make_pair( Nopt, Mopt );
1258 ///////////////////////////////////////////////////////////////////////////////