// This may look like C code, but it is really -*- C++ -*- /* Copyright (C) 1988 Free Software Foundation written by Doug Lea (dl@rocky.oswego.edu) This file is part of the GNU C++ Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _List_h #ifdef __GNUG__ #pragma interface #endif #define _List_h 1 #include #include ".defs.h" #ifndef __typedefs #define __typedefs 1 typedef void (*Procedure)(); typedef (*Mapper)(); typedef (*Combiner)(, ); typedef int (*Predicate)(); typedef int (*Comparator)(, ); #endif struct ListNode { ListNode* tl; short ref; hd; }; extern ListNode NilListNode; class List { protected: ListNode* P; List(ListNode* p); public: List(); List( head); List( head, List& tl); List(List& a); List(Pix p); ~List(); List& operator = (List& a); int null(); int valid(); operator const void* (); int operator ! (); int length(); int list_length(); & get(); & head(); & operator [] (int n); List nth(int n); List tail(); List last(); List find( targ); List find(List& targ); int contains( targ); int contains(List& targ); int position( targ); friend List copy(List& a); friend List concat(List& a, List& b); friend List append(List& a, List& b); friend List map(Mapper f, List& a); friend List merge(List& a, List& b, Comparator f); friend List combine(Combiner f, List& a, List& b); friend List reverse(List& a); friend List select(Predicate f, List& a); #undef remove friend List remove( targ, List& a); friend List remove(Predicate f, List& a); friend List subst( old, repl, List& a); void push( x); pop(); void set_tail(List& p); void append(List& p); void prepend(List& p); void del( targ); void del(Predicate f); void select(Predicate f); void subst( old, repl); void reverse(); void sort(Comparator f); void apply(Procedure f); reduce(Combiner f, base); friend int operator == (List& a, List& b); friend int operator != (List& a, List& b); Pix first(); void next(Pix& p); Pix seek( item); & operator () (Pix p); int owns(Pix p); void error(const char*); int OK(); }; inline void reference(ListNode* p) { if (p->ref >= 0) ++p->ref; } inline void dereference(ListNode* p) { while (p->ref > 0 && --p->ref == 0) { ListNode* n = p->tl; delete(p); p = n; } } inline ListNode* newListNode( h) { ListNode* p = new ListNode; p->ref = 1; p->hd = h; return p; } inline ListNode* newListNode( h, ListNode* t) { ListNode* p = new ListNode; p->ref = 1; p->hd = h; p->tl = t; return p; } inline List::~List() { dereference(P); } inline List::List() { P = &NilListNode; } inline List::List(ListNode* p) { P = p; } inline List::List( head) { P = newListNode(head); P->tl = &NilListNode; } inline List::List( head, List& tl) { P = newListNode(head, tl.P); reference(P->tl); } inline List::List(List& a) { reference(a.P); P = a.P; } inline & List::get() { return P->hd; } inline & List::head() { return P->hd; } inline List List::tail() { reference(P->tl); return List(P->tl); } inline int List::null() { return P == &NilListNode; } inline int List::valid() { return P != &NilListNode; } inline List::operator const void* () { return (P == &NilListNode)? 0 : this; } inline int List::operator ! () { return (P == &NilListNode); } inline void List::push( head) { ListNode* oldp = P; P = newListNode(head, oldp); } inline int operator != (List& x, List& y) { return !(x == y); } inline Pix List::first() { return (P == &NilListNode)? 0 : Pix(P); } inline & List::operator () (Pix p) { return ((ListNode*)p)->hd; } inline void List::next(Pix& p) { if (p != 0) { p = Pix(((ListNode*)p)->tl); if (p == &NilListNode) p = 0; } } inline List::List(Pix p) { P = (ListNode*)p; reference(P); } #endif