// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system * * Copyright (C) 2004-2006 Sage Weil * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #ifndef CEPH_DLIST_H #define CEPH_DLIST_H template class dlist { public: struct item { T _item; item *_prev, *_next; item(T i) : _item(i), _prev(this), _next(this) {} ~item() { assert(!is_on_list()); } // no copying! item(const item& other); const item& operator= (const item& right); bool empty() const { return _prev == this; } bool is_on_list() const { return !empty(); } bool remove_myself() { if (_next == this) { assert(_prev == this); return false; } _next->_prev = _prev; _prev->_next = _next; _prev = _next = this; return true; } void insert_after(item *other) { assert(other->empty()); other->_prev = this; other->_next = _next; _next->_prev = other; _next = other; } void insert_before(item *other) { assert(other->empty()); other->_next = this; other->_prev = _prev; _prev->_next = other; _prev = other; } }; private: item _head; public: dlist(const dlist& other); const dlist& operator=(const dlist& other); dlist() : _head(NULL) {} ~dlist() { assert(_head.empty()); } bool empty() { return _head.empty(); } void clear() { while (!_head.empty()) remove(front()); } void push_front(item *i) { if (!i->empty()) i->remove_myself(); _head.insert_after(i); } void push_back(item *i) { if (!i->empty()) i->remove_myself(); _head.insert_before(i); } T front() { return (T)_head._next->_item; } T back() { return (T)_head._prev->_item; } void pop_front() { assert(!empty()); _head._next->remove_myself(); } void pop_back() { assert(!empty()); _head._prev->remove_myself(); } class iterator { private: item *cur; public: iterator(item *i = 0) : cur(i) {} T operator*() { return (T)cur->_item; } iterator& operator++() { assert(cur); cur = cur->_next; return *this; } bool end() { return cur->_item == 0; } }; iterator begin() { return iterator(_head._next); } }; #endif