这几天有点忙,先放代码,之后再来改注释.
承诺:list可以正常使用且无内存泄漏,只是写的功能比较少。
#pragma once
#include "alloc.h"
#include "construct.h"
template <typename T>
struct __list_node
{
typedef void* void_pointer;
void_pointer prev;
void_pointer next;
T data;
};
template <typename T, typename Alloc = alloc>
class list {
protected:
typedef __list_node<T> list_node;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
public:
typedef list_node* link_type;
typedef T* pointer;
typedef T& reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
protected:
template<typename Y = T, typename Ref = Y&, typename Ptr = Y* >
struct __list_iterator
{
typedef __list_iterator<Y, Y&, Y*> iterator;
typedef __list_iterator<Y, Ref, Ptr> self;
//typedef bidirectional_iterator_tag iterator_category;
typedef Y value_type;
typedef Ptr pointer;
typedef Ref reference;
link_type node;
__list_iterator(link_type x) :node(x) {}
__list_iterator() {}
__list_iterator(const iterator& x) :node(x.node) {}
bool operator==(const self& x)const { return node == x.node; }
bool operator!=(const self& x)const { return node != x.node; }
reference operator*() const { return (*node).data; }
pointer operator->() const { return &(operator*()); }
self& operator++() {
node = (link_type)((*node).next);
return *this;
}
self operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator--() {
node = (link_type)((*node).prev);
return *this;
}
self operator--(int) {
self tmp = *this;
--*this;
return tmp;
}
};
public:
typedef __list_iterator<T, T&, T*> iterator;
public:
iterator begin() { return (link_type)((*node).next); }
iterator end() { return node; }
bool empty() const { return node->next == node; }
size_type size() const;
reference& front() { return *begin(); }
reference& back() { return *(--end()); }
iterator insert(iterator position, const T& x);
void push_front(const T& x) { insert(begin(), x); }
void push_back(const T& x) { insert(end(), x); }
iterator erase(iterator position);
void pop_front() { erase(begin()); }
void pop_back() { iterator tmp = end(); erase(--tmp); }
void clear();
void splice(iterator position, list& x) {
if (!x.empty())
transfer(position, x.begin(), x.end());
}
void splice(iterator position, list&, iterator i) {
iterator j = i;
++j;
if (position == i || position == j)return;
transfer(position, i, j);
}
void splice(iterator position, list&, iterator first, iterator last) {
if (first != last)
transfer(position, first, last);
}
void merge(list<T, Alloc>&);
void sort();
void swap(list<T>&);
public:
list() { empty_initialize(); }
//list(const list&); //lazy-evaluation
//list& operator=(list& other) {
// if (this != &other) {
// ~list();
// //lazy-evaluation
// }
//}
//list(const list)
~list() {
clear();
destroy_node(node);
}
protected:
void swap_nonempty(int);
void transfer(iterator&, iterator&, iterator&);
void empty_initialize() {
node = get_node();
node->next = node;
node->prev = node;
}
link_type get_node() { return list_node_allocator::allocate(); }
void put_node(link_type p) { list_node_allocator::deallocate(p); }
link_type create_node(const T& x) {
link_type p = get_node();
construct(&p->data, x);
return p;
}
void destroy_node(link_type p) {
destroy(&p->data);
put_node(p);
}
protected:
link_type node;
};
template<typename T, typename Alloc>
void list<T, Alloc>::clear() {
link_type cur = (link_type)node->next, tmp;
while (cur!=node)
{
tmp = cur;
cur = (link_type)cur->next;
destroy_node(tmp);
}
node->prev = node;
node->next = node;
}
template<typename T, typename Alloc>
void list<T, Alloc>::merge(list<T, Alloc>& x)
{
iterator first1 = begin();
iterator last1 = end();
iterator first2 = x.begin();
iterator last2 = x.begin();
while (first1 != last1 && first2 != last2)
{
if (*first2 < *first1) {
iterator next = first2;
transfer(first1, first2, ++next);
first2 = next;
}
else
++first1;
}
if (first2 != last2) transfer(last1, first2, last2);
}
template<typename T, typename Alloc>
void list<T, Alloc>::sort()
{
if (node->next == node || link_type(node->next)->next == node)
return;
list<T, Alloc> carry;
list<T, Alloc> counter[64];
int fill = 0;
while (!empty())
{
carry.splice(carry.begin(), *this, begin());
int i = 0;
while (i < fill && !counter[i].empty())
{
counter[i].merge(carry);
carry.swap(counter[i++]);
}
carry.swap(counter[i]);
if (i == fill) ++fill;
}
for (int i = 1; i < fill; ++i)
counter[i].merge(counter[i - 1]);
this->swap(counter[fill - 1]);
}
template<typename T, typename Alloc>
inline void list<T, Alloc>::swap_nonempty(int i)
{
switch (i)
{
default:
break;
}
}
template<typename T, typename Alloc>
void list<T, Alloc>::swap(list<T>& rhs)
{
//switch? making?
if (node == rhs.node) return;
if (node == node->next && rhs.node != rhs.node->next) {
link_type tmp = node;
node = rhs.node;
rhs.node = tmp;
rhs.node->next = tmp;
rhs.node->prev = tmp;
}
else if (node != node->next && rhs.node == rhs.node->next) {
link_type tmp = rhs.node;
rhs.node = node;
node = tmp;
rhs.node->next = tmp;
rhs.node->prev = tmp;
}
else if (node == node->next && rhs.node != rhs.node->next) {
link_type tmp = node;
node = rhs.node;
rhs.node = tmp;
rhs.node->next = tmp;
rhs.node->prev = tmp;
}
}
template<typename T, typename Alloc>
void list<T, Alloc>::transfer(iterator& position, iterator& first, iterator& last)
{
if (position != last) {
(*(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;
}
}
template<typename T, typename Alloc>
typename list<T, Alloc>::iterator list<T, Alloc>::insert(iterator position, const T& x)
{
link_type tmp = create_node(x);
tmp->next = position.node;
tmp->prev = position.node->prev;
(link_type(position.node->prev))->next = tmp;
position.node->prev = tmp;
return tmp;
}
template<typename T, typename Alloc>
typename list<T, Alloc>::iterator list<T, Alloc>::erase(iterator position)
{
link_type next_node = link_type(position.node->next);
link_type prev_node = link_type(position.node->prev);
prev_node->next = next_node;
next_node->prev = prev_node;
destroy_node(position.node);
return iterator(next_node);
}
template<typename T, typename Alloc>
typename list<T, Alloc>::size_type list<T, Alloc>::size() const
{
size_type result = 0;
link_type beg = node;
while (beg->next != node)
{
++result;
beg = beg->next;
}
return result;
}