//----------------------------------------------------------- // Copyright Christian Arnault LAL-Orsay CNRS // arnault@lal.in2p3.fr // See the complete license in cmt_license.txt "http://www.cecill.info". //----------------------------------------------------------- #ifndef __cmt_list_h__ #define __cmt_list_h__ #include template class cmt_list_node { public: cmt_list_node (const T& t) : m_left(0), m_t(t), m_right(0) { } ~cmt_list_node () { } cmt_list_node* m_left; T m_t; cmt_list_node* m_right; }; template class cmt_list { public: typedef cmt_list_node NodeV; typedef NodeV* Node; class iterator { public: iterator () : m_node (0) { } iterator (Node node) : m_node (node) { } iterator& operator ++ () { if (m_node == 0) return (*this); m_node = m_node->m_right; return (*this); } iterator& operator -- () { if (m_node == 0) return (*this); m_node = m_node->m_left; return (*this); } int operator == (const iterator& other) const { return (m_node == other.m_node); } int operator != (const iterator& other) const { const iterator& me = *this; return (! (me == other)); } T& operator * () const { if (m_node == 0) { static T t; return (t); } else { return (m_node->m_t); } } Node get_node () const { return (m_node); } private: Node m_node; }; class const_iterator { public: const_iterator () : m_node (0) { } const_iterator (const Node node) : m_node (node) { } const_iterator& operator ++ () { if (m_node == 0) return (*this); m_node = m_node->m_right; return (*this); } const_iterator& operator -- () { if (m_node == 0) return (*this); m_node = m_node->m_left; return (*this); } int operator == (const const_iterator& other) const { return (m_node == other.m_node); } int operator != (const const_iterator& other) const { const iterator& me = *this; return (! (me == other)); } const T& operator * () const { if (m_node == 0) { static const T t; return (t); } else { return (m_node->m_t); } } const Node get_node () const { return (m_node); } private: const Node m_node; }; cmt_list () { m_first = 0; m_last = 0; } ~cmt_list () { while (m_last != 0) { remove (m_last); } } void push_front (const T& t) { Node node = new NodeV (t); if (m_first == 0) { m_last = node; } else { m_first->m_left = node; node->m_right = m_first; } m_first = node; } void push_back (const T& t) { Node node = new NodeV (t); if (m_last == 0) { m_first = node; } else { m_last->m_right = node; node->m_left = m_last; } m_last = node; } void pop_front () { remove (m_first); } void pop_back () { remove (m_last); } void erase (iterator it) { remove (it.get_node ()); } void erase (const_iterator it) { remove (it.get_node ()); } int size () { int count = 0; Node node = m_first; while (node != 0) { node = node->m_right; count++; } return (count); } iterator begin () { return (iterator (m_first)); } iterator last () { return (iterator (m_last)); } iterator end () { iterator it; return (it); } const_iterator begin () const { return (const_iterator (m_first)); } const_iterator last () const { return (const_iterator (m_last)); } const_iterator end () const { const_iterator it; return (it); } void exchange (iterator it1, iterator it2) { if (it1 == it2) return; Node node1 = it1.get_node (); if (node1 == 0) return; Node node2 = it2.get_node (); if (node2 == 0) return; Node l1 = node1->m_left; Node r1 = node1->m_right; Node l2 = node2->m_left; Node r2 = node2->m_right; Node f = m_first; Node l = m_last; if ((l2 != 0) && (l2 != node1)) l2->m_right = node1; if ((r2 != 0) && (r2 != node1)) r2->m_left = node1; if ((l1 != 0) && (l1 != node2)) r1->m_right = node2; if ((r1 != 0) && (r1 != node2)) r1->m_left = node2; node1->m_left = l2; node1->m_right = r2; node2->m_left = l1; node2->m_right = r1; if (node1 == f) { m_first = node2; } if (node1 == l) { m_last = node2; } if (node2 == f) { m_first = node1; } if (node2 == l) { m_last = node1; } } void insert_before (iterator it, const T& t) { Node node = it.get_node (); if (node == 0) { push_front (t); } else { Node new_node = new NodeV (t); new_node->m_right = node; new_node->m_left = node->m_left; if (node->m_left != 0) { node->m_left->m_right = new_node; } node->m_left = new_node; if (node == m_first) { m_first = new_node; } } } void insert_after (iterator it, const T& t) { Node node = it.get_node (); if (node == 0) { push_back (t); } else { Node new_node = new NodeV (t); new_node->m_left = node; new_node->m_right = node->m_right; if (node->m_right != 0) { node->m_right->m_left = new_node; } node->m_right = new_node; if (node == m_last) { m_last = new_node; } } } void move_to_front (iterator source_it) { move_before (source_it, begin ()); } void move_to_back (iterator source_it) { move_before (source_it, end ()); } void move_before (iterator source_it, iterator dest_it) { if (source_it == dest_it) return; Node source = source_it.get_node (); if (source == 0) return; Node dest = dest_it.get_node (); // First remove the source if (source == m_first) { m_first = source->m_right; } if (source == m_last) { m_last = source->m_left; } if (source->m_right != 0) source->m_right->m_left = source->m_left; if (source->m_left != 0) source->m_left->m_right = source->m_right; source->m_right = 0; source->m_left = 0; if (dest == 0) { // = move_to_back source->m_right = 0; source->m_left = m_last; if (m_last != 0) { m_last->m_right = source; } m_last = source; if (m_first == 0) m_first = source; } else { source->m_right = dest; source->m_left = dest->m_left; if (dest->m_left != 0) { dest->m_left->m_right = source; } dest->m_left = source; if (dest == m_first) { m_first = source; } } } void move_after (iterator source_it, iterator dest_it) { if (source_it == dest_it) return; Node source = source_it.get_node (); if (source == 0) return; Node dest = dest_it.get_node (); // First remove the source if (source == m_first) { m_first = source->m_right; } if (source == m_last) { m_last = source->m_left; } if (source->m_right != 0) source->m_right->m_left = source->m_left; if (source->m_left != 0) source->m_left->m_right = source->m_right; source->m_right = 0; source->m_left = 0; if (dest == 0) { // = move_to_front source->m_left = 0; source->m_right = m_first; if (m_first != 0) { m_first->m_left = source; } m_first = source; if (m_last == 0) m_last = source; } else { source->m_left = dest; source->m_right = dest->m_right; if (dest->m_right != 0) { dest->m_right->m_left = source; } dest->m_right = source; if (dest == m_last) { m_last = source; } } } private: void remove (Node node) { if (node == 0) return; if (node == m_first) { m_first = node->m_right; } if (node == m_last) { m_last = node->m_left; } if (node->m_right != 0) node->m_right->m_left = node->m_left; if (node->m_left != 0) node->m_left->m_right = node->m_right; node->m_right = 0; node->m_left = 0; delete node; } Node m_first; Node m_last; }; class A { public: A () { static int id = 0; i = id; id++; } ~A () { std::cout << "kill A i=" << i << std::endl; } int i; }; #endif