模拟实现stl库中的list(支持const迭代器、移动语义)

cpp 复制代码
#pragma once

template<typename T>
class list
{
private:
	struct _listnode 
	{
		_listnode(const T& v)
			: data(v), prev(nullptr), next(nullptr) {}

		_listnode(T&& v)
			: data(static_cast<T&&>(v)), prev(nullptr), next(nullptr) {}

		_listnode* prev;
		_listnode* next;
		T data;
	};

	_listnode* _head;
	_listnode* _tail;
	size_t _size;

public:
	class _iterator
	{
	private:  
		_listnode* node;

	public:
		_iterator(_listnode* n = nullptr) :node(n) {}

		T& operator*() const {
			return node->data;
		}

		_iterator& operator++() {
			node = node->next;
			return *this;
		}

		_iterator operator++(int) {
			auto temp = *this;
			node = node->next;
			return temp;
		}

		_iterator& operator--(){
			node = node->prev;
			return *this;
		}

		_iterator operator--(int) {
			auto temp = *this;
			node = node->prev;
			return temp;
		}

		bool operator==(const _iterator& other) const {
			return node == other.node;
		}

		bool operator!=(const _iterator& other) const {
			return node != other.node;
		}

		_listnode* getNode() const {
			return node;
		}
	};

	class _const_iterator
	{
	private:
		const _listnode* node;

	public:
		_const_iterator(const _listnode* n = nullptr) :node(n) {}

		const T& operator*() const {
			return node->data;
		}

		_const_iterator& operator++() {
			node = node->next;
			return *this;
		}

		_const_iterator operator++(int) {
			auto temp = *this;
			node = node->next;
			return temp;
		}

		_const_iterator& operator--() {
			node = node->prev;
			return *this;
		}

		_const_iterator operator--(int) {
			auto temp = *this;
			node = node->prev;
			return temp;
		}

		bool operator==(const _const_iterator& other) const {
			return node == other.node;
		}

		bool operator!=(const _const_iterator& other) const {
			return node != other.node;
		}

		const _listnode* getNode() const {
			return node;
		}
	};
	


	list() : _head(nullptr), _tail(nullptr), _size(0) {}

	list(const list& other) : _head(nullptr), _tail(nullptr), _size(0) {
		for (auto it : other) { push_back(it); }
	}

	list(list&& other) : _head(other._head), _tail(other._tail), _size(other._size) {
		other._head = nullptr;
		other._tail = nullptr;
		other._size = 0;
	}

	~list() {
		clear();
	}

	list& operator=(const list& other) {
		if (this != &other)
		{
			clear();
			for (auto it : other) { push_back(it); }
		}
		return *this;
	}

	list& operator=(list&& other) {
		if (this != &other)
		{
			clear();
			_head = other._head;
			_tail = other._tail;
			_size = other._size;
			other._head = nullptr;
			other._tail = nullptr;
			other._size = 0;
		}
		return *this;
	}

	void clear() {
		while (_head)
		{
			auto temp = _head;
			_head = _head->next;
			delete temp;
		}

		_head = nullptr;
		_tail = nullptr;
		_size = 0;
	}

	void push_back(const T& value) {
		auto newNode = new _listnode(value);
		newNode->prev = _tail;
		newNode->next = nullptr;
		if (_tail)
			_tail->next = newNode;
		else 
			_head = newNode;

		_tail = newNode;
		_size++;
	}

	void push_back(T&& value) {
		auto newNode = new _listnode(static_cast<T&&>(value));
		newNode->prev = _tail;
		newNode->next = nullptr;
		if (_tail)
			_tail->next = newNode;
		else
			_head = newNode;

		_tail = newNode;
		_size++;
	}

	void push_front(const T& value) {
		auto newNode = new _listnode(value);
		newNode->prev = nullptr;
		newNode->next = _head;
		if (_head) 
			_head->prev = newNode;
		else 
			_tail = newNode;

		_head = newNode;
		_size++;
	}

	void push_front(T&& value) {
		auto newNode = new _listnode(static_cast<T&&>(value));
		newNode->prev = nullptr;
		newNode->next = _head;
		if (_head) 
			_head->prev = newNode;
		else 
			_tail = newNode;

		_head = newNode;
		_size++;
	}

	void pop_back() {
		if (_tail) 
		{
			auto temp = _tail;
			_tail = _tail->prev;
			if (_tail)
				_tail->next = nullptr;
			else
				_head = nullptr;

			delete temp;
			_size--;
		}
	}

	void pop_front() {
		if (_head)
		{
			auto temp = _head;
			_head = _head->next;
			if (_head)
				_head->prev = nullptr;
			else
				_tail = nullptr;

			delete temp;
			_size--;
		}
	}

	_iterator insert(_iterator pos, const T& value) {
		auto posNode = pos.getNode();
		if (!posNode)
		{
			push_back(value);
			return _iterator(_tail);
		}

		auto newNode = new _listnode(value);
		newNode->prev = posNode->prev;
		newNode->next = posNode;

		if (posNode->prev)
			posNode->prev->next = newNode;
		else
			_head = newNode;

		posNode->prev = newNode;
		_size++;
		return _iterator(newNode);
	}

	_iterator insert(_iterator pos, T&& value) {
		auto posNode = pos.getNode();
		if (!posNode)
		{
			push_back(static_cast<T&&>(value));
			return _iterator(_tail);
		}

		auto newNode = new _listnode(static_cast<T&&>(value));
		newNode->prev = posNode->prev;
		newNode->next = posNode;
		
		if (posNode->prev)
			posNode->prev->next = newNode;
		else
			_head = newNode;
		
		posNode->prev = newNode;
		_size++;
		return _iterator(newNode);
	}

	_iterator erase(_iterator pos) {
		auto posNode = pos.getNode();
		if (!posNode) return end();

		if (posNode->prev)
			posNode->prev->next = posNode->next;
		else
			_head = posNode->next;

		if (posNode->next)
			posNode->next->prev = posNode->prev;
		else
			_tail = posNode->prev;

		auto nextNode = posNode->next;
		delete posNode;
		_size--;
		return _iterator(nextNode);
	}

	size_t size() const {
		return _size;
	}

	bool empty() const {
		return _size == 0;
	}

	T& front() {
		return _head->data;
	}

	const T& front() const {
		return _head->data;
	}

	T& back() {
		return _tail->data;
	}

	const T& back() const {
		return _tail->data;
	}

	_iterator begin() {
		return _iterator(_head);
	}

	_const_iterator begin() const {
		return _const_iterator(_head);
	}

	_iterator end() {
		return _iterator(nullptr);
	}
	
	_const_iterator end() const {
		return _const_iterator(nullptr);
	}
};
相关推荐
还债大湿兄42 分钟前
《C++内存泄漏8大战场:Qt/MFC实战详解 + 面试高频陷阱破解》
c++·qt·mfc
珊瑚里的鱼4 小时前
LeetCode 692题解 | 前K个高频单词
开发语言·c++·算法·leetcode·职场和发展·学习方法
AI+程序员在路上4 小时前
QTextCodec的功能及其在Qt5及Qt6中的演变
开发语言·c++·qt
Risehuxyc4 小时前
C++卸载了会影响电脑正常使用吗?解析C++运行库的作用与卸载后果
开发语言·c++
景彡先生7 小时前
C++编译期计算:常量表达式(constexpr)全解析
服务器·c++
tan77º8 小时前
【Linux网络编程】应用层自定义协议与序列化
linux·运维·服务器·网络·c++·tcp/ip
悠哉清闲8 小时前
Android Studio C++/JNI/Kotlin 示例 三
c++·kotlin·android studio
AI迅剑9 小时前
模块三:现代C++工程实践(4篇)第二篇《性能调优:Profile驱动优化与汇编级分析》
汇编·c++
byte轻骑兵10 小时前
【Bluedroid】蓝牙协议栈enable流程深度解析
android·c++·bluedroid
Jooolin11 小时前
【C++】: list介绍以及模拟实现
c++·ai编程·编程语言