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


    #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);
    	}
    };
    
    
    
    
  • 相关阅读:
    交叉编译器环境配置与boa嵌入式web服务器移植问题
    AcWing 2811. 最长公共子串(后缀自动机 fa 指针的性质)
    OC-底层实现
    计算机竞赛 机器学习股票大数据量化分析与预测系统 - python 计算机竞赛
    1830. 【提高组NOIP2007】统计数字(count.pas/c/cpp)
    【golang】探索for-range遍历实现原理(slice、map、channel)
    1.MySQL库的操作
    go演示GRPC的用法
    IOS面试题object-c 51-60
    从零入门AI生图原理(一)(Datawhale X 魔搭 AI夏令营)
  • 原文地址:https://blog.csdn.net/shang_cm/article/details/139647304