430 lines
14 KiB
C++
430 lines
14 KiB
C++
|
#ifndef __VECTOR_CC
|
|||
|
#define __VECTOR_CC
|
|||
|
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
|
|||
|
/***************************************************************************
|
|||
|
*
|
|||
|
* vector.cc - Non-inline definitions for the Standard Library vector class
|
|||
|
*
|
|||
|
***************************************************************************
|
|||
|
*
|
|||
|
* 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.
|
|||
|
*
|
|||
|
*
|
|||
|
***************************************************************************
|
|||
|
*
|
|||
|
* Copyright (c) 1994-1999 Rogue Wave Software, Inc. All Rights Reserved.
|
|||
|
*
|
|||
|
* This computer software is owned by Rogue Wave Software, Inc. and is
|
|||
|
* protected by U.S. copyright laws and other laws and by international
|
|||
|
* treaties. This computer software is furnished by Rogue Wave Software,
|
|||
|
* Inc. pursuant to a written license agreement and may be used, copied,
|
|||
|
* transmitted, and stored only in accordance with the terms of such
|
|||
|
* license and with the inclusion of the above copyright notice. This
|
|||
|
* computer software or any other copies thereof may not be provided or
|
|||
|
* otherwise made available to any other person.
|
|||
|
*
|
|||
|
* U.S. Government Restricted Rights. This computer software is provided
|
|||
|
* with Restricted Rights. Use, duplication, or disclosure by the
|
|||
|
* Government is subject to restrictions as set forth in subparagraph (c)
|
|||
|
* (1) (ii) of The Rights in Technical Data and Computer Software clause
|
|||
|
* at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
|
|||
|
* Commercial Computer Software <EFBFBD> Restricted Rights at 48 CFR 52.227-19,
|
|||
|
* as applicable. Manufacturer is Rogue Wave Software, Inc., 5500
|
|||
|
* Flatiron Parkway, Boulder, Colorado 80301 USA.
|
|||
|
*
|
|||
|
**************************************************************************/
|
|||
|
#include <stdcomp.h>
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
namespace std {
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// This requires that T have a default constructor.
|
|||
|
//
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void vector<T,Allocator>::resize (size_type new_size)
|
|||
|
{
|
|||
|
// T value; // RW_BUG: bts-78526
|
|||
|
if (new_size > size())
|
|||
|
insert(end(), new_size - size(), T() ); // RW_BUG: bts-78526
|
|||
|
else if (new_size < size())
|
|||
|
erase(begin() + new_size, end());
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void vector<T,Allocator>::resize (size_type new_size, T value)
|
|||
|
{
|
|||
|
if (new_size > size())
|
|||
|
insert(end(), new_size - size(), value);
|
|||
|
else if (new_size < size())
|
|||
|
erase(begin() + new_size, end());
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
vector<T,Allocator>& vector<T,Allocator>::operator= (const vector<T,Allocator>& x)
|
|||
|
{
|
|||
|
if (&x == this) return *this;
|
|||
|
if (x.size() > capacity())
|
|||
|
{
|
|||
|
__value_alloc_type va(__end_of_storage);
|
|||
|
iterator tmp = va.allocate(x.end() - x.begin(),0);
|
|||
|
#ifndef _RWSTD_NO_EXCEPTIONS
|
|||
|
try {
|
|||
|
__end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
|
|||
|
} catch(...) {
|
|||
|
va.deallocate(tmp,x.end()-x.begin());
|
|||
|
throw;
|
|||
|
}
|
|||
|
#else
|
|||
|
__end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
|
|||
|
#endif // _RWSTD_NO_EXCEPTIONS
|
|||
|
__destroy(__start, __finish);
|
|||
|
va.deallocate(__start,__end_of_storage.data()-__start);
|
|||
|
__start = tmp;
|
|||
|
}
|
|||
|
else if (size() >= x.size())
|
|||
|
{
|
|||
|
iterator i = copy(x.begin(), x.end(), begin());
|
|||
|
__destroy(i, __finish);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
copy(x.begin(), x.begin() + size(), begin());
|
|||
|
uninitialized_copy(x.begin() + size(), x.end(), begin() + size());
|
|||
|
}
|
|||
|
__finish = begin() + x.size();
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void vector<T,Allocator>::__insert_aux (
|
|||
|
iterator position, const T& x)
|
|||
|
{
|
|||
|
if (__finish != __end_of_storage.data())
|
|||
|
{
|
|||
|
__value_alloc_type(__end_of_storage).construct(__finish, *(__finish - 1));
|
|||
|
copy_backward(position, __finish - 1, __finish);
|
|||
|
*position = x;
|
|||
|
++__finish;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// We always allocate enough space for a number of additional
|
|||
|
// elements in the vector, unless the size of each element is
|
|||
|
// very large. See definition of __rw_allocation_size in
|
|||
|
// memory.
|
|||
|
//
|
|||
|
__value_alloc_type va(__end_of_storage);
|
|||
|
size_type len = __RWSTD::__rw_allocation_size((value_type*)0,size(),__buffer_size);
|
|||
|
iterator tmp = va.allocate(len,__start);
|
|||
|
uninitialized_copy(begin(), position, tmp);
|
|||
|
va.construct((tmp + (position - begin())), x);
|
|||
|
#ifndef _RWSTD_NO_EXCEPTIONS
|
|||
|
try {
|
|||
|
uninitialized_copy(position, end(), tmp + (position - begin()) + 1);
|
|||
|
} catch(...) {
|
|||
|
va.deallocate(tmp,len);
|
|||
|
throw;
|
|||
|
}
|
|||
|
#else
|
|||
|
uninitialized_copy(position, end(), tmp + (position - begin()) + 1);
|
|||
|
#endif // _RWSTD_NO_EXCEPTIONS
|
|||
|
int tmp_size = size(); // RW_BUG: Fix for bts-78394
|
|||
|
__destroy(begin(), end());
|
|||
|
va.deallocate(begin(),__end_of_storage.data() - begin());
|
|||
|
__end_of_storage = tmp + len;
|
|||
|
__finish = tmp + tmp_size + 1; // RW_BUG: Fix for bts-78394
|
|||
|
__start = tmp;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void vector<T,Allocator>::__insert_aux (
|
|||
|
iterator position, size_type n, const T& x)
|
|||
|
{
|
|||
|
if (n == 0) return;
|
|||
|
if ((size_type)(__end_of_storage.data() - __finish) >= n)
|
|||
|
{
|
|||
|
iterator old_end = end();
|
|||
|
if ((size_type)(end() - position) > n)
|
|||
|
{
|
|||
|
uninitialized_copy(old_end - n, old_end, old_end);
|
|||
|
__finish += n;
|
|||
|
copy_backward(position, old_end - n, old_end);
|
|||
|
fill(position, position + n, x);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
size_type first_part = n - (old_end - position);
|
|||
|
uninitialized_fill_n(old_end, first_part, x);
|
|||
|
__finish += first_part;
|
|||
|
uninitialized_copy(position, old_end, position + n);
|
|||
|
__finish += n - first_part;
|
|||
|
fill(position, old_end, x);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
__value_alloc_type va(__end_of_storage);
|
|||
|
size_type len = size() + max(size(), n);
|
|||
|
iterator tmp = va.allocate(len,__start);
|
|||
|
#ifndef _RWSTD_NO_EXCEPTIONS
|
|||
|
try {
|
|||
|
uninitialized_copy(begin(), position, tmp);
|
|||
|
uninitialized_fill_n(tmp + (position - begin()), n, x);
|
|||
|
uninitialized_copy(position, end(), tmp + (position - begin() + n));
|
|||
|
} catch(...) {
|
|||
|
va.deallocate(tmp,len);
|
|||
|
throw;
|
|||
|
}
|
|||
|
#else
|
|||
|
uninitialized_copy(begin(), position, tmp);
|
|||
|
uninitialized_fill_n(tmp + (position - begin()), n, x);
|
|||
|
uninitialized_copy(position, end(), tmp + (position - begin() + n));
|
|||
|
#endif // _RWSTD_NO_EXCEPTIONS
|
|||
|
int tmp_size = size(); // RW_BUG: Fix for bts-78394
|
|||
|
__destroy(begin(), end());
|
|||
|
va.deallocate(begin(),__end_of_storage.data() - begin());
|
|||
|
__end_of_storage = tmp + len;
|
|||
|
__finish = tmp + tmp_size + n; // RW_BUG: Fix for bts-78394
|
|||
|
__start = tmp;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
template<class T, class Allocator>
|
|||
|
template<class InputIterator>
|
|||
|
void vector<T,Allocator>::__insert_aux2 (iterator position,
|
|||
|
InputIterator first,
|
|||
|
InputIterator last)
|
|||
|
#else
|
|||
|
template<class T, class Allocator>
|
|||
|
void vector<T,Allocator>::__insert_aux2 (iterator position,
|
|||
|
const_iterator first,
|
|||
|
const_iterator last)
|
|||
|
#endif
|
|||
|
{
|
|||
|
if (first == last) return;
|
|||
|
size_type n;
|
|||
|
__initialize(n, size_type(0));
|
|||
|
distance(first, last, n);
|
|||
|
|
|||
|
if ((size_type)(__end_of_storage.data() - __finish) >= n)
|
|||
|
{
|
|||
|
iterator old_end = end();
|
|||
|
if ((size_type)(old_end - position) > n)
|
|||
|
{
|
|||
|
uninitialized_copy(old_end - n, old_end, old_end);
|
|||
|
__finish += n;
|
|||
|
copy_backward(position, old_end - n, old_end);
|
|||
|
copy(first, last, position);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
size_type first_part = (old_end - position);
|
|||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
InputIterator iter(first);
|
|||
|
#else
|
|||
|
const_iterator iter(first);
|
|||
|
#endif
|
|||
|
advance(iter, first_part);
|
|||
|
uninitialized_copy(iter, last, old_end);
|
|||
|
// uninitialized_copy(first + first_part, last, old_end);
|
|||
|
__finish += n - first_part;
|
|||
|
uninitialized_copy(position, old_end, position + n);
|
|||
|
__finish += first_part;
|
|||
|
copy(first, iter, position);
|
|||
|
// copy(first, first + (old_end - position), position);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
__value_alloc_type va(__end_of_storage);
|
|||
|
size_type len = size() + max(size(), n);
|
|||
|
iterator tmp = va.allocate(len,__start);
|
|||
|
#ifndef _RWSTD_NO_EXCEPTIONS
|
|||
|
try {
|
|||
|
uninitialized_copy(begin(), position, tmp);
|
|||
|
uninitialized_copy(first, last, tmp + (position - begin()));
|
|||
|
uninitialized_copy(position, end(), tmp + (position - begin() + n));
|
|||
|
} catch(...) {
|
|||
|
va.deallocate(tmp,len);
|
|||
|
throw;
|
|||
|
}
|
|||
|
#else
|
|||
|
uninitialized_copy(begin(), position, tmp);
|
|||
|
uninitialized_copy(first, last, tmp + (position - begin()));
|
|||
|
uninitialized_copy(position, end(), tmp + (position - begin() + n));
|
|||
|
#endif // _RWSTD_NO_EXCEPTIONS
|
|||
|
int tmp_size = size(); // RW_BUG: Fix for bts-78394
|
|||
|
__destroy(begin(), end());
|
|||
|
va.deallocate(begin(),__end_of_storage.data() - begin());
|
|||
|
__end_of_storage = tmp + len;
|
|||
|
__finish = tmp + tmp_size + n; // RW_BUG: Fix for bts-78394
|
|||
|
__start = tmp;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
// The body of this function is duplicated in src/vecbool.cpp and
|
|||
|
// further down in this file as well.
|
|||
|
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
|
|||
|
template <class Allocator>
|
|||
|
template<class InputIterator>
|
|||
|
void vector<bool, Allocator >::insert
|
|||
|
#else
|
|||
|
template<class InputIterator>
|
|||
|
void vector<bool, allocator<bool> >::insert
|
|||
|
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
|
|||
|
(iterator position,
|
|||
|
InputIterator first,
|
|||
|
InputIterator last)
|
|||
|
|
|||
|
{
|
|||
|
if (first == last) return;
|
|||
|
size_type n;
|
|||
|
__initialize(n, size_type(0));
|
|||
|
distance(first, last, n);
|
|||
|
if (capacity() - size() >= n)
|
|||
|
{
|
|||
|
copy_backward(position, end(), __finish + n);
|
|||
|
copy(first, last, position);
|
|||
|
__finish += n;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
size_type len = size() + max(size(), n);
|
|||
|
unsigned int* q = __bit_alloc(len);
|
|||
|
iterator i = copy(begin(), position, iterator(q, 0));
|
|||
|
i = copy(first, last, i);
|
|||
|
__finish = copy(position, end(), i);
|
|||
|
__value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
|
|||
|
__end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
|
|||
|
__start = iterator(q, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
|
|||
|
// Duplicates of the followign functions exist in src/stl/vecbool.cpp.
|
|||
|
// Which set is used depends on the availability of partial specialization.
|
|||
|
|
|||
|
template <class Allocator>
|
|||
|
void vector<bool,Allocator >::flip ()
|
|||
|
{
|
|||
|
for (iterator i = begin(); !(i == end()); i++)
|
|||
|
*i = !(*i);
|
|||
|
}
|
|||
|
|
|||
|
template <class Allocator>
|
|||
|
void vector<bool,Allocator >::swap (reference x, reference y)
|
|||
|
{
|
|||
|
bool tmp = x; x = y; y = tmp;
|
|||
|
}
|
|||
|
|
|||
|
template <class Allocator>
|
|||
|
void vector<bool,Allocator >::__insert_aux (iterator position, bool x)
|
|||
|
{
|
|||
|
if (__finish.p != __end_of_storage.data())
|
|||
|
{
|
|||
|
__copy_backward(position, __finish - 1, __finish);
|
|||
|
*position = x;
|
|||
|
++__finish;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
size_type len = size() ? 2 * size() : _RWSTD_WORD_BIT;
|
|||
|
unsigned int* q = __bit_alloc(len);
|
|||
|
iterator i = __copy(begin(), position, iterator(q, 0));
|
|||
|
*i++ = x;
|
|||
|
__finish = __copy(position, end(), i);
|
|||
|
__value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
|
|||
|
__end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
|
|||
|
__start = iterator(q, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <class Allocator>
|
|||
|
void vector<bool,Allocator >::insert (iterator position, size_type n, const bool& x)
|
|||
|
{
|
|||
|
if (n == 0) return;
|
|||
|
if (capacity() - size() >= n)
|
|||
|
{
|
|||
|
__copy_backward(position, end(), __finish + n);
|
|||
|
__fill(position, position + n, x);
|
|||
|
__finish += n;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
size_type len = size() + max(size(), n);
|
|||
|
unsigned int* q = __bit_alloc(len);
|
|||
|
iterator i = __copy(begin(), position, iterator(q, 0));
|
|||
|
__fill_n(i, n, x);
|
|||
|
__finish = __copy(position, end(), i + n);
|
|||
|
__value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
|
|||
|
__end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
|
|||
|
__start = iterator(q, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
#ifdef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
template <class Allocator>
|
|||
|
void vector<bool,Allocator >::insert (iterator position, const_iterator first,
|
|||
|
const_iterator last)
|
|||
|
{
|
|||
|
if (first == last) return;
|
|||
|
size_type n;
|
|||
|
__initialize(n, size_type(0));
|
|||
|
distance(first, last, n);
|
|||
|
if (capacity() - size() >= n)
|
|||
|
{
|
|||
|
__copy_backward(position, end(), __finish + n);
|
|||
|
__copy(first, last, position);
|
|||
|
__finish += n;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
size_type len = size() + max(size(), n);
|
|||
|
unsigned int* q = __bit_alloc(len);
|
|||
|
iterator i = __copy(begin(), position, iterator(q, 0));
|
|||
|
i = __copy(first, last, i);
|
|||
|
__finish = __copy(position, end(), i);
|
|||
|
__value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
|
|||
|
__end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
|
|||
|
__start = iterator(q, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
|
|||
|
template <class Allocator>
|
|||
|
void vector<bool,Allocator >::resize (size_type new_size, bool c)
|
|||
|
{
|
|||
|
if (new_size > size())
|
|||
|
insert(end(), new_size - size(), c);
|
|||
|
else if (new_size < size())
|
|||
|
erase(begin() + new_size, end());
|
|||
|
}
|
|||
|
|
|||
|
#endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#pragma option pop
|
|||
|
#endif /* __VECTOR_CC */
|