360 lines
10 KiB
C++
360 lines
10 KiB
C++
|
#ifndef __LIST_CC
|
|||
|
#define __LIST_CC
|
|||
|
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
|
|||
|
|
|||
|
/***************************************************************************
|
|||
|
*
|
|||
|
* list.cc - Non-nline list definitions for the Standard Library
|
|||
|
*
|
|||
|
***************************************************************************
|
|||
|
*
|
|||
|
* 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>
|
|||
|
#include <limits>
|
|||
|
|
|||
|
#define _RWSTD_LIST_SORT_COUNTERS 64
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
namespace std {
|
|||
|
#endif
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T,Allocator>::__deallocate_buffers ()
|
|||
|
{
|
|||
|
while (__buffer_list.data())
|
|||
|
{
|
|||
|
__buffer_pointer tmp = __buffer_list;
|
|||
|
__buffer_list = (__buffer_pointer)(__buffer_list.data()->next_buffer);
|
|||
|
__list_node_alloc_type(__buffer_list).deallocate(tmp->buffer,tmp->size);
|
|||
|
__buffer_alloc_type(__buffer_list).deallocate(tmp,1);
|
|||
|
}
|
|||
|
__free_list = 0;
|
|||
|
__next_avail = 0;
|
|||
|
__last = 0;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// This requires that T have a default constructor.
|
|||
|
//
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<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())
|
|||
|
{
|
|||
|
iterator tmp = begin();
|
|||
|
advance(tmp, (difference_type) new_size);
|
|||
|
erase(tmp, end());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T,Allocator>::resize (size_type new_size, T value)
|
|||
|
{
|
|||
|
if (new_size > size())
|
|||
|
insert(end(), new_size - size(), value);
|
|||
|
else if (new_size < size())
|
|||
|
{
|
|||
|
iterator tmp = begin();
|
|||
|
advance(tmp, (difference_type) new_size);
|
|||
|
erase(tmp, end());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
template <class T, class Allocator>
|
|||
|
template<class InputIterator>
|
|||
|
void list<T,Allocator>::__insert_aux2 (iterator position, InputIterator first,
|
|||
|
InputIterator locallast)
|
|||
|
{
|
|||
|
while (first != locallast) insert(position, *first++);
|
|||
|
}
|
|||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
|
|||
|
#ifdef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::insert (iterator position,
|
|||
|
const_iterator first,
|
|||
|
const_iterator locallast)
|
|||
|
{
|
|||
|
while (first != locallast) insert(position, *first++);
|
|||
|
}
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::insert (iterator position,
|
|||
|
const T* first, const T* locallast)
|
|||
|
{
|
|||
|
while (first != locallast) insert(position, *first++);
|
|||
|
}
|
|||
|
#endif // _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::__insert_aux (iterator position,
|
|||
|
size_type n, const T& x)
|
|||
|
{
|
|||
|
while (n--) insert(position, x);
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
_TYPENAME list<T, Allocator>::iterator
|
|||
|
list<T, Allocator>::erase (iterator first, iterator locallast)
|
|||
|
{
|
|||
|
iterator tmp = end();
|
|||
|
while (first != locallast)
|
|||
|
{
|
|||
|
tmp = erase(first++);
|
|||
|
}
|
|||
|
return tmp;
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
list<T, Allocator>& list<T, Allocator>::operator= (const list<T, Allocator>& x)
|
|||
|
{
|
|||
|
if (this != &x)
|
|||
|
{
|
|||
|
iterator first1 = begin();
|
|||
|
iterator last1 = end();
|
|||
|
const_iterator first2 = x.begin();
|
|||
|
const_iterator last2 = x.end();
|
|||
|
while (first1 != last1 && first2 != last2) *first1++ = *first2++;
|
|||
|
if (first2 == last2)
|
|||
|
erase(first1, last1);
|
|||
|
else
|
|||
|
insert(last1, first2, last2);
|
|||
|
}
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::remove (const T& value)
|
|||
|
{
|
|||
|
iterator first = begin();
|
|||
|
iterator last = end();
|
|||
|
while (first != last)
|
|||
|
{
|
|||
|
iterator next = first;
|
|||
|
++next;
|
|||
|
if (*first == value) erase(first);
|
|||
|
first = next;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::unique ()
|
|||
|
{
|
|||
|
iterator first = begin();
|
|||
|
iterator last = end();
|
|||
|
if (first == last) return;
|
|||
|
iterator next = first;
|
|||
|
while (++next != last)
|
|||
|
{
|
|||
|
if (*first == *next)
|
|||
|
erase(next);
|
|||
|
else
|
|||
|
first = next;
|
|||
|
next = first;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::merge (list<T, Allocator>& x)
|
|||
|
{
|
|||
|
|
|||
|
iterator first1 = begin();
|
|||
|
iterator last1 = end();
|
|||
|
iterator first2 = x.begin();
|
|||
|
iterator last2 = x.end();
|
|||
|
while (first1 != last1 && first2 != last2)
|
|||
|
{
|
|||
|
if (*first2 < *first1)
|
|||
|
{
|
|||
|
iterator next = first2;
|
|||
|
__transfer(first1, first2, ++next, x);
|
|||
|
first2 = next;
|
|||
|
}
|
|||
|
else
|
|||
|
first1++;
|
|||
|
}
|
|||
|
if (first2 != last2)
|
|||
|
__transfer(last1, first2, last2, x);
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::reverse ()
|
|||
|
{
|
|||
|
if (size() < 2) return;
|
|||
|
for (iterator first = ++begin(); first != end();)
|
|||
|
{
|
|||
|
iterator old = first++;
|
|||
|
__transfer(begin(), old, first, *this);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// sorts list by moving nodes within list. This preserves iterators pointing to
|
|||
|
// elements of the list.
|
|||
|
template <class T, class Allocator>
|
|||
|
void list<T, Allocator>::sort ()
|
|||
|
{
|
|||
|
for (unsigned int n = 1; n < size(); n *= 2) {
|
|||
|
iterator i1 = begin(), i2 = begin(), i3 = begin();
|
|||
|
__advance(i2, (difference_type) n, end());
|
|||
|
__advance(i3, (difference_type) (2*n), end());
|
|||
|
for (unsigned int m = 0; m < (size()+(2*n))/(n*2); m++) {
|
|||
|
if (i1 != end() && i2 != end()) {
|
|||
|
__adjacent_merge(i1, i2, i3);
|
|||
|
i1 = i3;
|
|||
|
i2 = i3;
|
|||
|
__advance(i2, (difference_type) n, end());
|
|||
|
__advance(i3, (difference_type) 2*n, end());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
|
|||
|
template<class T, class Allocator>
|
|||
|
template<class Predicate> void list<T, Allocator>::remove_if (Predicate pred)
|
|||
|
{
|
|||
|
iterator first = begin();
|
|||
|
iterator last = end();
|
|||
|
while (first != last)
|
|||
|
{
|
|||
|
iterator next = first;
|
|||
|
++next;
|
|||
|
if (pred(*first)) erase(first);
|
|||
|
first = next;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template<class T, class Allocator>
|
|||
|
template<class BinaryPredicate> void list<T, Allocator>::unique (BinaryPredicate pred)
|
|||
|
{
|
|||
|
iterator first = begin();
|
|||
|
iterator last = end();
|
|||
|
if (first == last) return;
|
|||
|
iterator next = first;
|
|||
|
while (++next != last)
|
|||
|
{
|
|||
|
if (pred(*first, *next))
|
|||
|
erase(next);
|
|||
|
else
|
|||
|
first = next;
|
|||
|
next = first;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template<class T, class Allocator>
|
|||
|
template<class Compare> void list<T, Allocator>::merge (list<T, Allocator>& x, Compare comp)
|
|||
|
{
|
|||
|
iterator first1 = begin();
|
|||
|
iterator last1 = end();
|
|||
|
iterator first2 = x.begin();
|
|||
|
iterator last2 = x.end();
|
|||
|
while (first1 != last1 && first2 != last2)
|
|||
|
{
|
|||
|
if (comp(*first2, *first1))
|
|||
|
{
|
|||
|
iterator next = first2;
|
|||
|
__transfer(first1, first2, ++next, x);
|
|||
|
first2 = next;
|
|||
|
}
|
|||
|
else
|
|||
|
first1++;
|
|||
|
}
|
|||
|
if (first2 != last2)
|
|||
|
__transfer(last1, first2, last2, x);
|
|||
|
}
|
|||
|
|
|||
|
template <class T, class Allocator>
|
|||
|
template<class Compare> void list<T, Allocator>::sort (Compare comp)
|
|||
|
{
|
|||
|
for (int n = 1; n < size(); n *= 2) {
|
|||
|
iterator i1 = begin(), i2 = begin(), i3 = begin();
|
|||
|
__advance(i2, (difference_type) n, end());
|
|||
|
__advance(i3, (difference_type) (2*n), end());
|
|||
|
for (int m = 0; m < (size()+(2*n))/(n*2); m++) {
|
|||
|
if (i1 != end() && i2 != end()) {
|
|||
|
__adjacent_merge(i1, i2, i3, comp);
|
|||
|
i1 = i3;
|
|||
|
i2 = i3;
|
|||
|
__advance(i2, (difference_type) n, end());
|
|||
|
__advance(i3, (difference_type) 2*n, end());
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
template<class T, class Allocator>
|
|||
|
template<class Compare> void list<T, Allocator>::sort (Compare comp)
|
|||
|
{
|
|||
|
if (size() < 2) return;
|
|||
|
|
|||
|
list<T, Allocator> carry(get_allocator());
|
|||
|
list<T, Allocator> counter[ _RWSTD_LIST_SORT_COUNTERS];
|
|||
|
for (int i = 0; i < _RWSTD_LIST_SORT_COUNTERS; i++)
|
|||
|
counter[i].__set_allocator(get_allocator());
|
|||
|
int fill = 0;
|
|||
|
while (!empty())
|
|||
|
{
|
|||
|
carry.splice(carry.begin(), *this, begin());
|
|||
|
int i = 0;
|
|||
|
while (i < fill && !counter[i].empty())
|
|||
|
{
|
|||
|
counter[i].merge(carry, comp);
|
|||
|
carry.swap(counter[i++]);
|
|||
|
}
|
|||
|
carry.swap(counter[i]);
|
|||
|
if (i == fill) ++fill;
|
|||
|
}
|
|||
|
while (fill--) merge(counter[fill], comp);
|
|||
|
}
|
|||
|
*/
|
|||
|
#endif /*_RWSTD_NO_MEMBER_TEMPLATES*/
|
|||
|
|
|||
|
#undef _RWSTD_LIST_SORT_COUNTERS
|
|||
|
|
|||
|
#ifndef _RWSTD_NO_NAMESPACE
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#pragma option pop
|
|||
|
#endif /* __LIST_CC */
|