#include #include #include #include #include namespace vp { template class list { private: struct node { node(); node(T Value, node *pnode); node(T Value, node *Prev, node *Next); ~node(); void insert_after(node *pnode); void insert_before(node *pnode); void remove(); T value; node *prev; node *next; }; node *firstNode; node *lastNode; unsigned int mSize; typedef T& reference; typedef const T& const_reference; public: class iterator { private: node *current; public: friend class list; iterator(); iterator(node* node); reference operator ->(); reference operator *(); bool operator ==(const iterator it) const; bool operator !=(const iterator it) const; iterator& operator ++(); iterator operator ++(int); iterator& operator --(); iterator operator --(int); }; private: typedef const typename vp::list::iterator const_iterator; public: list(); list(unsigned n, const_reference value = T()); list(list& x); ~list(); bool operator == (const list& l); bool operator < (const list& l); bool operator > (const list& l); bool operator != (const list& l); bool operator >= (const list& l); bool operator <= (const list& l); list& operator =(const list& l); void assign(iterator first, iterator last); void assign(unsigned n, const_reference value); reference back(); const_reference back() const; iterator begin(); const_iterator begin() const; void clear(); bool empty() const; iterator end(); const_iterator end() const; iterator erase(iterator it); iterator erase(iterator first, iterator last); reference front(); const_reference front() const; iterator insert(iterator it, const_reference value); void insert(iterator it, unsigned n, const_reference value); void insert(iterator it, iterator first, iterator last); unsigned max_size() const; void merge(list l); // void merge (list& l, Compare comp); void pop_back(); void pop_front(); void push_back(T x); void push_front(T x); iterator rbegin(); // reverse_iterator rbegin(); // const_reverse_iterator rbegin() const; void remove(const_reference value); // void remove_if(Predicate pred); iterator rend(); // reverse_iterator rend(); // const_reverse_iterator rend() const; void resize(unsigned n, T value = T()); void reverse(); unsigned int size() const; void sort(); // void sort(Compare comp); // void splice(iterator it, list& l); // void splice(iterator it, list& l, iterator i); // void splice(iterator it, list& l, iterator first, iterator last); void swap(list l); void unique(); void unique(BinaryPredicate binary_pred); }; } /** Node definitions **/ template vp::list::node::node() : value(T()), prev(NULL), next(NULL) {} template vp::list::node::node(T Value, node *pnode) : value(Value), prev(pnode->prev), next(pnode) { pnode->prev = this; if (prev) prev->next = this; } template vp::list::node::node(T Value, node *Prev, node *Next) : value(Value), prev(Prev), next(Next) { if (prev) prev->next = this; if (next) next->prev = this; } template vp::list::node::~node() { remove(); } template void vp::list::node::insert_after(node *pnode) { if (!pnode || pnode == this) return; remove(); prev = pnode; next = pnode->next; if (pnode->next) pnode->next->prev = this; pnode->next = this; } template void vp::list::node::insert_before(node *pnode) { if (!pnode || pnode == this) return; remove(); next = pnode; prev = pnode->prev; if (pnode->prev) pnode->prev->next = this; pnode->prev = this; } template void vp::list::node::remove() { if (prev) prev->next = next; if (next) next->prev = prev; next = prev = NULL; } /** Iterator definitions **/ template vp::list::iterator::iterator() : current(NULL) {} template vp::list::iterator::iterator(node *n) : current(n) {} template typename vp::list::reference vp::list::iterator::operator ->() { return current->value; } template typename vp::list::reference vp::list::iterator::operator *() { return current->value; } template bool vp::list::iterator::operator ==(const iterator it) const { return (current == it.current); } template bool vp::list::iterator::operator !=(const iterator it) const { return !operator == (it); } template typename vp::list::iterator& vp::list::iterator::operator ++() { if (current) current = current->next; return *this; } template typename vp::list::iterator vp::list::iterator::operator ++(int) { iterator result = *this; if (current) current = current->next; return result; } template typename vp::list::iterator& vp::list::iterator::operator --() { if (current) current = current->prev; return *this; } template typename vp::list::iterator vp::list::iterator::operator --(int) { iterator result = *this; if (current) current = current->prev; return result; } /** List definitions **/ template vp::list::list() : firstNode(NULL), lastNode(NULL), mSize(0) {} template vp::list::list(unsigned n, const_reference value) : firstNode(NULL), lastNode(NULL), mSize(0) { for (unsigned i = 0; i < n; i ++) push_back(value); } template vp::list::list(list& x) : firstNode(NULL), lastNode(NULL), mSize(0) { for (auto it : x) push_back(it); } template vp::list::~list() { while (firstNode != NULL) { node *n = firstNode->next; delete firstNode; firstNode = n; } } template bool vp::list::operator == (const list& l) { if (mSize != l.mSize) return false; for(vp::list::iterator lhsIt = firstNode, rhsIt = l.firstNode; lhsIt != NULL; lhsIt ++, rhsIt ++) if (*lhsIt != *rhsIt) return false; return true; } template bool vp::list::operator < (const list& l) { if (mSize < l.mSize) return true; else if (mSize > l.mSize) return false; for(vp::list::iterator lhsIt = firstNode, rhsIt = l.firstNode; lhsIt != NULL; lhsIt ++, rhsIt ++) if (*lhsIt < *rhsIt) return true; else if (*lhsIt > *rhsIt) return false; return false; } template bool vp::list::operator > (const list& l) { if (mSize > l.mSize) return true; else if (mSize < l.mSize) return false; for(vp::list::iterator lhsIt = firstNode, rhsIt = l.firstNode; lhsIt != NULL; lhsIt ++, rhsIt ++) if (*lhsIt > *rhsIt) return true; else if (*lhsIt < *rhsIt) return false; return false; } template bool vp::list::operator != (const list& l) { return !(*this == l); } template bool vp::list::operator >= (const list& l) { return !(*this < l); } template bool vp::list::operator <= (const list& l) { return !(*this > l); } template vp::list& vp::list::operator = (const list& l) { clear(); for (T val : l) push_back(val); return *this; } template void vp::list::assign(iterator first, iterator last) { clear(); for (; first != last; first ++) push_back(*first); } template void vp::list::assign(unsigned n, const_reference value) { clear(); for (unsigned i = 0; i < n; i ++) push_back(value); } template typename vp::list::reference vp::list::back() { if (empty()) throw std::logic_error("list: Invoked back() on empty list") ; return lastNode->value; } template typename vp::list::const_reference vp::list::back() const { if (empty()) throw std::logic_error("list: Invoked back() on empty list") ; return lastNode->value; } template typename vp::list::iterator vp::list::begin() { return iterator(firstNode); } template typename vp::list::const_iterator vp::list::begin() const { return iterator(firstNode); } template void vp::list::clear() { while (firstNode != NULL) { node *n = firstNode->next; delete firstNode; firstNode = n; } lastNode = firstNode; mSize = 0; } template bool vp::list::empty() const { return !mSize; } template typename vp::list::iterator vp::list::erase(iterator it) { if (it != end()) { if (firstNode == it.current) firstNode = it.current->next; if (lastNode == it.current) lastNode = it.current->prev; mSize --; delete(it++).current; } return it; } template typename vp::list::iterator vp::list::erase(iterator first, iterator last) { for (; first != last; first ++) erase(first); return (++ last); } template typename vp::list::iterator vp::list::end() { return iterator(); } template typename vp::list::const_iterator vp::list::end() const { return iterator(); } template typename vp::list::reference vp::list::front() { if (empty()) throw std::logic_error("list: Invoked front() on empty list") ; return firstNode->value; } template typename vp::list::const_reference vp::list::front() const { if (empty()) throw std::logic_error("list: Invoked front() on empty list") ; return firstNode->value; } template typename vp::list::iterator vp::list::insert(iterator it, const_reference value) { iterator result(new node(value, it.current->prev, it.current->next)); mSize ++; return result; } template void vp::list::insert(iterator it, unsigned n, const_reference value) { for (unsigned i = 0; i < n; i ++) it = insert(it, value); } template void vp::list::insert(iterator it, iterator first, iterator last) { for (; first != last; first ++) it = insert(it, *first); } template unsigned vp::list::max_size() const { return mSize; } template void vp::list::merge(list l) { node *p = firstNode; while (l.size()) { node *q = l.firstNode; if (q->value < p->value) { l.firstNode = l.firstNode->next; q->insert_before(p); if (p == firstNode) firstNode = q; mSize ++; l.mSize --; } else if (p == lastNode) { l.firstNode = l.firstNode->next; q->insert_after(p); p = lastNode = q; mSize ++; l.mSize --; } else p = p->next; } } template void vp::list::pop_back() { if (empty()) return; node *n = lastNode->prev; n->next = NULL; delete lastNode; lastNode = n; mSize --; if (empty()) firstNode = lastNode; } template void vp::list::pop_front() { if (empty()) return; node *n = firstNode->next; n->prev = NULL; delete firstNode; firstNode = n; mSize --; if (empty()) lastNode = firstNode; } template void vp::list::push_back(T x) { lastNode = new node(x, lastNode, NULL); if (firstNode == NULL) firstNode = lastNode; mSize ++; } template void vp::list::push_front(T x) { firstNode = new node(x, NULL, firstNode); if (lastNode == NULL) lastNode = firstNode; mSize ++; } /** Need to add and change to reverse_iterator **/ template typename vp::list::iterator vp::list::rbegin() { return iterator(lastNode); } template void vp::list::remove(const_reference value) { for (iterator it(firstNode); it != end(); it ++) if (*it == value) erase(it); } template typename vp::list::iterator vp::list::rend() { return iterator(); } template void vp::list::resize(unsigned n, T value) { if (n < mSize) while (mSize > n) pop_back(); else for (unsigned i = 0; i < n; i ++) push_back(value); } template void vp::list::reverse() { node* temp = lastNode; lastNode = firstNode; firstNode = temp; for (node* tempNode = temp; temp; temp = temp->next) { tempNode = temp->prev; temp->prev = temp->next; temp->next = tempNode; } } template unsigned int vp::list::size() const { return mSize; } template void vp::list::sort() { if (size() <= 1) return; for (int merges = 0, k = 1; merges != 1; k *= 2) { node *p = firstNode, *q = p; for (int qsize = merges = 0; p; merges ++, p = q) { for (qsize = 0; qsize < k && q; qsize ++, q = q->next); while (qsize && q) { if (q->value <= p->value) { if (q->next) { q = q->next; q->prev->insert_before(p); } else { q->insert_before(p); q = NULL; lastNode = lastNode->prev; } if (p == firstNode) firstNode = firstNode->prev; qsize --; } else p = p->next; } } } } //void splice(iterator it, list& l); //void splice(iterator it, list& l, iterator i); //void splice(iterator it, list& l, iterator first, iterator last); template void vp::list::swap(list l) { list temp = l; l = *this; this = temp; } template void vp::list::unique() { for (iterator it = begin(); it != end(); it ++) if ((it != begin()) && (*it == it.current->prev->value)) erase(it --); } template void vp::list::unique(BinaryPredicate binary_pred) { for (iterator it = begin(); it != end(); it ++) if ((it != begin()) && (binary_pred(*it, it.current->prev->value))) erase(it --); } bool isSame(int a, int b) { return a == b; } int main() { vp::list list1, list2; for (int i = 0; i < 10; i ++) { list1.push_back(i); list2.push_back(i); } list1.pop_back(); list1.push_back(7); list1.sort(); list1.unique(isSame); for (auto it : list1) std::cout << *it << "\n"; return 0; }