/** -*- C++ -*- ** ** KAI C++ Compiler ** ** Copyright (C) 1997-2001, Intel Corp. All rights reserved. **/ /** ** Lib++ : The Modena C++ Standard Library, ** Version 2.4, October 1997 ** ** Copyright (c) 1995-1997 Modena Software Inc. **/ #ifndef MSIPL_VECTOR_H #define MSIPL_VECTOR_H #include #include #include #include #include #include #include #include #include #ifdef __KAI_NONSTD_VECTOR #include // to get basic_istream<> #endif /* __KAI_NONSTD_VECTOR */ namespace std { // Subclause 23.2.8 -- class vector template > class vector: public __kai::allocator_base { public: typedef typename Allocator::reference reference; typedef typename Allocator::const_reference const_reference; typedef typename Allocator::pointer iterator; typedef typename Allocator::const_pointer const_iterator; typedef typename Allocator::size_type size_type; typedef typename Allocator::difference_type difference_type; typedef T value_type; typedef Allocator allocator_type; typedef typename Allocator::pointer pointer; typedef typename Allocator::const_pointer const_pointer; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; private: typedef __kai::allocator_base value_allocator_type; pointer start; pointer finish; pointer end_of_storage; void insert_aux(pointer position, const T& x); void _initialize_storage(size_type n, const T& value); template class _Helper { }; template void _initialize(InputIterator first, InputIterator last, _Helper *) { size_type n = static_cast(first); const T value = static_cast(last); _initialize_storage(n,value); } template void _initialize(InputIterator first, InputIterator last, _Helper *) { _initialize_iterator(first,last, (iterator_traits::iterator_category *)0); } template void _initialize_iterator(InputIterator first, InputIterator last, forward_iterator_tag *) { size_type n = distance(first, last); start = _get_allocator().allocate(n); MSIPL_TRY { finish = uninitialized_copy(first, last, start); end_of_storage = finish; } MSIPL_CATCH { _get_allocator().deallocate(start, n); start = NULL; finish = NULL; end_of_storage = NULL; MSIPL_RETHROW; } } template void _initialize_iterator(InputIterator first, InputIterator last, input_iterator_tag *) { while (first!=last) { push_back(*first); ++first; } } template inline void _insert(iterator position, InputIterator first, InputIterator last, _Helper *) { size_type n = static_cast(first); const T value = static_cast(last); insert(position, n, value); } template inline void _insert(iterator position, InputIterator first, InputIterator last, _Helper *) { _insert_iterator(position, first, last, (iterator_traits::iterator_category *)0); } template __noinline void _insert_iterator(iterator position, InputIterator first, InputIterator last, input_iterator_tag *) { // We cannot compute the distance without destructivily stepping through the iterator. // So we create a new vector of the values and then insert that range(which we can compute the size) vector tmp(first,last); insert(position, tmp.begin(), tmp.end()); } template void _insert_iterator(iterator position, InputIterator first, InputIterator last, random_access_iterator_tag *); public: // 23.2.4.1 construct/copy/destroy explicit vector(const Allocator& a=Allocator()) : value_allocator_type(a), start(0), finish(0), end_of_storage(0) { } explicit vector(size_type n, const T& value=T(), const Allocator& a=Allocator()) : value_allocator_type(a), start(0), finish(0), end_of_storage(0) { _initialize_storage(n,value); } template vector(InputIterator first, InputIterator last, const Allocator& a=Allocator()) : value_allocator_type(a), start(0), finish(0), end_of_storage(0) { _initialize(first, last, (_Helper::is_integer> *)0); } vector(const vector& x); ~vector(); vector& operator=(const vector& x); template void assign(InputIterator first, InputIterator last) { erase(begin(), end()); _insert(begin(), first, last, (_Helper::is_integer> *)0); } void assign(size_type n, const T &val) { erase(begin(), end()); insert(begin(), n, val); } // iterators: iterator begin() { return iterator(start); } const_iterator begin() const { return const_iterator(iterator(start)); } iterator end() { return iterator(finish); } const_iterator end() const { return const_iterator(iterator(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: size_type size() const { return size_type(finish - start); } void resize(size_type new_size) { resize(new_size, T() ); } void resize(size_type new_size, T c) { const size_type len = size(); if (new_size > len) insert(end(), new_size - len, c); else if (new_size < len) erase(begin() + new_size, end()); } size_type capacity() const { return size_type(end_of_storage - start); } bool empty() const { return finish == start; } void reserve(size_type n); // element access: reference operator[] (size_type n) { return *(start+n); } const_reference operator[] (size_type n) const { return *(start+n); } const_reference at(size_type n) const { if ( n >= (finish - start)) out_of_range::__throw("Out of range exception\n"); return *(start + n); } reference at(size_type n) { if ( n >= (finish - start) ) out_of_range::__throw("Out of range exception\n"); return *(start + n); } reference front() { return *start; } const_reference front() const { return *start; } reference back() { return *(finish - 1); } const_reference back() const { return *(finish - 1); } // 23.2.4.3 modifiers: void push_back(const T& x) { if (finish != end_of_storage) { _get_allocator().construct(finish, x); ++finish; } else insert_aux(finish, x); } void pop_back() { // Failure of following assertion indicates that vector is empty. assert( !(finish == start) ); --finish; _get_allocator().destroy(finish); } iterator insert(iterator position) { return insert(position,T()); } iterator insert(iterator position, const T& x) { size_type n = position - start; if (n > finish - start) out_of_range::__throw("Out of range exception\n"); if (finish != end_of_storage && position == finish) { _get_allocator().construct(finish, x); ++finish; } else insert_aux(position, x); return begin() + n; } void insert(iterator position, size_type n, const T& x); template void insert(iterator position, InputIterator first, InputIterator last) { _insert(position, first, last, (_Helper::is_integer> *)0); } iterator erase(iterator position); iterator erase(iterator first, iterator last); void swap(vector& x) { std::swap( *(value_allocator_type*)this, *(value_allocator_type*)&x ); std::swap(start, x.start); std::swap(finish, x.finish); std::swap(end_of_storage, x.end_of_storage); } void clear() { pointer i = start; while (i != finish) _get_allocator().destroy(i++); finish = start; } }; template inline bool operator==(const vector& x, const vector& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } template inline bool operator<(const vector& x, const vector& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } template inline bool operator!=(const vector& x, const vector& y) { return ! (x == y); } template inline bool operator>(const vector& x, const vector& y) { return (y < x); } template inline bool operator>=(const vector& x, const vector& y) { return ! (x < y); } template inline bool operator<=(const vector& x, const vector& y) { return ! (y < x); } template void vector::_initialize_storage(size_type n, const T& value) { start = _get_allocator().allocate(n); MSIPL_TRY { uninitialized_fill_n(start, n, value); finish = start + n; end_of_storage = finish; } MSIPL_CATCH { _get_allocator().deallocate(start, n); MSIPL_RETHROW; } } template vector::vector(const vector& x) : value_allocator_type(x), start(0), finish(0), end_of_storage(0) { size_type n = x.finish - x.start; if (n) { start = _get_allocator().allocate(n); MSIPL_TRY { finish = uninitialized_copy(x.start, x.finish, start); end_of_storage = start + n; } MSIPL_CATCH { _get_allocator().deallocate(start, n); start = 0; MSIPL_RETHROW; } } } template vector::~vector() { for( pointer i = start; i != finish; i++ ) _get_allocator().destroy(i); if (start) _get_allocator().deallocate(start, end_of_storage - start); } template vector& vector::operator=(const vector& x) { if (&x == this) return *this; if ((x.finish - x.start) > (end_of_storage - start)) { pointer tmp = _get_allocator().allocate(x.finish - x.start); MSIPL_TRY { uninitialized_copy(x.start, x.finish, tmp); } MSIPL_CATCH { _get_allocator().deallocate(tmp, x.finish - x.start); MSIPL_RETHROW; } pointer i = start; while (i != finish) _get_allocator().destroy(i++); if (start) _get_allocator().deallocate(start, end_of_storage - start); start = tmp; end_of_storage = start + (x.finish - x.start); } else if ((finish - start) >= (x.finish - x.start)) { pointer i = copy(x.start, x.finish, start); while (i != finish) _get_allocator().destroy(i++); } else { copy(x.start, x.start + (finish - start), start); uninitialized_copy(x.start + (finish - start), x.finish, finish); } finish = start + (x.finish - x.start); return *this; } template void vector::reserve(size_type n) { if ((end_of_storage - start) < n) { size_type old_size = finish - start; pointer tmp = _get_allocator().allocate(n); MSIPL_TRY { uninitialized_copy(start, finish, tmp); } MSIPL_CATCH { _get_allocator().deallocate(tmp, n); MSIPL_RETHROW; } pointer i = start; while (i != finish) _get_allocator().destroy(i++); if (start) _get_allocator().deallocate(start, end_of_storage - start); start = tmp; finish = start + old_size; end_of_storage = start + n; } } template void vector::insert_aux(pointer position, const T& x) { if (finish != end_of_storage) { _get_allocator().construct(finish, *(finish - 1)); ++finish; copy_backward(position, finish-2, finish-1); *position = x; } else { size_type len = 2 * (finish - start); size_type min_size = (4*sizeof(void*)/sizeof(T)) > 0 ? 4*sizeof(void*)/sizeof(T) : 1; if( len void vector::insert(iterator position, size_type n, const T& x) { if (n == 0) return; size_type n1 = position - start; if (n1 > finish - start) out_of_range::__throw("Out of range exception\n"); if (end_of_storage - finish >= n) { pointer old_finish = finish; if (finish - (position) > n) { uninitialized_copy(finish - n, finish , finish); finish += n; copy_backward(position, old_finish - n, old_finish); fill(position, position + n, x); } else { size_t n_uninit = position + n - old_finish; uninitialized_fill_n(finish, n_uninit, x); finish += n_uninit; uninitialized_copy(position, old_finish, finish); finish = old_finish + n; fill(position, old_finish, x); } } else { size_type len = (finish - start) + max(size_type(finish - start), n); pointer tmp = _get_allocator().allocate(len); pointer tmp_end = tmp; MSIPL_TRY { tmp_end = uninitialized_copy(start, start + n1, tmp); uninitialized_fill_n(tmp_end, n, x); tmp_end += n; tmp_end = uninitialized_copy(start + n1, finish, tmp_end); } MSIPL_CATCH { for (pointer i = tmp; i != tmp_end; ++i) _get_allocator().destroy(i); _get_allocator().deallocate(tmp, len); MSIPL_RETHROW; } for (pointer i = start; i != finish; ++i) _get_allocator().destroy(i); if (start) _get_allocator().deallocate(start, end_of_storage - start); start = tmp; finish = tmp_end; end_of_storage = tmp + len; } } template template void vector::_insert_iterator(iterator position, InputIterator first, InputIterator last, random_access_iterator_tag *) { if (first == last) return; size_type n = distance(first, last); size_type n1 = distance(begin(), position); if (n1 > finish - start) out_of_range::__throw("Out of range exception\n"); if (end_of_storage - finish >= n) { if (finish - (start + n1) > n) { uninitialized_copy(finish - n, finish, finish); copy_backward(start + n1, finish - n, finish); copy(first, last, position); } else { uninitialized_copy(position, end(), position + n); copy(first, first + (end() - position), position); uninitialized_copy(first + (end() - position), last, end()); } finish += n; } else { size_type len = (finish - start) + max(size_type(finish - start), n); pointer tmp = _get_allocator().allocate(len); pointer tmp_end = tmp; MSIPL_TRY { tmp_end = uninitialized_copy(start, start + n1, tmp); tmp_end = uninitialized_copy(first, last, tmp_end); tmp_end = uninitialized_copy(start + n1, finish, tmp_end); } MSIPL_CATCH { for (pointer i=tmp; i!=tmp_end; ++i) _get_allocator().destroy(i); _get_allocator().deallocate(tmp, len); MSIPL_RETHROW; } for (pointer i=start; i!=finish; ++i) _get_allocator().destroy(i); if (start) _get_allocator().deallocate(start, end_of_storage - start); start = tmp; finish = tmp_end; end_of_storage = tmp + len; } } template vector::iterator vector::erase(iterator position) { assert( start<=position || position < finish ); if (position + 1 != finish) copy(position + 1, finish, position); --finish; _get_allocator().destroy(finish); return position; } template vector::iterator vector::erase( iterator first, iterator last ) { assert( start<=first && first<=last && last<=finish ); pointer i = copy(last, finish, first); while (i != finish) _get_allocator().destroy(--finish); return first; } // Subclause 23.2.5 -- class vector template class vector: public __kai::allocator_base { typedef __kai::chunk_t word_t; typedef unsigned int offset_t; // Offset of bit in word static const offset_t n_bit_per_word = __kai::chunk_bits; typedef typename Allocator::template rebind::other word_alloc_type; typedef __kai::allocator_base value_allocator_type; public: // types: typedef bool const_reference; class iterator; class const_iterator; typedef typename Allocator::size_type size_type; typedef typename Allocator::difference_type difference_type; typedef bool value_type; typedef Allocator allocator_type; typedef typename Allocator::pointer pointer; typedef typename Allocator::const_pointer const_pointer; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; friend class iterator; friend class const_iterator; friend iterator operator+(difference_type n, iterator iter) { vector::iterator tmp = iter; return tmp += n; } // bit reference: class reference; friend class reference; class reference { friend class vector; friend class iterator; friend class const_iterator; reference(); // deny access. reference(word_t* x, word_t msk) : p(x), mask(msk) {} word_t * p; word_t mask; public: inline operator bool() const { return (*p & mask)!=0; } reference& operator=(const bool x) { if (x) *p |= mask; else *p &=~mask; return *this; } inline reference& operator=(const reference& x) { return *this = bool(x); } void flip() { *p ^= mask; } }; private: template class _Helper { }; template void _initialize(InputIterator first, InputIterator last, _Helper *) { size_type n = static_cast(first); const bool value = static_cast(last); initialize(n); fill_n(start.cp, get_size(n), (word_t)0-value ); } template void _initialize(InputIterator first, InputIterator last, _Helper *) { _initialize_iterator(first,last, (iterator_traits::iterator_category *)0); } template void _initialize_iterator(InputIterator first, InputIterator last, forward_iterator_tag *); template void _initialize_iterator(InputIterator first, InputIterator last, input_iterator_tag *); public: // construct/copy/destroy: explicit vector(const allocator_type &a = allocator_type()) : value_allocator_type(a), start(0), finish(0,0), end_of_storage(0) {} explicit vector(size_type n, const bool& value=bool(), const allocator_type &a = allocator_type() ) : value_allocator_type(a), start(0), finish(0,0), end_of_storage(0) { initialize(n); fill_n(start.cp, get_size(n), (word_t)0-value ); } template vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : value_allocator_type(a), start(0), finish(0,0), end_of_storage(0) { _initialize(first, last, (_Helper::is_integer> *)0); } vector(const vector& x); ~vector(); vector& operator=(const vector& x); template void assign(InputIterator first, InputIterator last) { finish = start; insert(start, first, last); } template void assign(Size n, const bool& t = bool()) { finish = start + n; fill_n(start.cp, get_size(n), (word_t)0-t ); } // iterators: iterator begin() { return start; } const_iterator begin() const { return const_iterator(start); } iterator end() { return finish; } const_iterator end() const { return const_iterator(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()); } // capacity: size_type size() const { return size_type(finish - start); } void resize(size_type new_size, bool c = false) { const size_type len = finish - start; if (new_size > len) insert(finish, new_size - len, c); else if (new_size < len) finish = start + new_size; } size_type capacity() const { return (size_type)(end_of_storage - start); } bool empty() const { return begin() == end(); } void reserve(size_type n) { if (capacity() < n) { word_t* q = (word_t*)bit_alloc(n); finish = copy(iterator(start), finish, iterator(q, 0)); bit_dealloc(); start = q; end_of_storage = q + get_size(n); } } // element access: reference operator[] (size_type n) { return *(start+n); } const_reference operator[] (size_type n) const { return *(start+n); } const_reference at(size_type n) const { if ( n >= (finish - start) ) out_of_range::__throw("Out of range exception\n"); return *(start + n); } reference at(size_type n) { if ( n >= (finish - start) ) out_of_range::__throw("Out of range exception\n"); return *(start + 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 ( end_of_storage==finish ) insert_aux(finish, x); else *finish++ = x; } void pop_back() { // Failure of following assertion indicates that vector is empty. assert( !(start==finish) ); --finish; } iterator insert(iterator position, const bool& x) { size_type n = position - start; if( end_of_storage>finish && position == finish) *finish++ = x; else insert_aux(position, x); return start + n; } void insert(iterator position, size_type n, const bool& x); template void insert(iterator position, InputIterator first, InputIterator last); iterator erase(iterator position) { if (finish != position + 1) copy(position + 1, finish, position); --finish; return position; } iterator erase(iterator first, iterator last) { finish = copy(last, finish, first); return first; } void swap(vector & x) { std::swap( *(value_allocator_type*)this, *(value_allocator_type*)&x ); std::swap(start, x.start); std::swap(finish, x.finish); std::swap(end_of_storage, x.end_of_storage); } static void swap(reference x, reference y) { bool tmp = x; x = y; y = tmp; } void flip() { word_t * q = end_of_storage.cp; for( word_t * p = start.cp; p( const bool_iterator_base& x ) const {return cp>x.cp;} difference_type operator-(const word_iterator& x) const { return n_bit_per_word * (cp - x.cp); } iterator operator+( size_type n ) const { return iterator( cp + n / n_bit_per_word, n % n_bit_per_word ); } }; class bool_iterator_base { friend class vector; friend class word_iterator; protected: word_t* cp; offset_t offset; bool_iterator_base() {} bool_iterator_base(word_t* base, offset_t off) : cp(base), offset(off) {} void bump_up() { if( (offset = (offset+1)%n_bit_per_word) == 0 ) { ++cp; } } void bump_down() { if( (offset = (offset-1)%n_bit_per_word) == n_bit_per_word-1 ) { --cp; } } void adjust( const difference_type i ) { difference_type n = i + (difference_type)offset; difference_type m = n / (difference_type)n_bit_per_word; n -= m*n_bit_per_word; if( n < 0 ) { n += n_bit_per_word; --m; } cp += m; offset = n; } public: bool_iterator_base(const bool_iterator_base & x) : cp(x.cp), offset(x.offset) {} bool operator==(const bool_iterator_base& x) const { return cp == x.cp && offset == x.offset; } bool operator<(const bool_iterator_base& x) const { return cp < x.cp || (cp == x.cp && offset < x.offset); } bool operator!=(const bool_iterator_base& y) const { return ! (*this == y); } bool operator>(const bool_iterator_base& y) const { return y < *this; } bool operator>=(const bool_iterator_base& y) const { return ! (*this < y); } bool operator<=(const bool_iterator_base& y) const { return ! (y < *this); } }; public: class iterator : public bool_iterator_base, public std::iterator { friend class vector; friend class word_iterator; iterator(word_t* base, offset_t offset) : bool_iterator_base(base, offset) { } iterator(const word_iterator& x) : bool_iterator_base(x.cp,0) {} public: iterator() {} iterator(const iterator &i) : bool_iterator_base(i) { } reference operator*() const { return reference(cp, (word_t)1 << offset); } reference operator[](const difference_type i) { return *(*this + i); } iterator& operator++() { bump_up(); return *this; } iterator operator++(int) { iterator tmp = *this; bump_up(); return tmp; } iterator& operator--() { bump_down(); return *this; } iterator operator--(int) { iterator tmp = *this; bump_down(); return tmp; } iterator& operator+=(const difference_type i) { adjust(i); return *this; } iterator& operator-=(const difference_type i) { adjust(-i); return *this; } iterator operator+(const difference_type i) const { iterator tmp = *this; return tmp += i; } iterator operator-(const difference_type i) const { iterator tmp = *this; return tmp -= i; } difference_type operator-(const iterator& x) const { return n_bit_per_word * (cp - x.cp) + offset - x.offset; } }; class const_iterator : public bool_iterator_base, public std::iterator { friend class vector; const_iterator(word_t* base, difference_type offset) : bool_iterator_base(base,offset) { } const_iterator(const word_iterator& x) : bool_iterator_base(x.cp,0) {} public: const_iterator() {} const_iterator(const vector::iterator& x) : bool_iterator_base(x) { } const reference operator*() const { return reference(cp, (word_t)1 << offset); } const reference operator[](const difference_type i) const { return *(*this + i); } const_iterator& operator++() { bump_up(); return *this; } const_iterator operator++(int) { const_iterator tmp = *this; bump_up(); return tmp; } const_iterator& operator--() { bump_down(); return *this; } const_iterator operator--(int) { const_iterator tmp = *this; bump_down(); return tmp; } const_iterator& operator+=(const difference_type i) { adjust(i); return *this; } const_iterator& operator-= (const difference_type i) { adjust(-i); return *this; } const_iterator operator+(const difference_type i) const { const_iterator tmp = *this; return tmp += i; } const_iterator operator-(const difference_type i) const { const_iterator tmp = *this; return tmp -= i; } difference_type operator-(const const_iterator& x) const { return n_bit_per_word * (cp - x.cp) + offset - x.offset; } }; private: word_iterator start; iterator finish; word_iterator end_of_storage; size_type get_size(size_type n) { return (n + n_bit_per_word - 1) / n_bit_per_word; } word_t* bit_alloc(size_type n) { return _get_rebound_allocator().allocate(get_size(n)); } void bit_dealloc() { if (start.cp) _get_rebound_allocator().deallocate(start.cp, (end_of_storage.cp-start.cp) ); } word_t * initialize(size_type n) { word_t* p = bit_alloc(n); start.cp = p; finish = start + n; end_of_storage.cp = p + get_size(n); return p; } void insert_aux(iterator position, bool x); }; template const vector::offset_t vector::n_bit_per_word; template inline bool operator==(const vector& x, const vector& y) { return x.size() == y.size() && equal(x.begin(), x.end(), y.begin()); } template inline bool operator<(const vector& x, const vector& y) { return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } template inline bool operator!=(const vector& x, const vector& y) { return ! (x == y); } template inline bool operator>(const vector& x, const vector& y) { return (y < x); } template inline bool operator>=(const vector& x, const vector& y) { return ! (x < y); } template inline bool operator<=(const vector& x, const vector& y) { return ! (y < x); } // specialized algorithms: template inline void swap(vector& x, vector& y) { x.swap(y); } template vector::vector(const vector& x) : value_allocator_type(x), start(0), finish(0,0), end_of_storage(0) { if (x.size()) { initialize(x.size()); copy( x.start.cp, x.start.cp+(end_of_storage.cp-start.cp), start.cp ); } } template vector::~vector() { bit_dealloc(); } template vector& vector::operator=(const vector& x) { if (&x == this) { } else { if (x.size() > (end_of_storage - start)) { bit_dealloc(); initialize(x.size()); } copy( x.start.cp, x.start.cp+(end_of_storage.cp-start.cp), start.cp ); finish = begin() + x.size(); } return *this; } template template void vector::_initialize_iterator(InputIterator first, InputIterator last, forward_iterator_tag *) { size_type n = distance(first, last); word_t * p = initialize(n); word_t w = 0; unsigned int offset = 0; for( ; first!=last; ++first ) { if( *first ) w |= (word_t)1< template void vector::_initialize_iterator(InputIterator first, InputIterator last, input_iterator_tag *) { for( ; first!=last; ++first ) { push_back(*first); } } template template void vector::insert(iterator position, InputIterator first, InputIterator last) { if (first == last) return; size_type n = 0; n = distance(first, last); if ((end_of_storage-start) - size() >= n) { copy_backward(position, end(), finish + n); copy(first, last, position); finish += n; } else { size_type len = size() + max(size(), n); word_t* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); i = copy(first, last, i); finish = copy(position, end(), i); bit_dealloc(); end_of_storage = q + get_size(len); start = q; } } template void vector::insert_aux(iterator position, bool x) { if( end_of_storage==finish ) { size_type len = size() ? 2 * size() : n_bit_per_word; word_t* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); *i = x; ++i; finish = copy(position, end(), i); bit_dealloc(); end_of_storage = q + get_size(len); start = q; } else { copy_backward(position, finish, finish+1); ++finish; *position = x; } } template void vector::insert(iterator position, size_type n, const bool& x) { if (n == 0) return; if ((end_of_storage-start) - size() >= n) { copy_backward(position, end(), finish + n); fill(position, position + n, x); finish += n; } else { size_type len = size() + max(size(), n); word_t* q = bit_alloc(len); iterator i = copy(begin(), position, iterator(q, 0)); fill_n(i, n, x); finish = copy(position, end(), i + n); bit_dealloc(); end_of_storage = q + get_size(len); start = q; } } #ifdef __KAI_NONSTD_VECTOR // The C++ standard has a hole in the definition of vector. // It does not seem to allow: // vector a(1); // cin >> a[0]; // The only way to fix it is to add an operator>> that takes a // vector::reference. There might be an include loop / ordering // problem to overcome but this seems like a good thing to "fix". template basic_istream &operator>>(basic_istream &is, typename vector::reference r) { bool foo; basic_istream &rv = is>>foo; r = foo; return rv; } #endif /* __KAI_NONSTD_VECTOR */ } /* namespace std */ #endif /* MSIPL_VECTOR_H */