/* -*- mia-c++  -*-
 *
 * This file is part of MIA - a toolbox for medical image analysis 
 * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
 *
 * MIA is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MIA; if not, see <http://www.gnu.org/licenses/>.
 *
 */
	
#ifndef CLIST_HH
#define CLIST_HH

#include <cassert>

NS_MIA_BEGIN

template <class T> 
class clist {
	
public:
	typedef T value_type; 
	

	struct node {
		T value;
		node *prev; 
		node *succ; 
		node(T v, node *p, node *s):
			value(v), prev(p), succ(s)
		{
		}
		
		T& operator *() {
			return value; 
		}
		const T& operator *() const {
			return value; 
		}

		
	};

	typedef node *iterator; 
	typedef const node *const_iterator; 

	
	clist(): m_head(NULL){
		
	}
	~clist() {
		if (m_head != NULL) {
			node *head = m_head;
			while (head != head->succ) 
				remove(head->succ);
			delete m_head; 
		}
	}
	
	iterator begin() {
		return m_head; 
	}
	
	iterator end() {
		return m_head;
	}

	const_iterator begin() const {
		return m_head; 
	}
	
	const_iterator end() const  {
		return m_head;
	}

	
	void remove(node *n){
		if (n->prev != n) {
			n->succ->prev = n->prev; 
			n->prev->succ = n->succ; 
			if (n == m_head) {
				m_head = n->prev; 
			}
			delete n;
		}else { // only head left
			assert(n == m_head);
			delete n; 
			m_head = NULL; 
		}
	}
	void push_back(T val)
	{
		if (m_head) {
			node *nn = new node(val, m_head, m_head->succ);
			nn->prev->succ = nn; 
			nn->succ->prev = nn; 
		}else {
			assert (m_head == NULL);
			m_head = new node(val,NULL,NULL);
			m_head->prev = m_head->succ = m_head;  
		}
	}
	int size() {
		int s = 0; 
		if (m_head) {
			node *n = m_head; 
			while (n->succ != m_head) {
				n = n->succ; 
				++s; 
			}
		}
		return s; 
	}
private:
	node *m_head;
};

NS_MIA_END

#endif

/*
  $Log$
  Revision 1.3  2005/06/29 13:22:20  wollny
  switch to version 0.7

  Revision 1.1.1.1  2005/03/17 13:44:20  gerddie
  initial import 

  Revision 1.2  2004/10/15 14:05:37  wollny
  log entrys

*/
