| author | Dmitriy Morozov <morozov@cs.duke.edu> |
| Thu, 21 Dec 2006 13:32:34 -0500 | |
| changeset 5 | ee9052408c40 |
| parent 0 | d95020656286 |
| permissions | -rw-r--r-- |
/** * Singly-linked circular list implementation by Donovan Rebbechi <elflord@pegasus.rutgers.edu>. * Tiny modifications by DM to make ISO C++ compliant (i.e., so that the compiler stops complaining), * added size(), and boost serialization */ #ifndef __CIRCULAR_LIST_H__ #define __CIRCULAR_LIST_H__ #include <iterator> #include <boost/serialization/access.hpp> #include <boost/serialization/split_member.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/binary_object.hpp> #include "types.h" template <class T> class List { struct Node { Node(const T& x,Node* y = 0):m_data(x),m_next(y){} T m_data; Node* m_next; private: // Serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, version_type ) { ar & make_nvp("data", m_data); ar & make_nvp("next", m_next); } }; Node* m_node; size_t sz; private: // Serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, version_type ) { ar & make_nvp("root", m_node); } public: class const_iterator; class iterator : public std::iterator<std::forward_iterator_tag, T> { Node* m_rep; public: friend class List; friend class const_iterator; typedef T value_type; typedef T& reference; typedef T* pointer; typedef int difference_type; typedef std::forward_iterator_tag iterator_category; inline iterator(Node* x=0):m_rep(x){} inline iterator(const iterator& x):m_rep(x.m_rep) {} inline iterator(const const_iterator& x):m_rep(const_cast<Node*>(x.m_rep)) {} // not very safe inline iterator& operator=(const iterator& x) { m_rep=x.m_rep; return *this; } inline iterator& operator++() { m_rep = m_rep->m_next; return *this; } inline iterator operator++(int) { iterator tmp(*this); m_rep = m_rep->m_next; return tmp; } inline reference operator*() const { return m_rep->m_next->m_data; } inline pointer operator->() const { return m_rep->m_next; } inline bool operator==(const iterator& x) const { return m_rep == x.m_rep; } inline bool operator!=(const iterator& x) const { return m_rep != x.m_rep; } }; class const_iterator : public std::iterator<std::forward_iterator_tag, const T> { const Node* m_rep; public: friend class List; friend class iterator; typedef T value_type; typedef T& reference; typedef T* pointer; typedef int difference_type; typedef std::forward_iterator_tag iterator_category; inline const_iterator(const Node* x=0):m_rep(x){} inline const_iterator(const const_iterator& x):m_rep(x.m_rep) {} inline const_iterator(const iterator& x):m_rep(x.m_rep){} inline const_iterator& operator=(const const_iterator& x) { m_rep=x.m_rep; return *this; } inline const_iterator& operator=(const iterator& x) { m_rep=x.m_rep; return *this; } inline const_iterator& operator++() { m_rep = m_rep->m_next; return *this; } inline const_iterator operator++(int) { const_iterator tmp(*this); m_rep = m_rep->m_next; return tmp; } inline reference operator*() const { return m_rep->m_next->m_data; } inline pointer operator->() const { return m_rep->m_next; } inline bool operator==(const const_iterator& x) const { return m_rep == x.m_rep; } inline bool operator!=(const const_iterator& x) const { return m_rep != x.m_rep; } }; typedef T& reference; typedef const T& const_reference; typedef T* pointer; typedef const T* const_pointer; List() : m_node(new Node(T())), sz(0) { m_node->m_next = m_node; } List(const List& L) : m_node(new Node(T())), sz(L.sz) { m_node->m_next=m_node; for ( const_iterator i = L.begin(); i!= L.end(); ++i ) push_front(*i); reverse(); } void reverse() { if (empty()) return; Node* new_m_node = m_node->m_next->m_next; Node* p = m_node; Node* i = m_node->m_next; Node* n; do { n = i->m_next; i->m_next = p; p = i; i = n; } while (p!=m_node); m_node = new_m_node; } void swap(List& x) { std::swap(m_node, x.m_node); std::swap(sz, x.sz); } List& operator=(const List& x) { List tmp(x); swap(tmp); return *this; } ~List() { clear(); delete m_node; } void clear() { while (!empty()) pop_front(); sz = 0; } inline size_t size() const { return sz; } inline void push_front(const T&x) { insert (begin(),x); } inline void push_back(const T& x) { insert (end(),x); } inline void pop_front() { erase(begin()); } inline bool empty() const { return m_node == m_node->m_next; } inline T& front() { return *begin(); } inline const T& front() const { return *begin(); } inline T& back() { return m_node->m_data; } inline const T& back() const { return m_node->m_data; } inline iterator begin() { return iterator(m_node->m_next); } inline iterator end() { return iterator(m_node); } inline const_iterator begin() const { return const_iterator(m_node->m_next); } inline const_iterator end() const { return const_iterator(m_node); } iterator erase (iterator x) { if (x == end()) return x; if (x.m_rep->m_next == m_node) m_node = x.m_rep; Node* tmp = x.m_rep->m_next; x.m_rep->m_next = x.m_rep->m_next->m_next; delete tmp; --sz; return x; } iterator insert (iterator x, const T& y) { Node* tmp = new Node(y,x.m_rep->m_next); if (x.m_rep == m_node) // if inserting before end m_node = tmp; x.m_rep->m_next = tmp; ++sz; return x++; // x points to the new data, return it, and slide it over } // rotate x to beginning void rotate (iterator x) { if (x == end()) return; Node* sentinel = m_node->m_next; m_node->m_next = m_node->m_next->m_next; sentinel->m_next = x.m_rep->m_next; x.m_rep->m_next = sentinel; m_node = x.m_rep; } }; #endif // __CIRCULAR_LIST_H__