template <typename Object> class NodeList { protected: // ... (insert Node class definition here) public: // ... (insert Position class definition here) protected: // utility to convert Position to node pointer NodePtr nodePtr(const Position& p) const throw(InvalidPositionException) { if (p.node == NULL) throw InvalidPositionException("Attempt to use null position"); else return p.node; } protected: // data members int sz; // number of items NodePtr header; // head of list sentinel NodePtr trailer; // tail of list sentinel public: NodeList() { // default constructor sz = 0; header = new Node; // create sentinels trailer = new Node; header->next = trailer; // head points to trailer trailer->prev = header; // trailer points to head } int size() const // list size { return sz; } bool isEmpty() const // is the list empty? { return (sz == 0); } bool isFirst(const Position& p) const // is this the first? throw(InvalidPositionException) { NodePtr v = nodePtr(p); return v->prev == header; } bool isLast(const Position& p) const // is this the last? throw(InvalidPositionException) { NodePtr v = nodePtr(p); return v->next == trailer; } // ...