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//-----------------------------------------------------------------------------
44template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
45DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
48//-----------------------------------------------------------------------------
49template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
50DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
52 : myIdx( 0 ), myDatas( 0 )
54//-----------------------------------------------------------------------------
55template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
56DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
57BlockIterator( const Self & other)
58 : myIdx( other.myIdx ), myNbDatas( other.myNbDatas ),
59 myDatas( other.myDatas ), myNext( other.myNext )
61//-----------------------------------------------------------------------------
62template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
63DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
64BlockIterator( __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//-----------------------------------------------------------------------------
118template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
120typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self &
121DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
122operator=( const Self & other )
124 if ( this != &other )
127 myNbDatas = other.myNbDatas;
128 myDatas = other.myDatas;
129 myNext = other.myNext;
133//-----------------------------------------------------------------------------
134template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
136typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Reference
137DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
140 ASSERT( myDatas != 0 );
141 return myDatas[ myIdx ];
143//-----------------------------------------------------------------------------
144template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
146typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Pointer
147DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
150 ASSERT( myDatas != 0 );
151 return myDatas + myIdx;
153//-----------------------------------------------------------------------------
154template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
156typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self &
157DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
160 return this->operator+=( 1 );
162//-----------------------------------------------------------------------------
163template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
165typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self
166DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
173//-----------------------------------------------------------------------------
174template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
177DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
178operator==( const Self & other ) const
180 return ( myDatas == other.myDatas ) && ( myIdx == other.myIdx );
182//-----------------------------------------------------------------------------
183template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
186DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
187operator!=( const Self & other ) const
189 return ( myDatas != other.myDatas ) || ( myIdx != other.myIdx );
191//-----------------------------------------------------------------------------
192template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
194typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Self &
195DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
196operator+=( DifferenceType n )
199 while ( myIdx >= myNbDatas )
208 myDatas = myNext->datas;
210 myNext = myNext->next;
214//-----------------------------------------------------------------------------
215template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
217typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::Reference
218DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator::
219operator[]( DifferenceType n ) const
226///////////////////////////////////////////////////////////////////////////////
227// class LabelledMap::BlockConstIterator
228//-----------------------------------------------------------------------------
229template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
230DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
233//-----------------------------------------------------------------------------
234template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
235DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
237 : myIdx( 0 ), myDatas( 0 )
239//-----------------------------------------------------------------------------
240template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
241DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
242BlockConstIterator( const Self & other)
243 : myIdx( other.myIdx ), myNbDatas( other.myNbDatas ),
244 myDatas( other.myDatas ), myNext( other.myNext )
246//-----------------------------------------------------------------------------
247template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
248DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
249BlockConstIterator( 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//-----------------------------------------------------------------------------
303template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
305typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self &
306DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
307operator=( const Self & other )
309 if ( this != &other )
312 myNbDatas = other.myNbDatas;
313 myDatas = other.myDatas;
314 myNext = other.myNext;
318//-----------------------------------------------------------------------------
319template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
321typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Reference
322DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
325 ASSERT( myDatas != 0 );
326 return myDatas[ myIdx ];
328//-----------------------------------------------------------------------------
329template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
331typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Pointer
332DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
335 ASSERT( myDatas != 0 );
336 return myDatas + myIdx;
338//-----------------------------------------------------------------------------
339template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
341typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self &
342DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
345 return this->operator+=( 1 );
347//-----------------------------------------------------------------------------
348template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
350typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self
351DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
358//-----------------------------------------------------------------------------
359template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
362DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
363operator==( const Self & other ) const
365 return ( myDatas == other.myDatas ) && ( myIdx == other.myIdx );
367//-----------------------------------------------------------------------------
368template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
371DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
372operator!=( const Self & other ) const
374 return ( myDatas != other.myDatas ) || ( myIdx != other.myIdx );
376//-----------------------------------------------------------------------------
377template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
379typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Self &
380DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
381operator+=( DifferenceType n )
384 while ( myIdx >= myNbDatas )
393 myDatas = myNext->datas;
395 myNext = myNext->next;
399//-----------------------------------------------------------------------------
400template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
402typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::Reference
403DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator::
404operator[]( DifferenceType n ) const
411///////////////////////////////////////////////////////////////////////////////
412// class LabelledMap::ConstIterator
413//-----------------------------------------------------------------------------
414template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
416DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
417ConstIterator( LabelsConstIterator lIt, BlockConstIterator bIt )
418 : myLabelsIt( lIt ), myBlockIt( bIt )
420//-----------------------------------------------------------------------------
421template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
423DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
426//-----------------------------------------------------------------------------
427template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
429DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
432//-----------------------------------------------------------------------------
433template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
435DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
436ConstIterator( const ConstIterator & other )
437 : myLabelsIt( other.myLabelsIt ), myBlockIt( other.myBlockIt )
439//-----------------------------------------------------------------------------
440template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
442typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Self &
443DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
444operator= ( const Self & other )
446 if ( this != &other )
448 myLabelsIt = other.myLabelsIt;
449 myBlockIt = other.myBlockIt;
453//-----------------------------------------------------------------------------
454template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
456typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Reference
457DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
460 return std::make_pair( *myLabelsIt, *myBlockIt );
462//-----------------------------------------------------------------------------
463template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
465typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Pointer
466DGtal::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//-----------------------------------------------------------------------------
475template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
477typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Self&
478DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
485//-----------------------------------------------------------------------------
486template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
488typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::Self
489DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
496//-----------------------------------------------------------------------------
497template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
500DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
501operator==( const Self & other ) const
503 return myLabelsIt == other.myLabelsIt;
505//-----------------------------------------------------------------------------
506template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
509DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
510operator!=( const Self & other ) const
512 return myLabelsIt != other.myLabelsIt;
514//-----------------------------------------------------------------------------
515template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
517typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data&
518DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
521 return const_cast<Data&>( *myBlockIt );
523//-----------------------------------------------------------------------------
524template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
526const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data&
527DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator::
533///////////////////////////////////////////////////////////////////////////////
535//-----------------------------------------------------------------------------
536template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
538DGtal::LabelledMap<TData, L, TWord, N, M>::
540{ // default constructor of myLabels and myFirstBlock is automatically called.
542//-----------------------------------------------------------------------------
543template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
545DGtal::LabelledMap<TData, L, TWord, N, M>::
548 blockClear( size() );
550//-----------------------------------------------------------------------------
551template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
553DGtal::LabelledMap<TData, L, TWord, N, M>::
554LabelledMap( 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//-----------------------------------------------------------------------------
574template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
575template <typename InputIterator>
577DGtal::LabelledMap<TData, L, TWord, N, M>::
578LabelledMap( 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//-----------------------------------------------------------------------------
587template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
589DGtal::LabelledMap<TData, L, TWord, N, M> &
590DGtal::LabelledMap<TData, L, TWord, N, M>::
591operator=( 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//-----------------------------------------------------------------------------
617template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
620DGtal::LabelledMap<TData, L, TWord, N, M>::
623 blockClear( size() );
626//-----------------------------------------------------------------------------
627template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
630DGtal::LabelledMap<TData, L, TWord, N, M>::
631blockClear( 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//-----------------------------------------------------------------------------
646template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
648const typename DGtal::LabelledMap<TData, L, TWord, N, M>::LabelsType &
649DGtal::LabelledMap<TData, L, TWord, N, M>::
654//-----------------------------------------------------------------------------
655template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
657typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
658DGtal::LabelledMap<TData, L, TWord, N, M>::
661 return myLabels.count();
663//-----------------------------------------------------------------------------
664template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
667DGtal::LabelledMap<TData, L, TWord, N, M>::
672//-----------------------------------------------------------------------------
673template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
675typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
676DGtal::LabelledMap<TData, L, TWord, N, M>::
679 return L; //SizeType( -1 ) / (2*sizeof( Data ));
681//-----------------------------------------------------------------------------
682template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
684typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
685DGtal::LabelledMap<TData, L, TWord, N, M>::
688 return ( size() <= (N+1) )
690 : ( 1 + ( size() - 1 - N ) / M ) * M + N;
692//-----------------------------------------------------------------------------
693template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
695typename DGtal::LabelledMap<TData, L, TWord, N, M>::KeyCompare
696DGtal::LabelledMap<TData, L, TWord, N, M>::
701//-----------------------------------------------------------------------------
702template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
704typename DGtal::LabelledMap<TData, L, TWord, N, M>::ValueCompare
705DGtal::LabelledMap<TData, L, TWord, N, M>::
708 return ValueCompare();
710//-----------------------------------------------------------------------------
711template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
714DGtal::LabelledMap<TData, L, TWord, N, M>::
717 std::swap( myLabels, other.myLabels );
718 std::swap( myFirstBlock, other.myFirstBlock );
720//-----------------------------------------------------------------------------
721template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
723typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
724DGtal::LabelledMap<TData, L, TWord, N, M>::
725count( const Key & key ) const
727 return myLabels.test( key ) ? 1 : 0;
729//-----------------------------------------------------------------------------
730template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
732const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
733DGtal::LabelledMap<TData, L, TWord, N, M>::
734blockAt( 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//-----------------------------------------------------------------------------
752template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
754typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
755DGtal::LabelledMap<TData, L, TWord, N, M>::
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//-----------------------------------------------------------------------------
774template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
776const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
777DGtal::LabelledMap<TData, L, TWord, N, M>::
778operator[]( 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//-----------------------------------------------------------------------------
794template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
796typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
797DGtal::LabelledMap<TData, L, TWord, N, M>::
798operator[]( 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//-----------------------------------------------------------------------------
814template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
816const typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
817DGtal::LabelledMap<TData, L, TWord, N, M>::
818fastAt( const Key & key ) const
821 ASSERT( myLabels.test( key ) );
822 return blockAt( myLabels.index( key ) );
824//-----------------------------------------------------------------------------
825template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
827typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
828DGtal::LabelledMap<TData, L, TWord, N, M>::
829fastAt( const Key & key )
832 ASSERT( myLabels.test( key ) );
833 return blockAt( myLabels.index( key ) );
835//-----------------------------------------------------------------------------
836template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
839DGtal::LabelledMap<TData, L, TWord, N, M>::
840erase( Iterator position )
842 Key key = (*position).first;
843 ASSERT( myLabels.test( key ) );
844 blockErase( myLabels.index( key ) );
845 myLabels.reset( key );
847//-----------------------------------------------------------------------------
848template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
850typename DGtal::LabelledMap<TData, L, TWord, N, M>::SizeType
851DGtal::LabelledMap<TData, L, TWord, N, M>::
854 if ( myLabels.test( key ) )
856 blockErase( myLabels.index( key ) );
857 myLabels.reset( key );
862//-----------------------------------------------------------------------------
863template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
866DGtal::LabelledMap<TData, L, TWord, N, M>::
867erase( Iterator first, Iterator last )
869 for ( ; first != last; ++first )
873//-----------------------------------------------------------------------------
874template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
876std::pair<typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator, bool>
877DGtal::LabelledMap<TData, L, TWord, N, M>::
878insert( 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//-----------------------------------------------------------------------------
897template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
899typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
900DGtal::LabelledMap<TData, L, TWord, N, M>::
901insert ( 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//-----------------------------------------------------------------------------
919template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
920template <typename InputIterator>
923DGtal::LabelledMap<TData, L, TWord, N, M>::
924insert( 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//-----------------------------------------------------------------------------
939template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
941std::pair< typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator,
942 typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator >
943DGtal::LabelledMap<TData, L, TWord, N, M>::
944equal_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//-----------------------------------------------------------------------------
961template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
963std::pair< typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator,
964 typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator >
965DGtal::LabelledMap<TData, L, TWord, N, M>::
966equal_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//-----------------------------------------------------------------------------
977template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
979typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
980DGtal::LabelledMap<TData, L, TWord, N, M>::
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//-----------------------------------------------------------------------------
992template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
994typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
995DGtal::LabelledMap<TData, L, TWord, N, M>::
996find( 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//-----------------------------------------------------------------------------
1007template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1009typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1010DGtal::LabelledMap<TData, L, TWord, N, M>::
1011lower_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//-----------------------------------------------------------------------------
1021template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1023typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1024DGtal::LabelledMap<TData, L, TWord, N, M>::
1025lower_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//-----------------------------------------------------------------------------
1035template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1037typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1038DGtal::LabelledMap<TData, L, TWord, N, M>::
1039upper_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//-----------------------------------------------------------------------------
1049template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1051typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1052DGtal::LabelledMap<TData, L, TWord, N, M>::
1053upper_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//-----------------------------------------------------------------------------
1064template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1066typename DGtal::LabelledMap<TData, L, TWord, N, M>::Data &
1067DGtal::LabelledMap<TData, L, TWord, N, M>::
1068blockInsert( 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//-----------------------------------------------------------------------------
1074template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1077DGtal::LabelledMap<TData, L, TWord, N, M>::
1078blockErase( size_t idx )
1080 ASSERT( idx < size() ); // end is not ok.
1081 myFirstBlock.erase( idx, size() );
1083//-----------------------------------------------------------------------------
1084template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1086typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1087DGtal::LabelledMap<TData, L, TWord, N, M>::
1090 const Self* ptr = (const Self *) this;
1091 return Iterator( myLabels.begin(), ptr->blockBegin() );
1093//-----------------------------------------------------------------------------
1094template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1096typename DGtal::LabelledMap<TData, L, TWord, N, M>::Iterator
1097DGtal::LabelledMap<TData, L, TWord, N, M>::
1100 const Self* ptr = (const Self *) this;
1101 return Iterator( myLabels.end(), ptr->blockEnd() );
1103//-----------------------------------------------------------------------------
1104template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1106typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1107DGtal::LabelledMap<TData, L, TWord, N, M>::
1110 return ConstIterator( myLabels.begin(), blockBegin() );
1112//-----------------------------------------------------------------------------
1113template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1115typename DGtal::LabelledMap<TData, L, TWord, N, M>::ConstIterator
1116DGtal::LabelledMap<TData, L, TWord, N, M>::
1119 return ConstIterator( myLabels.end(), blockEnd() );
1121//-----------------------------------------------------------------------------
1122template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1124typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator
1125DGtal::LabelledMap<TData, L, TWord, N, M>::
1128 return BlockIterator( myFirstBlock, 0, size() );
1130//-----------------------------------------------------------------------------
1131template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1133typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockIterator
1134DGtal::LabelledMap<TData, L, TWord, N, M>::
1137 SizeType s = size();
1138 return BlockIterator( myFirstBlock, s, s );
1140//-----------------------------------------------------------------------------
1141template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1143typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator
1144DGtal::LabelledMap<TData, L, TWord, N, M>::
1147 return BlockConstIterator( myFirstBlock, 0, size() );
1149//-----------------------------------------------------------------------------
1150template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1152typename DGtal::LabelledMap<TData, L, TWord, N, M>::BlockConstIterator
1153DGtal::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.
1167template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1170DGtal::LabelledMap<TData, L, TWord, N, M>::
1171selfDisplay( 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.
1208template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1211DGtal::LabelledMap<TData, L, TWord, N, M>::isValid() const
1218///////////////////////////////////////////////////////////////////////////////
1219// Implementation of inline functions //
1221template <typename TData, unsigned int L, typename TWord, unsigned int N, unsigned int M>
1224DGtal::operator<< ( std::ostream & out,
1225 const LabelledMap<TData, L, TWord, N, M> & object )
1227 object.selfDisplay( out );
1231template <typename TData>
1232std::pair< unsigned int, unsigned int >
1233DGtal::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///////////////////////////////////////////////////////////////////////////////