tinystl实现(第十四步:list实现)

39 篇文章 4 订阅
28 篇文章 36 订阅

经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
list.h

#pragma once
#ifndef _LIST_H_
#define _LIST_H_

#include "Allocator.h"
#include "Iterator.h"
#include "ReverseIterator.h"
#include "UninitializedFunctions.h"

#include <type_traits>

namespace mySTL {
	template<class T>
	class list;
	namespace Detail {
		//the class of node
		template<class T>
		struct node {
			T data;
			node *prev;
			node *next;
			list<T> *container;
			node(const T& d, node *p, node *n, list<T> *c) :
				data(d), prev(p), next(n), container(c) {}
			bool operator ==(const node& n) {
				return data == n.data && prev == n.prev && next == n.next && container == n.container;
			}
		};
		//the class of list iterator
		template<class T>
		struct listIterator :public iterator<bidirectional_iterator_tag, T> {
			template<class T>
			friend class list;
		public:
			typedef node<T>* nodePtr;
			nodePtr p;
		public:
			explicit listIterator(nodePtr ptr = nullptr) :p(ptr) {}

			listIterator& operator++();
			listIterator operator++(int);
			listIterator& operator --();
			listIterator operator --(int);
			T& operator *() { return p->data; }
			T* operator ->() { return &(operator*()); }

			template<class T>
			friend bool operator ==(const listIterator<T>& lhs, const listIterator<T>& rhs);
			template<class T>
			friend bool operator !=(const listIterator<T>& lhs, const listIterator<T>& rhs);
		};
	}//end of namespace


	//the class of list
	template<class T>
	class list {
		template<class T>
		friend struct listIterator;
	private:
		typedef allocator<Detail::node<T>> nodeAllocator;
		typedef Detail::node<T> *nodePtr;
	public:
		typedef T value_type;
		typedef Detail::listIterator<T> iterator;
		typedef Detail::listIterator<const T> const_iterator;
		typedef reverse_iterator_t<iterator> reverse_iterator;
		typedef T& reference;
		typedef size_t size_type;
	private:
		iterator head;
		iterator tail;
	public:
		list();
		explicit list(size_type n, const value_type& val = value_type());
		template <class InputIterator>
		list(InputIterator first, InputIterator last);
		list(const list& l);
		list& operator = (const list& l);
		~list();

		bool empty()const { return head == tail; }
		size_type size()const;
		reference front() { return (head.p->data); }
		reference back() { return (tail.p->prev->data); }

		void push_front(const value_type& val);
		void pop_front();
		void push_back(const value_type& val);
		void pop_back();

		iterator begin();
		iterator end();
		const_iterator begin()const;
		const_iterator end()const;
		reverse_iterator rbegin();
		reverse_iterator rend();

		iterator insert(iterator position, const value_type& val);
		void insert(iterator position, size_type n, const value_type& val);
		template <class InputIterator>
		void insert(iterator position, InputIterator first, InputIterator last);
		iterator erase(iterator position);
		iterator erase(iterator first, iterator last);
		void swap(list& x);
		void clear();
		void splice(iterator position, list& x);
		void splice(iterator position, list& x, iterator i);
		void splice(iterator position, list& x, iterator first, iterator last);
		void remove(const value_type& val);
		template <class Predicate>
		void remove_if(Predicate pred);
		void unique();
		template <class BinaryPredicate>
		void unique(BinaryPredicate binary_pred);
		void merge(list& x);
		template <class Compare>
		void merge(list& x, Compare comp);
		void sort();
		template <class Compare>
		void sort(Compare comp);
		void reverse();
	private:
		void ctorAux(size_type n, const value_type& val, std::true_type);
		template <class InputIterator>
		void ctorAux(InputIterator first, InputIterator last, std::false_type);
		nodePtr newNode(const T& val = T());
		void deleteNode(nodePtr p);
		void insert_aux(iterator position, size_type n, const T& val, std::true_type);
		template<class InputIterator>
		void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type);
		const_iterator changeIteratorToConstIterator(iterator& it)const;
	public:
		template<class T>
		friend void swap(list<T>& x, list<T>& y);
		template <class T>
		friend bool operator== (const list<T>& lhs, const list<T>& rhs);
		template <class T>
		friend bool operator!= (const list<T>& lhs, const list<T>& rhs);
	};//end of List

}

#include "Detail\List.impl.h"
#endif

List.impl.h

#pragma once
#ifndef _LIST_IMPL_H_
#define _LIST_IMPL_H_

namespace mySTL {
	namespace Detail {
		template<class T>
		listIterator<T>& listIterator<T>::operator++() {
			p = p->next;
			return *this;
		}
		template<class T>
		listIterator<T> listIterator<T>::operator++(int) {
			auto res = *this;
			++*this;
			return res;
		}
		template<class T>
		listIterator<T>& listIterator<T>::operator --() {
			p = p->prev;
			return *this;
		}
		template<class T>
		listIterator<T> listIterator<T>::operator --(int) {
			auto res = *this;
			--*this;
			return res;
		}
		template<class T>
		bool operator ==(const listIterator<T>& lhs, const listIterator<T>& rhs) {
			return lhs.p == rhs.p;
		}
		template<class T>
		bool operator !=(const listIterator<T>& lhs, const listIterator<T>& rhs) {
			return !(lhs == rhs);
		}
	}//end of Detail namespace
	template<class T>
	void list<T>::insert_aux(iterator position, size_type n, const T& val, std::true_type) {
		for (auto i = n; i != 0; --i) {
			position = insert(position, val);//注意这时insert_aux调用了insert而非反过来,这和之前的设计结构不一样
		}
	}
	template<class T>
	template<class InputIterator>
	void list<T>::insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type) {
		for (--last; first != last; --last) {//由于最后一个不插入。所以初始化for循环时要--
			position = insert(position, *last);//注意这时insert_aux调用了insert而非反过来,这和之前的设计结构不一样
		}
		insert(position, *last);
	}
	template<class T>
	typename list<T>::nodePtr list<T>::newNode(const T& val = T()) {
		nodePtr res = nodeAllocator::allocate();
		nodeAllocator::construct(res, Detail::node<T>(val, nullptr, nullptr, this));
		return res;
	}//
	template<class T>
	void list<T>::deleteNode(nodePtr p) {
		p->prev = p->next = nullptr;
		nodeAllocator::destroy(p);
		nodeAllocator::deallocate(p);
	}
	//ctor是constructor的缩写,辅助构造函数
	template<class T>
	void list<T>::ctorAux(size_type n, const value_type& val, std::true_type) {
		head.p = newNode();//add a dummy node
		tail.p = head.p;
		while (n--)
			push_back(val);
	}
	template<class T>
	template <class InputIterator>
	void list<T>::ctorAux(InputIterator first, InputIterator last, std::false_type) {
		head.p = newNode();//add a dummy node
		tail.p = head.p;
		for (; first != last; ++first)
			push_back(*first);
	}
	//由于没有具体标准,这里的size复杂度为n。。。不过问题不大
	template<class T>
	typename list<T>::size_type list<T>::size()const {
		size_type length = 0;
		for (auto h = head; h != tail; ++h)
			++length;
		return length;
	}
//
	template<class T>
	list<T>::list() {
		head.p = newNode();//add a dummy node
		tail.p = head.p;
	}
	//调用不同的构造函数
	template<class T>
	list<T>::list(size_type n, const value_type& val = value_type()) {
		ctorAux(n, val, std::is_integral<value_type>());
	}
	template<class T>
	template <class InputIterator>
	list<T>::list(InputIterator first, InputIterator last) {
		ctorAux(first, last, std::is_integral<InputIterator>());
	}
	//复制构造函数
	template<class T>
	list<T>::list(const list& l) {
		head.p = newNode();//add a dummy node
		tail.p = head.p;
		for (auto node = l.head.p; node != l.tail.p; node = node->next)
			push_back(node->data);
	}
	//???
	template<class T>
	list<T>& list<T>::operator = (const list& l) {
		if (this != &l) {
			list(l).swap(*this);
		}
		return *this;
	}
	template<class T>
	list<T>::~list() {
		for (; head != tail;) {
			auto temp = head++;
			//bug fix
			nodeAllocator::destroy(temp.p);
			nodeAllocator::deallocate(temp.p);//逐一销毁
		}
		nodeAllocator::deallocate(tail.p);
	}
//前方加入
	template<class T>
	void list<T>::push_front(const value_type& val) {
		auto node = newNode(val);
		head.p->prev = node;
		node->next = head.p;//双向链表建立
		head.p = node;
	}
	//前方移除
	template<class T>
	void list<T>::pop_front() {
		auto oldNode = head.p;
		head.p = oldNode->next;
		head.p->prev = nullptr;
		deleteNode(oldNode);
	}
	//后方加入
	template<class T>
	void list<T>::push_back(const value_type& val) {
		auto node = newNode();
		(tail.p)->data = val;
		(tail.p)->next = node;
		node->prev = tail.p;
		tail.p = node;
	}
	//后方移除
	template<class T>
	void list<T>::pop_back() {
		auto newTail = tail.p->prev;
		newTail->next = nullptr;
		deleteNode(tail.p);
		tail.p = newTail;
	}
	//真正的插入
	template<class T>
	typename list<T>::iterator list<T>::insert(iterator position, const value_type& val) {
		if (position == begin()) {
			push_front(val);
			return begin();
		}
		else if (position == end()) {
			auto ret = position;
			push_back(val);
			return ret;
		}
		auto node = newNode(val);
		auto prev = position.p->prev;
		node->next = position.p;
		node->prev = prev;
		prev->next = node;
		position.p->prev = node;
		return iterator(node);
	}
	//调用aux辅助函数的insert(这个函数出现了两个功能完全不同的insert,令人迷惑)
	template<class T>
	void list<T>::insert(iterator position, size_type n, const value_type& val) {
		insert_aux(position, n, val, typename std::is_integral<InputIterator>::type());
	}
	//
	template<class T>
	template <class InputIterator>
	void list<T>::insert(iterator position, InputIterator first, InputIterator last) {
		insert_aux(position, first, last, typename std::is_integral<InputIterator>::type());
	}
	//删除单个节点
	template<class T>
	typename list<T>::iterator list<T>::erase(iterator position) {
		if (position == head) {
			pop_front();
			return head;
		}
		else {
			auto prev = position.p->prev;
			prev->next = position.p->next;
			position.p->next->prev = prev;
			deleteNode(position.p);
			return iterator(prev->next);
		}
	}
	//删除多个节点
	template<class T>
	typename list<T>::iterator list<T>::erase(iterator first, iterator last) {
		typename list<T>::iterator res;
		for (; first != last;) {
			auto temp = first++;
			res = erase(temp);
		}
		return res;
	}
	//删除全部节点
	template<class T>
	void list<T>::clear() {
		erase(begin(), end());
	}
	//返回首尾节点
	template<class T>
	typename list<T>::iterator list<T>::begin() {
		return head;
	}
	template<class T>
	typename list<T>::iterator list<T>::end() {
		return tail;
	}
	//转化为常迭代器
	template<class T>
	typename list<T>::const_iterator list<T>::changeIteratorToConstIterator(iterator& it)const {
		using nodeP = Detail::node<const T>*;
		auto temp = (list<const T>*const)this;
		auto ptr = it.p;
		Detail::node<const T> node(ptr->data, (nodeP)(ptr->prev), (nodeP)(ptr->next), temp);
		return const_iterator(&node);
	}
	//返回首尾节点
	template<class T>
	typename list<T>::const_iterator list<T>::begin()const {
		auto temp = (list*const)this;
		return changeIteratorToConstIterator(temp->head);
	}
	template<class T>
	typename list<T>::const_iterator list<T>::end()const {
		auto temp = (list*const)this;
		return changeIteratorToConstIterator(temp->tail);
	}
	//
	template<class T>
	typename list<T>::reverse_iterator list<T>::rbegin() {
		return reverse_iterator(tail);
	}
	template<class T>
	typename list<T>::reverse_iterator list<T>::rend() {
		return reverse_iterator(head);
	}
	//翻转list
	template<class T>
	void list<T>::reverse() {//采用尾插法
		if (empty() || head.p->next == tail.p) return;
		auto curNode = head.p;
		head.p = tail.p->prev;
		head.p->prev = nullptr;
		do {
			auto nextNode = curNode->next;
			curNode->next = head.p->next;
			head.p->next->prev = curNode;
			head.p->next = curNode;
			curNode->prev = head.p;
			curNode = nextNode;
		} while (curNode != head.p);
	}
	//移除符合条件的节点
	template<class T>
	void list<T>::remove(const value_type& val) {
		for (auto it = begin(); it != end();) {
			if (*it == val)
				it = erase(it);
			else
				++it;
		}
	}
	template<class T>
	template <class Predicate>
	void list<T>::remove_if(Predicate pred) {
		for (auto it = begin(); it != end();) {
			if (pred(*it))
				it = erase(it);
			else
				++it;
		}
	}
	//交换顺序
	template<class T>
	void list<T>::swap(list& x) {
		TinySTL::swap(head.p, x.head.p);
		TinySTL::swap(tail.p, x.tail.p);
	}
	template<class T>
	void swap(list<T>& x, list<T>& y) {
		x.swap(y);
	}
	//删除部分节点
	template<class T>
	template <class BinaryPredicate>
	void list<T>::unique(BinaryPredicate binary_pred) {
		nodePtr curNode = head.p;
		while (curNode != tail.p) {
			nodePtr nextNode = curNode->next;
			if (binary_pred(curNode->data, nextNode->data)) {
				if (nextNode == tail.p) {
					curNode->next = nullptr;
					tail.p = curNode;
				}
				else {
					curNode->next = nextNode->next;
					nextNode->next->prev = curNode;
				}
				deleteNode(nextNode);
			}
			else {
				curNode = nextNode;
			}
		}
	}
	//将两条list合并到当前链表的position
	template<class T>
	void list<T>::splice(iterator position, list& x) {
		this->insert(position, x.begin(), x.end());
		x.head.p = x.tail.p;
	}
	//部分插入链表???
	template<class T>
	void list<T>::splice(iterator position, list& x, iterator first, iterator last) {
		if (first.p == last.p) return;
		auto tailNode = last.p->prev;
		if (x.head.p == first.p) {
			x.head.p = last.p;
			x.head.p->prev = nullptr;
		}
		else {
			first.p->prev->next = last.p;
			last.p->prev = first.p->prev;
		}
		if (position.p == head.p) {//从第一个开始插入
			first.p->prev = nullptr;
			tailNode->next = head.p;
			head.p->prev = tailNode;
			head.p = first.p;
		}
		else {//从其他地方插入
			position.p->prev->next = first.p;
			first.p->prev = position.p->prev;
			tailNode->next = position.p;
			position.p->prev = tailNode;
		}
	}
	//插入单个的情况
	template<class T>
	void list<T>::splice(iterator position, list& x, iterator i) {
		auto next = i;
		this->splice(position, x, i, ++next);
	}
	//归并两条list
	template<class T>
	void list<T>::merge(list& x) {
		auto it1 = begin(), it2 = x.begin();
		while (it1 != end() && it2 != x.end()) {
			if (*it1 <= *it2)
				++it1;
			else {
				auto temp = it2++;
				this->splice(it1, x, temp);//list1较大时插入
			}
		}
		if (it1 == end()) {
			this->splice(it1, x, it2, x.end());//1到终点,全部插入
		}
	}
	//借助cmp的归并
	template<class T>
	template <class Compare>
	void list<T>::merge(list& x, Compare comp) {
		auto it1 = begin(), it2 = x.begin();
		while (it1 != end() && it2 != x.end()) {
			if (comp(*it2, *it1)) {
				auto temp = it2++;
				this->splice(it1, x, temp);
			}
			else
				++it1;
		}
		if (it1 == end()) {
			this->splice(it1, x, it2, x.end());
		}
	}
	//大同小异的判断==
	template <class T>
	bool operator== (const list<T>& lhs, const list<T>& rhs) {
		auto node1 = lhs.head.p, node2 = rhs.head.p;
		for (; node1 != lhs.tail.p && node2 != rhs.tail.p; node1 = node1->next, node2 = node2->next) {
			if (node1->data != node2->data)
				break;
		}
		if (node1 == lhs.tail.p && node2 == rhs.tail.p)
			return true;
		return false;
	}
	template <class T>
	bool operator!= (const list<T>& lhs, const list<T>& rhs) {
		return !(lhs == rhs);
	}
	//sort的默认调用版本
	template<class T>
	void list<T>::sort() {
		sort(mySTL::less<T>());
	}
	//sort排序
	void list<T>::sort(Compare comp) {
		if (empty() || head.p->next == tail.p)
			return;

		list carry;
		list 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, comp);
				carry.swap(counter[i++]);
			}
			carry.swap(counter[i]);
			if (i == fill)
				++fill;
		}
		for (int i = 0; i != fill; ++i) {
			counter[i].merge(counter[i - 1], comp);//这句怎么看都会越界
		}
		swap(counter[fill - 1]);
	}
}
#endif // !_LIST_IMPL_H_

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值