// -*-c++-*- /* $Id: list.h,v 1.4 1998/11/23 02:26:20 dm Exp $ */ /* * * Copyright (C) 1998 David Mazieres (dm@uun.org) * * This program 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 2, 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #ifndef _LIST_H_INCLUDED_ #define _LIST_H_INCLUDED_ 1 template struct list_entry { T *next; T **pprev; }; template T::*field> struct list { T *first; list() {first = NULL;} void insert_head (T *elm) { if (((elm->*field).next = first)) (first->*field).pprev = &(elm->*field).next; first = elm; (elm->*field).pprev = &first; } static T *remove (T *elm) { if ((elm->*field).next) ((elm->*field).next->*field).pprev = (elm->*field).pprev; *(elm->*field).pprev = (elm->*field).next; return elm; } static T *next (T *elm) { return (elm->*field).next; } void traverse (callback::ref cb) const { T *p, *np; for (p = first; p; p = np) { np = (p->*field).next; (*cb) (p); } } }; #if 0 template inline void list_remove (T *elm, list_entry T::*field) { list::remove (elm); } #endif template struct tailq_entry { T *next; T **pprev; }; template T::*field> struct tailq { T *first; T **plast; tailq () {first = NULL; plast = &first;} void insert_head (T *elm) { if (((elm->*field).next = first)) (first->*field).pprev = &(elm->*field).next; else plast = &(elm->*field).next; first = elm; (elm->*field).pprev = &first; } void insert_tail (T *elm) { (elm->*field).next = NULL; (elm->*field).pprev = plast; *plast = elm; plast = &(elm->*field).next; } T *remove (T *elm) { if ((elm->*field).next) ((elm->*field).next->*field).pprev = (elm->*field).pprev; else plast = (elm->*field).pprev; *(elm->*field).pprev = (elm->*field).next; return elm; } static T *next (T *elm) { return (elm->*field).next; } void traverse (callback::ref cb) const { T *p, *np; for (p = first; p; p = np) { np = (p->*field).next; (*cb) (p); } } }; #endif /* !_LIST_H_INCLUDED_ */