1 // Profiling vector implementation -*- C++ -*-
3 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
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 2, or (at your option)
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.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file profile/vector
31 * This file is a GNU profile extension to the Standard C++ Library.
34 #ifndef _GLIBCXX_PROFILE_VECTOR
35 #define _GLIBCXX_PROFILE_VECTOR 1
39 #include <profile/base.h>
40 #include <profile/iterator_tracker.h>
42 namespace std _GLIBCXX_VISIBILITY(default)
46 template<typename _Tp,
47 typename _Allocator = std::allocator<_Tp> >
49 : public _GLIBCXX_STD_C::vector<_Tp, _Allocator>
51 typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator> _Base;
54 typedef typename _Base::reference reference;
55 typedef typename _Base::const_reference const_reference;
57 typedef __iterator_tracker<typename _Base::iterator, vector>
59 typedef __iterator_tracker<typename _Base::const_iterator, vector>
62 typedef typename _Base::size_type size_type;
63 typedef typename _Base::difference_type difference_type;
65 typedef _Tp value_type;
66 typedef _Allocator allocator_type;
67 typedef typename _Base::pointer pointer;
68 typedef typename _Base::const_pointer const_pointer;
69 typedef std::reverse_iterator<iterator> reverse_iterator;
70 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
73 _M_base() { return *this; }
76 _M_base() const { return *this; }
78 // 23.2.4.1 construct/copy/destroy:
80 vector(const _Allocator& __a = _Allocator())
83 __profcxx_vector_construct(this, this->capacity());
84 __profcxx_vector_construct2(this);
87 #ifdef __GXX_EXPERIMENTAL_CXX0X__
92 __profcxx_vector_construct(this, this->capacity());
93 __profcxx_vector_construct2(this);
96 vector(size_type __n, const _Tp& __value,
97 const _Allocator& __a = _Allocator())
98 : _Base(__n, __value, __a)
100 __profcxx_vector_construct(this, this->capacity());
101 __profcxx_vector_construct2(this);
105 vector(size_type __n, const _Tp& __value = _Tp(),
106 const _Allocator& __a = _Allocator())
107 : _Base(__n, __value, __a)
109 __profcxx_vector_construct(this, this->capacity());
110 __profcxx_vector_construct2(this);
114 template<class _InputIterator>
115 vector(_InputIterator __first, _InputIterator __last,
116 const _Allocator& __a = _Allocator())
117 : _Base(__first, __last, __a)
119 __profcxx_vector_construct(this, this->capacity());
120 __profcxx_vector_construct2(this);
123 vector(const vector& __x)
126 __profcxx_vector_construct(this, this->capacity());
127 __profcxx_vector_construct2(this);
130 /// Construction from a release-mode vector
131 vector(const _Base& __x)
134 __profcxx_vector_construct(this, this->capacity());
135 __profcxx_vector_construct2(this);
138 #ifdef __GXX_EXPERIMENTAL_CXX0X__
140 : _Base(std::move(__x))
142 __profcxx_vector_construct(this, this->capacity());
143 __profcxx_vector_construct2(this);
146 vector(initializer_list<value_type> __l,
147 const allocator_type& __a = allocator_type())
148 : _Base(__l, __a) { }
152 __profcxx_vector_destruct(this, this->capacity(), this->size());
153 __profcxx_vector_destruct2(this);
157 operator=(const vector& __x)
159 static_cast<_Base&>(*this) = __x;
163 #ifdef __GXX_EXPERIMENTAL_CXX0X__
165 operator=(vector&& __x)
175 operator=(initializer_list<value_type> __l)
177 static_cast<_Base&>(*this) = __l;
183 using _Base::get_allocator;
189 { return iterator(_Base::begin(), this); }
193 { return const_iterator(_Base::begin(), this); }
197 { return iterator(_Base::end(), this); }
201 { return const_iterator(_Base::end(), this); }
205 { return reverse_iterator(end()); }
207 const_reverse_iterator
209 { return const_reverse_iterator(end()); }
213 { return reverse_iterator(begin()); }
215 const_reverse_iterator
217 { return const_reverse_iterator(begin()); }
219 #ifdef __GXX_EXPERIMENTAL_CXX0X__
222 { return const_iterator(_Base::begin(), this); }
226 { return const_iterator(_Base::end(), this); }
228 const_reverse_iterator
230 { return const_reverse_iterator(end()); }
232 const_reverse_iterator
234 { return const_reverse_iterator(begin()); }
237 // 23.2.4.2 capacity:
239 using _Base::max_size;
241 #ifdef __GXX_EXPERIMENTAL_CXX0X__
243 resize(size_type __sz)
245 __profcxx_vector_invalid_operator(this);
246 _M_profile_resize(this, this->capacity(), __sz);
251 resize(size_type __sz, const _Tp& __c)
253 __profcxx_vector_invalid_operator(this);
254 _M_profile_resize(this, this->capacity(), __sz);
255 _Base::resize(__sz, __c);
259 resize(size_type __sz, _Tp __c = _Tp())
261 __profcxx_vector_invalid_operator(this);
262 _M_profile_resize(this, this->capacity(), __sz);
263 _Base::resize(__sz, __c);
267 #ifdef __GXX_EXPERIMENTAL_CXX0X__
268 using _Base::shrink_to_fit;
275 operator[](size_type __n)
277 __profcxx_vector_invalid_operator(this);
278 return _M_base()[__n];
281 operator[](size_type __n) const
283 __profcxx_vector_invalid_operator(this);
284 return _M_base()[__n];
292 return _Base::front();
298 return _Base::front();
304 return _Base::back();
310 return _Base::back();
313 // _GLIBCXX_RESOLVE_LIB_DEFECTS
314 // DR 464. Suggestion for new member functions in standard containers.
317 // 23.2.4.3 modifiers:
319 push_back(const _Tp& __x)
321 size_type __old_size = this->capacity();
322 _Base::push_back(__x);
323 _M_profile_resize(this, __old_size, this->capacity());
326 #ifdef __GXX_EXPERIMENTAL_CXX0X__
330 size_type __old_size = this->capacity();
331 _Base::push_back(__x);
332 _M_profile_resize(this, __old_size, this->capacity());
338 insert(iterator __position, const _Tp& __x)
340 __profcxx_vector_insert(this, __position.base() - _Base::begin(),
342 size_type __old_size = this->capacity();
343 typename _Base::iterator __res = _Base::insert(__position.base(), __x);
344 _M_profile_resize(this, __old_size, this->capacity());
345 return iterator(__res, this);
348 #ifdef __GXX_EXPERIMENTAL_CXX0X__
350 insert(iterator __position, _Tp&& __x)
352 __profcxx_vector_insert(this, __position.base() - _Base::begin(),
354 size_type __old_size = this->capacity();
355 typename _Base::iterator __res = _Base::insert(__position.base(), __x);
356 _M_profile_resize(this, __old_size, this->capacity());
357 return iterator(__res, this);
361 insert(iterator __position, initializer_list<value_type> __l)
362 { this->insert(__position, __l.begin(), __l.end()); }
365 #ifdef __GXX_EXPERIMENTAL_CXX0X__
380 insert(iterator __position, size_type __n, const _Tp& __x)
382 __profcxx_vector_insert(this, __position.base() - _Base::begin(),
384 size_type __old_size = this->capacity();
385 _Base::insert(__position, __n, __x);
386 _M_profile_resize(this, __old_size, this->capacity());
389 template<class _InputIterator>
391 insert(iterator __position,
392 _InputIterator __first, _InputIterator __last)
394 __profcxx_vector_insert(this, __position.base()-_Base::begin(),
396 size_type __old_size = this->capacity();
397 _Base::insert(__position, __first, __last);
398 _M_profile_resize(this, __old_size, this->capacity());
403 erase(iterator __position)
405 typename _Base::iterator __res = _Base::erase(__position.base());
406 return iterator(__res, this);
410 erase(iterator __first, iterator __last)
412 // _GLIBCXX_RESOLVE_LIB_DEFECTS
413 // 151. can't currently clear() empty container
414 typename _Base::iterator __res = _Base::erase(__first.base(),
416 return iterator(__res, this);
422 __profcxx_vector_destruct(this, this->capacity(), this->size());
423 __profcxx_vector_destruct2(this);
427 inline void _M_profile_find() const
429 __profcxx_vector_find(this, size());
432 inline void _M_profile_iterate(int __rewind = 0) const
434 __profcxx_vector_iterate(this);
438 void _M_profile_resize(void* obj, size_type __old_size,
439 size_type __new_size)
441 if (__old_size < __new_size) {
442 __profcxx_vector_resize(this, this->size(), __new_size);
443 __profcxx_vector_resize2(this, this->size(), __new_size);
448 template<typename _Tp, typename _Alloc>
450 operator==(const vector<_Tp, _Alloc>& __lhs,
451 const vector<_Tp, _Alloc>& __rhs)
452 { return __lhs._M_base() == __rhs._M_base(); }
454 template<typename _Tp, typename _Alloc>
456 operator!=(const vector<_Tp, _Alloc>& __lhs,
457 const vector<_Tp, _Alloc>& __rhs)
458 { return __lhs._M_base() != __rhs._M_base(); }
460 template<typename _Tp, typename _Alloc>
462 operator<(const vector<_Tp, _Alloc>& __lhs,
463 const vector<_Tp, _Alloc>& __rhs)
464 { return __lhs._M_base() < __rhs._M_base(); }
466 template<typename _Tp, typename _Alloc>
468 operator<=(const vector<_Tp, _Alloc>& __lhs,
469 const vector<_Tp, _Alloc>& __rhs)
470 { return __lhs._M_base() <= __rhs._M_base(); }
472 template<typename _Tp, typename _Alloc>
474 operator>=(const vector<_Tp, _Alloc>& __lhs,
475 const vector<_Tp, _Alloc>& __rhs)
476 { return __lhs._M_base() >= __rhs._M_base(); }
478 template<typename _Tp, typename _Alloc>
480 operator>(const vector<_Tp, _Alloc>& __lhs,
481 const vector<_Tp, _Alloc>& __rhs)
482 { return __lhs._M_base() > __rhs._M_base(); }
484 template<typename _Tp, typename _Alloc>
486 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
487 { __lhs.swap(__rhs); }
489 #ifdef __GXX_EXPERIMENTAL_CXX0X__
490 template<typename _Tp, typename _Alloc>
492 swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
493 { __lhs.swap(__rhs); }
495 template<typename _Tp, typename _Alloc>
497 swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
498 { __lhs.swap(__rhs); }
501 } // namespace __profile
503 #ifdef __GXX_EXPERIMENTAL_CXX0X__
505 /// std::hash specialization for vector<bool>.
506 template<typename _Alloc>
507 struct hash<__profile::vector<bool, _Alloc>>
508 : public __hash_base<size_t, __profile::vector<bool, _Alloc>>
511 operator()(const __profile::vector<bool, _Alloc>& __b) const
512 { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()