5 * Hewlett-Packard Company
7 * Copyright (c) 1996,1997
8 * Silicon Graphics Computer Systems, Inc.
11 * Moscow Center for SPARC Technology
16 * This material is provided "as is", with absolutely no warranty expressed
17 * or implied. Any use is at your own risk.
19 * Permission to use or copy this software for any purpose is hereby granted
20 * without fee, provided the above notices are retained on all copies.
21 * Permission to modify the code and to distribute modified code is granted,
22 * provided the above notices are retained, and a notice that the code was
23 * modified is included with the above copyright notice.
26 #ifndef _STLP_VECTOR_C
27 #define _STLP_VECTOR_C
29 #if !defined (_STLP_INTERNAL_VECTOR_H)
30 # include <stl/_vector.h>
33 #include <stl/_range_errors.h>
37 _STLP_MOVE_TO_PRIV_NAMESPACE
39 template <class _Tp
, class _Alloc
>
40 void _Vector_base
<_Tp
,_Alloc
>::_M_throw_length_error() const
41 { __stl_throw_length_error("vector"); }
43 template <class _Tp
, class _Alloc
>
44 void _Vector_base
<_Tp
, _Alloc
>::_M_throw_out_of_range() const
45 { __stl_throw_out_of_range("vector"); }
47 #if defined (_STLP_USE_PTR_SPECIALIZATIONS)
48 # define vector _STLP_PTR_IMPL_NAME(vector)
49 #elif defined (_STLP_DEBUG)
50 # define vector _STLP_NON_DBG_NAME(vector)
52 _STLP_MOVE_TO_STD_NAMESPACE
55 #if defined (_STLP_NESTED_TYPE_PARAM_BUG)
56 # define __iterator__ _Tp*
58 # define __iterator__ _STLP_TYPENAME_ON_RETURN_TYPE vector<_Tp, _Alloc>::iterator
61 template <class _Tp
, class _Alloc
>
62 void vector
<_Tp
, _Alloc
>::reserve(size_type __n
) {
63 if (capacity() < __n
) {
64 if (max_size() < __n
) {
65 this->_M_throw_length_error();
68 const size_type __old_size
= size();
71 __tmp
= _M_allocate_and_copy(__n
, this->_M_start
, this->_M_finish
);
74 __tmp
= this->_M_end_of_storage
.allocate(__n
, __n
);
76 _M_set(__tmp
, __tmp
+ __old_size
, __tmp
+ __n
);
80 template <class _Tp
, class _Alloc
>
81 void vector
<_Tp
, _Alloc
>::_M_insert_overflow_aux(pointer __pos
, const _Tp
& __x
, const __false_type
& /*DO NOT USE!!*/,
82 size_type __fill_len
, bool __atend
) {
83 typedef typename __type_traits
<_Tp
>::has_trivial_copy_constructor _TrivialUCopy
;
84 #if !defined (_STLP_NO_MOVE_SEMANTIC)
85 typedef typename __move_traits
<_Tp
>::implemented _Movable
;
87 size_type __len
= _M_compute_next_size(__fill_len
);
88 pointer __new_start
= this->_M_end_of_storage
.allocate(__len
, __len
);
89 pointer __new_finish
= __new_start
;
91 __new_finish
= _STLP_PRIV
__uninitialized_move(this->_M_start
, __pos
, __new_start
, _TrivialUCopy(), _Movable());
93 if (__fill_len
== 1) {
94 _Copy_Construct(__new_finish
, __x
);
97 __new_finish
= _STLP_PRIV
__uninitialized_fill_n(__new_finish
, __fill_len
, __x
);
99 __new_finish
= _STLP_PRIV
__uninitialized_move(__pos
, this->_M_finish
, __new_finish
, _TrivialUCopy(), _Movable()); // copy remainder
101 _STLP_UNWIND((_STLP_STD::_Destroy_Range(__new_start
,__new_finish
),
102 this->_M_end_of_storage
.deallocate(__new_start
,__len
)))
103 _M_clear_after_move();
104 _M_set(__new_start
, __new_finish
, __new_start
+ __len
);
107 template <class _Tp
, class _Alloc
>
108 void vector
<_Tp
, _Alloc
>::_M_insert_overflow(pointer __pos
, const _Tp
& __x
, const __true_type
& /*_TrivialCopy*/,
109 size_type __fill_len
, bool __atend
) {
110 size_type __len
= _M_compute_next_size(__fill_len
);
111 pointer __new_start
= this->_M_end_of_storage
.allocate(__len
, __len
);
112 pointer __new_finish
= __STATIC_CAST(pointer
, _STLP_PRIV
__copy_trivial(this->_M_start
, __pos
, __new_start
));
114 __new_finish
= _STLP_PRIV
__fill_n(__new_finish
, __fill_len
, __x
);
116 __new_finish
= __STATIC_CAST(pointer
, _STLP_PRIV
__copy_trivial(__pos
, this->_M_finish
, __new_finish
)); // copy remainder
118 _M_set(__new_start
, __new_finish
, __new_start
+ __len
);
121 template <class _Tp
, class _Alloc
>
122 void vector
<_Tp
, _Alloc
>::_M_fill_insert_aux(iterator __pos
, size_type __n
,
123 const _Tp
& __x
, const __true_type
& /*_Movable*/) {
124 if (_M_is_inside(__x
)) {
126 _M_fill_insert_aux(__pos
, __n
, __x_copy
, __true_type());
129 iterator __src
= this->_M_finish
- 1;
130 iterator __dst
= __src
+ __n
;
131 for (; __src
>= __pos
; --__dst
, --__src
) {
132 _STLP_STD::_Move_Construct(__dst
, *__src
);
133 _STLP_STD::_Destroy_Moved(__src
);
135 _STLP_PRIV
__uninitialized_fill_n(__pos
, __n
, __x
);
136 this->_M_finish
+= __n
;
139 template <class _Tp
, class _Alloc
>
140 void vector
<_Tp
, _Alloc
>::_M_fill_insert_aux (iterator __pos
, size_type __n
,
141 const _Tp
& __x
, const __false_type
& /*_Movable*/) {
142 typedef typename __type_traits
<_Tp
>::has_trivial_copy_constructor _TrivialUCopy
;
143 typedef typename __type_traits
<_Tp
>::has_trivial_assignment_operator _TrivialCopy
;
144 //Here self referencing needs to be checked even for non movable types.
145 if (_M_is_inside(__x
)) {
147 _M_fill_insert_aux(__pos
, __n
, __x_copy
, __false_type());
150 const size_type __elems_after
= this->_M_finish
- __pos
;
151 pointer __old_finish
= this->_M_finish
;
152 if (__elems_after
> __n
) {
153 _STLP_PRIV
__ucopy_ptrs(this->_M_finish
- __n
, this->_M_finish
, this->_M_finish
, _TrivialUCopy());
154 this->_M_finish
+= __n
;
155 _STLP_PRIV
__copy_backward_ptrs(__pos
, __old_finish
- __n
, __old_finish
, _TrivialCopy());
156 _STLP_STD::fill(__pos
, __pos
+ __n
, __x
);
158 this->_M_finish
= _STLP_PRIV
__uninitialized_fill_n(this->_M_finish
, __n
- __elems_after
, __x
);
159 _STLP_PRIV
__ucopy_ptrs(__pos
, __old_finish
, this->_M_finish
, _TrivialUCopy());
160 this->_M_finish
+= __elems_after
;
161 _STLP_STD::fill(__pos
, __old_finish
, __x
);
165 template <class _Tp
, class _Alloc
>
166 void vector
<_Tp
, _Alloc
>::_M_fill_insert(iterator __pos
,
167 size_type __n
, const _Tp
& __x
) {
168 #if !defined (_STLP_NO_MOVE_SEMANTIC)
169 typedef typename __move_traits
<_Tp
>::implemented _Movable
;
172 if (size_type(this->_M_end_of_storage
._M_data
- this->_M_finish
) >= __n
) {
173 _M_fill_insert_aux(__pos
, __n
, __x
, _Movable());
175 typedef typename __type_traits
<_Tp
>::has_trivial_assignment_operator _TrivialCopy
;
176 _M_insert_overflow(__pos
, __x
, _TrivialCopy(), __n
);
181 template <class _Tp
, class _Alloc
>
182 vector
<_Tp
, _Alloc
>& vector
<_Tp
, _Alloc
>::operator = (const vector
<_Tp
, _Alloc
>& __x
) {
183 typedef typename __type_traits
<_Tp
>::has_trivial_assignment_operator _TrivialCopy
;
184 typedef typename __type_traits
<_Tp
>::has_trivial_copy_constructor _TrivialUCopy
;
186 const size_type __xlen
= __x
.size();
187 if (__xlen
> capacity()) {
188 size_type __len
= __xlen
;
189 pointer __tmp
= _M_allocate_and_copy(__len
, __CONST_CAST(const_pointer
, __x
._M_start
) + 0,
190 __CONST_CAST(const_pointer
, __x
._M_finish
) + 0);
192 this->_M_start
= __tmp
;
193 this->_M_end_of_storage
._M_data
= this->_M_start
+ __len
;
194 } else if (size() >= __xlen
) {
195 pointer __i
= _STLP_PRIV
__copy_ptrs(__CONST_CAST(const_pointer
, __x
._M_start
) + 0,
196 __CONST_CAST(const_pointer
, __x
._M_finish
) + 0, this->_M_start
, _TrivialCopy());
197 _STLP_STD::_Destroy_Range(__i
, this->_M_finish
);
199 _STLP_PRIV
__copy_ptrs(__CONST_CAST(const_pointer
, __x
._M_start
),
200 __CONST_CAST(const_pointer
, __x
._M_start
) + size(), this->_M_start
, _TrivialCopy());
201 _STLP_PRIV
__ucopy_ptrs(__CONST_CAST(const_pointer
, __x
._M_start
) + size(),
202 __CONST_CAST(const_pointer
, __x
._M_finish
) + 0, this->_M_finish
, _TrivialUCopy());
204 this->_M_finish
= this->_M_start
+ __xlen
;
209 template <class _Tp
, class _Alloc
>
210 void vector
<_Tp
, _Alloc
>::_M_fill_assign(size_t __n
, const _Tp
& __val
) {
211 if (__n
> capacity()) {
212 vector
<_Tp
, _Alloc
> __tmp(__n
, __val
, get_allocator());
214 } else if (__n
> size()) {
215 fill(begin(), end(), __val
);
216 this->_M_finish
= _STLP_PRIV
__uninitialized_fill_n(this->_M_finish
, __n
- size(), __val
);
218 erase(_STLP_PRIV
__fill_n(begin(), __n
, __val
), end());
221 template <class _Tp
, class _Alloc
>
223 vector
<_Tp
, _Alloc
>::insert(iterator __pos
, const _Tp
& __x
) {
224 size_type __n
= __pos
- begin();
225 _M_fill_insert(__pos
, 1, __x
);
226 return begin() + __n
;
233 _STLP_MOVE_TO_STD_NAMESPACE
238 #endif /* _STLP_VECTOR_C */