STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
deque.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/containers/deque.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2006 Roman Dementiev <[email protected]>
7  * Copyright (C) 2008, 2009 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2013 Timo Bingmann <[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_CONTAINERS_DEQUE_HEADER
16 #define STXXL_CONTAINERS_DEQUE_HEADER
17 
18 #include <limits>
19 #include <stxxl/vector>
20 
21 
23 
24 template <class ValueType, class VectorType>
25 class deque;
26 
27 template <class DequeType>
29 
30 template <class DequeType>
32 {
33 public:
34  typedef DequeType deque_type;
35  typedef typename deque_type::vector_type vector_type;
36 
37  typedef typename deque_type::value_type value_type;
38  typedef typename deque_type::pointer pointer;
39  typedef typename deque_type::const_pointer const_pointer;
40  typedef typename deque_type::reference reference;
41  typedef typename deque_type::const_reference const_reference;
42  typedef typename deque_type::size_type size_type;
43  typedef typename deque_type::difference_type difference_type;
46 
47  typedef std::random_access_iterator_tag iterator_category;
48 
50  friend class deque<value_type, vector_type>;
51 
52 protected:
54 
57 
59  : m_deque(deque), m_offset(offset)
60  { }
61 
62 public:
63  deque_iterator() : m_deque(NULL), m_offset(0) { }
64 
65  difference_type operator - (const self_type& a) const
66  {
67  size_type SelfAbsOffset = (m_offset >= m_deque->m_begin) ?
68  m_offset : (m_deque->m_vector.size() + m_offset);
69  size_type aAbsOffset = (a.m_offset >= m_deque->m_begin) ?
70  a.m_offset : (m_deque->m_vector.size() + a.m_offset);
71 
72  return SelfAbsOffset - aAbsOffset;
73  }
74 
75  difference_type operator - (const const_iterator& a) const
76  {
77  size_type SelfAbsOffset = (m_offset >= m_deque->m_begin) ?
78  m_offset : (m_deque->m_vector.size() + m_offset);
79  size_type aAbsOffset = (a.m_offset >= m_deque->m_begin) ?
80  a.m_offset : (m_deque->m_vector.size() + a.m_offset);
81 
82  return SelfAbsOffset - aAbsOffset;
83  }
84 
85  self_type operator - (size_type op) const
86  {
87  return self_type(m_deque, (m_offset + m_deque->m_vector.size() - op) % m_deque->m_vector.size());
88  }
89 
90  self_type operator + (size_type op) const
91  {
92  return self_type(m_deque, (m_offset + op) % m_deque->m_vector.size());
93  }
94 
95  self_type& operator -= (size_type op)
96  {
97  m_offset = (m_offset + m_deque->m_vector.size() - op) % m_deque->m_vector.size();
98  return *this;
99  }
100 
102  {
103  m_offset = (m_offset + op) % m_deque->m_vector.size();
104  return *this;
105  }
106 
107  reference operator * ()
108  {
109  return m_deque->m_vector[m_offset];
110  }
111 
112  pointer operator -> ()
113  {
114  return &(m_deque->m_vector[m_offset]);
115  }
116 
117  const_reference operator * () const
118  {
119  return m_deque->m_vector[m_offset];
120  }
121 
122  const_pointer operator -> () const
123  {
124  return &(m_deque->m_vector[m_offset]);
125  }
126 
127  reference operator [] (size_type op)
128  {
129  return m_deque->m_vector[(m_offset + op) % m_deque->m_vector.size()];
130  }
131 
132  const_reference operator [] (size_type op) const
133  {
134  return m_deque->m_vector[(m_offset + op) % m_deque->m_vector.size()];
135  }
136 
138  {
139  m_offset = (m_offset + 1) % m_deque->m_vector.size();
140  return *this;
141  }
143  {
144  self_type tmp = *this;
145  m_offset = (m_offset + 1) % m_deque->m_vector.size();
146  return tmp;
147  }
149  {
150  m_offset = (m_offset + m_deque->m_vector.size() - 1) % m_deque->m_vector.size();
151  return *this;
152  }
154  {
155  self_type tmp = *this;
156  m_offset = (m_offset + m_deque->m_vector.size() - 1) % m_deque->m_vector.size();
157  return tmp;
158  }
159  bool operator == (const self_type& a) const
160  {
161  assert(m_deque == a.m_deque);
162  return m_offset == a.m_offset;
163  }
164  bool operator != (const self_type& a) const
165  {
166  assert(m_deque == a.m_deque);
167  return m_offset != a.m_offset;
168  }
169 
170  bool operator < (const self_type& a) const
171  {
172  assert(m_deque == a.m_deque);
173  return (a - (*this)) > 0;
174  }
175 
176  bool operator > (const self_type& a) const
177  {
178  return a < (*this);
179  }
180 
181  bool operator <= (const self_type& a) const
182  {
183  return !((*this) > a);
184  }
185 
186  bool operator >= (const self_type& a) const
187  {
188  return !((*this) < a);
189  }
190 
191  bool operator == (const const_iterator& a) const
192  {
193  assert(m_deque == a.m_deque);
194  return m_offset == a.m_offset;
195  }
196  bool operator != (const const_iterator& a) const
197  {
198  assert(m_deque == a.m_deque);
199  return m_offset != a.m_offset;
200  }
201 
202  bool operator < (const const_iterator& a) const
203  {
204  assert(m_deque == a.m_deque);
205  return (a - (*this)) > 0;
206  }
207 
208  bool operator > (const const_iterator& a) const
209  {
210  return a < (*this);
211  }
212 
213  bool operator <= (const const_iterator& a) const
214  {
215  return !((*this) > a);
216  }
217 
218  bool operator >= (const const_iterator& a) const
219  {
220  return !((*this) < a);
221  }
222 };
223 
224 template <class DequeType>
225 class const_deque_iterator
226 {
227 public:
228  typedef DequeType deque_type;
229  typedef typename deque_type::vector_type vector_type;
230 
231  typedef typename deque_type::value_type value_type;
232  typedef typename deque_type::const_pointer pointer;
233  typedef typename deque_type::const_pointer const_pointer;
234  typedef typename deque_type::const_reference reference;
235  typedef typename deque_type::const_reference const_reference;
236  typedef typename deque_type::size_type size_type;
237  typedef typename deque_type::difference_type difference_type;
238 
241 
242  typedef std::random_access_iterator_tag iterator_category;
243 
244  friend class deque_iterator<deque_type>;
245  friend class deque<value_type, vector_type>;
246 
247 protected:
249 
252 
254  : m_deque(deque), m_offset(offset)
255  { }
256 
257 public:
258  const_deque_iterator() : m_deque(NULL), m_offset(0) { }
259 
261  m_deque(it.m_deque), m_offset(it.m_offset)
262  { }
263 
264  difference_type operator - (const self_type& a) const
265  {
266  size_type SelfAbsOffset = (m_offset >= m_deque->m_begin) ?
267  m_offset : (m_deque->m_vector.size() + m_offset);
268  size_type aAbsOffset = (a.m_offset >= m_deque->m_begin) ?
269  a.m_offset : (m_deque->m_vector.size() + a.m_offset);
270 
271  return SelfAbsOffset - aAbsOffset;
272  }
273 
274  difference_type operator - (const iterator& a) const
275  {
276  size_type SelfAbsOffset = (m_offset >= m_deque->m_begin) ?
277  m_offset : (m_deque->m_vector.size() + m_offset);
278  size_type aAbsOffset = (a.m_offset >= m_deque->m_begin) ?
279  a.m_offset : (m_deque->m_vector.size() + a.m_offset);
280 
281  return SelfAbsOffset - aAbsOffset;
282  }
283 
284  self_type operator - (size_type op) const
285  {
286  return self_type(m_deque, (m_offset + m_deque->m_vector.size() - op) % m_deque->m_vector.size());
287  }
288 
289  self_type operator + (size_type op) const
290  {
291  return self_type(m_deque, (m_offset + op) % m_deque->m_vector.size());
292  }
293 
294  self_type& operator -= (size_type op)
295  {
296  m_offset = (m_offset + m_deque->m_vector.size() - op) % m_deque->m_vector.size();
297  return *this;
298  }
299 
301  {
302  m_offset = (m_offset + op) % m_deque->m_vector.size();
303  return *this;
304  }
305 
306  const_reference operator * () const
307  {
308  return m_deque->m_vector[m_offset];
309  }
310 
311  const_pointer operator -> () const
312  {
313  return &(m_deque->m_vector[m_offset]);
314  }
315 
316  const_reference operator [] (size_type op) const
317  {
318  return m_deque->m_vector[(m_offset + op) % m_deque->m_vector.size()];
319  }
320 
322  {
323  m_offset = (m_offset + 1) % m_deque->m_vector.size();
324  return *this;
325  }
327  {
328  self_type tmp = *this;
329  m_offset = (m_offset + 1) % m_deque->m_vector.size();
330  return tmp;
331  }
333  {
334  m_offset = (m_offset + m_deque->m_vector.size() - 1) % m_deque->m_vector.size();
335  return *this;
336  }
338  {
339  self_type tmp = *this;
340  m_offset = (m_offset + m_deque->m_vector.size() - 1) % m_deque->m_vector.size();
341  return tmp;
342  }
343  bool operator == (const self_type& a) const
344  {
345  assert(m_deque == a.m_deque);
346  return m_offset == a.m_offset;
347  }
348  bool operator != (const self_type& a) const
349  {
350  assert(m_deque == a.m_deque);
351  return m_offset != a.m_offset;
352  }
353 
354  bool operator < (const self_type& a) const
355  {
356  assert(m_deque == a.m_deque);
357  return (a - (*this)) > 0;
358  }
359 
360  bool operator > (const self_type& a) const
361  {
362  return a < (*this);
363  }
364 
365  bool operator <= (const self_type& a) const
366  {
367  return !((*this) > a);
368  }
369 
370  bool operator >= (const self_type& a) const
371  {
372  return !((*this) < a);
373  }
374 
375  bool operator == (const iterator& a) const
376  {
377  assert(m_deque == a.m_deque);
378  return m_offset == a.m_offset;
379  }
380  bool operator != (const iterator& a) const
381  {
382  assert(m_deque == a.m_deque);
383  return m_offset != a.m_offset;
384  }
385 
386  bool operator < (const iterator& a) const
387  {
388  assert(m_deque == a.m_deque);
389  return (a - (*this)) > 0;
390  }
391 
392  bool operator > (const iterator& a) const
393  {
394  return a < (*this);
395  }
396 
397  bool operator <= (const iterator& a) const
398  {
399  return !((*this) > a);
400  }
401 
402  bool operator >= (const iterator& a) const
403  {
404  return !((*this) < a);
405  }
406 };
407 
408 //! \addtogroup stlcont
409 //! \{
410 
411 //! A deque container. \n
412 //! <b> Introduction </b> to deque container: see \ref tutorial_deque tutorial. \n
413 //! <b> Design and Internals </b> of deque container: see \ref design_deque
414 //!
415 //! It is an adaptor of the \c VectorType.
416 //! The implementation wraps the elements around
417 //! the end of the \c VectorType circularly.
418 //! \tparam ValueType type of the contained objects (POD with no references to internal memory)
419 //! \tparam VectorType the type of the underlying vector container,
420 //! the default is \c stxxl::vector<ValueType>
421 template <class ValueType, class VectorType = stxxl::vector<ValueType> >
422 class deque : private noncopyable
423 {
425 
426 public:
427  typedef typename VectorType::size_type size_type;
428  typedef typename VectorType::difference_type difference_type;
429  typedef VectorType vector_type;
430  typedef ValueType value_type;
431  typedef ValueType* pointer;
432  typedef const value_type* const_pointer;
433  typedef ValueType& reference;
434  typedef const ValueType& const_reference;
437  typedef std::reverse_iterator<iterator> reverse_iterator;
438  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
439 
440  friend class deque_iterator<self_type>;
442 
443 private:
445  size_type m_begin, m_end, m_size;
446 
448  {
449  const size_type old_size = m_vector.size();
450  m_vector.resize(2 * old_size);
451  if (m_begin > m_end)
452  { // copy data to the new end of the vector
453  const size_type new_begin = old_size + m_begin;
454  std::copy(m_vector.begin() + m_begin,
455  m_vector.begin() + old_size,
456  m_vector.begin() + new_begin);
457  m_begin = new_begin;
458  }
459  }
460 
461 public:
462  //! \name Constructors/Destructors
463  //! \{
464 
466  : m_vector((STXXL_DEFAULT_BLOCK_SIZE(T)) / sizeof(value_type)),
467  m_begin(0), m_end(0), m_size(0)
468  { }
469 
471  : m_vector(STXXL_MAX<size_type>(STXXL_DEFAULT_BLOCK_SIZE(ValueType) / sizeof(value_type), 2 * n)),
472  m_begin(0), m_end(n), m_size(n)
473  { }
474 
475  ~deque() // empty so far
476  { }
477 
478  //! \}
479 
480  //! \name Iterators
481  //! \{
482 
484  {
485  return iterator(this, m_begin);
486  }
488  {
489  return iterator(this, m_end);
490  }
492  {
493  return const_iterator(this, m_begin);
494  }
496  {
497  return begin();
498  }
500  {
501  return const_iterator(this, m_end);
502  }
504  {
505  return end();
506  }
507 
509  {
510  return reverse_iterator(end());
511  }
513  {
514  return const_reverse_iterator(end());
515  }
517  {
518  return const_reverse_iterator(end());
519  }
521  {
522  return reverse_iterator(begin());
523  }
525  {
526  return const_reverse_iterator(begin());
527  }
529  {
530  return const_reverse_iterator(begin());
531  }
532 
533  //! \}
534 
535  //! \name Capacity
536  //! \{
537 
538  size_type size() const
539  {
540  return m_size;
541  }
542 
544  {
545  return std::numeric_limits<size_type>::max() / 2 - 1;
546  }
547 
548  bool empty() const
549  {
550  return m_size == 0;
551  }
552 
553  //! \}
554 
555  //! \name Operators
556  //! \{
557 
558  reference operator [] (size_type n)
559  {
560  assert(n < size());
561  return m_vector[(m_begin + n) % m_vector.size()];
562  }
563 
564  const_reference operator [] (size_type n) const
565  {
566  assert(n < size());
567  return m_vector[(m_begin + n) % m_vector.size()];
568  }
569 
571  {
572  assert(!empty());
573  return m_vector[m_begin];
574  }
575 
577  {
578  assert(!empty());
579  return m_vector[m_begin];
580  }
581 
583  {
584  assert(!empty());
585  return m_vector[(m_end + m_vector.size() - 1) % m_vector.size()];
586  }
587 
589  {
590  assert(!empty());
591  return m_vector[(m_end + m_vector.size() - 1) % m_vector.size()];
592  }
593 
594  //! \}
595 
596  //! \name Modifiers
597  //! \{
598 
599  void push_front(const value_type& el)
600  {
601  if ((m_begin + m_vector.size() - 1) % m_vector.size() == m_end)
602  {
603  // an overflow will occur: resize the array
604  double_array();
605  }
606 
607  m_begin = (m_begin + m_vector.size() - 1) % m_vector.size();
608  m_vector[m_begin] = el;
609  ++m_size;
610  }
611 
612  void push_back(const value_type& el)
613  {
614  if ((m_end + 1) % m_vector.size() == m_begin)
615  {
616  // an overflow will occur: resize the array
617  double_array();
618  }
619  m_vector[m_end] = el;
620  m_end = (m_end + 1) % m_vector.size();
621  ++m_size;
622  }
623 
624  void pop_front()
625  {
626  assert(!empty());
627  m_begin = (m_begin + 1) % m_vector.size();
628  --m_size;
629  }
630 
631  void pop_back()
632  {
633  assert(!empty());
634  m_end = (m_end + m_vector.size() - 1) % m_vector.size();
635  --m_size;
636  }
637 
638  //! \}
639 
640  //! \name Modifiers
641  //! \{
642 
643  void swap(deque& obj)
644  {
645  std::swap(m_vector, obj.m_vector);
646  std::swap(m_begin, obj.m_begin);
647  std::swap(m_end, obj.m_end);
648  std::swap(m_size, obj.m_size);
649  }
650 
651  void clear()
652  {
653  m_vector.clear();
654  m_vector.resize((STXXL_DEFAULT_BLOCK_SIZE(T)) / sizeof(value_type));
655  m_begin = 0;
656  m_end = 0;
657  m_size = 0;
658  }
659 
660  //! \}
661 
662  //! \name Capacity
663  //! \{
664 
666  {
667  if (n < size())
668  {
669  do
670  {
671  pop_back();
672  } while (n < size());
673  }
674  else
675  {
676  if (n + 1 > m_vector.size())
677  { // need to resize
678  const size_type old_size = m_vector.size();
679  m_vector.resize(2 * n);
680  if (m_begin > m_end)
681  { // copy data to the new end of the vector
682  const size_type new_begin = m_vector.size() - old_size + m_begin;
683  std::copy(m_vector.begin() + m_begin,
684  m_vector.begin() + old_size,
685  m_vector.begin() + new_begin);
686  m_begin = new_begin;
687  }
688  }
689  m_end = (m_end + n - size()) % m_vector.size();
690  m_size = n;
691  }
692  }
693 
694  //! \}
695 };
696 
697 template <class ValueType, class VectorType>
699 {
700  return std::equal(a.begin(), a.end(), b.begin());
701 }
702 
703 template <class ValueType, class VectorType>
704 bool operator < (const deque<ValueType, VectorType>& a, const deque<ValueType, VectorType>& b)
705 {
706  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
707 }
708 
709 //! \}
710 
712 
713 namespace std {
714 
715 template <typename ValueType, typename VectorType>
718 {
719  a.swap(b);
720 }
721 
722 } // namespace std
723 
724 #endif // !STXXL_CONTAINERS_DEQUE_HEADER
vector_type m_vector
Definition: deque.h:444
deque_type::reference reference
Definition: deque.h:40
deque_type::const_reference const_reference
Definition: deque.h:41
#define STXXL_DEFAULT_BLOCK_SIZE(type)
deque_iterator(deque_type *deque, size_type offset)
Definition: deque.h:58
const_deque_iterator< deque_type > const_iterator
Definition: deque.h:45
VectorType::difference_type difference_type
Definition: deque.h:428
const value_type * const_pointer
Definition: deque.h:432
deque_type * m_deque
Definition: deque.h:55
deque_type::size_type size_type
Definition: deque.h:236
const_deque_iterator(const deque_iterator< deque_type > &it)
Definition: deque.h:260
std::reverse_iterator< iterator > reverse_iterator
Definition: deque.h:437
const_reference front() const
Definition: deque.h:576
const_reference back() const
Definition: deque.h:588
iterator begin()
Definition: deque.h:483
A deque container. Introduction to deque container: see STXXL Deque tutorial. Design and Interna...
Definition: deque.h:25
size_type m_offset
Definition: deque.h:56
const_deque_iterator< self_type > const_iterator
Definition: deque.h:436
size_type size() const
Definition: deque.h:538
ValueType & reference
Definition: deque.h:433
reverse_iterator rbegin()
Definition: deque.h:508
deque_iterator< deque_type > iterator
Definition: deque.h:44
std::random_access_iterator_tag iterator_category
Definition: deque.h:47
deque< ValueType, VectorType > self_type
Definition: deque.h:424
deque(size_type n)
Definition: deque.h:470
deque_type::difference_type difference_type
Definition: deque.h:43
void swap(deque &obj)
Definition: deque.h:643
void clear()
Definition: deque.h:651
const_iterator end() const
Definition: deque.h:499
deque_type::const_pointer const_pointer
Definition: deque.h:39
uint_pair & operator++()
prefix increment operator (directly manipulates the integer parts)
Definition: uint_types.h:166
std::random_access_iterator_tag iterator_category
Definition: deque.h:242
reference back()
Definition: deque.h:582
VectorType vector_type
Definition: deque.h:429
const_deque_iterator< deque_type > const_iterator
Definition: deque.h:240
deque_type::vector_type vector_type
Definition: deque.h:229
uint_pair & operator+=(const uint_pair &b)
addition operator (uses 64-bit arithmetic)
Definition: uint_types.h:186
void pop_back()
Definition: deque.h:631
deque_type::difference_type difference_type
Definition: deque.h:237
bool operator!=(const uint_pair &b) const
inequality checking operator
Definition: uint_types.h:201
bool operator<=(const uint_pair &b) const
less-or-equal comparison operator
Definition: uint_types.h:213
const Tp & STXXL_MAX(const Tp &a, const Tp &b)
Definition: utils.h:154
bool operator>(const uint_pair &b) const
greater comparison operator
Definition: uint_types.h:219
const_reverse_iterator rbegin() const
Definition: deque.h:512
Container::value_type pop_back(Container &c)
Definition: utils.h:286
size_type max_size() const
Definition: deque.h:543
DequeType deque_type
Definition: deque.h:34
const_iterator begin() const
Definition: deque.h:491
ValueType * pointer
Definition: deque.h:431
bool operator>=(const uint_pair &b) const
greater-or-equal comparison operator
Definition: uint_types.h:225
bool operator<(const uint_pair &b) const
less-than comparison operator
Definition: uint_types.h:207
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
ValueType value_type
Definition: deque.h:430
uint_pair & operator--()
prefix decrement operator (directly manipulates the integer parts)
Definition: uint_types.h:176
deque_iterator< self_type > iterator
Definition: deque.h:435
const_deque_iterator(const deque_type *deque, size_type offset)
Definition: deque.h:253
deque_type::value_type value_type
Definition: deque.h:37
deque_iterator< deque_type > iterator
Definition: deque.h:239
VectorType::size_type size_type
Definition: deque.h:427
deque_type::vector_type vector_type
Definition: deque.h:35
void double_array()
Definition: deque.h:447
static uint_pair max()
return an uint_pair instance containing the largest value possible
Definition: uint_types.h:244
const_reverse_iterator rend() const
Definition: deque.h:524
deque_type::const_pointer const_pointer
Definition: deque.h:233
deque_iterator< deque_type > self_type
Definition: deque.h:53
deque_type::const_reference const_reference
Definition: deque.h:235
void pop_front()
Definition: deque.h:624
const_iterator cend() const
Definition: deque.h:503
const_deque_iterator< deque_type > self_type
Definition: deque.h:248
reference front()
Definition: deque.h:570
const_reverse_iterator crbegin() const
Definition: deque.h:516
void push_back(const value_type &el)
Definition: deque.h:612
void resize(size_type n)
Definition: deque.h:665
const ValueType & const_reference
Definition: deque.h:434
size_type m_size
Definition: deque.h:445
const_iterator cbegin() const
Definition: deque.h:495
deque_type::const_reference reference
Definition: deque.h:234
bool empty() const
Definition: deque.h:548
reverse_iterator rend()
Definition: deque.h:520
deque_type::const_pointer pointer
Definition: deque.h:232
deque_type::value_type value_type
Definition: deque.h:231
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: deque.h:438
deque_type::pointer pointer
Definition: deque.h:38
deque_type::size_type size_type
Definition: deque.h:42
void push_front(const value_type &el)
Definition: deque.h:599
bool operator==(const uint_pair &b) const
equality checking operator
Definition: uint_types.h:195
const deque_type * m_deque
Definition: deque.h:250
iterator end()
Definition: deque.h:487
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
const_reverse_iterator crend() const
Definition: deque.h:528