STXXL  1.4-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
adaptor.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/mng/adaptor.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002-2003 Roman Dementiev <[email protected]>
7  * Copyright (C) 2007 Johannes Singler <[email protected]>
8  * Copyright (C) 2009-2010 Andreas Beckmann <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_MNG_ADAPTOR_HEADER
16 #define STXXL_MNG_ADAPTOR_HEADER
17 
18 #include <iterator>
19 
21 
23 
24 //! \addtogroup mnglayer
25 //!
26 //! \{
27 
28 template <unsigned_type modulo>
30 {
34 
35  //! \invariant block * modulo + offset = pos
36 
37  void set(unsigned_type pos)
38  {
39  this->pos = pos;
40  block = pos / modulo;
41  offset = pos % modulo;
42  }
43 
44 public:
46  {
47  set(0);
48  }
49 
51  {
52  set(pos);
53  }
54 
56  {
57  this->block = block;
58  this->offset = offset;
59  pos = block * modulo + offset;
60  }
61 
62  void operator = (unsigned_type pos)
63  {
64  set(pos);
65  }
66 
67  //pre-increment operator
69  {
70  ++pos;
71  ++offset;
72  if (offset == modulo)
73  {
74  offset = 0;
75  ++block;
76  }
77  return *this;
78  }
79 
80  //post-increment operator
82  {
83  blocked_index former(*this);
84  operator ++ ();
85  return former;
86  }
87 
88  //pre-increment operator
90  {
91  --pos;
92  if (offset == 0)
93  {
94  offset = modulo;
95  --block;
96  }
97  --offset;
98  return *this;
99  }
100 
101  //post-increment operator
103  {
104  blocked_index former(*this);
105  operator -- ();
106  return former;
107  }
108 
110  {
111  set(pos + addend);
112  return *this;
113  }
114 
115  blocked_index& operator >>= (unsigned_type shift)
116  {
117  set(pos >> shift);
118  return *this;
119  }
120 
121  operator unsigned_type () const
122  {
123  return pos;
124  }
125 
126  const unsigned_type & get_block() const
127  {
128  return block;
129  }
130 
131  const unsigned_type & get_offset() const
132  {
133  return offset;
134  }
135 };
136 
137 #define STXXL_ADAPTOR_ARITHMETICS(pos) \
138  bool operator == (const self_type &a) const \
139  { \
140  return (a.pos == pos); \
141  } \
142  bool operator != (const self_type& a) const \
143  { \
144  return (a.pos != pos); \
145  } \
146  bool operator < (const self_type& a) const \
147  { \
148  return (pos < a.pos); \
149  } \
150  bool operator > (const self_type& a) const \
151  { \
152  return (pos > a.pos); \
153  } \
154  bool operator <= (const self_type& a) const \
155  { \
156  return (pos <= a.pos); \
157  } \
158  bool operator >= (const self_type& a) const \
159  { \
160  return (pos >= a.pos); \
161  } \
162  self_type operator + (pos_type off) const \
163  { \
164  return self_type(array, pos + off); \
165  } \
166  self_type operator - (pos_type off) const \
167  { \
168  return self_type(array, pos - off); \
169  } \
170  self_type& operator ++ () \
171  { \
172  pos++; \
173  return *this; \
174  } \
175  self_type operator ++ (int) \
176  { \
177  self_type tmp = *this; \
178  pos++; \
179  return tmp; \
180  } \
181  self_type& operator -- () \
182  { \
183  pos--; \
184  return *this; \
185  } \
186  self_type operator -- (int) \
187  { \
188  self_type tmp = *this; \
189  pos--; \
190  return tmp; \
191  } \
192  pos_type operator - (const self_type& a) const \
193  { \
194  return pos - a.pos; \
195  } \
196  self_type& operator -= (pos_type off) \
197  { \
198  pos -= off; \
199  return *this; \
200  } \
201  self_type& operator += (pos_type off) \
202  { \
203  pos += off; \
204  return *this; \
205  }
206 
207 template <class OneDimArrayType, class DataType, class PosType>
209  : public std::iterator<std::random_access_iterator_tag, DataType, unsigned_type>
210 {
211  typedef OneDimArrayType one_dim_array_type;
212  typedef DataType data_type;
213  typedef PosType pos_type;
214 
217 
220 
222  { }
223 
225  : array(a), pos(p)
226  { }
228  : array(a.array), pos(a.pos)
229  { }
230 
232 };
233 
234 //////////////////////////////
235 
236 #define BLOCK_ADAPTOR_OPERATORS(two_to_one_dim_array_adaptor_base) \
237  \
238  template <unsigned BlockSize, typename RunType, class PosType> \
239  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& operator ++ ( \
240  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a) \
241  { \
242  a.pos++; \
243  return a; \
244  } \
245  \
246  template <unsigned BlockSize, typename RunType, class PosType> \
247  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> operator ++ ( \
248  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a, int) \
249  { \
250  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> tmp = a; \
251  a.pos++; \
252  return tmp; \
253  } \
254  \
255  template <unsigned BlockSize, typename RunType, class PosType> \
256  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& operator -- ( \
257  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a) \
258  { \
259  a.pos--; \
260  return a; \
261  } \
262  \
263  template <unsigned BlockSize, typename RunType, class PosType> \
264  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> operator -- ( \
265  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a, int) \
266  { \
267  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> tmp = a; \
268  a.pos--; \
269  return tmp; \
270  } \
271  \
272  template <unsigned BlockSize, typename RunType, class PosType> \
273  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& operator -= ( \
274  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a, \
275  typename two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>::_pos_type off) \
276  { \
277  a.pos -= off; \
278  return a; \
279  } \
280  \
281  template <unsigned BlockSize, typename RunType, class PosType> \
282  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& operator += ( \
283  two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a, \
284  typename two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>::_pos_type off) \
285  { \
286  a.pos += off; \
287  return a; \
288  } \
289  \
290  template <unsigned BlockSize, typename RunType, class PosType> \
291  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> operator + ( \
292  const two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a, \
293  typename two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>::_pos_type off) \
294  { \
295  return two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>(a.array, a.pos + off); \
296  } \
297  \
298  template <unsigned BlockSize, typename RunType, class PosType> \
299  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> operator + ( \
300  typename two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>::_pos_type off, \
301  const two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a) \
302  { \
303  return two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>(a.array, a.pos + off); \
304  } \
305  \
306  template <unsigned BlockSize, typename RunType, class PosType> \
307  inline two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType> operator - ( \
308  const two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>& a, \
309  typename two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>::_pos_type off) \
310  { \
311  return two_to_one_dim_array_adaptor_base<BlockSize, RunType, PosType>(a.array, a.pos - off); \
312  }
313 
314 #if 0
315 //////////////////////////
316 template <class OneDimArrayType, class DataType,
317  unsigned DimSize, class PosType = blocked_index<DimSize> >
318 struct two2one_dim_array_row_adapter
319  : public two2one_dim_array_adapter_base<OneDimArrayType, DataType, PosType>
320 {
321  typedef OneDimArrayType one_dim_array_type;
322  typedef DataType data_type;
323  typedef DimSize dim_type;
324  typedef PosType pos_type;
325 
326  typedef two2one_dim_array_row_adapter<one_dim_array_type,
327  data_type, dim_size, pos_type> self_type;
328 
329  typedef two2one_dim_array_adapter_base<one_dim_array_type,
330  data_type, pos_type> base_type;
331  using base_type::array;
332  using base_type::pos;
333 
334  two2one_dim_array_row_adapter()
335  { }
336  two2one_dim_array_row_adapter(one_dim_array_type* a, pos_type p)
337  : two2one_dim_array_adapter_base<one_dim_array_type, data_type, pos_type>(a, p)
338  { }
339  two2one_dim_array_row_adapter(const two2one_dim_array_row_adapter& a)
340  : two2one_dim_array_adapter_base<one_dim_array_type, data_type, pos_type>(a)
341  { }
342 
343  data_type& operator * ()
344  {
345  return array[(pos).get_block()][(pos).get_offset()];
346  }
347 
348  data_type* operator -> () const
349  {
350  return &(array[(pos).get_block()][(pos).get_offset()]);
351  }
352 
353  data_type& operator [] (pos_type n)
354  {
355  n += pos;
356  return array[(n) / dim_size][(n) % dim_size];
357  }
358 
359  const data_type& operator [] (pos_type n) const
360  {
361  n += pos;
362  return array[(n) / dim_size][(n) % dim_size];
363  }
365 };
366 
367 template <class OneDimArrayType, class DataType,
368  unsigned DimSize, class PosType = blocked_index<DimSize> >
369 struct two2one_dim_array_column_adapter
370  : public two2one_dim_array_adapter_base<OneDimArrayType, DataType, PosType>
371 {
372  typedef two2one_dim_array_column_adapter<one_dim_array_type,
373  data_type, dim_size, pos_type> self_type;
374 
375  using two2one_dim_array_adapter_base<one_dim_array_type, data_type, pos_type>::pos;
376  using two2one_dim_array_adapter_base<one_dim_array_type, data_type, pos_type>::array;
377 
378  two2one_dim_array_column_adapter(one_dim_array_type* a, pos_type p)
379  : two2one_dim_array_adapter_base<one_dim_array_type, data_type, pos_type>(a, p)
380  { }
381  two2one_dim_array_column_adapter(const self_type& a)
382  : two2one_dim_array_adapter_base<one_dim_array_type, data_type, pos_type>(a)
383  { }
384 
385  data_type& operator * ()
386  {
387  return array[(pos).get_offset()][(pos).get_block()];
388  }
389 
390  data_type* operator -> () const
391  {
392  return &(array[(pos).get_offset()][(pos).get_block()]);
393  }
394 
395  const data_type& operator [] (pos_type n) const
396  {
397  n += pos;
398  return array[(n) % dim_size][(n) / dim_size];
399  }
400 
401  data_type& operator [] (pos_type n)
402  {
403  n += pos;
404  return array[(n) % dim_size][(n) / dim_size];
405  }
407 };
408 #endif
409 
410 template <typename ArrayType, typename ValueType, unsigned_type modulo>
412  : public std::iterator<std::random_access_iterator_tag, ValueType, unsigned_type>
413 {
414 public:
415  typedef ArrayType array_type;
416  typedef ValueType value_type;
417 
418 protected:
424 
425  //! \invariant block * modulo + offset = pos
426 
427  void set(unsigned_type pos)
428  {
429  this->pos = pos;
430  offset = pos % modulo;
431  base = arrays + pos / modulo;
432  base_element = base->elem;
433  }
434 
435 public:
437  {
438  this->arrays = NULL;
439  set(0);
440  }
441 
443  {
444  this->arrays = arrays;
445  set(0);
446  }
447 
449  {
450  this->arrays = arrays;
451  set(pos);
452  }
453 
454  void operator = (unsigned_type pos)
455  {
456  set(pos);
457  }
458 
459  //pre-increment operator
461  {
462  ++pos;
463  ++offset;
464  if (offset == modulo)
465  {
466  offset = 0;
467  ++base;
468  base_element = base->elem;
469  }
470  return *this;
471  }
472 
473  //post-increment operator
475  {
476  array_of_sequences_iterator former(*this);
477  operator ++ ();
478  return former;
479  }
480 
481  //pre-increment operator
483  {
484  --pos;
485  if (offset == 0)
486  {
487  offset = modulo;
488  --base;
489  base_element = base->elem;
490  }
491  --offset;
492  return *this;
493  }
494 
495  //post-increment operator
497  {
498  array_of_sequences_iterator former(*this);
499  operator -- ();
500  return former;
501  }
502 
504  {
505  set(pos + addend);
506  return *this;
507  }
508 
510  {
511  set(pos - addend);
512  return *this;
513  }
514 
515  array_of_sequences_iterator operator + (unsigned_type addend) const
516  {
517  return array_of_sequences_iterator(arrays, pos + addend);
518  }
519 
520  array_of_sequences_iterator operator - (unsigned_type subtrahend) const
521  {
522  return array_of_sequences_iterator(arrays, pos - subtrahend);
523  }
524 
525  unsigned_type operator - (const array_of_sequences_iterator& subtrahend) const
526  {
527  return pos - subtrahend.pos;
528  }
529 
531  {
532  return pos == aoai.pos;
533  }
534 
536  {
537  return pos != aoai.pos;
538  }
539 
540  bool operator < (const array_of_sequences_iterator& aoai) const
541  {
542  return pos < aoai.pos;
543  }
544 
546  {
547  return pos <= aoai.pos;
548  }
549 
550  bool operator > (const array_of_sequences_iterator& aoai) const
551  {
552  return pos > aoai.pos;
553  }
554 
556  {
557  return pos >= aoai.pos;
558  }
559 
560  const value_type& operator * () const
561  {
562  return base_element[offset];
563  }
564 
565  value_type& operator * ()
566  {
567  return base_element[offset];
568  }
569 
570  const value_type& operator -> () const
571  {
572  return &(base_element[offset]);
573  }
574 
575  value_type& operator -> ()
576  {
577  return &(base_element[offset]);
578  }
579 
580  const value_type& operator [] (unsigned_type index) const
581  {
582  return arrays[index / modulo][index % modulo];
583  }
584 
585  value_type& operator [] (unsigned_type index)
586  {
587  return arrays[index / modulo][index % modulo];
588  }
589 };
590 
591 namespace helper {
592 
593 template <typename BlockType, typename SizeType, bool CanUseTrivialPointer>
595 { };
596 
597 // default case for blocks with fillers or other data: use array_of_sequences_iterator
598 template <typename BlockType, typename SizeType>
599 class element_iterator_generator<BlockType, SizeType, false>
600 {
601  typedef BlockType block_type;
602  typedef typename block_type::value_type value_type;
603 
604  typedef SizeType size_type;
605 
606 public:
608 
609  iterator operator () (block_type* blocks, SizeType offset) const
610  {
611  return iterator(blocks, offset);
612  }
613 };
614 
615 // special case for completely filled blocks: use trivial pointers
616 template <typename BlockType, typename SizeType>
617 class element_iterator_generator<BlockType, SizeType, true>
618 {
619  typedef BlockType block_type;
620  typedef typename block_type::value_type value_type;
621 
622  typedef SizeType size_type;
623 
624 public:
626 
627  iterator operator () (block_type* blocks, SizeType offset) const
628  {
629  return blocks[0].elem + offset;
630  }
631 };
632 
633 } // namespace helper
634 
635 template <typename BlockType, typename SizeType>
637 {
638  typedef typename helper::element_iterator_generator<
639  BlockType, SizeType, BlockType::has_only_data
640  >::iterator element_iterator;
641 };
642 
643 template <typename BlockType, typename SizeType>
644 inline
646 make_element_iterator(BlockType* blocks, SizeType offset)
647 {
649  BlockType, SizeType, BlockType::has_only_data
650  > iter_gen;
651  return iter_gen(blocks, offset);
652 }
653 
654 //! \}
655 
657 
658 #endif // !STXXL_MNG_ADAPTOR_HEADER
659 // vim: et:ts=4:sw=4
const unsigned_type & get_offset() const
Definition: adaptor.h:131
array_of_sequences_iterator< block_type, value_type, block_type::size > iterator
Definition: adaptor.h:607
blocked_index(unsigned_type pos)
Definition: adaptor.h:50
blocked_index(unsigned_type block, unsigned_type offset)
Definition: adaptor.h:55
unsigned_type block
Definition: adaptor.h:32
const unsigned_type & get_block() const
Definition: adaptor.h:126
uint_pair & operator++()
prefix increment operator (directly manipulates the integer parts)
Definition: uint_types.h:163
two2one_dim_array_adapter_base(const two2one_dim_array_adapter_base &a)
Definition: adaptor.h:227
uint_pair & operator+=(const uint_pair &b)
addition operator (uses 64-bit arithmetic)
Definition: uint_types.h:183
two2one_dim_array_adapter_base(one_dim_array_type *a, pos_type p)
Definition: adaptor.h:224
bool operator!=(const uint_pair &b) const
inequality checking operator
Definition: uint_types.h:198
bool operator<=(const uint_pair &b) const
less-or-equal comparison operator
Definition: uint_types.h:210
bool operator>(const uint_pair &b) const
greater comparison operator
Definition: uint_types.h:216
bool operator>=(const uint_pair &b) const
greater-or-equal comparison operator
Definition: uint_types.h:222
bool operator<(const uint_pair &b) const
less-than comparison operator
Definition: uint_types.h:204
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
array_of_sequences_iterator(array_type *arrays, unsigned_type pos)
Definition: adaptor.h:448
uint_pair & operator--()
prefix decrement operator (directly manipulates the integer parts)
Definition: uint_types.h:173
void set(unsigned_type pos)
Definition: adaptor.h:427
array_of_sequences_iterator(array_type *arrays)
Definition: adaptor.h:442
two2one_dim_array_adapter_base< one_dim_array_type, data_type, pos_type > self_type
Definition: adaptor.h:216
element_iterator_traits< BlockType, SizeType >::element_iterator make_element_iterator(BlockType *blocks, SizeType offset)
Definition: adaptor.h:646
void set(unsigned_type pos)
Definition: adaptor.h:37
#define STXXL_ADAPTOR_ARITHMETICS(pos)
Definition: adaptor.h:137
choose_int_types< my_pointer_size >::unsigned_type unsigned_type
Definition: types.h:64
unsigned_type offset
Definition: adaptor.h:33
one_dim_array_type * array
Definition: adaptor.h:218
unsigned_type pos
Definition: adaptor.h:31
bool operator==(const uint_pair &b) const
equality checking operator
Definition: uint_types.h:192
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
helper::element_iterator_generator< BlockType, SizeType, BlockType::has_only_data >::iterator element_iterator
Definition: adaptor.h:640