4 * Hewlett-Packard Company
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
16 * Silicon Graphics Computer Systems, Inc.
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
27 #ifndef __SGI_STL_VECTOR_H
28 #define __SGI_STL_VECTOR_H
34 template <class T
, class Alloc
= alloc
>
38 typedef value_type
* pointer
;
39 typedef value_type
* iterator
;
40 typedef const value_type
* const_iterator
;
41 typedef value_type
& reference
;
42 typedef const value_type
& const_reference
;
43 typedef size_t size_type
;
44 typedef ptrdiff_t difference_type
;
45 typedef reverse_iterator
<const_iterator
, value_type
, const_reference
,
46 difference_type
> const_reverse_iterator
;
47 typedef reverse_iterator
<iterator
, value_type
, reference
, difference_type
>
50 typedef simple_alloc
<value_type
, Alloc
> data_allocator
;
53 iterator end_of_storage
;
54 void insert_aux(iterator position
, const T
& x
);
56 if (start
) data_allocator::deallocate(start
, end_of_storage
- start
);
59 iterator
begin() { return start
; }
60 const_iterator
begin() const { return start
; }
61 iterator
end() { return finish
; }
62 const_iterator
end() const { return finish
; }
63 reverse_iterator
rbegin() { return reverse_iterator(end()); }
64 const_reverse_iterator
rbegin() const {
65 return const_reverse_iterator(end());
67 reverse_iterator
rend() { return reverse_iterator(begin()); }
68 const_reverse_iterator
rend() const {
69 return const_reverse_iterator(begin());
71 size_type
size() const { return size_type(end() - begin()); }
72 size_type
max_size() const { return size_type(-1); }
73 size_type
capacity() const { return size_type(end_of_storage
- begin()); }
74 bool empty() const { return begin() == end(); }
75 reference
operator[](size_type n
) { return *(begin() + n
); }
76 const_reference
operator[](size_type n
) const { return *(begin() + n
); }
77 vector() : start(0), finish(0), end_of_storage(0) {}
78 vector(size_type n
, const T
& value
) {
79 start
= allocate_and_fill(n
, value
);
81 end_of_storage
= finish
;
83 explicit vector(size_type n
) {
84 start
= allocate_and_fill(n
, T());
86 end_of_storage
= finish
;
88 vector(const vector
<T
, Alloc
>& x
) {
89 start
= allocate_and_copy(x
.end() - x
.begin(), x
.begin(), x
.end());
90 finish
= start
+ (x
.end() - x
.begin());
91 end_of_storage
= finish
;
93 #ifdef __STL_MEMBER_TEMPLATES
94 template <class InputIterator
>
95 vector(InputIterator first
, InputIterator last
) :
96 start(0), finish(0), end_of_storage(0) {
97 range_initialize(first
, last
, iterator_category(first
));
99 #else /* __STL_MEMBER_TEMPLATES */
100 vector(const_iterator first
, const_iterator last
) {
102 distance(first
, last
, n
);
103 start
= allocate_and_copy(n
, first
, last
);
105 end_of_storage
= finish
;
107 #endif /* __STL_MEMBER_TEMPLATES */
109 destroy(start
, finish
);
112 vector
<T
, Alloc
>& operator=(const vector
<T
, Alloc
>& x
);
113 void reserve(size_type n
) {
114 if (capacity() < n
) {
115 const size_type old_size
= size();
116 const iterator tmp
= allocate_and_copy(n
, start
, finish
);
117 destroy(start
, finish
);
120 finish
= tmp
+ old_size
;
121 end_of_storage
= start
+ n
;
124 reference
front() { return *begin(); }
125 const_reference
front() const { return *begin(); }
126 reference
back() { return *(end() - 1); }
127 const_reference
back() const { return *(end() - 1); }
128 void push_back(const T
& x
) {
129 if (finish
!= end_of_storage
) {
130 construct(finish
, x
);
133 insert_aux(end(), x
);
135 void swap(vector
<T
, Alloc
>& x
) {
136 ::swap(start
, x
.start
);
137 ::swap(finish
, x
.finish
);
138 ::swap(end_of_storage
, x
.end_of_storage
);
140 iterator
insert(iterator position
, const T
& x
) {
141 size_type n
= position
- begin();
142 if (finish
!= end_of_storage
&& position
== end()) {
143 construct(finish
, x
);
146 insert_aux(position
, x
);
149 iterator
insert(iterator position
) { return insert(position
, T()); }
150 #ifdef __STL_MEMBER_TEMPLATES
151 template <class InputIterator
>
152 void insert(iterator position
, InputIterator first
, InputIterator last
) {
153 range_insert(position
, first
, last
, iterator_category(first
));
155 #else /* __STL_MEMBER_TEMPLATES */
156 void insert(iterator position
,
157 const_iterator first
, const_iterator last
);
158 #endif /* __STL_MEMBER_TEMPLATES */
159 void insert (iterator position
, size_type n
, const T
& x
);
164 void erase(iterator position
) {
165 if (position
+ 1 != end())
166 copy(position
+ 1, finish
, position
);
170 void erase(iterator first
, iterator last
) {
171 iterator i
= copy(last
, finish
, first
);
173 finish
= finish
- (last
- first
);
175 void resize(size_type new_size
, const T
& x
) {
176 if (new_size
< size())
177 erase(begin() + new_size
, end());
179 insert(end(), new_size
- size(), x
);
181 void resize(size_type new_size
) { resize(new_size
, T()); }
182 void clear() { erase(begin(), end()); }
185 iterator
allocate_and_fill(size_type n
, const T
& x
) {
186 iterator result
= data_allocator::allocate(n
);
187 # ifdef __STL_USE_EXCEPTIONS
189 # endif /* __STL_USE_EXCEPTIONS */
190 uninitialized_fill_n(result
, n
, x
);
192 # ifdef __STL_USE_EXCEPTIONS
195 data_allocator::deallocate(result
, n
);
198 # endif /* __STL_USE_EXCEPTIONS */
201 #ifdef __STL_MEMBER_TEMPLATES
202 template <class ForwardIterator
>
203 iterator
allocate_and_copy(size_type n
,
204 ForwardIterator first
, ForwardIterator last
) {
205 iterator result
= data_allocator::allocate(n
);
206 # ifdef __STL_USE_EXCEPTIONS
208 # endif /* __STL_USE_EXCEPTIONS */
209 uninitialized_copy(first
, last
, result
);
211 # ifdef __STL_USE_EXCEPTIONS
214 data_allocator::deallocate(result
, n
);
217 # endif /* __STL_USE_EXCEPTIONS */
219 #else /* __STL_MEMBER_TEMPLATES */
220 iterator
allocate_and_copy(size_type n
,
221 const_iterator first
, const_iterator last
) {
222 iterator result
= data_allocator::allocate(n
);
223 # ifdef __STL_USE_EXCEPTIONS
225 # endif /* __STL_USE_EXCEPTIONS */
226 uninitialized_copy(first
, last
, result
);
228 # ifdef __STL_USE_EXCEPTIONS
231 data_allocator::deallocate(result
, n
);
234 # endif /* __STL_USE_EXCEPTIONS */
236 #endif /* __STL_MEMBER_TEMPLATES */
239 #ifdef __STL_MEMBER_TEMPLATES
240 template <class InputIterator
>
241 void range_initialize(InputIterator first
, InputIterator last
,
242 input_iterator_tag
) {
243 for ( ; first
!= last
; ++first
)
247 // This function is only called by the constructor. We have to worry
248 // about resource leaks, but not about maintaining invariants.
249 template <class ForwardIterator
>
250 void range_initialize(ForwardIterator first
, ForwardIterator last
,
251 forward_iterator_tag
) {
253 distance(first
, last
, n
);
254 start
= allocate_and_copy(n
, first
, last
);
256 end_of_storage
= finish
;
259 template <class BidirectionalIterator
>
260 void range_initialize(BidirectionalIterator first
,
261 BidirectionalIterator last
,
262 bidirectional_iterator_tag
) {
263 range_initialize(first
, last
, forward_iterator_tag());
266 template <class RandomAccessIterator
>
267 void range_initialize(RandomAccessIterator first
,
268 RandomAccessIterator last
,
269 random_access_iterator_tag
) {
270 range_initialize(first
, last
, forward_iterator_tag());
273 template <class InputIterator
>
274 void range_insert(iterator pos
,
275 InputIterator first
, InputIterator last
,
278 template <class ForwardIterator
>
279 void range_insert(iterator pos
,
280 ForwardIterator first
, ForwardIterator last
,
281 forward_iterator_tag
);
283 template <class BidirectionalIterator
>
284 void range_insert(iterator pos
,
285 BidirectionalIterator first
, BidirectionalIterator last
,
286 bidirectional_iterator_tag
) {
287 range_insert(pos
, first
, last
, forward_iterator_tag());
290 template <class RandomAccessIterator
>
291 void range_insert(iterator pos
,
292 RandomAccessIterator first
, RandomAccessIterator last
,
293 random_access_iterator_tag
) {
294 range_insert(pos
, first
, last
, forward_iterator_tag());
296 #endif /* __STL_MEMBER_TEMPLATES */
299 template <class T
, class Alloc
>
300 inline bool operator==(const vector
<T
, Alloc
>& x
, const vector
<T
, Alloc
>& y
) {
301 return x
.size() == y
.size() && equal(x
.begin(), x
.end(), y
.begin());
304 template <class T
, class Alloc
>
305 inline bool operator<(const vector
<T
, Alloc
>& x
, const vector
<T
, Alloc
>& y
) {
306 return lexicographical_compare(x
.begin(), x
.end(), y
.begin(), y
.end());
311 template <class T
, class Alloc
>
312 vector
<T
, Alloc
>& vector
<T
, Alloc
>::operator=(const vector
<T
, Alloc
>& x
) {
314 if (x
.size() > capacity()) {
315 const iterator tmp
= allocate_and_copy(x
.end() - x
.begin(),
317 destroy(start
, finish
);
320 end_of_storage
= start
+ (x
.end() - x
.begin());
322 else if (size() >= x
.size()) {
323 iterator i
= copy(x
.begin(), x
.end(), begin());
327 copy(x
.begin(), x
.begin() + size(), start
);
328 uninitialized_copy(x
.begin() + size(), x
.end(), finish
);
330 finish
= start
+ x
.size();
335 template <class T
, class Alloc
>
336 void vector
<T
, Alloc
>::insert_aux(iterator position
, const T
& x
) {
337 if (finish
!= end_of_storage
) {
338 construct(finish
, *(finish
- 1));
341 copy_backward(position
, finish
- 2, finish
- 1);
345 const size_type old_size
= size();
346 const size_type len
= old_size
!= 0 ? 2 * old_size
: 1;
347 const iterator new_start
= data_allocator::allocate(len
);
348 iterator new_finish
= new_start
;
349 # ifdef __STL_USE_EXCEPTIONS
351 # endif /* __STL_USE_EXCEPTIONS */
352 new_finish
= uninitialized_copy(start
, position
, new_start
);
353 construct(new_finish
, x
);
355 new_finish
= uninitialized_copy(position
, finish
, new_finish
);
356 # ifdef __STL_USE_EXCEPTIONS
359 destroy(new_start
, new_finish
);
360 data_allocator::deallocate(new_start
, len
);
363 # endif /* __STL_USE_EXCEPTIONS */
364 destroy(begin(), end());
368 end_of_storage
= new_start
+ len
;
372 template <class T
, class Alloc
>
373 void vector
<T
, Alloc
>::insert(iterator position
, size_type n
, const T
& x
) {
375 if (size_type (end_of_storage
- finish
) >= n
) {
377 const size_type elems_after
= finish
- position
;
378 const iterator old_finish
= finish
;
379 if (elems_after
> n
) {
380 uninitialized_copy(finish
- n
, finish
, finish
);
382 copy_backward(position
, old_finish
- n
, old_finish
);
383 fill(position
, position
+ n
, x_copy
);
386 uninitialized_fill_n(finish
, n
- elems_after
, x_copy
);
387 finish
+= n
- elems_after
;
388 uninitialized_copy(position
, old_finish
, finish
);
389 finish
+= elems_after
;
390 fill(position
, old_finish
, x_copy
);
394 const size_type old_size
= size();
395 const size_type len
= old_size
+ max(old_size
, n
);
396 const iterator new_start
= data_allocator::allocate(len
);
397 iterator new_finish
= new_start
;
398 # ifdef __STL_USE_EXCEPTIONS
400 # endif /* __STL_USE_EXCEPTIONS */
401 new_finish
= uninitialized_copy(start
, position
, new_start
);
402 new_finish
= uninitialized_fill_n(new_finish
, n
, x
);
403 new_finish
= uninitialized_copy(position
, finish
, new_finish
);
404 # ifdef __STL_USE_EXCEPTIONS
407 destroy(new_start
, new_finish
);
408 data_allocator::deallocate(new_start
, len
);
411 # endif /* __STL_USE_EXCEPTIONS */
412 destroy(start
, finish
);
416 end_of_storage
= new_start
+ len
;
421 #ifdef __STL_MEMBER_TEMPLATES
423 template <class T
, class Alloc
> template <class InputIterator
>
424 void vector
<T
, Alloc
>::range_insert(iterator pos
,
425 InputIterator first
, InputIterator last
,
426 input_iterator_tag
) {
427 for ( ; first
!= last
; ++first
) {
428 pos
= insert(pos
, *first
);
433 template <class T
, class Alloc
> template <class ForwardIterator
>
434 void vector
<T
, Alloc
>::range_insert(iterator position
,
435 ForwardIterator first
,
436 ForwardIterator last
,
437 forward_iterator_tag
) {
440 distance(first
, last
, n
);
441 if (size_type (end_of_storage
- finish
) >= n
) {
442 const size_type elems_after
= finish
- position
;
443 const iterator old_finish
= finish
;
444 if (elems_after
> n
) {
445 uninitialized_copy(finish
- n
, finish
, finish
);
447 copy_backward(position
, old_finish
- n
, old_finish
);
448 copy(first
, last
, position
);
451 ForwardIterator mid
= first
;
452 advance(mid
, elems_after
);
453 uninitialized_copy(mid
, last
, finish
);
454 finish
+= n
- elems_after
;
455 uninitialized_copy(position
, old_finish
, finish
);
456 finish
+= elems_after
;
457 copy(first
, mid
, position
);
461 const size_type old_size
= size();
462 const size_type len
= old_size
+ max(old_size
, n
);
463 const iterator new_start
= data_allocator::allocate(len
);
464 iterator new_finish
= new_start
;
465 # ifdef __STL_USE_EXCEPTIONS
467 # endif /* __STL_USE_EXCEPTIONS */
468 new_finish
= uninitialized_copy(start
, position
, new_start
);
469 new_finish
= uninitialized_copy(first
, last
, new_finish
);
470 new_finish
= uninitialized_copy(position
, finish
, new_finish
);
471 # ifdef __STL_USE_EXCEPTIONS
474 destroy(new_start
, new_finish
);
475 data_allocator::deallocate(new_start
, len
);
478 # endif /* __STL_USE_EXCEPTIONS */
479 destroy(start
, finish
);
483 end_of_storage
= new_start
+ len
;
488 #else /* __STL_MEMBER_TEMPLATES */
490 template <class T
, class Alloc
>
491 void vector
<T
, Alloc
>::insert(iterator position
,
492 const_iterator first
,
493 const_iterator last
) {
496 distance(first
, last
, n
);
497 if (end_of_storage
- finish
>= n
) {
498 const size_type elems_after
= finish
- position
;
499 const iterator old_finish
= finish
;
500 if (elems_after
> n
) {
501 uninitialized_copy(finish
- n
, finish
, finish
);
503 copy_backward(position
, old_finish
- n
, old_finish
);
504 copy(first
, last
, position
);
507 uninitialized_copy(first
+ elems_after
, last
, finish
);
508 finish
+= n
- elems_after
;
509 uninitialized_copy(position
, old_finish
, finish
);
510 finish
+= elems_after
;
511 copy(first
, first
+ elems_after
, position
);
515 const size_type old_size
= size();
516 const size_type len
= old_size
+ max(old_size
, n
);
517 const iterator new_start
= data_allocator::allocate(len
);
518 iterator new_finish
= new_start
;
519 # ifdef __STL_USE_EXCEPTIONS
521 # endif /* __STL_USE_EXCEPTIONS */
522 new_finish
= uninitialized_copy(start
, position
, new_start
);
523 new_finish
= uninitialized_copy(first
, last
, new_finish
);
524 new_finish
= uninitialized_copy(position
, finish
, new_finish
);
525 # ifdef __STL_USE_EXCEPTIONS
528 destroy(new_start
, new_finish
);
529 data_allocator::deallocate(new_start
, len
);
532 # endif /* __STL_USE_EXCEPTIONS */
533 destroy(start
, finish
);
537 end_of_storage
= new_start
+ len
;
542 #endif /* __STL_MEMBER_TEMPLATES */
544 #endif /* __SGI_STL_VECTOR_H */