DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
LabelledMap.h
1 
17 #pragma once
18 
31 #if defined(LabelledMap_RECURSES)
32 #error Recursive header files inclusion detected in LabelledMap.h
33 #else // defined(LabelledMap_RECURSES)
34 
35 #define LabelledMap_RECURSES
36 
37 #if !defined LabelledMap_h
38 
39 #define LabelledMap_h
40 
42 // Inclusions
43 #include <cstring>
44 #include <cmath>
45 #include <iostream>
46 #include "DGtal/base/Common.h"
47 #include "DGtal/base/Labels.h"
48 //#include "DGtal/base/FakeKeyValuePair.h"
50 
51 namespace DGtal
52 {
53 
55  // template class LabelledMap
117  template <typename TData, unsigned int L, typename TWord,
118  unsigned int N, unsigned int M>
120  {
121  BOOST_STATIC_ASSERT( L >= 1 );
122  BOOST_STATIC_ASSERT( N >= 0 );
123  BOOST_STATIC_ASSERT( M >= 2 );
124  public:
125  // ----------------------- Public types ------------------------------
127  typedef TData Data;
128  typedef TWord Word;
130  typedef typename LabelsType::Label Label;
131  typedef Label Key;
132  typedef std::pair<const Key, Data> Value;
133  //typedef FakeKeyValuePair<Key, Data> Value;
134 
136  typedef std::ptrdiff_t DifferenceType;
137  typedef std::size_t SizeType;
138  typedef Value& Reference;
139  typedef Value* Pointer;
140  typedef const Value& ConstReference;
141  typedef const Value* ConstPointer;
142 
143  //class Iterator; //< Forward declaration
144  class ConstIterator; //< Forward declaration
145  class KeyCompare; //< Forward declaration
146  class ValueCompare; //< Forward declaration
147  // ----------------------- Standard types ------------------------------
148  typedef Key key_type;
149  typedef Value value_type;
150  typedef Data data_type;
151  typedef Data mapped_type;
154  typedef Pointer pointer;
158  typedef ConstIterator iterator;
159  typedef ConstIterator const_iterator;
160  typedef KeyCompare key_compare;
161  typedef ValueCompare value_compare;
162 
163  struct __FirstBlock; //< Forward declaration
164  struct __AnyBlock; //< Forward declaration
165 
166  union BlockPointer {
169  };
170 
173  Data lastData; // used when at the end of the list
174  __AnyBlock* nextBlock; // used otherwise
175  };
176 
179  struct __FirstBlock {
180  inline
182  { data.nextBlock = 0; }
183 
184  inline
185  Data & insert( unsigned int idx, unsigned int size, const Data & v )
186  {
187  ASSERT( idx <= size );
188  if ( size < N )
189  {
190  std::copy_backward( datas + idx, datas + size, datas + size + 1 );
191  return ( datas[ idx ] = v );
192  }
193  else if ( size == N )
194  {
195  if ( idx < N )
196  {
197  data.lastData = datas[ N - 1 ];
198  std::copy_backward( datas + idx, datas + N - 1, datas + N );
199  return ( datas[ idx ] = v );
200  }
201  else // idx == N
202  {
203  return ( data.lastData = v );
204  }
205  }
206  else if ( size == (N+1) )
207  {
208  // This cannot be tested.
209  // ASSERT( data.nextBlock == 0 );
210  __AnyBlock* next = new __AnyBlock;
211  if ( idx < N )
212  {
213  next->datas[ 0 ] = datas[ N - 1 ];
214  next->datas[ 1 ] = data.lastData;
215  std::copy_backward( datas + idx, datas + N - 1, datas + N );
216  data.nextBlock = next;
217  return ( datas[ idx ] = v );
218  }
219  else if ( idx == N )
220  {
221  next->datas[ 1 ] = data.lastData;
222  data.nextBlock = next;
223  return ( next->datas[ 0 ] = v );
224  }
225  else //if ( idx > N )
226  {
227  next->datas[ 0 ] = data.lastData;
228  data.nextBlock = next;
229  return ( next->datas[ 1 ] = v );
230  }
231  }
232  else // size > N + 1
233  {
234  if ( idx < N )
235  {
236  Data v1 = datas[ N - 1 ];
237  std::copy_backward( datas + idx, datas + N - 1, datas + N );
238  data.nextBlock->insert( 0, size - N, v1 );
239  return ( datas[ idx ] = v );
240  }
241  else
242  return data.nextBlock->insert( idx - N, size - N, v );
243  }
244  }
245 
246  inline
247  void erase( unsigned int idx, unsigned int size )
248  {
249  // std::cerr << "__FirstBlock::erase(" << idx << ")"
250  // << " this=" << this
251  // << " next=" << data.nextBlock
252  // << std::endl;
253  ASSERT( idx < size );
254  if ( size <= ( N + 1 ) )
255  {
256  // works also in the case we use 'data' to store a N+1-th data.
257  std::copy( datas + idx + 1, datas + size, datas + idx );
258  data.nextBlock = 0;
259  }
260  else if ( size == N + 2 )
261  {
262  if ( idx < N )
263  {
264  std::copy( datas + idx + 1, datas + N, datas + idx );
265  datas[ N - 1 ] = data.nextBlock->datas[ 0 ];
266  Data tmp = data.nextBlock->datas[ 1 ];
267  delete data.nextBlock;
268  data.lastData = tmp;
269  }
270  else if ( idx == N )
271  {
272  Data tmp = data.nextBlock->datas[ 1 ];
273  delete data.nextBlock;
274  data.lastData = tmp;
275  }
276  else // idx == N + 1
277  {
278  Data tmp = data.nextBlock->datas[ 0 ];
279  delete data.nextBlock;
280  data.lastData = tmp;
281  }
282  }
283  else // size > N + 2
284  {
285  if ( idx < N )
286  {
287  std::copy( datas + idx + 1, datas + N, datas + idx );
288  datas[ N - 1 ] = data.nextBlock->datas[ 0 ];
289  data.nextBlock = data.nextBlock->erase( 0, size - N );
290  }
291  else
292  data.nextBlock = data.nextBlock->erase( idx - N, size - N );
293  }
294  }
295 
296  Data datas[ N ];
298  };
299 
302  struct __AnyBlock {
303  inline __AnyBlock() : next( 0 ) {}
304 
305  inline
306  Data & insert( unsigned int idx, unsigned int size, const Data & v )
307  {
308  ASSERT( idx <= size );
309  if ( idx >= M )
310  {
311  if ( next == 0 )
312  {
313  ASSERT( size == M );
314  ASSERT( idx == M );
315  next = new __AnyBlock;
316  return ( next->datas[ 0 ] = v );
317  }
318  else
319  {
320  ASSERT( size > M );
321  return next->insert( idx - M, size - M, v );
322  }
323  }
324  else
325  { // idx < M
326  if ( size <= ( M - 1) ) // ( size < ( M - 1) )
327  {
328  ASSERT( next == 0 );
329  std::copy_backward( datas + idx, datas + size,
330  datas + size + 1 );
331  return ( datas[ idx ] = v );
332  }
333  else
334  {
335  Data v1 = datas[ M - 1 ];
336  std::copy_backward( datas + idx, datas + M - 1, datas + M );
337  // if ( size >= M )
338  // {
339  if ( next == 0 )
340  {
341  ASSERT( size == M );
342  next = new __AnyBlock;
343  next->datas[ 0 ] = v1;
344  }
345  else
346  {
347  ASSERT( size > M );
348  next->insert( 0, size - M, v1 );
349  }
350  // }
351  return ( datas[ idx ] = v );
352  }
353  }
354  }
355 
356  inline
357  __AnyBlock* erase( unsigned int idx, unsigned int size )
358  {
359  // std::cerr << "__AnyBlock::erase(" << idx << "," << size << ")"
360  // << " this=" << this
361  // << " next=" << next
362  // << std::endl;
363  if ( size == 1 )
364  {
365  ASSERT( idx == 0 );
366  delete this;
367  return 0;
368  }
369  if ( idx < M )
370  {
371  std::copy( datas + idx + 1, datas + M, datas + idx );
372  if ( next != 0 )
373  {
374  ASSERT( size > M );
375  datas[ M - 1 ] = next->datas[ 0 ];
376  next = next->erase( 0, size - M );
377  }
378  }
379  else
380  next = next->erase( idx - M, size - M );
381  return this;
382  }
383 
384 
385  Data datas[ M ];
387  };
388 
395  public:
397  typedef TData Value;
398  typedef Value* Pointer;
399  typedef Value& Reference;
400  typedef std::ptrdiff_t DifferenceType; //< only positive offsets allowed.
401 
402  // ----------------------- std types ----------------------------------
403  typedef Value value_type;
404  typedef std::size_t size_type;
406  typedef Pointer pointer;
408  //typedef const Reference const_reference;
409  typedef std::forward_iterator_tag iterator_category;
410 
411 
412  protected:
413  unsigned int myIdx; //< current index in \a myDatas of the iterator
414  unsigned int myNbDatas; //< number of valid datas in array \a myDatas
415  Data* myDatas; //< array of \a myNbDatas datas.
416  __AnyBlock* myNext; //< pointer to next block or 0 if last block.
417 
418  friend class LabelledMap;
419 
420  protected:
424  BlockIterator( __FirstBlock & block, unsigned int idx, unsigned int size );
425 
426  public:
430  ~BlockIterator();
431 
435  BlockIterator();
436 
441  BlockIterator( const BlockIterator & other );
442 
448  Self & operator= ( const Self & other );
449 
454  Reference operator*() const;
455 
460  Pointer operator->() const;
461 
466  Self& operator++();
467 
472  Self operator++( int );
473 
480 
487 
493  bool operator==( const Self & other ) const;
494 
500  bool operator!=( const Self & other ) const;
501 
502 
503  };
504 
505 
512  public:
514  typedef TData Value;
515  typedef const Value* Pointer;
516  typedef const Value& Reference;
517  typedef std::ptrdiff_t DifferenceType; //< only positive offsets allowed.
518 
519  // ----------------------- std types ----------------------------------
520  typedef Value value_type;
521  typedef std::size_t size_type;
523  typedef Pointer pointer;
525  // typedef Reference const_reference;
526  typedef std::forward_iterator_tag iterator_category;
527 
528 
529  protected:
530  unsigned int myIdx; //< current index in \a myDatas of the iterator
531  unsigned int myNbDatas; //< number of valid datas in array \a myDatas
532  const Data* myDatas; //< array of \a myNbDatas datas.
533  const __AnyBlock* myNext; //< pointer to next block or 0 if last block.
534 
535  friend class LabelledMap;
536 
537  protected:
542  BlockConstIterator( const __FirstBlock & block, unsigned int idx, unsigned int size );
543 
544  public:
549 
554 
559  BlockConstIterator( const BlockConstIterator & other );
560 
566  Self & operator= ( const Self & other );
567 
572  Reference operator*() const;
573 
578  Pointer operator->() const;
579 
584  Self& operator++();
585 
590  Self operator++( int );
591 
598 
605 
611  bool operator==( const Self & other ) const;
612 
618  bool operator!=( const Self & other ) const;
619 
620 
621  };
622 
623  // ----------------------- Iterator services ------------------------------
624  public:
625 
630  public:
631  friend class LabelledMap;
633  // The following line is removed so that gcc-4.2 and gcc-4.6 compiles.
634  //typedef typename LabelledMap<TData, L, TWord, N, M>::Value Value;
635  typedef const Value* Pointer;
637  typedef Value Reference;
638  typedef std::ptrdiff_t DifferenceType;
639 
640  // ----------------------- std types ----------------------------------
641  typedef Value value_type;
642  typedef std::size_t size_type;
644  typedef Pointer pointer;
646  // typedef Reference const_reference;
647  typedef std::forward_iterator_tag iterator_category;
648 
649  private:
654 
655  protected:
660 
661  public:
665  ~ConstIterator();
666 
670  ConstIterator();
671 
676  ConstIterator( const ConstIterator & other );
677 
683  Self & operator= ( const Self & other );
684 
689  Reference operator*() const;
690 
696  Pointer operator->() const;
697 
702  Self& operator++();
703 
708  Self operator++( int );
709 
715  bool operator==( const Self & other ) const;
716 
722  bool operator!=( const Self & other ) const;
723 
724 
725  Data & _data() const;
726  const Data & _const_data() const;
727  };
728 
730  typedef ConstIterator Iterator;
732  class KeyCompare {
733  public:
734  inline KeyCompare() {}
735  inline bool operator()( Key k1, Key k2 ) const
736  {
737  return k1 < k2;
738  }
739  };
741  class ValueCompare {
742  public:
743  inline ValueCompare() {}
744  inline bool operator()( const Value & v1, const Value & v2 ) const
745  {
746  return v1.first < v2.first;
747  }
748  };
749 
750 
751  // ----------------------- Standard services ------------------------------
752  public:
753 
757  LabelledMap();
758 
763  LabelledMap ( const LabelledMap & other );
764 
774  template <typename InputIterator>
775  LabelledMap( InputIterator first, InputIterator last );
776 
782  LabelledMap & operator= ( const LabelledMap & other );
783 
787  ~LabelledMap();
788 
789  // ----------------------- Container services -----------------------------
790  public:
791 
795  const LabelsType & labels() const;
796 
800  SizeType size() const;
801 
805  bool empty() const;
806 
810  SizeType max_size() const;
811 
815  SizeType capacity() const;
816 
820  KeyCompare key_comp() const;
821 
825  ValueCompare value_comp() const;
826 
840  void swap( Self & other );
841 
845  void clear();
846 
853  SizeType count( const Key & key ) const;
854 
862  Data & operator[]( const Key & key );
863 
871  const Data & operator[]( const Key & key ) const;
872 
879  Data & fastAt( const Key & key );
880 
887  const Data & fastAt( const Key & key ) const;
888 
905  std::pair<Iterator, bool> insert( const Value & val );
906 
920  Iterator insert( Iterator position, const Value & val );
921 
933  template <typename InputIterator>
934  void insert( InputIterator first, InputIterator last );
935 
941  void erase( Iterator position );
942 
949  SizeType erase( Key key );
950 
960  void erase( Iterator first, Iterator last );
961 
963  ConstIterator begin() const;
964 
966  ConstIterator end() const;
967 
969  Iterator begin();
970 
972  Iterator end();
973 
995  std::pair<Iterator, Iterator> equal_range( const Key & x );
996 
1018  std::pair<ConstIterator, ConstIterator> equal_range( const Key & x ) const;
1019 
1037  Iterator find ( const Key & x );
1038 
1056  ConstIterator find ( const Key & x ) const;
1057 
1080  Iterator lower_bound( const Key & x );
1081 
1103  ConstIterator lower_bound ( const Key & x ) const;
1104 
1125  Iterator upper_bound ( const Key & x );
1126 
1147  ConstIterator upper_bound ( const Key & x ) const;
1148 
1149 
1154  void blockClear( unsigned int size );
1155 
1163  Data & blockAt( unsigned int idx );
1164 
1172  const Data & blockAt( unsigned int idx ) const;
1173 
1183  Data & blockInsert( unsigned int idx, unsigned int block_size, const Data & data );
1184 
1192  void blockErase( unsigned int idx );
1193 
1194 
1196  BlockIterator blockBegin();
1197 
1199  BlockIterator blockEnd();
1200 
1202  BlockConstIterator blockBegin() const;
1203 
1205  BlockConstIterator blockEnd() const;
1206 
1207  // ----------------------- Interface --------------------------------------
1208  public:
1209 
1214  void selfDisplay ( std::ostream & out ) const;
1215 
1220  bool isValid() const;
1221 
1222  // ------------------------- Protected Datas ------------------------------
1223  private:
1224  // ------------------------- Private Datas --------------------------------
1225  private:
1226 
1229 
1233  __FirstBlock myFirstBlock;
1234 
1235  // ------------------------- Hidden services ------------------------------
1236  protected:
1237 
1238  // ------------------------- Internals ------------------------------------
1239  private:
1240 
1241  }; // end of class LabelledMap
1242 
1243 
1255  template <typename TData, unsigned int L, typename TWord,
1256  unsigned int N, unsigned int M>
1257  std::ostream&
1258  operator<< ( std::ostream & out,
1259  const LabelledMap<TData, L, TWord, N, M> & object );
1260 
1261  namespace detail {
1262 
1268  {
1269  double _p; double _q;
1270  unsigned int _sL;
1271  unsigned int _sV;
1272  unsigned int _sP;
1273  unsigned int _sA;
1274  LabelledMapMemFunctor( double p, double q,
1275  unsigned int sL, unsigned int sV,
1276  unsigned int sP, unsigned int sA )
1277  : _p( p ), _q( q ), _sL( sL ), _sV( sV ), _sP( sP ), _sA( sA )
1278  {}
1279 
1280  inline
1281  double fctNM( unsigned int N, unsigned int M ) const
1282  {
1283  double alpha0 = _sL + _sV * ( N+1 );
1284  double beta0 = _sV * M + _sA + _sP;
1285  return alpha0
1286  + beta0 * _q * pow(1.0 - _p, (double)N+1)
1287  * ( 1.0 + pow(1.0 - _p, (double)M-1 )
1288  / ( 1.0 - pow(1.0 - _p, (double)M ) ) );
1289  }
1290  inline
1291  double fctNMpq( unsigned int N, unsigned int M, double p, double q ) const
1292  {
1293  double alpha0 = _sL + _sV * ( N+1 );
1294  double beta0 = _sV * M + _sA + _sP;
1295  return alpha0
1296  + beta0 * q * pow(1.0 - p, (double)N+1)
1297  * ( 1.0 + pow(1.0 - p, (double)M-1 )
1298  / ( 1.0 - pow(1.0 - p, (double)M ) ) );
1299  }
1300 
1301  };
1302 
1322  template <typename TData>
1323  std::pair< unsigned int, unsigned int >
1325  ( unsigned int L, double prob_no_data, double prob_one_data );
1326  }
1327 
1328 } // namespace DGtal
1329 
1330 
1332 // Includes inline functions.
1333 #include "DGtal/base/LabelledMap.ih"
1334 
1335 // //
1337 
1338 #endif // !defined LabelledMap_h
1339 
1340 #undef LabelledMap_RECURSES
1341 #endif // else defined(LabelledMap_RECURSES)