This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/Borland/BCC55/Include/list.h

852 lines
25 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __LIST_H
#define __LIST_H
#pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
// -*- C++ -*-
#ifndef __STD_LIST__
#define __STD_LIST__
/***************************************************************************
*
* list - list declarations 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 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 <algorithm>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <rw/rwdispatch.h>
#ifndef list
#define list list
#endif
#ifndef _RWSTD_NO_NAMESPACE
namespace std {
#endif
//
// Note that _RWSTD_COMPLEX_DEFAULT(x)
// will expand to: ' = x', or nothing,
// depending on your compiler's capabilities and/or
// flag settings (see stdcomp.h).
//
template <class T, class Allocator _RWSTD_COMPLEX_DEFAULT(allocator<T>) >
class list
{
protected:
struct __list_node;
struct __list_node_buffer;
friend struct __list_node;
friend struct __list_node_buffer;
#ifdef _RWSTD_ALLOCATOR
typedef _TYPENAME Allocator::template rebind<__list_node>::other __list_node_alloc_type;
typedef _TYPENAME Allocator::template rebind<T>::other __value_alloc_type;
typedef _TYPENAME Allocator::template rebind<__list_node_buffer>::other __buffer_alloc_type;
#else
typedef allocator_interface<Allocator,__list_node> __list_node_alloc_type;
typedef allocator_interface<Allocator,T> __value_alloc_type;
typedef allocator_interface<Allocator,__list_node_buffer> __buffer_alloc_type;
#endif // _RWSTD_ALLOCATOR
public:
//
// types
//
typedef _TYPENAME __value_alloc_type::reference reference;
typedef _TYPENAME __value_alloc_type::const_reference const_reference;
typedef _TYPENAME __value_alloc_type::size_type size_type;
typedef _TYPENAME __value_alloc_type::difference_type difference_type;
typedef T value_type;
typedef Allocator allocator_type;
typedef _TYPENAME __value_alloc_type::pointer pointer;
typedef _TYPENAME __value_alloc_type::const_pointer const_pointer;
protected:
typedef _TYPENAME __list_node_alloc_type::pointer __link_type;
typedef _TYPENAME __buffer_alloc_type::pointer __buffer_pointer;
struct __list_node
{
__link_type next;
__link_type prev;
T data;
};
struct __list_node_buffer
{
__buffer_pointer next_buffer;
size_type size;
__link_type buffer;
};
size_type __buffer_size;
__RWSTD::__rw_basis<__buffer_pointer,allocator_type> __buffer_list;
__link_type __free_list;
__link_type __next_avail;
__link_type __last;
__link_type __node;
size_type __length;
void __add_new_buffer (size_type n)
{
__buffer_pointer tmp =
__buffer_alloc_type(__buffer_list).allocate(
_RWSTD_STATIC_CAST(size_type,1),__buffer_list.data());
#ifndef _RWSTD_NO_EXCEPTIONS
try {
tmp->buffer = __list_node_alloc_type(__buffer_list).allocate(n,__last);
} catch(...) {
__buffer_alloc_type(__buffer_list).deallocate(tmp,1);
throw;
}
#else
tmp->buffer = __list_node_alloc_type(__buffer_list).allocate(n,__last);
#endif // _RWSTD_NO_EXCEPTIONS
tmp->next_buffer = __buffer_list;
tmp->size = n;
__buffer_list = tmp;
__next_avail = __buffer_list.data()->buffer;
__last = __next_avail + n;
}
void __deallocate_buffers ();
__link_type __get_node (size_type n)
{
__link_type tmp = __free_list;
return __free_list ? (__free_list = (__link_type)(__free_list->next), tmp)
: (__next_avail == __last ? (__add_new_buffer(n), __next_avail++)
: __next_avail++);
}
void __put_node (__link_type p) { p->next = __free_list; __free_list = p; }
void __init(size_type n = 0)
{
__buffer_size = max((size_type)1,
__RWSTD::__rw_allocation_size((value_type*)0,
(size_type)0,
(size_type)0));
__node = __get_node(n == 0 ? __buffer_size : n + 1);
(*__node).next = __node;
(*__node).prev = __node;
}
void __init(size_type n, value_type value)
{
__init(n);
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), n, value);
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), n, value);
#endif
}
typedef _RW_STD::iterator<bidirectional_iterator_tag, value_type,
difference_type, pointer,reference> __it;
typedef _RW_STD::iterator<bidirectional_iterator_tag, value_type,
difference_type, const_pointer, const_reference> __cit;
public:
class iterator;
class const_iterator;
friend class iterator;
friend class const_iterator;
class iterator : public __it
{
friend class list<T,Allocator>;
friend class const_iterator;
protected:
__link_type node;
iterator (__link_type x) : node(x) {}
public:
iterator () {}
bool operator== (const iterator& x) const { return node == x.node; }
bool operator!= (const iterator& x) const { return !(*this == x); }
reference operator* () const { return (*node).data; }
#ifndef _RWSTD_NO_NONCLASS_ARROW_RETURN
pointer operator-> () const { return &(node->data); }
#endif
iterator& operator++ ()
{
node = (__link_type)((*node).next); return *this;
}
iterator operator++ (int)
{
iterator tmp = *this; ++*this; return tmp;
}
iterator& operator-- ()
{
node = (__link_type)((*node).prev); return *this;
}
iterator operator-- (int)
{
iterator tmp = *this; --*this; return tmp;
}
}; // End of definition of iterator class.
class const_iterator : public __cit
{
friend class list<T,Allocator>;
protected:
__link_type node;
const_iterator (__link_type x) : node(x) {}
public:
const_iterator () {}
#if !defined(_MSC_VER) || defined(__BORLANDC__)
const_iterator (const _TYPENAME list<T,Allocator>::iterator& x) : node(x.node) {}
#else
const_iterator (const iterator& x) : node(x.node) {}
#endif
bool operator== (const const_iterator& x) const {return node==x.node;}
bool operator!= (const const_iterator x) const { return !(*this == x); }
const_reference operator* () const { return (*node).data; }
#ifndef _RWSTD_NO_NONCLASS_ARROW_RETURN
const_pointer operator-> () const { return &(node->data); }
#endif
const_iterator& operator++ ()
{
node = (__link_type)((*node).next); return *this;
}
const_iterator operator++ (int)
{
const_iterator tmp = *this; ++*this; return tmp;
}
const_iterator& operator-- ()
{
node = (__link_type)((*node).prev); return *this;
}
const_iterator operator-- (int)
{
const_iterator tmp = *this;
--*this;
return tmp;
}
}; // End of definition of const_iterator class.
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
typedef _RW_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef _RW_STD::reverse_iterator<iterator> reverse_iterator;
#else
typedef __reverse_bi_iterator<const_iterator,
bidirectional_iterator_tag, value_type,
const_reference, const_pointer, difference_type>
const_reverse_iterator;
typedef __reverse_bi_iterator<iterator,
bidirectional_iterator_tag, value_type,
reference, pointer, difference_type>
reverse_iterator;
#endif
//
// construct/copy/destroy
//
list (const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
: __length(0), __buffer_list(0,alloc),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init(1);
}
#ifdef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
list (void)
: __length(0), __buffer_list(0,Allocator()),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init(1);
}
list (size_type n, const T& value)
: __length(0), __buffer_list(0,Allocator()),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init(n,value);
}
#endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
_EXPLICIT list (size_type n)
: __length(0), __buffer_list(0,Allocator()),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
T value = T();
__init(n,value);
}
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template<class InputIterator>
void __init_aux (InputIterator first, InputIterator locallast, _RW_is_not_integer)
{
__init();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), first, locallast);
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), first, locallast);
#endif
}
template<class InputIterator>
void __init_aux (InputIterator first, InputIterator last, _RW_is_integer)
{ __init(first, last); }
template<class InputIterator>
list (InputIterator first, InputIterator locallast,
const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
: __length(0), __buffer_list(0,alloc),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
typedef _TYPENAME _RWdispatch<InputIterator>::_RWtype _RWtype;
__init_aux(first, locallast, _RWtype());
}
list (size_type n, const T& value,
const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
: __length(0), __buffer_list(0,alloc),
__free_list(0), __next_avail(0), __last(0), __node(0)
{ __init(n, value); }
#else
//
// Build a list of size n with each element set to a copy of value.
//
list (size_type n, const T& value,
const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
: __length(0), __buffer_list(0,alloc),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init(n, value);
}
list (const_iterator first, const_iterator locallast,
const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
: __length(0), __buffer_list(0,alloc),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), first, locallast);
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), first, locallast);
#endif
}
list (const T* first, const T* locallast,
const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
: __length(0), __buffer_list(0,alloc),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), first, locallast);
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), first, locallast);
#endif
}
#ifdef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
list (const_iterator first, const_iterator locallast)
: __length(0), __buffer_list(0,Allocator()),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), first, locallast);
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), first, locallast);
#endif
}
list (const T* first, const T* locallast)
: __length(0), __buffer_list(0,Allocator()),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), first, locallast);
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), first, locallast);
#endif
}
#endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
#endif // _RWSTD_NO_MEMBER_TEMPLATES
list (const list<T,Allocator>& x) : __length(0), __buffer_list(0,x.get_allocator()),
__free_list(0), __next_avail(0), __last(0), __node(0)
{
__init();
#ifndef _RWSTD_NO_EXCEPTIONS
try {
insert(begin(), x.begin(), x.end());
} catch(...) {
__deallocate_buffers();
throw;
}
#else
insert(begin(), x.begin(), x.end());
#endif
}
~list ()
{
if (__node)
{
erase(begin(), end());
__put_node(__node);
__deallocate_buffers();
}
}
list<T,Allocator>& operator= (const list<T,Allocator>& x);
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template<class InputIterator>
void assign (InputIterator first, InputIterator last)
{
erase(begin(), end());
typedef _TYPENAME _RWdispatch<InputIterator>::_RWtype _RWtype;
__insert_aux(begin(), first, last, _RWtype());
}
void assign (size_type n, const T& t)
{
erase(begin(), end()); insert(begin(), n, t);
}
#else
void assign (const_iterator first, const_iterator last)
{ erase(begin(), end()); insert(begin(), first, last); }
void assign (const T* first, const T* last)
{ erase(begin(), end()); insert(begin(), first, last); }
//
// Assign n copies of t to this list.
//
void assign (size_type n, const T& t)
{ erase(begin(), end()); insert(begin(), n, t); }
#endif // _RWSTD_NO_MEMBER_TEMPLATES
allocator_type get_allocator() const
{
return (allocator_type)__buffer_list;
}
//
// Iterators.
//
iterator begin () { return _RWSTD_STATIC_CAST(__link_type,((*__node).next)); }
const_iterator begin () const { return _RWSTD_STATIC_CAST(__link_type,((*__node).next)); }
iterator end () { return __node; }
const_iterator end () const { return __node; }
reverse_iterator rbegin ()
{
reverse_iterator tmp(end()); return tmp;
}
const_reverse_iterator rbegin () const
{
const_reverse_iterator tmp(end()); return tmp;
}
reverse_iterator rend ()
{
reverse_iterator tmp(begin()); return tmp;
}
const_reverse_iterator rend () const
{
const_reverse_iterator tmp(begin()); return tmp;
}
//
// Capacity.
//
bool empty () const { return __length == 0; }
size_type size () const { return __length; }
size_type max_size () const
{ return __list_node_alloc_type(__buffer_list).max_size(); }
void resize (size_type new_size);
void resize (size_type new_size, T value);
//
// Element access.
//
reference front () { return *begin(); }
const_reference front () const { return *begin(); }
reference back () { return *(--end()); }
const_reference back () const { return *(--end()); }
//
// Modifiers.
//
//
void push_front (const T& x) { insert(begin(), x); }
void push_back (const T& x) { insert(end(), x); }
void pop_front () { erase(begin()); }
void pop_back () { iterator tmp = end(); erase(--tmp); }
//
// Insert x at position.
//
iterator insert (iterator position, const T& x)
{
__value_alloc_type va(__buffer_list);
__link_type tmp = __get_node(__buffer_size);
#ifndef _RWSTD_NO_EXCEPTIONS
try {
va.construct(va.address((*tmp).data),x);
} catch(...) {
__put_node(tmp);
throw;
}
#else
va.construct(va.address((*tmp).data),x);
#endif // _RWSTD_NO_EXCEPTIONS
(*tmp).next = position.node;
(*tmp).prev = (*position.node).prev;
(*(__link_type((*position.node).prev))).next = tmp;
(*position.node).prev = tmp;
++__length;
return tmp;
}
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template<class InputIterator>
void insert (iterator position, InputIterator first,
InputIterator last)
{
typedef _TYPENAME _RWdispatch<InputIterator>::_RWtype _RWtype;
__insert_aux(position, first, last, _RWtype());
}
void insert (iterator position, size_type n, const T& value)
{ __insert_aux(position,n,value); }
#else
void insert (iterator position, size_type n, const T& x)
{ __insert_aux(position,n,x); }
void insert (iterator position, const T* first, const T* last);
void insert (iterator position, const_iterator first, const_iterator last);
#endif // _RWSTD_NO_MEMBER_TEMPLATES
iterator erase (iterator position)
{
if (position == end())
return end();
iterator tmp = (iterator)(__link_type((*position.node).next));
(*(__link_type((*position.node).prev))).next = (*position.node).next;
(*(__link_type((*position.node).next))).prev = (*position.node).prev;
--__length;
__value_alloc_type va(__buffer_list);
va.destroy(va.address((*position.node).data));
__put_node(position.node);
return tmp;
}
iterator erase (iterator first, iterator last);
void swap (list<T,Allocator>& x)
{
if((allocator_type)__buffer_list==(allocator_type)x.__buffer_list)
{
#ifndef _RWSTD_NO_NAMESPACE
std::swap(__node, x.__node);
std::swap(__length, x.__length);
std::swap(__buffer_list,x.__buffer_list);
std::swap(__free_list,x.__free_list);
std::swap(__next_avail,x.__next_avail);
std::swap(__last,x.__last);
#else
::swap(__node, x.__node);
::swap(__length, x.__length);
::swap(__buffer_list,x.__buffer_list);
::swap(__free_list,x.__free_list);
::swap(__next_avail,x.__next_avail);
::swap(__last,x.__last);
#endif // _RWSTD_NO_NAMESPACE
}
else
{
list<T,Allocator> _x = *this;
*this=x;
x=_x;
}
}
void clear()
{
erase(begin(),end());
}
protected:
void __transfer (iterator position, iterator first,
iterator last, list<T,Allocator>& x)
{
if (this == &x)
{
(*(__link_type((*last.node).prev))).next = position.node;
(*(__link_type((*first.node).prev))).next = last.node;
(*(__link_type((*position.node).prev))).next = first.node;
__link_type tmp = __link_type((*position.node).prev);
(*position.node).prev = (*last.node).prev;
(*last.node).prev = (*first.node).prev;
(*first.node).prev = tmp;
}
else
{
insert(position,first,last);
x.erase(first,last);
}
}
void __advance(iterator &i, difference_type n, iterator end)
{
for (int j = 0; j < (int) n; j++) {
if (i != end) ++i;
}
}
// uses transfer_node to merge in list by transfering nodes to list
void __adjacent_merge (iterator first1, iterator last1,
iterator last2)
{
iterator first2 = last1;
int n = 0;
distance(first1, last1, n);
int count = 0;
while (count <= n && first2 != last2)
{
if (*first2 < *first1)
{
iterator next = first2;
__transfer(first1, first2, ++next, *this);
first2 = next;
}
else {
first1++;
count++;
}
}
}
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
// uses transfer_node to merge in list by transfering nodes to list
template<class Compare>
void __adjacent_merge (iterator first1, iterator last1,
iterator last2, Compare comp)
{
iterator first2 = last1;
int n = 0;
distance(first1, last1, n);
int count = 0;
while (count <= n && first2 != last2)
{
if (comp(*first2,*first1))
{
iterator next = first2;
__transfer(first1, first2, ++next, *this);
first2 = next;
}
else {
first1++;
count++;
}
}
}
#endif
// used by the sort() member function
void __set_allocator(allocator_type a)
{
__buffer_list = a;
}
void __insert_aux (iterator position, size_type n, const T& x);
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template<class InputIterator>
void __insert_aux (iterator position, InputIterator first, InputIterator last, _RW_is_not_integer)
{ __insert_aux2 (position, first, last); }
template<class InputIterator>
void __insert_aux (iterator position, InputIterator first, InputIterator last, _RW_is_integer)
{ __insert_aux (position, (size_type)first, last); }
template<class InputIterator>
void __insert_aux2 (iterator position, InputIterator first, InputIterator last);
#endif
public:
//
// list operations.
//
void splice (iterator position, list<T,Allocator>& x)
{
if (!x.empty())
__transfer(position, x.begin(), x.end(), x);
}
void splice (iterator position, list<T,Allocator>& x, iterator i)
{
iterator k = i;
if (k != position && ++k != position)
{
iterator j = i;
__transfer(position, i, ++j, x);
}
}
void splice (iterator position, list<T,Allocator>& x, iterator first, iterator last)
{
if (first != last)
{
difference_type n;
__initialize(n, difference_type(0));
distance(first, last, n);
__transfer(position, first, last, x);
}
}
void remove (const T& value);
void unique ();
void merge (list<T,Allocator>& x);
void reverse ();
void sort ();
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template<class Predicate> void remove_if (Predicate pred);
template<class BinaryPredicate> void unique (BinaryPredicate pred);
template<class Compare> void merge (list<T,Allocator>& x, Compare comp);
template<class Compare> void sort (Compare comp);
#endif // _RWSTD_NO_MEMBER_TEMPLATES
#ifndef _RWSTD_STRICT_ANSI
// Non-standard function for setting buffer allocation size
size_type allocation_size() { return __buffer_size; }
size_type allocation_size(size_type new_size)
{
size_type tmp = __buffer_size;
__buffer_size = max((size_type)1,new_size);
return tmp;
}
#endif // _RWSTD_STRICT_ANSI
};
template <class T, class Allocator>
inline bool operator== (const list<T,Allocator>& x, const list<T,Allocator>& y)
{
return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
}
template <class T, class Allocator>
inline bool operator< (const list<T,Allocator>& x, const list<T,Allocator>& y)
{
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
#if !defined(_RWSTD_NO_NAMESPACE) || !defined(_RWSTD_NO_PART_SPEC_OVERLOAD)
template <class T, class Allocator>
inline bool operator!= (const list<T,Allocator>& x, const list<T,Allocator>& y)
{
return !(x == y);
}
template <class T, class Allocator>
inline bool operator> (const list<T,Allocator>& x, const list<T,Allocator>& y)
{
return y < x;
}
template <class T, class Allocator>
inline bool operator>= (const list<T,Allocator>& x, const list<T,Allocator>& y)
{
return !(x < y);
}
template <class T, class Allocator>
inline bool operator<= (const list<T,Allocator>& x, const list<T,Allocator>& y)
{
return !(y < x);
}
template <class T, class Allocator>
inline void swap(list<T,Allocator>& a, list<T,Allocator>& b)
{
a.swap(b);
}
#endif // !defined(_RWSTD_NO_NAMESPACE) || !defined(_RWSTD_NO_PART_SPEC_OVERLOAD)
#ifndef _RWSTD_NO_NAMESPACE
}
#endif
#ifdef _RWSTD_NO_TEMPLATE_REPOSITORY
#include <list.cc>
#endif
#undef list
#endif /*__STD_LIST__*/
#ifndef __USING_STD_NAMES__
using namespace std;
#endif
#pragma option pop
#endif /* __LIST_H */