#ifndef my_include_list_hh
#define my_include_list_hh
template<class X>
class List
{
friend class Node<X>;
private:
Node<X>* private_first;
Node<X>* private_last;
private:
List(const List&);
List& operator= (const List&);
public:
List()
{
private_first = null;
private_last = null;
}
~List();
Node<X>* first() const { return private_first; }
Node<X>* last() const { return private_last; }
void add(const X& x);
void add_to_start(const X& x);
void add_to_end(const X& x);
find_element
int length() const;
bool is_empty() const;
void reverse();
List<X>* clone();
void OK() const;
};
template<class X>
class Node
{
friend class List<X>;
private:
Node() {}
private:
Node(const Node&);
Node& operator= (const Node&);
private:
Node* private_next;
Node* private_previous;
List<X>* private_owner;
public:
X current;
~Node();
bool is_first() { return private_previous == null; }
bool is_last() { return private_next == null; }
Node* next() const { return private_next; }
Node* previous() const { return private_previous; }
Node* cyclic_next() const;
Node* cyclic_previous() const;
List<X>* owner() const { return private_owner; }
void add(const X& x);
void add_previous(const X& x);
void add_next(const X& x);
};
#define INSTANTIATE_OUTPUT_PROTOTYPE(X) Writer& operator<<(Writer& w, const List<X>& x)
#define INSTANTIATE_OUTPUT_DEFINITION(X) \
INSTANTIATE_OUTPUT_PROTOTYPE(X) \
{ \
w << '('; \
int count = 0; \
for (Node<X>* n=x.first(); n != null; n=n->next(), count++) { \
if (count != 0) { \
cout << ' '; \
} \
w << n->current; \
} \
w << ')'; \
return w; \
}
#define INSTANTIATE_OUTPUT_DEFINITION_STAR(X) \
INSTANTIATE_OUTPUT_PROTOTYPE(X) \
{ \
w << '('; \
int count = 0; \
for (Node<X>* n=x.first(); n != null; n=n->next(), count++) { \
if (count != 0) { \
cout << ' '; \
} \
if (n->current != null) { \
w << *n->current; \
} \
else { \
w << "null"; \
} \
} \
w << ')'; \
return w; \
}
#endif