重构
This commit is contained in:
401
TinySTL/Detail/List.impl.h
Normal file
401
TinySTL/Detail/List.impl.h
Normal file
@@ -0,0 +1,401 @@
|
||||
#ifndef _LIST_IMPL_H_
|
||||
#define _LIST_IMPL_H_
|
||||
|
||||
namespace TinySTL{
|
||||
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);
|
||||
}
|
||||
}
|
||||
template<class T>
|
||||
template<class InputIterator>
|
||||
void list<T>::insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type){
|
||||
for (; first != last; ++first){
|
||||
insert(position, *first);
|
||||
}
|
||||
}
|
||||
template<class T>
|
||||
typename list<T>::nodePtr list<T>::newNode(const T& val = T()){
|
||||
nodePtr res = nodeAllocator::allocate();
|
||||
res->container = this;
|
||||
//res->data = val; //-> bug
|
||||
//nodeAllocator::construct(&(res->data), val);
|
||||
TinySTL::construct(&(res->data), val);//fix
|
||||
res->prev = nullptr;
|
||||
res->next = nullptr;
|
||||
return res;
|
||||
}
|
||||
template<class T>
|
||||
void list<T>::deleteNode(nodePtr p){
|
||||
p->prev = nullptr;
|
||||
p->next = nullptr;
|
||||
nodeAllocator::deallocate(p);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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){
|
||||
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);
|
||||
}
|
||||
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>
|
||||
void list<T>::reverse(){//<2F><><EFBFBD><EFBFBD>β<EFBFBD>巨
|
||||
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>
|
||||
void list<T>::unique(){
|
||||
nodePtr curNode = head.p;
|
||||
while (curNode != tail.p){
|
||||
nodePtr nextNode = curNode->next;
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (it1 == end()){
|
||||
this->splice(it1, x, it2, x.end());
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
template<class T>
|
||||
void list<T>::sort(){
|
||||
sort(TinySTL::less<T>());
|
||||
}
|
||||
template<class T>
|
||||
template <class Compare>
|
||||
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
|
||||
398
TinySTL/List.h
398
TinySTL/List.h
@@ -11,7 +11,7 @@
|
||||
namespace TinySTL{
|
||||
template<class T>
|
||||
class list;
|
||||
namespace{
|
||||
namespace Detail{
|
||||
//the class of node
|
||||
template<class T>
|
||||
struct node{
|
||||
@@ -36,24 +36,10 @@ namespace TinySTL{
|
||||
public:
|
||||
explicit listIterator(nodePtr ptr = nullptr) :p(ptr){}
|
||||
|
||||
listIterator& operator++(){
|
||||
p = p->next;
|
||||
return *this;
|
||||
}
|
||||
listIterator operator++(int){
|
||||
auto res = *this;
|
||||
++*this;
|
||||
return res;
|
||||
}
|
||||
listIterator& operator --(){
|
||||
p = p->prev;
|
||||
return *this;
|
||||
}
|
||||
listIterator operator --(int){
|
||||
auto res = *this;
|
||||
--*this;
|
||||
return res;
|
||||
}
|
||||
listIterator& operator++();
|
||||
listIterator operator++(int);
|
||||
listIterator& operator --();
|
||||
listIterator operator --(int);
|
||||
T& operator *(){ return p->data; }
|
||||
T* operator &(){ return &(operator*()); }
|
||||
|
||||
@@ -62,27 +48,20 @@ namespace TinySTL{
|
||||
template<class T>
|
||||
friend bool operator !=(const listIterator<T>& lhs, const listIterator<T>& rhs);
|
||||
};
|
||||
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 namespace
|
||||
|
||||
|
||||
//the class of list
|
||||
template<class T>
|
||||
class list{
|
||||
template<class T>
|
||||
friend struct listIterator;
|
||||
private:
|
||||
typedef allocator<node<T>> nodeAllocator;
|
||||
typedef node<T> *nodePtr;
|
||||
typedef allocator<Detail::node<T>> nodeAllocator;
|
||||
typedef Detail::node<T> *nodePtr;
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef listIterator<T> iterator;
|
||||
typedef Detail::listIterator<T> iterator;
|
||||
typedef reverse_iterator_t<iterator> reverse_iterator;
|
||||
typedef T& reference;
|
||||
typedef size_t size_type;
|
||||
@@ -90,48 +69,16 @@ namespace TinySTL{
|
||||
iterator head;
|
||||
iterator tail;
|
||||
public:
|
||||
list(){
|
||||
head.p = newNode();//add a dummy node
|
||||
tail.p = head.p;
|
||||
}
|
||||
explicit list(size_type n, const value_type& val = value_type()){
|
||||
ctorAux(n, val, std::is_integral<value_type>());
|
||||
}
|
||||
list();
|
||||
explicit list(size_type n, const value_type& val = value_type());
|
||||
template <class InputIterator>
|
||||
list(InputIterator first, InputIterator last){
|
||||
ctorAux(first, last, std::is_integral<InputIterator>());
|
||||
}
|
||||
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);
|
||||
}
|
||||
list& operator = (const list& l){
|
||||
if (this != &l){
|
||||
list(l).swap(*this);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~list(){
|
||||
for (; head != tail;){
|
||||
auto temp = head++;
|
||||
//bug fix
|
||||
nodeAllocator::destroy(temp.p);
|
||||
nodeAllocator::deallocate(temp.p);
|
||||
}
|
||||
nodeAllocator::deallocate(tail.p);
|
||||
}
|
||||
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{
|
||||
size_type length = 0;
|
||||
for (auto h = head; h != tail; ++h)
|
||||
++length;
|
||||
return length;
|
||||
}
|
||||
bool empty()const{ return head == tail; }
|
||||
size_type size()const;
|
||||
reference front(){ return (head.p->data); }
|
||||
reference back(){ return (tail.p->prev->data); }
|
||||
|
||||
@@ -170,45 +117,14 @@ namespace TinySTL{
|
||||
void sort(Compare comp);
|
||||
void reverse();
|
||||
private:
|
||||
void 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);
|
||||
}
|
||||
void ctorAux(size_type n, const value_type& val, std::true_type);
|
||||
template <class InputIterator>
|
||||
void 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);
|
||||
}
|
||||
nodePtr newNode(const T& val = T()){
|
||||
nodePtr res = nodeAllocator::allocate();
|
||||
res->container = this;
|
||||
//res->data = val; //-> bug
|
||||
//nodeAllocator::construct(&(res->data), val);
|
||||
TinySTL::construct(&(res->data), val);//fix
|
||||
res->prev = nullptr;
|
||||
res->next = nullptr;
|
||||
return res;
|
||||
}
|
||||
void deleteNode(nodePtr p){
|
||||
p->prev = nullptr;
|
||||
p->next = nullptr;
|
||||
nodeAllocator::deallocate(p);
|
||||
}
|
||||
void insert_aux(iterator position, size_type n, const T& val, std::true_type){
|
||||
for (auto i = n; i != 0; --i){
|
||||
position = insert(position, val);
|
||||
}
|
||||
}
|
||||
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){
|
||||
for (; first != last; ++first){
|
||||
insert(position, *first);
|
||||
}
|
||||
}
|
||||
void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type);
|
||||
public:
|
||||
template<class T>
|
||||
friend void swap(list<T>& x, list<T>& y);
|
||||
@@ -217,273 +133,7 @@ namespace TinySTL{
|
||||
template <class T>
|
||||
friend bool operator!= (const list<T>& lhs, const list<T>& rhs);
|
||||
};//end of List
|
||||
|
||||
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){
|
||||
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);
|
||||
}
|
||||
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>
|
||||
void list<T>::reverse(){//<2F><><EFBFBD><EFBFBD>β<EFBFBD>巨
|
||||
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>
|
||||
void list<T>::unique(){
|
||||
nodePtr curNode = head.p;
|
||||
while (curNode != tail.p){
|
||||
nodePtr nextNode = curNode->next;
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (it1 == end()){
|
||||
this->splice(it1, x, it2, x.end());
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
template<class T>
|
||||
void list<T>::sort(){
|
||||
sort(TinySTL::less<T>());
|
||||
}
|
||||
template<class T>
|
||||
template <class Compare>
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
#include "Detail\List.impl.h"
|
||||
#endif
|
||||
Reference in New Issue
Block a user