1// Profiling deque implementation -*- C++ -*-
2
3// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file profile/deque
26 *  This file is a GNU profile extension to the Standard C++ Library.
27 */
28
29#ifndef _GLIBCXX_PROFILE_DEQUE
30#define _GLIBCXX_PROFILE_DEQUE 1
31
32#include <deque>
33
34namespace std _GLIBCXX_VISIBILITY(default)
35{
36namespace __profile
37{
38  /// Class std::deque wrapper with performance instrumentation.
39  template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
40    class deque
41    : public _GLIBCXX_STD_C::deque<_Tp, _Allocator>
42    {
43      typedef  _GLIBCXX_STD_C::deque<_Tp, _Allocator> _Base;
44
45    public:
46      typedef typename _Base::reference             reference;
47      typedef typename _Base::const_reference       const_reference;
48
49      typedef typename _Base::iterator             iterator;
50      typedef typename _Base::const_iterator       const_iterator;
51      typedef typename _Base::reverse_iterator     reverse_iterator;
52      typedef typename _Base::const_reverse_iterator const_reverse_iterator;
53
54      typedef typename _Base::size_type             size_type;
55      typedef typename _Base::difference_type       difference_type;
56
57      typedef _Tp				    value_type;
58      typedef _Allocator			    allocator_type;
59      typedef typename _Base::pointer               pointer;
60      typedef typename _Base::const_pointer         const_pointer;
61
62      // 23.2.1.1 construct/copy/destroy:
63      explicit
64      deque(const _Allocator& __a = _Allocator())
65      : _Base(__a) { }
66
67#ifdef __GXX_EXPERIMENTAL_CXX0X__
68      explicit
69      deque(size_type __n)
70      : _Base(__n) { }
71
72      deque(size_type __n, const _Tp& __value,
73	    const _Allocator& __a = _Allocator())
74      : _Base(__n, __value, __a) { }
75#else
76      explicit
77      deque(size_type __n, const _Tp& __value = _Tp(),
78	    const _Allocator& __a = _Allocator())
79      : _Base(__n, __value, __a) { }
80#endif
81
82      template<class _InputIterator>
83        deque(_InputIterator __first, _InputIterator __last,
84	      const _Allocator& __a = _Allocator())
85	: _Base(__first, __last, __a)
86        { }
87
88      deque(const deque& __x)
89      : _Base(__x) { }
90
91      deque(const _Base& __x)
92      : _Base(__x) { }
93
94#ifdef __GXX_EXPERIMENTAL_CXX0X__
95      deque(deque&& __x)
96      : _Base(std::move(__x))
97      { }
98
99      deque(initializer_list<value_type> __l,
100	    const allocator_type& __a = allocator_type())
101      : _Base(__l, __a) { }
102#endif
103
104      ~deque() _GLIBCXX_NOEXCEPT { }
105
106      deque&
107      operator=(const deque& __x)
108      {
109	*static_cast<_Base*>(this) = __x;
110	return *this;
111      }
112
113#ifdef __GXX_EXPERIMENTAL_CXX0X__
114      deque&
115      operator=(deque&& __x)
116      {
117	// NB: DR 1204.
118	// NB: DR 675.
119	this->clear();
120	this->swap(__x);
121	return *this;
122      }
123
124      deque&
125      operator=(initializer_list<value_type> __l)
126      {
127	*static_cast<_Base*>(this) = __l;
128	return *this;
129      }
130#endif
131
132      template<class _InputIterator>
133        void
134        assign(_InputIterator __first, _InputIterator __last)
135        {
136	  _Base::assign(__first, __last);
137	}
138
139      void
140      assign(size_type __n, const _Tp& __t)
141      {
142	_Base::assign(__n, __t);
143      }
144
145#ifdef __GXX_EXPERIMENTAL_CXX0X__
146      void
147      assign(initializer_list<value_type> __l)
148      {
149	_Base::assign(__l);
150      }
151#endif
152
153      using _Base::get_allocator;
154
155      // iterators:
156      iterator
157      begin() _GLIBCXX_NOEXCEPT
158      { return iterator(_Base::begin()); }
159
160      const_iterator
161      begin() const _GLIBCXX_NOEXCEPT
162      { return const_iterator(_Base::begin()); }
163
164      iterator
165      end() _GLIBCXX_NOEXCEPT
166      { return iterator(_Base::end()); }
167
168      const_iterator
169      end() const _GLIBCXX_NOEXCEPT
170      { return const_iterator(_Base::end()); }
171
172      reverse_iterator
173      rbegin() _GLIBCXX_NOEXCEPT
174      { return reverse_iterator(end()); }
175
176      const_reverse_iterator
177      rbegin() const _GLIBCXX_NOEXCEPT
178      { return const_reverse_iterator(end()); }
179
180      reverse_iterator
181      rend() _GLIBCXX_NOEXCEPT
182      { return reverse_iterator(begin()); }
183
184      const_reverse_iterator
185      rend() const _GLIBCXX_NOEXCEPT
186      { return const_reverse_iterator(begin()); }
187
188#ifdef __GXX_EXPERIMENTAL_CXX0X__
189      const_iterator
190      cbegin() const noexcept
191      { return const_iterator(_Base::begin()); }
192
193      const_iterator
194      cend() const noexcept
195      { return const_iterator(_Base::end()); }
196
197      const_reverse_iterator
198      crbegin() const noexcept
199      { return const_reverse_iterator(end()); }
200
201      const_reverse_iterator
202      crend() const noexcept
203      { return const_reverse_iterator(begin()); }
204#endif
205
206      // 23.2.1.2 capacity:
207      using _Base::size;
208      using _Base::max_size;
209
210#ifdef __GXX_EXPERIMENTAL_CXX0X__
211      void
212      resize(size_type __sz)
213      {
214	_Base::resize(__sz);
215      }
216
217      void
218      resize(size_type __sz, const _Tp& __c)
219      {
220	_Base::resize(__sz, __c);
221      }
222#else
223      void
224      resize(size_type __sz, _Tp __c = _Tp())
225      {
226	_Base::resize(__sz, __c);
227      }
228#endif
229
230#ifdef __GXX_EXPERIMENTAL_CXX0X__
231      using _Base::shrink_to_fit;
232#endif
233
234      using _Base::empty;
235
236      // element access:
237      reference
238      operator[](size_type __n)
239      {
240	return _M_base()[__n];
241      }
242
243      const_reference
244      operator[](size_type __n) const
245      {
246	return _M_base()[__n];
247      }
248
249      using _Base::at;
250
251      reference
252      front()
253      {
254	return _Base::front();
255      }
256
257      const_reference
258      front() const
259      {
260	return _Base::front();
261      }
262
263      reference
264      back()
265      {
266	return _Base::back();
267      }
268
269      const_reference
270      back() const
271      {
272	return _Base::back();
273      }
274
275      // 23.2.1.3 modifiers:
276      void
277      push_front(const _Tp& __x)
278      {
279	_Base::push_front(__x);
280      }
281
282      void
283      push_back(const _Tp& __x)
284      {
285	_Base::push_back(__x);
286      }
287
288#ifdef __GXX_EXPERIMENTAL_CXX0X__
289      void
290      push_front(_Tp&& __x)
291      { emplace_front(std::move(__x)); }
292
293      void
294      push_back(_Tp&& __x)
295      { emplace_back(std::move(__x)); }
296
297      template<typename... _Args>
298        void
299        emplace_front(_Args&&... __args)
300	{
301	  _Base::emplace_front(std::forward<_Args>(__args)...);
302	}
303
304      template<typename... _Args>
305        void
306        emplace_back(_Args&&... __args)
307	{
308	  _Base::emplace_back(std::forward<_Args>(__args)...);
309	}
310
311      template<typename... _Args>
312        iterator
313        emplace(iterator __position, _Args&&... __args)
314	{
315	  typename _Base::iterator __res = _Base::emplace(__position,
316					    std::forward<_Args>(__args)...);
317	  return iterator(__res);
318	}
319#endif
320
321      iterator
322      insert(iterator __position, const _Tp& __x)
323      {
324	typename _Base::iterator __res = _Base::insert(__position, __x);
325	return iterator(__res);
326      }
327
328#ifdef __GXX_EXPERIMENTAL_CXX0X__
329      iterator
330      insert(iterator __position, _Tp&& __x)
331      { return emplace(__position, std::move(__x)); }
332
333      void
334      insert(iterator __p, initializer_list<value_type> __l)
335      {
336	_Base::insert(__p, __l);
337      }
338#endif
339
340      void
341      insert(iterator __position, size_type __n, const _Tp& __x)
342      {
343	_Base::insert(__position, __n, __x);
344      }
345
346      template<class _InputIterator>
347        void
348        insert(iterator __position,
349	       _InputIterator __first, _InputIterator __last)
350        {
351	  _Base::insert(__position, __first, __last);
352	}
353
354      void
355      pop_front()
356      {
357	_Base::pop_front();
358      }
359
360      void
361      pop_back()
362      {
363	_Base::pop_back();
364      }
365
366      iterator
367      erase(iterator __position)
368      {
369	if (__position == begin() || __position == end()-1)
370	  {
371	    return iterator(_Base::erase(__position));
372	  }
373	else
374	  {
375	    typename _Base::iterator __res = _Base::erase(__position);
376	    return iterator(__res);
377	  }
378      }
379
380      iterator
381      erase(iterator __first, iterator __last)
382      {
383	// _GLIBCXX_RESOLVE_LIB_DEFECTS
384	// 151. can't currently clear() empty container
385        return iterator(_Base::erase(__first, __last));
386      }
387
388      void
389      swap(deque& __x)
390      {
391	_Base::swap(__x);
392      }
393
394      void
395      clear() _GLIBCXX_NOEXCEPT
396      {
397	_Base::clear();
398      }
399
400      _Base&
401      _M_base() _GLIBCXX_NOEXCEPT       { return *this; }
402
403      const _Base&
404      _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
405    };
406
407  template<typename _Tp, typename _Alloc>
408    inline bool
409    operator==(const deque<_Tp, _Alloc>& __lhs,
410	       const deque<_Tp, _Alloc>& __rhs)
411    { return __lhs._M_base() == __rhs._M_base(); }
412
413  template<typename _Tp, typename _Alloc>
414    inline bool
415    operator!=(const deque<_Tp, _Alloc>& __lhs,
416	       const deque<_Tp, _Alloc>& __rhs)
417    { return __lhs._M_base() != __rhs._M_base(); }
418
419  template<typename _Tp, typename _Alloc>
420    inline bool
421    operator<(const deque<_Tp, _Alloc>& __lhs,
422	      const deque<_Tp, _Alloc>& __rhs)
423    { return __lhs._M_base() < __rhs._M_base(); }
424
425  template<typename _Tp, typename _Alloc>
426    inline bool
427    operator<=(const deque<_Tp, _Alloc>& __lhs,
428	       const deque<_Tp, _Alloc>& __rhs)
429    { return __lhs._M_base() <= __rhs._M_base(); }
430
431  template<typename _Tp, typename _Alloc>
432    inline bool
433    operator>=(const deque<_Tp, _Alloc>& __lhs,
434	       const deque<_Tp, _Alloc>& __rhs)
435    { return __lhs._M_base() >= __rhs._M_base(); }
436
437  template<typename _Tp, typename _Alloc>
438    inline bool
439    operator>(const deque<_Tp, _Alloc>& __lhs,
440	      const deque<_Tp, _Alloc>& __rhs)
441    { return __lhs._M_base() > __rhs._M_base(); }
442
443  template<typename _Tp, typename _Alloc>
444    inline void
445    swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
446    { __lhs.swap(__rhs); }
447
448} // namespace __profile
449} // namespace std
450
451#endif
452