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
PGP signature