第1个回答 2007-03-20
template<typename _Tp, typename _Alloc = allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
// Concept requirements.
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
typedef _Vector_base<_Tp, _Alloc> _Base;
typedef vector<_Tp, _Alloc> vector_type;
public:
typedef _Tp value_type;
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
typedef typename _Alloc::reference reference;
typedef typename _Alloc::const_reference const_reference;
typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type;
protected:
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_impl;
public:
explicit
vector(const allocator_type& __a = allocator_type())
: _Base(__a) { }
explicit
vector(size_type __n)
: _Base(__n, allocator_type())
{ this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
__n, value_type()); }
vector(const vector& __x)
: _Base(__x.size(), __x.get_allocator())
{ this->_M_impl._M_finish = std::uninitialized_copy(__x.begin(), __x.end(),
this->_M_impl._M_start);
}
template<typename _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
}
~vector() { std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish); }
vector&
operator=(const vector& __x);
void
assign(size_type __n, const value_type& __val)
{ _M_fill_assign(__n, __val); }
template<typename _InputIterator>
void
assign(_InputIterator __first, _InputIterator __last)
{
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_assign_dispatch(__first, __last, _Integral());
}
/// Get a copy of the memory allocation object.
using _Base::get_allocator;
iterator
begin() { return iterator (this->_M_impl._M_start); }
const_iterator
begin() const { return const_iterator (this->_M_impl._M_start); }
iterator
end() { return iterator (this->_M_impl._M_finish); }
const_iterator
end() const { return const_iterator (this->_M_impl._M_finish); }
reverse_iterator
rbegin() { return reverse_iterator(end()); }
const_reverse_iterator
rbegin() const { return const_reverse_iterator(end()); }
reverse_iterator
rend() { return reverse_iterator(begin()); }
const_reverse_iterator
rend() const { return const_reverse_iterator(begin()); }
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const { return size_type(end() - begin()); }
/** Returns the size() of the largest possible %vector. */
size_type
max_size() const { return size_type(-1) / sizeof(value_type); }
void
resize(size_type __new_size, const value_type& __x)
{
if (__new_size < size())
erase(begin() + __new_size, end());
else
insert(end(), __new_size - size(), __x);
}
void
resize(size_type __new_size) { resize(__new_size, value_type()); }
size_type
capacity() const
{ return size_type(const_iterator(this->_M_impl._M_end_of_storage) - begin()); }
bool
empty() const { return begin() == end(); }
void
reserve(size_type __n);
reference
operator[](size_type __n) { return *(begin() + __n); }
const_reference
operator[](size_type __n) const { return *(begin() + __n); }
protected:
/// @if maint Safety check used only from at(). @endif
void
_M_range_check(size_type __n) const
{
if (__n >= this->size())
__throw_out_of_range(__N("vector::_M_range_check"));
}
public:
reference
at(size_type __n) { _M_range_check(__n); return (*this)[__n]; }
const_reference
at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; }
reference
front() { return *begin(); }
const_reference
front() const { return *begin(); }
reference
back() { return *(end() - 1); }
const_reference
back() const { return *(end() - 1); }
void
push_back(const value_type& __x)
{
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{
std::_Construct(this->_M_impl._M_finish, __x);
++this->_M_impl._M_finish;
}
else
_M_insert_aux(end(), __x);
}
void
pop_back()
{
--this->_M_impl._M_finish;
std::_Destroy(this->_M_impl._M_finish);
}
iterator
insert(iterator __position, const value_type& __x);
void
insert(iterator __position, size_type __n, const value_type& __x)
{ _M_fill_insert(__position, __n, __x); }
template<typename _InputIterator>
void
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_insert_dispatch(__position, __first, __last, _Integral());
}
iterator
erase(iterator __position);
iterator
erase(iterator __first, iterator __last);
void
swap(vector& __x)
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
std::swap(this->_M_impl._M_end_of_storage, __x._M_impl._M_end_of_storage);
}
void
clear() { erase(begin(), end()); }
protected:
template<typename _ForwardIterator>
pointer
_M_allocate_and_copy(size_type __n,
_ForwardIterator __first, _ForwardIterator __last)
{
pointer __result = this->_M_allocate(__n);
try
{
std::uninitialized_copy(__first, __last, __result);
return __result;
}
catch(...)
{
_M_deallocate(__result, __n);
__throw_exception_again;
}
}
template<typename _Integer>
void
_M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
{
this->_M_impl._M_start = _M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish = std::uninitialized_fill_n(this->_M_impl._M_start,
__n, __value);
}
// Called by the range constructor to implement [23.1.1]/9
template<typename _InputIterator>
void
_M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
{
typedef typename iterator_traits<_InputIterator>::iterator_category
_IterCategory;
_M_range_initialize(__first, __last, _IterCategory());
}
// Called by the second initialize_dispatch above
template<typename _InputIterator>
void
_M_range_initialize(_InputIterator __first,
_InputIterator __last, input_iterator_tag)
{
for ( ; __first != __last; ++__first)
push_back(*__first);
}
// Called by the second initialize_dispatch above
template<typename _ForwardIterator>
void
_M_range_initialize(_ForwardIterator __first,
_ForwardIterator __last, forward_iterator_tag)
{
size_type __n = std::distance(__first, __last);
this->_M_impl._M_start = this->_M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
this->_M_impl._M_finish = std::uninitialized_copy(__first, __last,
this->_M_impl._M_start);
}
// Internal assign functions follow. The *_aux functions do the actual
// assignment work for the range versions.
// Called by the range assign to implement [23.1.1]/9
template<typename _Integer>
void
_M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
{
_M_fill_assign(static_cast<size_type>(__n),
static_cast<value_type>(__val));
}
// Called by the range assign to implement [23.1.1]/9
template<typename _InputIterator>
void
_M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type)
{
typedef typename iterator_traits<_InputIterator>::iterator_category
_IterCategory;
_M_assign_aux(__first, __last, _IterCategory());
}
// Called by the second assign_dispatch above
template<typename _InputIterator>
void
_M_assign_aux(_InputIterator __first, _InputIterator __last,
input_iterator_tag);
// Called by the second assign_dispatch above
template<typename _ForwardIterator>
void
_M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
forward_iterator_tag);
// Called by assign(n,t), and the range assign when it turns out
// to be the same thing.
void
_M_fill_assign(size_type __n, const value_type& __val);
// Internal insert functions follow.
// Called by the range insert to implement [23.1.1]/9
template<typename _Integer>
void
_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
__true_type)
{
_M_fill_insert(__pos, static_cast<size_type>(__n),
static_cast<value_type>(__val));
}
// Called by the range insert to implement [23.1.1]/9
template<typename _InputIterator>
void
_M_insert_dispatch(iterator __pos, _InputIterator __first,
_InputIterator __last, __false_type)
{
typedef typename iterator_traits<_InputIterator>::iterator_category
_IterCategory;
_M_range_insert(__pos, __first, __last, _IterCategory());
}
// Called by the second insert_dispatch above
template<typename _InputIterator>
void
_M_range_insert(iterator __pos, _InputIterator __first,
_InputIterator __last, input_iterator_tag);
// Called by the second insert_dispatch above
template<typename _ForwardIterator>
void
_M_range_insert(iterator __pos, _ForwardIterator __first,
_ForwardIterator __last, forward_iterator_tag);
// Called by insert(p,n,x), and the range insert when it turns out to be
// the same thing.
void
_M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
// Called by insert(p,x)
void
_M_insert_aux(iterator __position, const value_type& __x);
};本回答被提问者采纳