经过长时间的学习终于可以开始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_