CP::list

The list class [code lang="c++"] #ifndef CP_LIST_INCLUDED #define CP_LIST_INCLUDED

#include #include //#pragma once

namespace CP {

template class list { protected: class node { friend class list; public: T data; node *prev; node *next;

    node() :
      data( T() ), prev( this ), next( this ) { }

    node(const T& data,node* prev, node* next) :
      data ( T(data) ), prev( prev ), next( next ) { }
};

class list_iterator {
  friend class list;
  protected:
    node* ptr;
  public:

    list_iterator() : ptr( NULL ) { }

    list_iterator(node *a) : ptr(a) { }

    list_iterator& operator++() { 
      ptr = ptr->next; 
      return (*this);
    }

    list_iterator& operator--() { 
      ptr = ptr->prev; 
      return (*this);
    }

    list_iterator operator++(int) {
      list_iterator tmp(*this);
      operator++();
      return tmp;

    }
    list_iterator operator--(int) {
      list_iterator tmp(*this);
      operator--();
      return tmp;
    }

    T& operator*() { return ptr->data; }
    T* operator->() { return &(ptr->data); }
    bool operator==(const list_iterator& other) { return other.ptr == ptr; }
    bool operator!=(const list_iterator& other) { return other.ptr != ptr; }
};

public: typedef list_iterator iterator;

protected: node *mHeader; // pointer to a header node size_t mSize;

public: //-------------- constructor & copy operator ----------

// copy constructor
list(list<T>& a) :
  mHeader( new node() ), mSize( 0 ) {
  for (iterator it = a.begin();it != a.end();it++) {
    push_back(*it);
  }
}

// default constructor
list() :
  mHeader( new node() ), mSize( 0 ) { }

// copy assignment operator using copy-and-swap idiom
list<T>& operator=(list<T> other) {
  // other is copy-constructed which will be destruct at the end of this scope
  // we swap the content of this class to the other class and let it be descructed
  using std::swap;
  swap(this->mHeader, other.mHeader);
  swap(this->mSize, other.mSize);
  return *this;
}

~list() {
  clear();
  delete mHeader;
}

//------------- capacity function -------------------
bool empty() const {
  return mSize == 0;
}

size_t size() const {
  return mSize;
}


//----------------- iterator ---------------
iterator begin() {
  return iterator(mHeader->next);
}

iterator end() {
  return iterator(mHeader);
}
//----------------- access -----------------
T& front() { return mHeader->next->data; }

T& back() { return mHeader->prev->data; }

//----------------- modifier -------------
void push_back(const T& element) {
  insert(end(),element);
}

void push_front(const T& element) {
  insert(begin(),element);
}

void pop_back() {
  erase(iterator(mHeader->prev));
}

void pop_front() {
  erase(begin());
}

iterator insert(iterator it,const T& element) {
  node *n = new node(element,it.ptr->prev, it.ptr);
  it.ptr->prev->next = n;
  it.ptr->prev = n;
  mSize++;
  return iterator(n);
}

iterator erase(iterator it) {
  iterator tmp(it.ptr->next);
  it.ptr->prev->next = it.ptr->next;
  it.ptr->next->prev = it.ptr->prev;
  delete it.ptr;
  mSize--;
  return tmp;
}

void clear() {
  while (mSize > 0) erase(begin());
}

void print() {
  std::cout << " Header address = " << (mHeader) << std::endl;
  int i;
  iterator before;
  for (iterator it = begin();it!=end();before = it, it++,i++) {
    std::cout << "Node " << i << ": " << *it;
    std::cout << " (prev = " << it.ptr->prev << ", I'm at " << it.ptr << ", next = " << it.ptr->next << ")" <<  std:: endl;
  }
}

};

}

#endif [/code]

The testing program [code lang="c++"] #include #include <assert.h> #include "list.h" #include

bool test1() { CP::list a;

CP::list::iterator it,it2; it =a.begin(); it2 = it; it2++; assert(it == it2); a.push_back(10); it2++; assert(it != it2); a.push_back(11); a.push_back(12); a.push_back(30); a.push_back(99); a.print();

a.clear(); assert(a.size() == 0); a.push_front(1); a.push_front(2); a.push_front(3); a.push_front(4); a.push_front(5); a.pop_front(); a.pop_back(); a.print();

assert(a.front() == 4); assert(a.back() == 2);

return true; }

bool test2() { CP::liststd::string l,l2; l.push_back("AAA1"); l.push_back("AAA2"); l.push_back("AAA3"); l.push_front("BBB"); l2 = l; CP::liststd::string::iterator it1,it2; it1 = l.begin(); it2 = l2.begin(); for (;it1 != l.end();it1++,it2++) { assert(*it1 == *it2); } l2.print(); return true; }

bool test3() { CP::list<std::pairstd::string,int > l,l2; l.push_back(std::make_pair("A",1)); l.push_back(std::make_pair("B",2)); l.push_back(std::make_pair("C",3)); l.push_back(std::make_pair("D",4));

auto it = l.begin(); it--;it--;

for (size_t i = 0;i < l.size();i++) { l2.push_front(*it); it--; } for (auto& x: l2) { std::cout << x.first << ":" << x.second << std::endl; }

return true; }

int main() { if (test1()) std::cout << " ------------------------ TEST1 OK -------------------------" << std::endl; if (test2()) std::cout << " ------------------------ TEST2 OK -------------------------" << std::endl; if (test3()) std::cout << " ------------------------ TEST3 OK -------------------------" << std::endl; } [/code]