Click
Loading...
Searching...
No Matches
deque.hh
1#ifndef CLICK_DEQUE_HH
2#define CLICK_DEQUE_HH 1
3#include <click/algorithm.hh>
4#include <click/array_memory.hh>
5CLICK_DECLS
6
8template <typename AM> class deque_memory { public:
9 typedef int size_type;
10 typedef typename AM::type type;
11 inline bool need_argument_copy(const type *argp) const {
12 return fast_argument<type>::is_reference && (uintptr_t) argp - (uintptr_t) l_ < (size_t) (capacity_ * sizeof(type));
13 }
14 inline size_type canonp(size_type p) const {
15 return p < capacity_ ? p : p - capacity_;
16 }
17 inline size_type i2p(size_type i) const {
18 return canonp(head_ + i);
19 }
20 inline size_type prevp(size_type p) const {
21 return p ? p - 1 : capacity_ - 1;
22 }
23 inline size_type nextp(size_type p) const {
24 return p + 1 != capacity_ ? p + 1 : 0;
25 }
26 inline size_type naccess(size_type n) const {
27 return head_ + n <= capacity_ ? n : capacity_ - head_;
28 }
29
30 deque_memory()
31 : l_(0), head_(0), n_(0), capacity_(0) {
32 }
33 ~deque_memory();
34 void assign(const deque_memory<AM> &x);
35 void assign(size_type n, const type *vp);
36 void resize(size_type n, const type *vp);
37 bool insert(int i, const type *vp);
38 int erase(int ai, int bi);
39 inline void push_back(const type *vp) {
40 if (n_ < capacity_) {
41 size_type p = i2p(n_);
42 AM::mark_undefined(l_ + p, 1);
43 AM::fill(l_ + p, 1, vp);
44 ++n_;
45 } else
46 reserve_and_push(-1, false, vp);
47 }
48#if HAVE_CXX_RVALUE_REFERENCES
49 inline void move_construct_back(type* vp) {
50 if (n_ < capacity_) {
51 size_type p = i2p(n_);
52 AM::mark_undefined(l_ + p, 1);
53 AM::move_construct(l_ + p, vp);
54 ++n_;
55 } else
56 reserve_and_push(-1, false, vp);
57 }
58#endif
59 inline void pop_back() {
60 assert(n_ > 0);
61 --n_;
62 size_type p = i2p(n_);
63 AM::destroy(l_ + p, 1);
64 AM::mark_noaccess(l_ + p, 1);
65 }
66 inline void push_front(const type *vp) {
67 if (n_ < capacity_) {
68 head_ = prevp(head_);
69 AM::mark_undefined(l_ + head_, 1);
70 AM::fill(l_ + head_, 1, vp);
71 ++n_;
72 } else
73 reserve_and_push(-1, true, vp);
74 }
75#if HAVE_CXX_RVALUE_REFERENCES
76 inline void move_construct_front(type* vp) {
77 if (n_ < capacity_) {
78 head_ = prevp(head_);
79 AM::mark_undefined(l_ + head_, 1);
80 AM::move_construct(l_ + head_, vp);
81 ++n_;
82 } else
83 reserve_and_push(-1, true, vp);
84 }
85#endif
86 inline void pop_front() {
87 assert(n_ > 0);
88 --n_;
89 AM::destroy(l_ + head_, 1);
90 AM::mark_noaccess(l_ + head_, 1);
91 head_ = nextp(head_);
92 }
93 inline void clear() {
94 size_type f = naccess(n_);
95 AM::destroy(l_ + head_, f);
96 AM::destroy(l_, n_ - f);
97 AM::mark_noaccess(l_, capacity_);
98 head_ = n_ = 0;
99 }
100 bool reserve_and_push(size_type n, bool isfront, const type *vp);
101 void swap(deque_memory<AM> &x);
102 type *l_;
103 size_type head_;
104 size_type n_;
105 size_type capacity_;
106};
109template <typename T> class Deque_iterator;
110template <typename T> class Deque_const_iterator;
111
147template <typename T>
148class Deque {
149
150 typedef typename array_memory<T>::type array_memory_type;
151 mutable deque_memory<array_memory_type> vm_;
152
153 public:
154
155 typedef T value_type;
156 typedef T &reference;
157 typedef const T &const_reference;
158 typedef T *pointer;
159 typedef const T *const_pointer;
160
163 typedef const T &const_access_type;
164
165 typedef int size_type;
166
168 typedef Deque_const_iterator<T> const_iterator;
169
171 enum { RESERVE_GROW = (size_type) -1 };
172
173
174 explicit inline Deque();
175 explicit inline Deque(size_type n, value_argument_type v);
176 inline Deque(const Deque<T> &x);
177#if HAVE_CXX_RVALUE_REFERENCES
178 inline Deque(Deque<T> &&x);
179#endif
180
181 inline Deque<T> &operator=(const Deque<T> &x);
182#if HAVE_CXX_RVALUE_REFERENCES
183 inline Deque<T> &operator=(Deque<T> &&x);
184#endif
185 inline Deque<T> &assign(size_type n, value_argument_type v = T());
186
187 inline iterator begin();
188 inline iterator end();
189 inline const_iterator begin() const;
190 inline const_iterator end() const;
191 inline const_iterator cbegin() const;
192 inline const_iterator cend() const;
193
194 inline size_type size() const;
195 inline size_type capacity() const;
196 inline bool empty() const;
197 inline void resize(size_type n, value_argument_type v = T());
198 inline bool reserve(size_type n);
199
200 inline T &operator[](size_type i);
201 inline const T &operator[](size_type i) const;
202 inline T &at(size_type i);
203 inline const T &at(size_type i) const;
204 inline T &front();
205 inline const T &front() const;
206 inline T &back();
207 inline const T &back() const;
208
209 inline T &unchecked_at(size_type i);
210 inline const T &unchecked_at(size_type i) const;
211 inline T &at_u(size_type i) CLICK_DEPRECATED;
212 inline const T &at_u(size_type i) const CLICK_DEPRECATED;
213
214 inline void push_back(value_argument_type v);
215#if HAVE_CXX_RVALUE_REFERENCES
216 template <typename A = fast_argument<T> >
217 inline typename A::enable_rvalue_reference push_back(T &&v);
218#endif
219 inline void pop_back();
220 inline void push_front(value_argument_type v);
221#if HAVE_CXX_RVALUE_REFERENCES
222 template <typename A = fast_argument<T> >
223 inline typename A::enable_rvalue_reference push_front(T &&v);
224#endif
225 inline void pop_front();
226
228 inline iterator erase(iterator it);
229 inline iterator erase(iterator a, iterator b);
230
231 inline void clear();
232
233 inline void swap(Deque<T> &x);
234
235};
236
237template <typename T>
238class Deque_const_iterator {
239 const Deque<T> *q_;
240 typename Deque<T>::size_type p_;
241 friend class Deque<T>;
242 public:
243 typedef typename Deque<T>::size_type size_type;
244 typedef Deque_const_iterator<T> const_iterator;
245 typedef Deque_iterator<T> iterator;
246
247 Deque_const_iterator() {
248 }
249 Deque_const_iterator(const Deque<T> *q, size_type p)
250 : q_(q), p_(p) {
251 }
252 const T *operator->() const {
253 return &(*q_)[p_];
254 }
255 const T &operator*() const {
256 return (*q_)[p_];
257 }
258 const T &operator[](size_type i) const {
259 return (*q_)[p_ + i];
260 }
261 bool operator==(const const_iterator &x) const {
262 return p_ == x.p_ && q_ == x.q_;
263 }
264 bool operator!=(const const_iterator &x) const {
265 return p_ != x.p_ || q_ != x.q_;
266 }
267 bool operator<(const const_iterator &x) const {
268 assert(q_ == x.q_);
269 return p_ < x.p_;
270 }
271 bool operator<=(const const_iterator &x) const {
272 assert(q_ == x.q_);
273 return p_ <= x.p_;
274 }
275 bool operator>=(const const_iterator &x) const {
276 assert(q_ == x.q_);
277 return p_ >= x.p_;
278 }
279 bool operator>(const const_iterator &x) const {
280 assert(q_ == x.q_);
281 return p_ > x.p_;
282 }
283 size_type diff(const const_iterator &x) const {
284 assert(q_ == x.q_);
285 return p_ - x.p_;
286 }
287 void operator++(int) {
288 ++p_;
289 }
290 const_iterator &operator++() {
291 ++p_;
292 return *this;
293 }
294 void operator--(int) {
295 --p_;
296 }
297 const_iterator &operator--() {
298 --p_;
299 return *this;
300 }
301 const_iterator &operator+=(size_type n) {
302 p_ += n;
303 return *this;
304 }
305 const_iterator &operator-=(size_type n) {
306 p_ -= n;
307 return *this;
308 }
309};
310
311template <typename T>
312class Deque_iterator : public Deque_const_iterator<T> { public:
313 typedef typename Deque<T>::size_type size_type;
314 typedef Deque_const_iterator<T> const_iterator;
315 typedef Deque_iterator<T> iterator;
316
318 }
319 Deque_iterator(Deque<T> *q, int p)
320 : const_iterator(q, p) {
321 }
322 T *operator->() const {
323 return const_cast<T *>(const_iterator::operator->());
324 }
325 T &operator*() const {
326 return const_cast<T &>(const_iterator::operator*());
327 }
328 T &operator[](int n) const {
329 return const_cast<T &>(const_iterator::operator[](n));
330 }
331 iterator &operator+=(size_type n) {
332 const_iterator::operator+=(n);
333 return *this;
334 }
335 iterator &operator-=(size_type n) {
336 const_iterator::operator-=(n);
337 return *this;
338 }
339};
340
342template <typename T>
344}
345
347template <typename T>
349 vm_.resize(n, array_memory_type::cast(&v));
350}
351
353template <typename T>
354inline Deque<T>::Deque(const Deque<T> &x) {
355 vm_.assign(x.vm_);
356}
357
358#if HAVE_CXX_RVALUE_REFERENCES
360template <typename T>
361inline Deque<T>::Deque(Deque<T> &&x) {
362 vm_.assign(x.vm_);
363}
364#endif
365
367template <typename T>
368inline typename Deque<T>::size_type Deque<T>::size() const {
369 return vm_.n_;
370}
371
373template <typename T>
374inline bool Deque<T>::empty() const {
375 return vm_.n_ == 0;
376}
377
383template <typename T>
385 return vm_.capacity_;
386}
387
389template <typename T>
391 return iterator(this, 0);
392}
393
395template <typename T>
397 return const_iterator(this, 0);
398}
399
402template <typename T>
404 return iterator(this, vm_.n_);
405}
406
408template <typename T>
410 return const_iterator(this, vm_.n_);
411}
412
414template <typename T>
416 return const_iterator(this, 0);
417}
418
421template <typename T>
423 return const_iterator(this, vm_.n_);
424}
425
428template <typename T>
430 assert((unsigned) i < (unsigned) vm_.n_);
431 return *(T *)&vm_.l_[vm_.i2p(i)];
432}
433
435template <typename T>
436inline const T &Deque<T>::operator[](size_type i) const {
437 assert((unsigned) i < (unsigned) vm_.n_);
438 return *(T *)&vm_.l_[vm_.i2p(i)];
439}
440
444template <typename T>
446 return operator[](i);
447}
448
450template <typename T>
451inline const T &Deque<T>::at(size_type i) const {
452 return operator[](i);
453}
454
457template <typename T>
458inline T &Deque<T>::front() {
459 return operator[](0);
460}
461
463template <typename T>
464inline const T &Deque<T>::front() const {
465 return operator[](0);
466}
467
470template <typename T>
471inline T &Deque<T>::back() {
472 return operator[](vm_.n_ - 1);
473}
474
476template <typename T>
477inline const T &Deque<T>::back() const {
478 return operator[](vm_.n_ - 1);
479}
480
486template <typename T>
488 return *(T *)&vm_.l_[vm_.i2p(i)];
489}
490
492template <typename T>
493inline const T &Deque<T>::unchecked_at(size_type i) const {
494 return *(T *)&vm_.l_[vm_.i2p(i)];
495}
496
498template <typename T>
499inline T &Deque<T>::at_u(size_type i) {
500 return unchecked_at(i);
501}
502
503template <typename T>
504inline const T &Deque<T>::at_u(size_type i) const {
505 return unchecked_at(i);
506}
512template <typename T>
514 vm_.resize(n, array_memory_type::cast(&v));
515}
516
521template <typename T>
523 vm_.push_back(array_memory_type::cast(&v));
524}
525
526#if HAVE_CXX_RVALUE_REFERENCES
528template <typename T> template <typename A>
529inline typename A::enable_rvalue_reference Deque<T>::push_back(T&& v) {
530 vm_.move_construct_back(array_memory_type::cast(&v));
531}
532#endif
533
537template <typename T>
538inline void Deque<T>::pop_back() {
539 vm_.pop_back();
540}
541
546template <typename T>
548 vm_.push_front(array_memory_type::cast(&v));
549}
550
551#if HAVE_CXX_RVALUE_REFERENCES
553template <typename T> template <typename A>
554inline typename A::enable_rvalue_reference Deque<T>::push_front(T&& v) {
555 vm_.move_construct_front(array_memory_type::cast(&v));
556}
557#endif
558
562template <typename T>
563inline void Deque<T>::pop_front() {
564 vm_.pop_front();
565}
566
569template <typename T>
570inline typename Deque<T>::iterator
572 assert(it.q_ == this);
573 if (likely(vm_.insert(it.p_, array_memory_type::cast(&v))))
574 return it;
575 else
576 return end();
577}
578
581template <typename T>
582inline typename Deque<T>::iterator
584 assert(it.q_ == this);
585 return (it < end() ? erase(it, it + 1) : it);
586}
587
590template <typename T>
591inline typename Deque<T>::iterator
593 assert(a.q_ == this && b.q_ == this);
594 return iterator(this, vm_.erase(a.p_, b.p_));
595}
596
599template <typename T>
600inline void Deque<T>::clear() {
601 vm_.clear();
602}
603
610template <typename T>
612 return vm_.reserve_and_push(n, false, 0);
613}
614
616template <typename T>
617inline void Deque<T>::swap(Deque<T> &x) {
618 vm_.swap(x.vm_);
619}
620
622template <typename T>
624 vm_.assign(x.vm_);
625 return *this;
626}
627
628#if HAVE_CXX_RVALUE_REFERENCES
630template <typename T>
632 vm_.swap(x.vm_);
633 return *this;
634}
635#endif
636
639template <typename T>
641 vm_.assign(n, array_memory_type::cast(&v));
642 return *this;
643}
644
645template <typename T>
646Deque_const_iterator<T> operator+(Deque_const_iterator<T> it,
647 typename Deque<T>::size_type n) {
648 return it += n;
649}
650
651template <typename T>
652Deque_const_iterator<T> operator-(Deque_const_iterator<T> it,
653 typename Deque<T>::size_type n) {
654 return it -= n;
655}
656
657template <typename T>
659 typename Deque<T>::size_type n) {
660 return it += n;
661}
662
663template <typename T>
665 typename Deque<T>::size_type n) {
666 return it -= n;
667}
668
669template <typename T>
670typename Deque_const_iterator<T>::size_type
671operator-(const Deque_const_iterator<T> &a, const Deque_const_iterator<T> &b) {
672 return a.diff(b);
673}
674
675template <typename T>
676inline void click_swap(Deque<T> &a, Deque<T> &b) {
677 a.swap(b);
678}
679
680template <typename T>
681inline void assign_consume(Deque<T> &a, Deque<T> &b) {
682 a.swap(b);
683}
684
685CLICK_ENDDECLS
686#include <click/deque.cc>
687#endif
Definition deque.hh:312
Deque template.
Definition deque.hh:148
Deque_const_iterator< T > const_iterator
Const iterator type.
Definition deque.hh:168
Deque< T > & operator=(const Deque< T > &x)
Replace this deque's contents with a copy of x.
Definition deque.hh:623
void resize(size_type n, value_argument_type v=T())
Resize the deque to contain n elements.
Definition deque.hh:513
void pop_front()
Remove the first element.
Definition deque.hh:563
iterator erase(iterator it)
Remove the element at position it.
Definition deque.hh:583
const T & const_reference
Const reference to value type.
Definition deque.hh:157
void push_front(value_argument_type v)
Prepend element v.
Definition deque.hh:547
void clear()
Remove all elements.
Definition deque.hh:600
const_iterator cend() const
Return a const_iterator for the end of the deque.
Definition deque.hh:422
Deque_iterator< T > iterator
Iterator type.
Definition deque.hh:167
bool reserve(size_type n)
Reserve space for at least n more elements.
Definition deque.hh:611
int size_type
Type of sizes (size()).
Definition deque.hh:165
iterator end()
Return an iterator for the end of the deque.
Definition deque.hh:403
T & at(size_type i)
Return a reference to the ith element.
Definition deque.hh:445
T & front()
Return a reference to the first element.
Definition deque.hh:458
T & operator[](size_type i)
Return a reference to the ith element.
Definition deque.hh:429
Deque< T > & assign(size_type n, value_argument_type v=T())
Replace this deque's contents with n copies of v.
Definition deque.hh:640
fast_argument< T >::type value_argument_type
Type used for value arguments (either T or const T &).
Definition deque.hh:162
size_type size() const
Return the number of elements.
Definition deque.hh:368
T & reference
Reference to value type.
Definition deque.hh:156
T & back()
Return a reference to the last element (number size()-1).
Definition deque.hh:471
bool empty() const
Test if the deque is empty (size() == 0).
Definition deque.hh:374
void push_back(value_argument_type v)
Append v to the end of the deque.
Definition deque.hh:522
void pop_back()
Remove the last element.
Definition deque.hh:538
iterator insert(iterator it, value_argument_type v)
Insert v before position it.
Definition deque.hh:571
const T * const_pointer
Pointer to const value type.
Definition deque.hh:159
const_iterator cbegin() const
Return a const_iterator for the beginning of the deque.
Definition deque.hh:415
Deque()
Construct an empty deque.
Definition deque.hh:343
T * pointer
Pointer to value type.
Definition deque.hh:158
T value_type
Value type.
Definition deque.hh:155
void swap(Deque< T > &x)
Swap the contents of this deque and x.
Definition deque.hh:617
iterator begin()
Return an iterator for the first element in the deque.
Definition deque.hh:390
size_type capacity() const
Return the deque's capacity.
Definition deque.hh:384
T & unchecked_at(size_type i)
Return a reference to the ith element.
Definition deque.hh:487
Template defining a fast argument type for objects of type T.
Definition type_traits.hh:148
Timestamp operator*(const Timestamp &a, double b)
Scale a by a factor of b and return the result.
Definition timestamp.hh:1447