Stxxl  1.3.2
deque.h
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  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef _STXXL_DEQUE_H
15 #define _STXXL_DEQUE_H
16 
17 #include <limits>
18 #include <stxxl/vector>
19 
20 
21 __STXXL_BEGIN_NAMESPACE
22 
23 template <class T, class VectorType>
24 class deque;
25 
26 template <class DequeType>
27 class const_deque_iterator;
28 
29 template <class DequeType>
30 class deque_iterator
31 {
32  typedef typename DequeType::size_type size_type;
33  typedef typename DequeType::vector_type vector_type;
34  typedef deque_iterator<DequeType> _Self;
35  DequeType * Deque;
36  size_type Offset;
37 
38  deque_iterator(DequeType * Deque_, size_type Offset_) :
39  Deque(Deque_), Offset(Offset_)
40  { }
41 
42  friend class const_deque_iterator<DequeType>;
43 
44 public:
45  typedef typename DequeType::value_type value_type;
46  typedef typename DequeType::pointer pointer;
47  typedef typename DequeType::const_pointer const_pointer;
48  typedef typename DequeType::reference reference;
49  typedef typename DequeType::const_reference const_reference;
50  typedef deque_iterator<DequeType> iterator;
51  typedef const_deque_iterator<DequeType> const_iterator;
52  friend class deque<value_type, vector_type>;
53  typedef std::random_access_iterator_tag iterator_category;
54  typedef typename DequeType::difference_type difference_type;
55 
56  deque_iterator() : Deque(NULL), Offset(0) { }
57 
58  difference_type operator - (const _Self & a) const
59  {
60  size_type SelfAbsOffset = (Offset >= Deque->begin_o) ?
61  Offset : (Deque->Vector.size() + Offset);
62  size_type aAbsOffset = (a.Offset >= Deque->begin_o) ?
63  a.Offset : (Deque->Vector.size() + a.Offset);
64 
65  return SelfAbsOffset - aAbsOffset;
66  }
67 
68  difference_type operator - (const const_iterator & a) const
69  {
70  size_type SelfAbsOffset = (Offset >= Deque->begin_o) ?
71  Offset : (Deque->Vector.size() + Offset);
72  size_type aAbsOffset = (a.Offset >= Deque->begin_o) ?
73  a.Offset : (Deque->Vector.size() + a.Offset);
74 
75  return SelfAbsOffset - aAbsOffset;
76  }
77 
78  _Self operator - (size_type op) const
79  {
80  return _Self(Deque, (Offset + Deque->Vector.size() - op) % Deque->Vector.size());
81  }
82 
83  _Self operator + (size_type op) const
84  {
85  return _Self(Deque, (Offset + op) % Deque->Vector.size());
86  }
87 
88  _Self & operator -= (size_type op)
89  {
90  Offset = (Offset + Deque->Vector.size() - op) % Deque->Vector.size();
91  return *this;
92  }
93 
94  _Self & operator += (size_type op)
95  {
96  Offset = (Offset + op) % Deque->Vector.size();
97  return *this;
98  }
99 
100  reference operator * ()
101  {
102  return Deque->Vector[Offset];
103  }
104 
105  pointer operator -> ()
106  {
107  return &(Deque->Vector[Offset]);
108  }
109 
110  const_reference operator * () const
111  {
112  return Deque->Vector[Offset];
113  }
114 
115  const_pointer operator -> () const
116  {
117  return &(Deque->Vector[Offset]);
118  }
119 
120  reference operator [] (size_type op)
121  {
122  return Deque->Vector[(Offset + op) % Deque->Vector.size()];
123  }
124 
125  const_reference operator [] (size_type op) const
126  {
127  return Deque->Vector[(Offset + op) % Deque->Vector.size()];
128  }
129 
130  _Self & operator ++ ()
131  {
132  Offset = (Offset + 1) % Deque->Vector.size();
133  return *this;
134  }
135  _Self operator ++ (int)
136  {
137  _Self __tmp = *this;
138  Offset = (Offset + 1) % Deque->Vector.size();
139  return __tmp;
140  }
141  _Self & operator -- ()
142  {
143  Offset = (Offset + Deque->Vector.size() - 1) % Deque->Vector.size();
144  return *this;
145  }
146  _Self operator -- (int)
147  {
148  _Self __tmp = *this;
149  Offset = (Offset + Deque->Vector.size() - 1) % Deque->Vector.size();
150  return __tmp;
151  }
152  bool operator == (const _Self & a) const
153  {
154  assert(Deque == a.Deque);
155  return Offset == a.Offset;
156  }
157  bool operator != (const _Self & a) const
158  {
159  assert(Deque == a.Deque);
160  return Offset != a.Offset;
161  }
162 
163  bool operator < (const _Self & a) const
164  {
165  assert(Deque == a.Deque);
166  return (a - (*this)) > 0;
167  }
168 
169  bool operator > (const _Self & a) const
170  {
171  return a < (*this);
172  }
173 
174  bool operator <= (const _Self & a) const
175  {
176  return !((*this) > a);
177  }
178 
179  bool operator >= (const _Self & a) const
180  {
181  return !((*this) < a);
182  }
183 
184  bool operator == (const const_iterator & a) const
185  {
186  assert(Deque == a.Deque);
187  return Offset == a.Offset;
188  }
189  bool operator != (const const_iterator & a) const
190  {
191  assert(Deque == a.Deque);
192  return Offset != a.Offset;
193  }
194 
195  bool operator < (const const_iterator & a) const
196  {
197  assert(Deque == a.Deque);
198  return (a - (*this)) > 0;
199  }
200 
201  bool operator > (const const_iterator & a) const
202  {
203  return a < (*this);
204  }
205 
206  bool operator <= (const const_iterator & a) const
207  {
208  return !((*this) > a);
209  }
210 
211  bool operator >= (const const_iterator & a) const
212  {
213  return !((*this) < a);
214  }
215 };
216 
217 template <class DequeType>
218 class const_deque_iterator
219 {
220  typedef const_deque_iterator<DequeType> _Self;
221  typedef typename DequeType::size_type size_type;
222  typedef typename DequeType::vector_type vector_type;
223  const DequeType * Deque;
224  size_type Offset;
225 
226  const_deque_iterator(const DequeType * Deque_, size_type Offset_) :
227  Deque(Deque_), Offset(Offset_)
228  { }
229 
230 public:
231  typedef typename DequeType::value_type value_type;
232  typedef typename DequeType::const_pointer pointer;
233  typedef typename DequeType::const_pointer const_pointer;
234  typedef typename DequeType::const_reference reference;
235  typedef typename DequeType::const_reference const_reference;
236  typedef deque_iterator<DequeType> iterator;
237  typedef const_deque_iterator<DequeType> const_iterator;
238  friend class deque<value_type, vector_type>;
239  friend class deque_iterator<DequeType>;
240 
241  typedef std::random_access_iterator_tag iterator_category;
242  typedef typename DequeType::difference_type difference_type;
243 
244  const_deque_iterator() : Deque(NULL), Offset(0) { }
245  const_deque_iterator(const deque_iterator<DequeType> & it) :
246  Deque(it.Deque), Offset(it.Offset)
247  { }
248 
249  difference_type operator - (const _Self & a) const
250  {
251  size_type SelfAbsOffset = (Offset >= Deque->begin_o) ?
252  Offset : (Deque->Vector.size() + Offset);
253  size_type aAbsOffset = (a.Offset >= Deque->begin_o) ?
254  a.Offset : (Deque->Vector.size() + a.Offset);
255 
256  return SelfAbsOffset - aAbsOffset;
257  }
258 
259  difference_type operator - (const iterator & a) const
260  {
261  size_type SelfAbsOffset = (Offset >= Deque->begin_o) ?
262  Offset : (Deque->Vector.size() + Offset);
263  size_type aAbsOffset = (a.Offset >= Deque->begin_o) ?
264  a.Offset : (Deque->Vector.size() + a.Offset);
265 
266  return SelfAbsOffset - aAbsOffset;
267  }
268 
269  _Self operator - (size_type op) const
270  {
271  return _Self(Deque, (Offset + Deque->Vector.size() - op) % Deque->Vector.size());
272  }
273 
274  _Self operator + (size_type op) const
275  {
276  return _Self(Deque, (Offset + op) % Deque->Vector.size());
277  }
278 
279  _Self & operator -= (size_type op)
280  {
281  Offset = (Offset + Deque->Vector.size() - op) % Deque->Vector.size();
282  return *this;
283  }
284 
285  _Self & operator += (size_type op)
286  {
287  Offset = (Offset + op) % Deque->Vector.size();
288  return *this;
289  }
290 
291  const_reference operator * () const
292  {
293  return Deque->Vector[Offset];
294  }
295 
296  const_pointer operator -> () const
297  {
298  return &(Deque->Vector[Offset]);
299  }
300 
301  const_reference operator [] (size_type op) const
302  {
303  return Deque->Vector[(Offset + op) % Deque->Vector.size()];
304  }
305 
306  _Self & operator ++ ()
307  {
308  Offset = (Offset + 1) % Deque->Vector.size();
309  return *this;
310  }
311  _Self operator ++ (int)
312  {
313  _Self __tmp = *this;
314  Offset = (Offset + 1) % Deque->Vector.size();
315  return __tmp;
316  }
317  _Self & operator -- ()
318  {
319  Offset = (Offset + Deque->Vector.size() - 1) % Deque->Vector.size();
320  return *this;
321  }
322  _Self operator -- (int)
323  {
324  _Self __tmp = *this;
325  Offset = (Offset + Deque->Vector.size() - 1) % Deque->Vector.size();
326  return __tmp;
327  }
328  bool operator == (const _Self & a) const
329  {
330  assert(Deque == a.Deque);
331  return Offset == a.Offset;
332  }
333  bool operator != (const _Self & a) const
334  {
335  assert(Deque == a.Deque);
336  return Offset != a.Offset;
337  }
338 
339  bool operator < (const _Self & a) const
340  {
341  assert(Deque == a.Deque);
342  return (a - (*this)) > 0;
343  }
344 
345  bool operator > (const _Self & a) const
346  {
347  return a < (*this);
348  }
349 
350  bool operator <= (const _Self & a) const
351  {
352  return !((*this) > a);
353  }
354 
355  bool operator >= (const _Self & a) const
356  {
357  return !((*this) < a);
358  }
359 
360  bool operator == (const iterator & a) const
361  {
362  assert(Deque == a.Deque);
363  return Offset == a.Offset;
364  }
365  bool operator != (const iterator & a) const
366  {
367  assert(Deque == a.Deque);
368  return Offset != a.Offset;
369  }
370 
371  bool operator < (const iterator & a) const
372  {
373  assert(Deque == a.Deque);
374  return (a - (*this)) > 0;
375  }
376 
377  bool operator > (const iterator & a) const
378  {
379  return a < (*this);
380  }
381 
382  bool operator <= (const iterator & a) const
383  {
384  return !((*this) > a);
385  }
386 
387  bool operator >= (const iterator & a) const
388  {
389  return !((*this) < a);
390  }
391 };
392 
395 
404 template <class T, class VectorType = stxxl::vector<T> >
405 class deque : private noncopyable
406 {
407  typedef deque<T, VectorType> Self_;
408 
409 public:
410  typedef typename VectorType::size_type size_type;
411  typedef typename VectorType::difference_type difference_type;
412  typedef VectorType vector_type;
413  typedef T value_type;
414  typedef T * pointer;
415  typedef const value_type * const_pointer;
416  typedef T & reference;
417  typedef const T & const_reference;
418  typedef deque_iterator<Self_> iterator;
419  typedef const_deque_iterator<Self_> const_iterator;
420  typedef std::reverse_iterator<iterator> reverse_iterator;
421  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
422 
423  friend class deque_iterator<Self_>;
424  friend class const_deque_iterator<Self_>;
425 
426 private:
427  VectorType Vector;
428  size_type begin_o, end_o, size_;
429 
430  void double_array()
431  {
432  const size_type old_size = Vector.size();
433  Vector.resize(2 * old_size);
434  if (begin_o > end_o)
435  { // copy data to the new end of the vector
436  const size_type new_begin_o = old_size + begin_o;
437  std::copy(Vector.begin() + begin_o,
438  Vector.begin() + old_size,
439  Vector.begin() + new_begin_o);
440  begin_o = new_begin_o;
441  }
442  }
443 
444 public:
445  deque() : Vector((STXXL_DEFAULT_BLOCK_SIZE(T)) / sizeof(T)), begin_o(0), end_o(0), size_(0)
446  { }
447 
448  deque(size_type n)
449  : Vector(STXXL_MAX<size_type>(STXXL_DEFAULT_BLOCK_SIZE(T) / sizeof(T), 2 * n)),
450  begin_o(0), end_o(n), size_(n)
451  { }
452 
453  ~deque() // empty so far
454  { }
455 
456  iterator begin()
457  {
458  return iterator(this, begin_o);
459  }
460  iterator end()
461  {
462  return iterator(this, end_o);
463  }
464  const_iterator begin() const
465  {
466  return const_iterator(this, begin_o);
467  }
468  const_iterator cbegin() const
469  {
470  return begin();
471  }
472  const_iterator end() const
473  {
474  return const_iterator(this, end_o);
475  }
476  const_iterator cend() const
477  {
478  return end();
479  }
480 
481  reverse_iterator rbegin()
482  {
483  return reverse_iterator(end());
484  }
485  const_reverse_iterator rbegin() const
486  {
487  return const_reverse_iterator(end());
488  }
489  const_reverse_iterator crbegin() const
490  {
491  return const_reverse_iterator(end());
492  }
493  reverse_iterator rend()
494  {
495  return reverse_iterator(begin());
496  }
497  const_reverse_iterator rend() const
498  {
499  return const_reverse_iterator(begin());
500  }
501  const_reverse_iterator crend() const
502  {
503  return const_reverse_iterator(begin());
504  }
505 
506  size_type size() const
507  {
508  return size_;
509  }
510 
511  size_type max_size() const
512  {
513  return (std::numeric_limits<size_type>::max)() / 2 - 1;
514  }
515 
516  bool empty() const
517  {
518  return size_ == 0;
519  }
520 
521  reference operator [] (size_type n)
522  {
523  assert(n < size());
524  return Vector[(begin_o + n) % Vector.size()];
525  }
526 
527  const_reference operator [] (size_type n) const
528  {
529  assert(n < size());
530  return Vector[(begin_o + n) % Vector.size()];
531  }
532 
533  reference front()
534  {
535  assert(!empty());
536  return Vector[begin_o];
537  }
538 
539  const_reference front() const
540  {
541  assert(!empty());
542  return Vector[begin_o];
543  }
544 
545  reference back()
546  {
547  assert(!empty());
548  return Vector[(end_o + Vector.size() - 1) % Vector.size()];
549  }
550 
551  const_reference back() const
552  {
553  assert(!empty());
554  return Vector[(end_o + Vector.size() - 1) % Vector.size()];
555  }
556 
557  void push_front(const T & el)
558  {
559  if ((begin_o + Vector.size() - 1) % Vector.size() == end_o)
560  {
561  // an overflow will occur: resize the array
562  double_array();
563  }
564 
565  begin_o = (begin_o + Vector.size() - 1) % Vector.size();
566  Vector[begin_o] = el;
567  ++size_;
568  }
569 
570  void push_back(const T & el)
571  {
572  if ((end_o + 1) % Vector.size() == begin_o)
573  {
574  // an overflow will occur: resize the array
575  double_array();
576  }
577  Vector[end_o] = el;
578  end_o = (end_o + 1) % Vector.size();
579  ++size_;
580  }
581 
582  void pop_front()
583  {
584  assert(!empty());
585  begin_o = (begin_o + 1) % Vector.size();
586  --size_;
587  }
588 
589  void pop_back()
590  {
591  assert(!empty());
592  end_o = (end_o + Vector.size() - 1) % Vector.size();
593  --size_;
594  }
595 
596  void swap(deque & obj)
597  {
598  std::swap(Vector, obj.Vector);
599  std::swap(begin_o, obj.begin_o);
600  std::swap(end_o, obj.end_o);
601  std::swap(size_, obj.size_);
602  }
603 
604  void clear()
605  {
606  Vector.clear();
607  Vector.resize((STXXL_DEFAULT_BLOCK_SIZE(T)) / sizeof(T));
608  begin_o = 0;
609  end_o = 0;
610  size_ = 0;
611  }
612 
613  void resize(size_type n)
614  {
615  if (n < size())
616  {
617  do
618  {
619  pop_back();
620  } while (n < size());
621  }
622  else
623  {
624  if (n + 1 > Vector.size())
625  { // need to resize
626  const size_type old_size = Vector.size();
627  Vector.resize(2 * n);
628  if (begin_o > end_o)
629  { // copy data to the new end of the vector
630  const size_type new_begin_o = Vector.size() - old_size + begin_o;
631  std::copy(Vector.begin() + begin_o,
632  Vector.begin() + old_size,
633  Vector.begin() + new_begin_o);
634  begin_o = new_begin_o;
635  }
636  }
637  end_o = (end_o + n - size()) % Vector.size();
638  size_ = n;
639  }
640  }
641 };
642 
643 template <class T, class VectorType>
644 bool operator == (const deque<T, VectorType> & a, const deque<T, VectorType> & b)
645 {
646  return std::equal(a.begin(), a.end(), b.begin());
647 }
648 
649 template <class T, class VectorType>
650 bool operator < (const deque<T, VectorType> & a, const deque<T, VectorType> & b)
651 {
652  return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
653 }
654 
656 
657 __STXXL_END_NAMESPACE
658 
659 namespace std
660 {
661  template <typename T, typename VT>
662  void swap(stxxl::deque<T, VT> & a,
663  stxxl::deque<T, VT> & b)
664  {
665  a.swap(b);
666  }
667 }
668 
669 #endif /* _STXXL_DEQUE_H */
A deque container.
Definition: deque.h:24