eat std::list source code
list的好处是每次插入或删除一个元素,就配置或释放一个元素空间。因此,list对于空间的运用有绝对的精准,一点也不浪费。而且,对于任何位置的插入和元素移除都永远是常数时间。
可惜了当下有点忙能力欠缺,待有时间来补上可运行完整版本std::list源码实现
// DesignPatterns.cpp: 定义应用程序的入口点。
//#include "DesignPatterns.h"#include <list>
#include <utility>
#include <memory>
#include <set>
#include <malloc.h>
using namespace std;template<class T>
struct __list_node {typedef void* void_pointer;void_pointer prev; // 类型为 void*,其实可设为 __list_node<T>*void_pointer next;T data;
};template<class T, class Ref, class Ptr>
struct __list_iterator {typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, Ref, Ptr> self;typedef bidirectional_iterator_tag iterator_category;typedef T value_type;typedef Ptr pointer;typedef Ref reference;typedef __list_node<T>* link_type;typedef size_t size_type;typedef ptrdiff_t difference_type;link_type node;// constructor__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; }// 下面是对迭代器取值deference,取得是节点的数据值reference operator*() const { return (*node).data; }// 下面是迭代器的成员存取(member access)预算子的标准做法pointer operator->() const { return &(operator*()); }// 对迭代器累加1,就是前进一个节点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;}
};template<class T, class Alloc>
class list {
protected:// 中间加一层,就有了梦幻的数据typedef __list_node<T> list_node;public:// 组合一个数据的指针,链表不就有了么typedef list_node* link_type;protected:link_type node;// 专属之空间配置器,每次配置一个节点大小typedef simple_alloc<list_node, Alloc> list_node_allocator;protected:// 配置一个节点并传向link_type get_node() { return list_node_allocator::allocate(); }// 释放一个节点void put_node(link_type p) { list_node_allocator::deallocator(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);}
public:list() { empty_initialize(); }
protected:void empty_initialize() {node = get_node(); // 配置一个节点空间,令node指向它node->next = node; // 令node头尾都指向自己,不设元素值node->prev = node;}void push_back(const T& x) { insert(end(), x); }iterator insert(iterator position, const T& x) {link_type tmp = create_node(x); // 产生一个节点// 调整双向指针,使得tmp插进去tmp->next = position.node;tmp->prev = position.node->prev;(link_type(position.node->prev))->next = tmp;position.node->prev = tmp;return tmp;}void push_front(const T& x) { insert(begin(), x); }void push_back(const T& x) { insert(end(), x); }iterator 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);}void pop_front() {erase(begin());}void pop_back() {iterator tmp = end();erase(--tmp);}template<class T, class Alloc>void list<T, Alloc>::clear() {link_type cur = (link_type)node->next;while (cur != node) {link_type tmp - cur;cur = (link_type)cur->next;destroy_node(tmp);}node->next = node;node->prev = node;}template<class T, class Alloc>void list<T, Alloc>::remove(const T& value) {iterator first = begin();iterator last = end();while (first != last) {iterator next = first;++next;if (*first == value) erase(first);first = next;}}template<class T, class Alloc>void list<T, Alloc>::unique() {iterator first = begin();iterator last = end();if (first == last) return;iterator next = first;while (++next != last) {if (*first == *next) {erase(next);}else {first = next;}next = first;}}void 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;}}
public:void splice(iterator position, list& x) {if (!x.empty_initialize())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);}}template<class T, class Alloc>void list<T, Alloc>::merge(list<T, Alloc>& x) {iterator first1 = begin();iterator last1 = end();iterator first2 = x.begin();iterator last2 = x.end();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<class T, class Alloc>void list<T, Alloc>::reverse() {if (node->next == node || link_type(node->next())->next == node)return;iterator first = begin();++first;while (first != end()) {iterator old = first;++first;transfer(begin(), old, first);}}template<class T, class 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]);}swap(counter[fill - 1]);}/** push_front,push_back,erase,pop_front,pop_back,clear* remove,unique,splice,merge,reverse,sort**/};int main()
{int i;std::list<int> ilist;std::cout << "size=" << ilist.size() << std::endl;ilist.push_back(0);ilist.push_back(2);ilist.push_back(3);ilist.push_back(4);std::cout << "size=" << ilist.size() << std::endl;std::list<int>::iterator ite;for (ite = ilist.begin(); ite != ilist.end(); ++ite) {std::cout << *ite << ' ';}std::cout << std::endl;ite = std::find(ilist.begin(), ilist.end(), 3);if (ite != ilist.end()) {ilist.insert(ite, 9);}std::cout << "size=" << ilist.size() << std::endl;std::cout << *ite << std::endl;for (ite = ilist.begin(); ite != ilist.end(); ++ite) {std::cout << *ite << ' ';}std::cout << std::endl;ite = std::find(ilist.begin(), ilist.end(), 2);if (ite != ilist.end()) {std::cout << *(ilist.erase(ite)) << std::endl;}for (ite = ilist.begin(); ite != ilist.end(); ++ite) {std::cout << *ite << ' ';}std::cout << std::endl;int iv[5] = { 5,6,7,8,9 };std::list<int> list2(iv, iv + 5);// 目前ilist的内容为 0 2 99 3 4ite = std::find(ilist.begin(), ilist.end(), 99);ilist.splice(ite, list2); // 0 2 5 6 7 8 9 99 3 4ilist.reverse(); // 4 3 99 9 8 7 6 5 2 0ilist.sort(); // 0 2 3 4 5 6 7 8 9 99return 0;
}