home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magazyn Internet 2000 May
/
MICD_2000_05.iso
/
CBuilder5
/
INSTALL
/
DATA1.CAB
/
Program_Built_Files
/
Include
/
deque.cc
< prev
next >
Wrap
C/C++ Source or Header
|
2000-02-01
|
16KB
|
496 lines
#ifndef __DEQUE_CC
#define __DEQUE_CC
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
/***************************************************************************
*
* deque.cc - Non-iniline definitions for the Standard Library deque 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 û 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
template <class T, class Allocator>
deque<T,Allocator>::~deque()
{
while (!empty()) pop_front();
}
template <class T, class Allocator>
_TYPENAME deque<T,Allocator>::size_type deque<T,Allocator>::__buffer_size ()
{
static size_type b_size =
max((size_type)1,__RWSTD::__rw_allocation_size((value_type*)0,(size_type)0,(size_type)0));
return b_size;
}
template <class T, class Allocator>
void deque<T,Allocator>::__allocate_at_begin ()
{
pointer p = __value_alloc_type(__map_size).allocate(__buffer_size(),__start.current);
if (!empty())
{
if (__start.node == __map)
{
__map_alloc_type ma(__map_size);
difference_type i = __finish.node - __start.node;
size_type new_map_size = (i + 1) * 2;
__map_pointer tmp;
#ifndef _RWSTD_NO_EXCEPTIONS
try {
tmp = ma.allocate(new_map_size,__map);
} catch(...) {
__value_alloc_type(__map_size).deallocate(p,__buffer_size());
throw;
}
#else
tmp = ma.allocate(new_map_size,__map);
#endif // _RWSTD_NO_EXCEPTIONS
copy(__start.node, __finish.node + 1, tmp + new_map_size / 4 + 1);
ma.deallocate(__map,__map_size.data());
__map = tmp;
__map[new_map_size / 4] = p;
__start = iterator(p + __buffer_size(), __map + new_map_size / 4);
__finish = iterator(__finish.current, __map + new_map_size / 4 + i + 1);
__map_size = new_map_size;
}
else
{
*--__start.node = p;
__start = iterator(p + __buffer_size(), __start.node);
}
}
else
{
#ifndef _RWSTD_NO_EXCEPTIONS
try {
__map = __map_alloc_type(__map_size).allocate(__buffer_size(),__map);
} catch(...) {
__value_alloc_type(__map_size).deallocate(p,__buffer_size());
throw;
}
#else
__map = __map_alloc_type(__map_size).allocate(__buffer_size(),__map);
#endif // _RWSTD_NO_EXCEPTIONS
__map_size = __buffer_size();
__map[__map_size.data() / 2] = p;
__start = iterator(p + __buffer_size() / 2 + 1, __map + __map_size.data() / 2);
__finish = __start;
}
}
template <class T, class Allocator>
void deque<T,Allocator>::__allocate_at_end ()
{
pointer p = __value_alloc_type(__map_size).allocate(__buffer_size(),__start.current);
if (!empty())
{
if (__finish.node == __map + __map_size.data() - 1)
{
__map_alloc_type ma(__map_size);
difference_type i = __finish.node - __start.node;
size_type new_map_size = (i + 1) * 2;
__map_pointer tmp;
#ifndef _RWSTD_NO_EXCEPTIONS
try {
tmp = ma.allocate(new_map_size,__map);
} catch(...) {
__value_alloc_type(__map_size).deallocate(p,__buffer_size());
throw;
}
#else
tmp = ma.allocate(new_map_size,__map);
#endif // _RWSTD_NO_EXCEPTIONS
copy(__start.node, __finish.node + 1, tmp + new_map_size / 4);
ma.deallocate(__map,__map_size.data());
__map = tmp;
__map[new_map_size / 4 + i + 1] = p;
__start = iterator(__start.current, __map + new_map_size / 4);
__finish = iterator(p, __map + new_map_size / 4 + i + 1);
__map_size = new_map_size;
}
else
{
*++__finish.node = p;
__finish = iterator(p, __finish.node);
}
}
else
{
__map_size = __buffer_size();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
__map = __map_alloc_type(__map_size).allocate(__map_size.data(),__map);
} catch(...) {
__value_alloc_type(__map_size).deallocate(p,__buffer_size());
throw;
}
#else
__map = __map_alloc_type(__map_size).allocate(__map_size.data(),__map);
#endif // _RWSTD_NO_EXCEPTIONS
__map[__map_size.data() / 2] = p;
__start = iterator(p + __buffer_size() / 2, __map + __map_size.data() / 2);
__finish = __start;
}
}
template <class T, class Allocator>
void deque<T,Allocator>::__deallocate_at_begin ()
{
__value_alloc_type(__map_size).deallocate(*__start.node++,__buffer_size());
if (empty())
{
__start = iterator();
__finish = __start;
__map_alloc_type(__map_size).deallocate(__map,__map_size.data());
}
else
__start = iterator(*__start.node, __start.node);
}
template <class T, class Allocator>
void deque<T,Allocator>::__deallocate_at_end ()
{
__value_alloc_type(__map_size).deallocate(*__finish.node--,__buffer_size());
if (empty())
{
__start = iterator();
__finish = __start;
__map_alloc_type(__map_size).deallocate(__map,__map_size.data());
}
else
__finish = iterator(*__finish.node + __buffer_size(), __finish.node);
}
template <class T, class Allocator>
void deque<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>
void deque<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>
_TYPENAME deque<T,Allocator>::iterator
deque<T,Allocator>::insert (iterator position, const T& x)
{
if (position == begin())
{
push_front(x); return begin();
}
else if (position == end())
{
push_back(x); return end() - 1;
}
else
{
difference_type index = position - begin();
if ((size_type)index < __length/2)
{
push_front(*begin());
copy(begin() + 2, begin() + index + 1, begin() + 1);
}
else
{
push_back(*(end() - 1));
copy_backward(begin() + index, end() - 2, end() - 1);
}
*(begin() + index) = x;
return begin() + index;
}
}
template <class T, class Allocator>
void deque<T,Allocator>::__insert_aux(iterator position,
size_type n, const T& x)
{
difference_type index = position - begin();
difference_type remainder = __length - index;
if (remainder > index)
{
if (n > (size_type)index)
{
difference_type m = n - index;
while (m-- > 0) push_front(x);
difference_type i = index;
while (i--) push_front(*(begin() + n - 1));
fill(begin() + n, begin() + n + index, x);
}
else
{
difference_type i = n;
while (i--) push_front(*(begin() + n - 1));
copy(begin() + n + n, begin() + n + index, begin() + n);
fill(begin() + index, begin() + n + index, x);
}
}
else
{
difference_type orig_len = index + remainder;
if (n > (size_type)remainder)
{
difference_type m = n - remainder;
while (m-- > 0) push_back(x);
difference_type i = 0;
while (i < remainder) push_back(*(begin() + index + i++));
fill(begin() + index, begin() + orig_len, x);
}
else
{
difference_type i = 0;
while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
copy_backward(begin() + index, begin() + orig_len - n,
begin() + orig_len);
fill(begin() + index, begin() + index + n, x);
}
}
}
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template <class T, class Allocator>
template <class InputIterator>
void deque<T,Allocator>::__insert_aux2 (iterator position,
InputIterator first, InputIterator last)
{
difference_type index = position - begin();
difference_type remainder = __length - index;
size_type n;
__initialize(n, size_type(0));
distance(first, last, n);
if (remainder > (size_type)index)
{
if (n > (size_type)index)
{
InputIterator m = last - index;
while (m != first) push_front(*--m);
difference_type i = index;
while (i--) push_front(*(begin() + n - 1));
copy(last - index, last, begin() + n);
}
else
{
difference_type i = n;
while (i--) push_front(*(begin() + n - 1));
copy(begin() + n + n, begin() + n + index, begin() + n);
copy(first, last, begin() + index);
}
}
else
{
difference_type orig_len = index + remainder;
if (n > (size_type)remainder)
{
InputIterator m = first + remainder;
while (m != last) push_back(*m++);
difference_type i = 0;
while (i < remainder) push_back(*(begin() + index + i++));
copy(first, first + remainder, begin() + index);
}
else
{
difference_type i = 0;
while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
copy_backward(begin() + index, begin() + orig_len - n,
begin() + orig_len);
copy(first, last, begin() + index);
}
}
}
#else
template<class T, class Allocator>
void deque<T,Allocator>::insert (iterator position,
const_iterator first,
const_iterator last)
{
difference_type index = position - begin();
difference_type remainder = __length - index;
size_type n;
__initialize(n, size_type(0));
distance(first, last, n);
if (remainder > index)
{
if (n > (size_type)index)
{
const_iterator m = last - index;
while (m != first) push_front(*--m);
difference_type i = index;
while (i--) push_front(*(begin() + n - 1));
copy(last - index, last, begin() + n);
}
else
{
difference_type i = n;
while (i--) push_front(*(begin() + n - 1));
copy(begin() + n + n, begin() + n + index, begin() + n);
copy(first, last, begin() + index);
}
}
else
{
difference_type orig_len = index + remainder;
if (n > (size_type)remainder)
{
const_iterator m = first + remainder;
while (m != last) push_back(*m++);
difference_type i = 0;
while (i < remainder) push_back(*(begin() + index + i++));
copy(first, first + remainder, begin() + index);
}
else
{
difference_type i = 0;
while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
copy_backward(begin() + index, begin() + orig_len - n,
begin() + orig_len);
copy(first, last, begin() + index);
}
}
}
template<class T, class Allocator>
void deque<T,Allocator>::insert (iterator position,
const T* first, const T* last)
{
difference_type index = position - begin();
difference_type remainder = __length - index;
size_type n;
__initialize(n, size_type(0));
distance(first, last, n);
if (remainder > index)
{
if (n > (size_type)index)
{
const T* m = last - index;
while (m != first) push_front(*--m);
difference_type i = index;
while (i--) push_front(*(begin() + n - 1));
copy(last - index, last, begin() + n);
}
else
{
difference_type i = n;
while (i--) push_front(*(begin() + n - 1));
copy(begin() + n + n, begin() + n + index, begin() + n);
copy(first, last, begin() + index);
}
}
else
{
difference_type orig_len = index + remainder;
if (n > (size_type)remainder)
{
const T* m = first + remainder;
while (m != last) push_back(*m++);
difference_type i = 0;
while (i < remainder) push_back(*(begin() + index + i++));
copy(first, first + remainder, begin() + index);
}
else
{
difference_type i = 0;
while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
copy_backward(begin() + index, begin() + orig_len - n,
begin() + orig_len);
copy(first, last, begin() + index);
}
}
}
#endif /*_RWSTD_NO_MEMBER_TEMPLATES*/
template <class T, class Allocator>
_TYPENAME deque<T,Allocator>::iterator
deque<T,Allocator>::erase (iterator position)
{
if (end() - position > position - begin())
{
copy_backward(begin(), position, position + 1);
pop_front();
return position + 1;
}
else
{
copy(position + 1, end(), position);
pop_back();
return position;
}
}
template <class T, class Allocator>
_TYPENAME deque<T,Allocator>::iterator
deque<T,Allocator>::erase (iterator first, iterator last)
{
difference_type n = last - first;
if (end() - last > first - begin())
{
copy_backward(begin(), first, last);
while(n-- > 0) pop_front();
return last;
}
else
{
copy(last, end(), first);
while(n-- > 0) pop_back();
return first;
}
}
#ifndef _RWSTD_NO_NAMESPACE
}
#endif
#pragma option pop
#endif /* __DEQUE_CC */