Code Fragment: NodeList2



  // ... (continuation of NodeList)
  Position first() const 				// return first element
      throw(EmptyContainerException) {
    if (isEmpty()) throw EmptyContainerException("List is empty");
    return Position(header->next);
  }
  Position before(const Position& p) const 		// return item before p
      throw(BoundaryViolationException, InvalidPositionException) {
    NodePtr v = nodePtr(p);
    NodePtr prev = v->prev;
    if (prev == header)
      throw BoundaryViolationException("Advance past beginning of list");
    return Position(prev);
  }
  Position insertAfter(const Position& p, const Object& element)
      throw(InvalidPositionException) {			// insert after p
    NodePtr v = nodePtr(p);
    sz++;
    NodePtr newNode  = new Node(element, v, v->next);
    v->next->prev    = newNode;				// link node into list
    v->next	     = newNode;
    return Position(newNode);
  }
  void remove(const Position& p)			// remove a given node
      throw(InvalidPositionException) {
    sz--;
    NodePtr v = nodePtr(p);
    v->prev->next    = v->next;				// unlink from the list
    v->next->prev    = v->prev;
    delete v;
  }
  void replaceElement(const Position& p, const Object& element)
      throw(InvalidPositionException) {			// replace element
    NodePtr v  = nodePtr(p);
    v->element = element;
  }
  // ... (some functions omitted)
};