1 _vector.h |
1 /* |
|
2 * |
|
3 * Copyright (c) 1994 |
|
4 * Hewlett-Packard Company |
|
5 * |
|
6 * Copyright (c) 1996,1997 |
|
7 * Silicon Graphics Computer Systems, Inc. |
|
8 * |
|
9 * Copyright (c) 1997 |
|
10 * Moscow Center for SPARC Technology |
|
11 * |
|
12 * Copyright (c) 1999 |
|
13 * Boris Fomitchev |
|
14 * |
|
15 * This material is provided "as is", with absolutely no warranty expressed |
|
16 * or implied. Any use is at your own risk. |
|
17 * |
|
18 * Permission to use or copy this software for any purpose is hereby granted |
|
19 * without fee, provided the above notices are retained on all copies. |
|
20 * Permission to modify the code and to distribute modified code is granted, |
|
21 * provided the above notices are retained, and a notice that the code was |
|
22 * modified is included with the above copyright notice. |
|
23 * |
|
24 */ |
|
25 |
|
26 /* NOTE: This is an internal header file, included by other STL headers. |
|
27 * You should not attempt to use it directly. |
|
28 */ |
|
29 |
|
30 #ifndef _STLP_INTERNAL_DBG_VECTOR_H |
|
31 #define _STLP_INTERNAL_DBG_VECTOR_H |
|
32 |
|
33 #include <stl/debug/_iterator.h> |
|
34 |
|
35 # ifndef _STLP_USE_WRAPPER_FOR_ALLOC_PARAM |
|
36 # undef _DBG_vector |
|
37 # define _DBG_vector vector |
|
38 # endif |
|
39 |
|
40 # define _STLP_DBG_VECTOR_BASE __WORKAROUND_DBG_RENAME(vector) <_Tp, _Alloc> |
|
41 |
|
42 _STLP_BEGIN_NAMESPACE |
|
43 |
|
44 # ifdef _STLP_DEBUG_USE_DISTINCT_VALUE_TYPE_HELPERS |
|
45 template <class _Tp, class _Alloc> |
|
46 inline _Tp* |
|
47 value_type(const _DBG_iter_base< _STLP_DBG_VECTOR_BASE >&) { |
|
48 return (_Tp*)0; |
|
49 } |
|
50 template <class _Tp, class _Alloc> |
|
51 inline random_access_iterator_tag |
|
52 iterator_category(const _DBG_iter_base< _STLP_DBG_VECTOR_BASE >&) { |
|
53 return random_access_iterator_tag(); |
|
54 } |
|
55 # endif |
|
56 |
|
57 template <class _Tp, class _NcIt> |
|
58 struct _Vector_nonconst_traits |
|
59 { |
|
60 typedef _Nonconst_traits<_Tp> _BaseT; |
|
61 typedef _Tp value_type; |
|
62 typedef _Tp& reference; |
|
63 typedef _Tp* pointer; |
|
64 typedef _Vector_nonconst_traits<_Tp, _NcIt> _Non_const_traits; |
|
65 }; |
|
66 |
|
67 template <class _Tp, class _NcIt> |
|
68 struct _Vector_const_traits |
|
69 { |
|
70 typedef _Const_traits<_Tp> _BaseT; |
|
71 typedef _Tp value_type; |
|
72 typedef const _Tp& reference; |
|
73 typedef const _Tp* pointer; |
|
74 typedef _Vector_nonconst_traits<_Tp, _NcIt> _Non_const_traits; |
|
75 }; |
|
76 |
|
77 _STLP_TEMPLATE_NULL |
|
78 struct _Vector_nonconst_traits<bool, _Bit_iterator> |
|
79 { |
|
80 typedef _Bit_iterator::value_type value_type; |
|
81 typedef _Bit_iterator::reference reference; |
|
82 typedef _Bit_iterator::pointer pointer; |
|
83 typedef _Vector_nonconst_traits<bool, _Bit_iterator> _Non_const_traits; |
|
84 }; |
|
85 |
|
86 _STLP_TEMPLATE_NULL |
|
87 struct _Vector_const_traits<bool, _Bit_iterator> |
|
88 { |
|
89 typedef _Bit_const_iterator::value_type value_type; |
|
90 typedef _Bit_const_iterator::reference reference; |
|
91 typedef _Bit_const_iterator::pointer pointer; |
|
92 typedef _Vector_nonconst_traits<bool, _Bit_iterator> _Non_const_traits; |
|
93 }; |
|
94 |
|
95 template <class _Tp, _STLP_DBG_ALLOCATOR_SELECT(_Tp) > |
|
96 class _DBG_vector : public _STLP_DBG_VECTOR_BASE { |
|
97 private: |
|
98 typedef _STLP_DBG_VECTOR_BASE _Base; |
|
99 typedef _DBG_vector<_Tp, _Alloc> _Self; |
|
100 mutable __owned_list _M_iter_list; |
|
101 |
|
102 public: |
|
103 |
|
104 __IMPORT_CONTAINER_TYPEDEFS(_Base) |
|
105 |
|
106 typedef _DBG_iter<_Base, |
|
107 _Vector_nonconst_traits<value_type, typename _Base::iterator> > iterator; |
|
108 |
|
109 typedef _DBG_iter<_Base, |
|
110 _Vector_const_traits<value_type, typename _Base::iterator> > const_iterator; |
|
111 |
|
112 _STLP_DECLARE_RANDOM_ACCESS_REVERSE_ITERATORS; |
|
113 |
|
114 iterator begin() { return iterator(&_M_iter_list, this->_M_start); } |
|
115 const_iterator begin() const { return const_iterator(&_M_iter_list, this->_M_start); } |
|
116 iterator end() { return iterator(&_M_iter_list, this->_M_finish); } |
|
117 const_iterator end() const { return const_iterator(&_M_iter_list, this->_M_finish); } |
|
118 |
|
119 reverse_iterator rbegin() |
|
120 { return reverse_iterator(end()); } |
|
121 const_reverse_iterator rbegin() const |
|
122 { return const_reverse_iterator(end()); } |
|
123 reverse_iterator rend() |
|
124 { return reverse_iterator(begin()); } |
|
125 const_reverse_iterator rend() const |
|
126 { return const_reverse_iterator(begin()); } |
|
127 |
|
128 reference operator[](size_type __n) { |
|
129 _STLP_VERBOSE_ASSERT(__n < _Base::size(), _StlMsg_OUT_OF_BOUNDS) |
|
130 return _Base::operator[](__n); |
|
131 } |
|
132 |
|
133 const_reference operator[](size_type __n) const { |
|
134 _STLP_VERBOSE_ASSERT(__n < _Base::size(), _StlMsg_OUT_OF_BOUNDS) |
|
135 return _Base::operator[](__n); |
|
136 } |
|
137 |
|
138 _Base* _Get_base() { return (_Base*)this; } |
|
139 const _Base* _Get_base() const { return (const _Base*)this; } |
|
140 |
|
141 explicit _DBG_vector(const allocator_type& __a = allocator_type()) |
|
142 : _STLP_DBG_VECTOR_BASE(__a), _M_iter_list((const _Base*)this) {} |
|
143 |
|
144 _DBG_vector(size_type __n, const _Tp& __value, |
|
145 const allocator_type& __a = allocator_type()) |
|
146 : _STLP_DBG_VECTOR_BASE(__n, __value, __a), _M_iter_list((const _Base*)this) {} |
|
147 |
|
148 explicit _DBG_vector(size_type __n) |
|
149 : _STLP_DBG_VECTOR_BASE(__n), _M_iter_list((const _Base*)this) {} |
|
150 |
|
151 |
|
152 _DBG_vector(const _Self& __x) |
|
153 : _STLP_DBG_VECTOR_BASE(__x), _M_iter_list((const _Base*)this) {} |
|
154 |
|
155 #if defined (_STLP_MEMBER_TEMPLATES) |
|
156 # ifdef _STLP_NEEDS_EXTRA_TEMPLATE_CONSTRUCTORS |
|
157 template <class _InputIterator> |
|
158 _DBG_vector(_InputIterator __first, _InputIterator __last): |
|
159 _STLP_DBG_VECTOR_BASE(__first, __last), _M_iter_list((const _Base*)this) {} |
|
160 # endif |
|
161 template <class _InputIterator> |
|
162 _DBG_vector(_InputIterator __first, _InputIterator __last, |
|
163 const allocator_type& __a _STLP_ALLOCATOR_TYPE_DFL) : |
|
164 _STLP_DBG_VECTOR_BASE(__first, __last, __a), _M_iter_list((const _Base*)this) {} |
|
165 |
|
166 #else |
|
167 _DBG_vector(const _Tp* __first, const _Tp* __last, |
|
168 const allocator_type& __a = allocator_type()) |
|
169 : _STLP_DBG_VECTOR_BASE(__first, __last, __a), _M_iter_list((const _Base*)this) {} |
|
170 |
|
171 // mysterious VC++ bug ? |
|
172 _DBG_vector(const_iterator __first, const_iterator __last , |
|
173 const allocator_type& __a = allocator_type()) |
|
174 : _STLP_DBG_VECTOR_BASE(__first._M_iterator, __last._M_iterator, __a), |
|
175 _M_iter_list((const _Base*)this) { } |
|
176 |
|
177 #endif /* _STLP_MEMBER_TEMPLATES */ |
|
178 |
|
179 _Self& operator=(const _Self& __x) { |
|
180 _M_iter_list._Invalidate_all(); |
|
181 (_Base&)*this = (const _Base&)__x; |
|
182 return *this; |
|
183 } |
|
184 |
|
185 reference front() { return *begin(); } |
|
186 const_reference front() const { return *begin(); } |
|
187 |
|
188 reference back() { |
|
189 iterator __tmp = end(); |
|
190 --__tmp; |
|
191 return *__tmp; |
|
192 } |
|
193 const_reference back() const { |
|
194 const_iterator __tmp = end(); |
|
195 --__tmp; |
|
196 return *__tmp; |
|
197 } |
|
198 |
|
199 void swap(_Self& __x) { |
|
200 _M_iter_list._Swap_owners(__x._M_iter_list); |
|
201 _Base::swap((_Base&)__x); |
|
202 } |
|
203 |
|
204 iterator insert(iterator __position, const _Tp& __x) { |
|
205 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
206 if (this->size()+1 > this->capacity()) _M_iter_list._Invalidate_all(); |
|
207 return iterator(&_M_iter_list, _Base::insert(__position._M_iterator, __x)); |
|
208 } |
|
209 |
|
210 iterator insert(iterator __position) { |
|
211 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
212 if (this->size()+1 > this->capacity()) _M_iter_list._Invalidate_all(); |
|
213 return iterator(&_M_iter_list, _Base::insert(__position._M_iterator)); |
|
214 } |
|
215 |
|
216 #ifdef _STLP_MEMBER_TEMPLATES |
|
217 // Check whether it's an integral type. If so, it's not an iterator. |
|
218 template <class _InputIterator> |
|
219 void insert(iterator __position, _InputIterator __first, _InputIterator __last) { |
|
220 _STLP_DEBUG_CHECK(__check_range(__first,__last)) |
|
221 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
222 size_type __n = distance(__first, __last); |
|
223 if (this->size()+__n > this->capacity()) _M_iter_list._Invalidate_all(); |
|
224 _Base::insert(__position._M_iterator, __first, __last); |
|
225 } |
|
226 #else /* _STLP_MEMBER_TEMPLATES */ |
|
227 void insert(iterator __position, |
|
228 const_iterator __first, const_iterator __last) { |
|
229 _STLP_DEBUG_CHECK(__check_range(__first,__last)) |
|
230 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
231 size_type __n = distance(__first, __last); |
|
232 if (this->size()+__n > this->capacity()) _M_iter_list._Invalidate_all(); |
|
233 _Base::insert(__position._M_iterator, |
|
234 __first._M_iterator, __last._M_iterator); |
|
235 } |
|
236 |
|
237 void insert (iterator __position, const_pointer __first, const_pointer __last) { |
|
238 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
239 _STLP_DEBUG_CHECK(__check_range(__first,__last)) |
|
240 size_type __n = distance(__first, __last); |
|
241 if (this->size()+__n > this->capacity()) _M_iter_list._Invalidate_all(); |
|
242 _Base::insert(__position._M_iterator, __first, __last); |
|
243 } |
|
244 #endif /* _STLP_MEMBER_TEMPLATES */ |
|
245 |
|
246 void insert (iterator __position, size_type __n, const _Tp& __x){ |
|
247 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
248 if (this->size()+__n > this->capacity()) _M_iter_list._Invalidate_all(); |
|
249 _Base::insert(__position._M_iterator, __n, __x); |
|
250 } |
|
251 |
|
252 void pop_back() { |
|
253 _STLP_VERBOSE_ASSERT(!this->empty(), _StlMsg_EMPTY_CONTAINER) |
|
254 __invalidate_iterator(&_M_iter_list,end()); |
|
255 _Base::pop_back(); |
|
256 } |
|
257 iterator erase(iterator __position) { |
|
258 _STLP_DEBUG_CHECK(__check_if_owner(&_M_iter_list, __position)) |
|
259 _STLP_VERBOSE_ASSERT(__position._M_iterator !=this->_M_finish,_StlMsg_ERASE_PAST_THE_END) |
|
260 __invalidate_range(&_M_iter_list, __position+1, end()); |
|
261 return iterator(&_M_iter_list,_Base::erase(__position._M_iterator)); |
|
262 } |
|
263 iterator erase(iterator __first, iterator __last) { |
|
264 _STLP_DEBUG_CHECK(__check_range(__first,__last, begin(), end())) |
|
265 __invalidate_range(&_M_iter_list, __first._M_iterator == this->_M_finish ? |
|
266 __first : __first+1, end()); |
|
267 return iterator(&_M_iter_list, _Base::erase(__first._M_iterator, __last._M_iterator)); |
|
268 } |
|
269 void clear() { |
|
270 _M_iter_list._Invalidate_all(); |
|
271 _Base::clear(); |
|
272 } |
|
273 void push_back(const _Tp& __x) { |
|
274 if (this->size()+1 > this->capacity()) _M_iter_list._Invalidate_all(); |
|
275 _Base::push_back(__x); |
|
276 } |
|
277 }; |
|
278 |
|
279 #define _STLP_TEMPLATE_HEADER template <class _Tp, class _Alloc> |
|
280 #define _STLP_TEMPLATE_CONTAINER _DBG_vector<_Tp, _Alloc> |
|
281 #define _STLP_TEMPLATE_CONTAINER_BASE _STLP_DBG_VECTOR_BASE |
|
282 #include <stl/debug/_relops_cont.h> |
|
283 #undef _STLP_TEMPLATE_CONTAINER_BASE |
|
284 #undef _STLP_TEMPLATE_CONTAINER |
|
285 #undef _STLP_TEMPLATE_HEADER |
|
286 |
|
287 # if defined (_STLP_USE_TEMPLATE_EXPORT) |
|
288 _STLP_EXPORT_TEMPLATE_CLASS _DBG_vector <void*,allocator<void*> >; |
|
289 # endif /* _STLP_USE_TEMPLATE_EXPORT */ |
|
290 |
|
291 _STLP_END_NAMESPACE |
|
292 |
|
293 # undef _STLP_DBG_VECTOR_BASE |
|
294 # undef _DBG_vector |
|
295 |
|
296 #endif /* _STLP_DBG_VECTOR_H */ |
|
297 |
|
298 // Local Variables: |
|
299 // mode:C++ |
|
300 // End: |