blob: 9d912873c36611716fdb6d5094a9026ede81b9a8 [file] [log] [blame]
// -*- C++ -*-
/***************************************************************************
*
* <vector> - dfefinition of the C++ Standard Library vector class template
*
* $Id$
*
***************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 1994-2007 Rogue Wave Software, Inc.
*
***************************************************************************
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
**************************************************************************/
#ifndef _RWSTD_VECTOR_INCLUDED
#define _RWSTD_VECTOR_INCLUDED
#include <rw/_algobase.h>
#include <rw/_allocator.h>
#include <rw/_error.h>
#include <rw/_iterator.h>
#include <rw/_select.h>
#include <rw/_defs.h>
_RWSTD_NAMESPACE (std) {
_EXPORT
template <class _TypeT, class _Allocator = allocator<_TypeT> >
class vector;
_EXPORT
template <class _TypeT, class _Allocator>
class vector
{
public:
typedef _TypeT value_type;
typedef _Allocator allocator_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
public:
#ifndef _RWSTD_NO_DEBUG_ITER
typedef _RW::__rw_debug_iter <vector, pointer, pointer> iterator;
typedef _RW::__rw_debug_iter <vector, const_pointer, pointer>
const_iterator;
iterator _C_make_iter (pointer __ptr) {
return iterator (*this, __ptr);
}
const_iterator _C_make_iter (pointer __ptr) const {
return const_iterator (*this, __ptr);
}
#else // if defined (_RWSTD_NO_DEBUG_ITER)
typedef pointer iterator;
typedef const_pointer const_iterator;
iterator _C_make_iter (pointer __ptr) {
return __ptr;
}
const_iterator _C_make_iter (const_pointer __ptr) const {
return __ptr;
}
#endif // _RWSTD_NO_DEBUG_ITER
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef _STD::reverse_iterator<iterator> reverse_iterator;
#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
typedef _STD::reverse_iterator<const_iterator,
random_access_iterator_tag, value_type,
const_reference, const_pointer, difference_type>
const_reverse_iterator;
typedef _STD::reverse_iterator<iterator,
random_access_iterator_tag, value_type,
reference, pointer, difference_type>
reverse_iterator;
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
public:
explicit
vector (const allocator_type &__alloc = allocator_type ())
: _C_alloc (__alloc) { }
explicit
vector (size_type __n, const_reference __x = value_type (),
const allocator_type &__alloc = allocator_type ())
: _C_alloc (__alloc) {
assign (__n, __x);
}
template <class _InputIter>
vector (_InputIter __first, _InputIter __last,
const allocator_type &__alloc = allocator_type ())
: _C_alloc (__alloc) {
assign (__first, __last);
}
vector (const vector &__rhs)
: _C_alloc (__rhs.get_allocator ()) {
assign (__rhs.begin (), __rhs.end ());
}
~vector () {
_C_destroy (begin ());
_C_alloc.deallocate (_C_alloc._C_begin,
_C_alloc._C_bufend - _C_alloc._C_begin);
}
vector& operator= (const vector&);
template <class _InputIter>
void assign (_InputIter __first, _InputIter __last) {
// dispatch either to a range assign or to an assign with repetition
_C_assign (__first, __last, _RWSTD_DISPATCH (_InputIter));
}
void assign (size_type __n, const_reference __x) {
_C_assign_n (__n, __x);
}
allocator_type get_allocator () const {
return _C_alloc;
}
iterator begin () {
return _C_make_iter (_C_alloc._C_begin);
}
const_iterator begin () const {
return _C_make_iter (_C_alloc._C_begin);
}
iterator end () {
return _C_make_iter (_C_alloc._C_end);
}
const_iterator end () const {
return _C_make_iter (_C_alloc._C_end);
}
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 ());
}
size_type size () const {
return size_type (_C_alloc._C_end - _C_alloc._C_begin);
}
size_type max_size () const {
return _C_alloc.max_size ();
}
void resize (size_type, value_type = value_type ());
size_type capacity () const {
return _C_alloc._C_bufend - _C_alloc._C_begin;
}
bool empty () const {
return _C_alloc._C_begin == _C_alloc._C_end;
}
void reserve (size_type);
reference operator[] (size_type);
const_reference operator[] (size_type) const;
reference at (size_type);
const_reference at (size_type __n) const;
reference front () {
_RWSTD_ASSERT (!empty ());
return *begin ();
}
const_reference front () const {
_RWSTD_ASSERT (!empty ());
return *begin ();
}
reference back () {
_RWSTD_ASSERT (!empty ());
return *(end () - 1);
}
const_reference back () const {
_RWSTD_ASSERT (!empty ());
return *(end () - 1);
}
void push_back (const_reference);
void pop_back () {
_RWSTD_ASSERT (!empty ());
_C_alloc.destroy (_C_alloc._C_end - 1);
--_C_alloc._C_end;
}
iterator insert (iterator, const_reference);
template <class _InputIter>
void insert (iterator __it, _InputIter __first, _InputIter __last) {
_C_insert (__it, __first, __last, _RWSTD_DISPATCH (_InputIter));
}
void insert (iterator __it, size_type __n, const_reference __x) {
_C_insert_n (__it, __n, __x);
}
iterator erase (iterator);
iterator erase (iterator, iterator);
void swap (vector&);
void clear ();
#ifdef _RWSTD_NO_PART_SPEC_OVERLOAD
friend void swap (vector& __lhs, vector& __rhs) {
__lhs.swap (__rhs);
}
#endif // _RWSTD_NO_PART_SPEC_OVERLOAD
private:
// implements assign with repetition
void _C_assign_n (size_type, const_reference);
// implements a single-element insert
void _C_insert_1 (const iterator&, const_reference);
// implements insert with repetition
void _C_insert_n (const iterator&, size_type, const_reference);
// implements range insert for ForwardIterators
template <class _FwdIter>
void _C_insert_range (iterator, _FwdIter, _FwdIter,
forward_iterator_tag);
// implements range insert for InputIterators
template <class _InputIter>
void _C_insert_range (iterator, _InputIter, _InputIter,
input_iterator_tag);
// implements range assign
template <class _InputIter>
void _C_assign (_InputIter __first, _InputIter __last, void*) {
_RWSTD_ASSERT_RANGE (__first, __last);
// dispatch to an assign suitable for the category of InputIter
_RWSTD_ASSIGN_RANGE (__first, __last,
_RWSTD_ITERATOR_CATEGORY (_InputIter, __first));
}
// implements assign with repetition if value_type == size_type
template <class _IntType>
void _C_assign (_IntType __n, _IntType __x, int) {
_C_assign_n (size_type (__n), __x);
}
// implements range insert for ForwardIterators
template <class _FwdIter>
void _C_assign_range (_FwdIter, _FwdIter, forward_iterator_tag);
// implements range insert for InputIterators
template <class _InputIter>
void _C_assign_range (_InputIter, _InputIter, input_iterator_tag);
// implements range insert
template <class _InputIter>
void _C_insert (const iterator &__it,
_InputIter __first, _InputIter __last, void*) {
_RWSTD_ASSERT_RANGE (begin (), __it);
_RWSTD_ASSERT_RANGE (__first, __last);
// dispatch to an insert suitable for the category of InputIter
_RWSTD_INSERT_RANGE (__it, __first, __last,
_RWSTD_ITERATOR_CATEGORY (_InputIter, __first));
}
// implements insert with repetition if value_type == size_type
template <class _IntType>
void _C_insert (const iterator &__it,
_IntType __n, _IntType __x, int) {
_C_insert_n (__it, size_type (__n), __x);
}
void _C_realloc (size_type);
// constructs a copy at the end and grows the size of container
void _C_push_back (const_reference __x) {
_RWSTD_ASSERT (_C_alloc._C_end != _C_alloc._C_bufend);
_C_alloc.construct (_C_alloc._C_end, __x);
++_C_alloc._C_end;
}
// destroys elements from the iterator to the end of the vector
// and resets end() to point to the iterator
void _C_destroy (iterator);
// implements swap for objects with unequal allocator
void _C_unsafe_swap (vector&);
struct _C_VectorAlloc: allocator_type {
_C_VectorAlloc (const allocator_type &__alloc)
: allocator_type (__alloc), _C_begin (), _C_end (), _C_bufend ()
{ /* empty */}
pointer _C_begin;
pointer _C_end;
pointer _C_bufend;
} _C_alloc;
};
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::reference
vector<_TypeT, _Allocator>::
operator[] (size_type __n)
{
#ifdef _RWSTD_BOUNDS_CHECKING
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_OUT_OF_RANGE,
_RWSTD_FUNC ("vector::operator[](size_type)"),
__n, size ()));
#endif // _RWSTD_BOUNDS_CHECKING
return *(begin () + __n);
}
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::const_reference
vector<_TypeT, _Allocator>::
operator[] (size_type __n) const
{
#ifdef _RWSTD_BOUNDS_CHECKING
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_OUT_OF_RANGE,
_RWSTD_FUNC ("vector::operator[](size_type) const"),
__n, size ()));
#endif // _RWSTD_BOUNDS_CHECKING
return *(begin () + __n);
}
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::reference
vector<_TypeT, _Allocator>::
at (size_type __n)
{
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_OUT_OF_RANGE,
_RWSTD_FUNC ("vector::at (size_type)"),
__n, size ()));
return *(begin () + __n);
}
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::const_reference
vector<_TypeT, _Allocator>::
at (size_type __n) const
{
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_OUT_OF_RANGE,
_RWSTD_FUNC ("vector::at(size_type) const"),
__n, size ()));
return *(begin () + __n);
}
template <class _TypeT, class _Allocator>
inline void
vector<_TypeT, _Allocator>::
resize (size_type __new_size, value_type __x /* = value_type () */)
{
if (size () < __new_size)
insert (end (), __new_size - size (), __x);
else if (__new_size < size ())
erase (begin () + __new_size, end ());
}
template <class _TypeT, class _Allocator>
inline void
vector<_TypeT, _Allocator>::
reserve (size_type __n)
{
_RWSTD_REQUIRES (__n <= max_size (),
(_RWSTD_ERROR_LENGTH_ERROR,
_RWSTD_FUNC ("vector::reserve(size_type)"),
__n, max_size ()));
if (capacity () < __n)
_C_realloc (__n);
}
template <class _TypeT, class _Allocator>
inline void
vector<_TypeT, _Allocator>::
push_back (const_reference __x)
{
if (_C_alloc._C_end == _C_alloc._C_bufend)
_C_insert_1 (end (), __x);
else
_C_push_back (__x);
}
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::iterator
vector<_TypeT, _Allocator>::
insert (iterator __it, const_reference __x)
{
_RWSTD_ASSERT_RANGE (__it, end ());
const difference_type __off = __it - begin ();
if (end () == __it)
push_back (__x);
else
_C_insert_1 (__it, __x);
return begin () + __off;
}
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::iterator
vector<_TypeT, _Allocator>::
erase (iterator __it)
{
_RWSTD_ASSERT_RANGE (__it, end ());
_RWSTD_ASSERT (__it < end ()); // `it' must be dereferenceable
const iterator __next = __it + 1;
if (__next != end ())
_STD::copy (__next, end (), __it);
_C_alloc.destroy (_C_alloc._C_end - 1);
--_C_alloc._C_end;
return __it;
}
template <class _TypeT, class _Allocator>
inline typename vector<_TypeT, _Allocator>::iterator
vector<_TypeT, _Allocator>::
erase (iterator __first, iterator __last)
{
_RWSTD_ASSERT_RANGE (__first, __last);
_RWSTD_ASSERT_RANGE (begin (), __first);
_C_destroy (_STD::copy (__last, end (), __first));
return __first;
}
template <class _TypeT, class _Allocator>
inline void
vector<_TypeT, _Allocator>::
clear ()
{
if (!empty ())
_C_destroy (begin ());
}
template <class _TypeT, class _Allocator>
inline void
vector<_TypeT, _Allocator>::
swap (vector &__other)
{
if (get_allocator () == __other.get_allocator ()) {
pointer __tmp = _C_alloc._C_begin;
_C_alloc._C_begin = __other._C_alloc._C_begin;
__other._C_alloc._C_begin = __tmp;
__tmp = _C_alloc._C_end;
_C_alloc._C_end = __other._C_alloc._C_end;
__other._C_alloc._C_end = __tmp;
__tmp = _C_alloc._C_bufend;
_C_alloc._C_bufend = __other._C_alloc._C_bufend;
__other._C_alloc._C_bufend = __tmp;
}
else {
// not exception-safe
_C_unsafe_swap (__other);
}
}
template <class _TypeT, class _Allocator>
inline bool
operator== (const vector<_TypeT, _Allocator> &__x,
const vector<_TypeT, _Allocator> &__y)
{
return __x.size () == __y.size ()
&& _STD::equal(__x.begin (), __x.end (), __y.begin ());
}
template <class _TypeT, class _Allocator>
inline bool
operator< (const vector<_TypeT, _Allocator> &__x,
const vector<_TypeT, _Allocator> &__y)
{
return _STD::lexicographical_compare (__x.begin (), __x.end (),
__y.begin (), __y.end ());
}
template <class _TypeT, class _Allocator>
inline bool
operator!= (const vector<_TypeT, _Allocator> &__x,
const vector<_TypeT, _Allocator> &__y)
{
return !(__x == __y);
}
template <class _TypeT, class _Allocator>
inline bool
operator> (const vector<_TypeT, _Allocator> &__x,
const vector<_TypeT, _Allocator> &__y)
{
return __y < __x;
}
template <class _TypeT, class _Allocator>
inline bool
operator>= (const vector<_TypeT, _Allocator> &__x,
const vector<_TypeT, _Allocator> &__y)
{
return !(__x < __y);
}
template <class _TypeT, class _Allocator>
inline bool
operator<= (const vector<_TypeT, _Allocator> &__x,
const vector<_TypeT, _Allocator> &__y)
{
return !(__y < __x);
}
#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD
template <class _TypeT, class _Allocator>
inline void
swap (vector<_TypeT, _Allocator> &__x, vector<_TypeT, _Allocator> &__y)
{
__x.swap (__y);
}
#endif // _RWSTD_NO_PART_SPEC_OVERLOAD
/***************************************************************************/
#ifndef _RWSTD_NO_VECTOR_BOOL
#ifndef _RWSTD_NO_BOOL
// number of bits in a machine word
# define _RWSTD_WORD_BIT (int (_RWSTD_CHAR_BIT * sizeof (unsigned int)))
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
_EXPORT
template <class _Allocator>
class
#else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
// use a macro to mutate _Allocator into allocator<bool>
# define _Allocator allocator<bool>
_RWSTD_SPECIALIZED_CLASS
class _RWSTD_EXPORT
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
vector<bool, _Allocator >: private _Allocator
{
#if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
// clear typename
# undef typename
# define typename
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
typedef _RWSTD_REBIND(_Allocator, unsigned int) _C_value_alloc_type;
typedef vector _C_self;
public:
typedef _Allocator allocator_type;
typedef bool value_type;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
typedef typename _C_value_alloc_type::pointer pointer;
typedef typename _C_value_alloc_type::const_pointer const_pointer;
#if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)
// restore typename
# undef typename
# define typename typename
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
class iterator;
class const_iterator;
class reference {
#if !defined (__INTEL_COMPILER) || !defined (_MSC_VER)
// avoid MSVC 6.0 bug 576
friend class iterator;
#else // if Intel C++ 8.1 with MSVC
// work around Intel C++ 8.1 bug 575
friend class _C_self::iterator;
#endif // Intel C++ with MSVC
friend class const_iterator;
private:
unsigned int* _C_p;
unsigned int _C_mask;
reference (unsigned int* __x, unsigned int __y)
: _C_p (__x), _C_mask (__y) { }
public:
reference () : _C_p (), _C_mask () {}
operator bool () const {
return !!(*_C_p & _C_mask);
}
reference& operator= (bool __x) {
if (__x)
*_C_p |= _C_mask;
else
*_C_p &= ~_C_mask;
return *this;
}
reference& operator= (const reference& __x) {
return *this = bool(__x);
}
#ifndef _RWSTD_NO_EXT_VECTOR_BOOL_REF_OPS
bool operator== (const reference& __x) const {
return bool(*this) == bool(__x);
}
bool operator< (const reference& __x) const {
#ifndef _MSC_VER
return bool(*this) < bool(__x);
#else
return int(*this) < int(__x);
#endif
}
bool operator!= (const reference& __x) const {
return !(*this == __x);
}
bool operator> (const reference& __x) const {
return __x < *this;
}
bool operator>= (const reference& __x) const {
return !(*this < __x);
}
bool operator<= (const reference& __x) const {
return !(*this > __x);
}
#endif // _RWSTD_NO_EXT_VECTOR_BOOL_REF_OPS
void flip () {
*_C_p ^= _C_mask;
}
};
typedef bool const_reference;
// hacks working around bogus g++ 2.95.2 warnings coming out of
// iterators below as well as what's probably an MSVC 6.0 bug
typedef reference _C_ref;
typedef const_reference _C_const_ref;
typedef difference_type _C_diff_t;
class _C_iter {
friend class iterator;
friend class const_iterator;
private:
#if defined (__GNUG__)
// gcc 3.0.1 and prior take 14.5.3, p9 literally
public:
#elif defined (_MSC_VER) && _MSC_VER <= 1300 || defined (__APOGEE__)
friend class vector<bool, _Allocator>;
#else
friend class vector;
#endif
unsigned int* _C_p; // pointer to the current word
unsigned int _C_offset; // number of the pointed-to bit
_C_iter (unsigned int* __x = 0, unsigned int __y = 0)
: _C_p (__x), _C_offset (__y) { }
// On Sun, gcc 3.1 does generate an incorrect copy constructor
// that has as an effect an incompletely/incorrectly initialized
// iterator.
#if defined (__sun__) && defined (__GNUG__) \
|| defined (__SUNPRO_CC) && defined (__amd64__)
// working around a gcc 3.1 bug on Solaris where the compiler
// generates bad code for the implicitly defined copy ctor
// also working around a Sun C++ 5.9 optimizer ICE on x86_64
// in wide (64-bit) mode (see STDCXX-551)
_C_iter (const _C_iter& __it)
: _C_p (__it._C_p), _C_offset (__it._C_offset) {}
#endif // gcc 3.1/Solaris || Sun C++ 5.9/x86_64
void operator++ () {
if (_C_offset++ == _RWSTD_WORD_BIT - 1) {
_C_offset = 0;
++_C_p;
}
}
void operator-- () {
if (_C_offset-- == 0) {
_C_offset = _RWSTD_WORD_BIT - 1;
--_C_p;
}
}
void operator+= (difference_type __i) {
difference_type __n = __i + _C_offset;
_C_p += __n / _RWSTD_WORD_BIT;
__n = __n % _RWSTD_WORD_BIT;
if (__n < 0) {
_C_offset = _RWSTD_STATIC_CAST (unsigned int,
__n + _RWSTD_WORD_BIT);
--_C_p;
}
else
_C_offset = _RWSTD_STATIC_CAST (unsigned int,__n);
}
public:
bool operator== (const _C_iter& __x) const {
return _C_p == __x._C_p && _C_offset == __x._C_offset;
}
bool operator< (const _C_iter& __x) const {
return _C_p < __x._C_p ||
(_C_p == __x._C_p && _C_offset < __x._C_offset);
}
bool operator!= (const _C_iter& __x) const {
return !(*this == __x);
}
bool operator> (const _C_iter& __x) const {
return __x < *this;
}
bool operator>= (const _C_iter& __x) const {
return !(*this < __x);
}
bool operator<= (const _C_iter& __x) const {
return !(*this > __x);
}
};
class iterator
: public _C_iter,
public _STD::iterator<random_access_iterator_tag,
value_type, _C_diff_t,
pointer, _C_ref> {
public:
// bring names used in declarations below into scope
// (dependent base members not visible without qualification)
typedef _C_ref reference;
typedef _C_diff_t difference_type;
iterator (unsigned int *__x = 0, unsigned int __y = 0)
: _C_iter (__x, __y) { }
reference operator* () const {
return reference (this->_C_p, 1U << this->_C_offset);
}
iterator& operator++ () {
return _C_iter::operator++(), *this;
}
iterator operator++ (int) {
iterator __tmp = *this;
++*this;
return __tmp;
}
iterator& operator-- () {
return _C_iter::operator--(), *this;
}
iterator operator-- (int) {
iterator __tmp = *this;
--*this;
return __tmp;
}
iterator& operator+= (difference_type __i) {
return _C_iter::operator+= (__i), *this;
}
iterator& operator-= (difference_type __i) {
*this += -__i;
return *this;
}
iterator operator+ (difference_type __i) const {
iterator __tmp = *this;
return __tmp += __i;
}
iterator operator- (difference_type __i) const {
iterator __tmp = *this;
return __tmp -= __i;
}
difference_type operator- (iterator __x) const {
return _RWSTD_WORD_BIT * (this->_C_p - __x._C_p)
+ this->_C_offset - __x._C_offset;
}
reference operator[] (difference_type __i) {
return *(*this + __i);
}
friend iterator operator+ (difference_type __i,
const iterator &__x) {
return __x + __i;
}
};
class const_iterator
: public _C_iter,
public _STD::iterator<random_access_iterator_tag,
value_type, _C_diff_t,
const_pointer, _C_const_ref> {
public:
// bring names used in declarations below into scope
// (dependent base members not visible without qualification)
typedef _C_const_ref const_reference;
typedef _C_diff_t difference_type;
const_iterator (unsigned int *__x = 0, unsigned int __y = 0)
: _C_iter (__x, __y) { }
const_iterator (const _C_iter &__x)
: _C_iter (__x) { }
const_reference operator* () const {
return _C_ref (this->_C_p, 1U << this->_C_offset);
}
const_iterator& operator++ () {
return _C_iter::operator++(), *this;
}
const_iterator operator++ (int) {
const_iterator __tmp = *this;
++*this;
return __tmp;
}
const_iterator& operator-- () {
return _C_iter::operator--(), *this;
}
const_iterator operator-- (int) {
const_iterator __tmp = *this;
--*this;
return __tmp;
}
const_iterator& operator+= (difference_type __i) {
return _C_iter::operator+= (__i), *this;
}
const_iterator& operator-= (difference_type __i) {
return *this += -__i;
}
const_iterator
operator+ (difference_type __i) const {
return const_iterator (*this) += __i;
}
const_iterator operator- (difference_type __i) const {
return const_iterator (*this) -= __i;
}
difference_type operator- (const_iterator __x) const {
return _RWSTD_WORD_BIT * (this->_C_p - __x._C_p)
+ this->_C_offset - __x._C_offset;
}
const_reference operator[] (difference_type __i) {
return *(*this + __i);
}
friend const_iterator operator+ (difference_type __i,
const const_iterator &__x) {
return __x + __i;
}
};
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef _STD::reverse_iterator<iterator> reverse_iterator;
#else
typedef _STD::reverse_iterator<const_iterator,
random_access_iterator_tag, value_type,
const_reference, const_pointer, difference_type>
const_reverse_iterator;
typedef _STD::reverse_iterator<iterator,
random_access_iterator_tag, value_type,
reference, pointer, difference_type>
reverse_iterator;
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
private:
//
// These private functions are replicas of generic algorithms.
// We provide them here to avoid putting instantiations of
// the generic algorithms into an archive or shared library.
// This gives you full flexibilty in deciding where you want
// to put particular instantiations of the generic
// algorithms.
//
void _C_fill (iterator __first, iterator __last, bool __val) {
while (__first != __last) *__first++ = __val;
}
void _C_fill_n (iterator __first, size_type __n, bool __val) {
while (__n-- > 0) *__first++ = __val;
}
template <class _Iterator>
iterator _C_copy (_Iterator __first, _Iterator __last, iterator __res) {
while (__first != __last)
*__res++ = *__first++;
return __res;
}
template <class _Iterator>
iterator
_C_copy_backward (_Iterator __first, _Iterator __last, iterator __res) {
while (__first != __last) *--__res = *--__last;
return __res;
}
private:
iterator _C_begin;
iterator _C_end;
unsigned int * _C_bufend;
unsigned int* _C_bit_alloc (size_type __n) {
return _C_value_alloc_type(*this).
allocate ((__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT,
pointer(_C_begin._C_p));
}
void _C_init (size_type __n) {
unsigned int* __q = _C_bit_alloc(__n);
_C_bufend = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
_C_begin = iterator(__q, 0);
_C_end = _C_begin + __n;
}
void _C_insert (iterator, bool);
public:
vector (const _Allocator& __alloc = allocator_type ())
: allocator_type (__alloc), _C_begin(iterator()), _C_end(iterator()),
_C_bufend () { }
#if !defined (__SUNPRO_CC) || __SUNPRO_CC > 0x530
// working around a SunPro 5.3 bug (see PR #25962)
explicit
#endif // SunPro > 5.3
vector (size_type __n, bool __val = bool (),
const _Allocator& __alloc = allocator_type ())
: allocator_type (__alloc), _C_bufend () {
_C_init(__n);
unsigned int * __first = _C_begin._C_p;
size_type __m = (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
while (__m-- > 0) *__first++ = __val ? ~0 : 0;
}
vector (const _C_self &__x)
: allocator_type (__x.get_allocator ()), _C_bufend () {
_C_init (__x.size ());
_C_copy (__x.begin (), __x.end (), _C_begin);
}
template<class _InputIter>
vector (_InputIter __first, _InputIter __last)
: allocator_type (), _C_bufend ()
{
size_type __n = _DISTANCE (__first, __last, size_type);
_C_init(__n);
_C_copy(__first, __last, _C_begin);
}
~vector () {
_C_value_alloc_type(*this).deallocate(_C_begin._C_p,
_C_bufend - _C_begin._C_p);
}
_C_self& operator= (const _C_self& __x)
{
if (&__x == this) return *this;
if (__x.size() > capacity())
{
_C_value_alloc_type(*this).deallocate(_C_begin._C_p,
_C_bufend - _C_begin._C_p);
_C_init(__x.size());
}
_C_copy(__x.begin(), __x.end(), begin());
_C_end = begin() + __x.size();
return *this;
}
template<class _InputIter>
void assign (_InputIter __first, _InputIter __last) {
clear ();
insert (begin (), __first, __last);
}
void assign (size_type __n, const bool& __x = bool()) {
clear ();
insert (begin (), __n, __x);
}
allocator_type get_allocator() const {
return *this;
}
//
// iterators
//
iterator begin () { return _C_begin; }
const_iterator begin () const
{ return const_iterator(_C_begin._C_p,_C_begin._C_offset); }
iterator end () { return _C_end; }
const_iterator end () const
{ return const_iterator(_C_end._C_p,_C_end._C_offset); }
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());
}
//
// capacity
//
size_type size () const { return size_type(end() - begin()); }
size_type max_size () const {
return _C_value_alloc_type(*this).max_size();
}
void resize (size_type __new_size, bool __c = false);
size_type capacity () const
{
return size_type(const_iterator(_C_bufend, 0) - begin());
}
bool empty () const { return begin() == end(); }
void reserve (size_type __n)
{
_RWSTD_REQUIRES (__n <= max_size (),
(_RWSTD_ERROR_LENGTH_ERROR,
_RWSTD_FUNC ("vector<bool>::reserve (size_type)"),
__n, max_size ()));
if (capacity() < __n)
{
unsigned int* __q = _C_bit_alloc(__n);
_C_end = _C_copy(begin(), end(), iterator(__q, 0));
_C_value_alloc_type(*this).deallocate(_C_begin._C_p,
_C_bufend - _C_begin._C_p);
_C_begin = iterator(__q, 0);
_C_bufend = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
}
}
//
// element access
//
reference operator[] (size_type __n)
{
#ifdef _RWSTD_BOUNDS_CHECKING
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_LENGTH_ERROR,
_RWSTD_FUNC ("vector<bool>::[](size_type)"),
__n, size ()));
#endif // _RWSTD_BOUNDS_CHECKING
return *(begin() + __n);
}
const_reference operator[] (size_type __n) const
{
#ifdef _RWSTD_BOUNDS_CHECKING
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_LENGTH_ERROR,
_RWSTD_FUNC ("vector<bool>::[](size_type)"),
__n, size ()));
#endif // _RWSTD_BOUNDS_CHECKING
return *(begin() + __n);
}
reference at (size_type __n)
{
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_LENGTH_ERROR,
_RWSTD_FUNC ("vector<bool>::at(size_type)"),
__n, size ()));
return *(begin() + __n);
}
const_reference at (size_type __n) const
{
_RWSTD_REQUIRES (__n < size (),
(_RWSTD_ERROR_LENGTH_ERROR,
_RWSTD_FUNC ("vector<bool>::at(size_type) const"),
__n, size ()));
return *(begin() + __n);
}
reference front () { return *begin(); }
const_reference front () const { return *begin(); }
reference back () { return *(end() - 1); }
const_reference back () const { return *(end() - 1); }
//
// modifiers
//
void push_back (const bool& __x)
{
if (_C_end._C_p != _C_bufend) {
++_C_end;
*(_C_end-1) = __x;
}
else
_C_insert(end(), __x);
}
void pop_back () { --_C_end; }
iterator insert (iterator __it, const bool& __x = bool())
{
size_type __n = __it - begin();
if (_C_end._C_p != _C_bufend && __it == end()) {
++_C_end;
*(_C_end-1) = __x;
}
else
_C_insert(__it, __x);
return begin() + __n;
}
void insert (iterator __it, size_type __n, const bool& __x);
template<class _InputIter>
void insert (iterator __it, _InputIter __first,
_InputIter __last);
iterator erase (iterator __it)
{
if (!(__it + 1 == end()))
_C_copy(__it + 1, end(), __it);
--_C_end;
return __it;
}
iterator erase(iterator __first, iterator __last)
{
_C_end = _C_copy(__last, end(), __first);
return __first;
}
void swap (_C_self& __x)
{
if((_C_value_alloc_type)*this == (_C_value_alloc_type)__x)
{
_STD::swap (_C_begin, __x._C_begin);
_STD::swap (_C_end, __x._C_end);
_STD::swap (_C_bufend, __x._C_bufend);
}
else
{
_C_self _x = *this;
*this = __x;
__x=_x;
}
}
static void swap(reference __x, reference __y);
void flip ();
void clear()
{
erase(begin(),end());
}
#if defined (_RWSTD_NO_PART_SPEC_OVERLOAD)
friend void swap (vector& __lhs, vector& __rhs) {
__lhs.swap (__rhs);
}
#endif
};
#undef _Allocator
#endif // _RWSTD_NO_BOOL
#endif // _RWSTD_NO_VECTOR_BOOL
} // namespace std
#if defined (_RWSTD_NO_IMPLICIT_INCLUSION)
# include <vector.cc>
#endif
#endif // _RWSTD_VECTOR_INCLUDED