I'm getting the following errors while trying to build my package:

g++  -fpermissive  -c -o List.o List.cc
In file included from List.cc:4:
List.h:241: warning: ANSI C++ forbids declaration `BIstream' with no type
List.h:241: `BIstream' is neither function nor method; cannot be declared friend
List.h:241: parse error before `&'
make: *** [List.o] Error 1

The source that seems to be causing this is in the include file List.h
which gets included from List.cc:

friend BIstream & operator>> (BIstream & in, List<T> & list);

Can anyone see any problems with this?  I'd really like to package
this software but my c++ skills are lacking.  Any ideas?

The entire source for List.h is attached.
--
Chris Ruffin <[EMAIL PROTECTED]>


#ifndef List_h
#define List_h

// This file describes the List template-class and some additional stuff
// that is required by this one.

// The List class represents a doubly-linked list

// The ListItem class uses lazy-allocation by default (see AllocBuf.h)

#include "AllocBuf.h"

class ostream;

template <class T>
class List;

#pragma interface


template <class T>
class ListItem : public T {

LAZYCLASS

protected:

	ListItem * next;
	ListItem * prev;

public:	

	ListItem( void ) : T()
#ifdef DEBUG
	 , next((ListItem *)0), prev((ListItem *)0)
#endif DEBUG
	  { };
	  
	ListItem( const T & val ) : T(val)
#ifdef DEBUG
	 , next((ListItem *)0), prev((ListItem *)0)
#endif DEBUG
	  { };

	ListItem * get_next(void) const {
		return next;
	};
	
	ListItem * get_prev(void) const {
		return prev;
	};

	friend class List<T>;
};

LAZYOPS(template <class T>,ListItem<T>)


template <class T>
class List {
	
protected:

	ListItem<T> * first;
	ListItem<T> * last;
	
	unsigned long len;

public:
	
	List (void) : first((ListItem<T> *)0), last((ListItem<T> *)0), len(0)  { };
	
	List (const List<T> & rv) : first((ListItem<T> *)0), last((ListItem<T> *)0), len(0) {
		for (const ListItem<T> * lip = rv.get_head();
		     lip;
		     lip = lip->get_next()
		    ) {
			if (add_tail( *lip )) break;
		}
	}
	
	void clear(void);	
	~List(void) {
		clear();
	}

	// --------- operators ----------
	
	const List<T> & operator=(const List<T> & rv) {
		clear();
		for (const ListItem<T> * lip = rv.get_head();
		     lip;
		     lip = lip->get_next()
		    ) {
			if (add_tail( *lip )) break;
		}
		
		return *this;
	}
	
	// --------- member-functions ----------

	void add_head ( ListItem<T> * item ) {
		item->prev = (ListItem<T> *)0;
		item->next = first;
		if (first) {
			first->prev = item;
		} else {
			last = item;
		}
		first = item;
		len++;
	}
	
	int add_head ( const T & val ) {
		ListItem<T> * item = new ListItem<T> (val);
		if (! item) return -1;
		add_head (item);
		return 0;
	}
	
	ListItem<T> * rem_head (void) {
		ListItem<T> * res = first;
		if (first) {
			first = first->next;
			if (first) {
				first->prev = (ListItem<T> *)0;
			} else {
				last = (ListItem<T> *)0;
			}
			len--;
		}
		return res;
	};

	void add_tail ( ListItem<T> * item ) {
		item->next = (ListItem<T> *)0;
		item->prev = last;
		if (last) {
			last->next = item;
		} else {
			first = item;
		}
		last = item;
		len++;
	};

	int add_tail ( const T & val ) {
		ListItem<T> * item = new ListItem<T> (val);
		if (! item) return -1;
		add_tail (item);
		return 0;
	};

	void insert(ListItem<T> * item, ListItem<T> * pitem) {
		if (! pitem) {
			add_head(item);
		} else {
			if (! pitem->next) {
				add_tail(item);
			} else {
				item->next = pitem->next;
				item->prev = pitem;
				pitem->next = item;
				item->next->prev = item;
				len++;
			}
		}
	};

	int insert ( const T & val, ListItem<T> * pitem ) {
		ListItem<T> * item = new ListItem<T> (val);
		if (! item) return -1;
		insert (item, pitem);
		return 0;
	};

	ListItem<T> * rem_tail (void) {
		ListItem<T> * res = last;
		if (last) {
			last = last->prev;
			if (last) {
				last->next = (ListItem<T> *)0;
			} else {
				first = (ListItem<T> *)0; 
			}
			len--;
		}
		return res;
	};

	void remove(ListItem<T> * item) {
		if (item->prev) {
			item->prev->next = item->next;			
		} else {
			first = item->next;
		}
		if (item->next) {
			item->next->prev = item->prev;
		}	else {
			last = item->prev;
		}
		len--;
	};
	
	
	void append(List & rv) {	
		if (!first) {
			first = rv.first;
		} else {
			last->next = rv.first;
		}
		if (rv.first) {
			rv.first->prev = last;
		}
		if (rv.last) {
			last = rv.last;
		}
		
		rv.first = 0;
		rv.last = 0;
		
		len += rv.len;
		rv.len = 0;
		
	}

	// ----------- 'const' Functions ---------

	unsigned long length(void) const { return len; };
	
	ListItem<T> * get_head(void) const {
		return first;
	};

	ListItem<T> * get_tail(void) const {
		return last;
	};
	
	friend BIstream & operator>> (BIstream & in, List<T> & list);
};

template <class T>
void List<T>::clear(void) {
	ListItem<T> * p = first;
	while (p) {
		ListItem<T> * tp = p;
		p = p->next;
		delete tp;
	}
	len = 0;
	last = first = (ListItem<T> *)0;
}

// -----------------------------------------------------------------
// I/O routines  (non-member functions)
// -----------------------------------------------------------------


template <class T>
ostream & operator<< (ostream & o, const List<T> & l) {
	o << "List with " << l.length() << " elements:\n";
	ListItem<T> * li = l.get_head();
	int i = 1;
	while (li) {
		o << i << ". element: ";
		o << (T &)*li << "\n";
		li = li->get_next();
		i++;
	}
	return o;
}

class BIstream;

// important: this operator APPENDS to the list!!!
template <class T>
BIstream & operator>> (BIstream & in, List<T> & list) {
	int l;
	in >> l;
	if (in.fail()) return in;
	for (int cnt = 0; cnt < l; cnt++) {
		ListItem<T> * li = new ListItem<T>;
		in >> (T &)(*li);
		list.add_tail(li);
		if (in.fail()) return in;
	}
	return in;
}

class BOstream;

template <class T>
BOstream & operator<< (BOstream & o, const List<T> & l) {
	o << l.length();
	if (o.fail()) return o;
	ListItem<T> * li = l.get_head();
	while (li) {
		o << (T &)(*li);
		if (o.fail()) return o;
		li = li->get_next();
	}
	return o;
}


#endif List_h

Attachment: pgpg0ZuDja0Q0.pgp
Description: PGP signature

Reply via email to