SGI STL::list容器

文章描述了一个C++模板类`list`,用于管理动态数据结构,包含节点、内存分配、迭代器操作、插入、删除、合并、排序等功能,并保证了内存的正确释放。
摘要由CSDN通过智能技术生成

这几天有点忙,先放代码,之后再来改注释.

承诺: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;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值