alpar@797: // -*- c++ -*- // alpar@797: alpar@807: ///\ingroup skeletons alpar@797: ///\file alpar@797: ///\brief Classes for representing paths in graphs. alpar@797: hegyi@831: #ifndef HUGO_SKELETON_PATH_H hegyi@831: #define HUGO_SKELETON_PATH_H alpar@797: alpar@797: #include alpar@797: alpar@797: namespace hugo { alpar@803: namespace skeleton { alpar@803: /// \addtogroup skeletons alpar@803: /// @{ hegyi@831: hegyi@831: alpar@806: //! \brief A skeletom structure for representing directed paths in a graph. alpar@803: //! alpar@806: //! A skeleton structure for representing directed paths in a graph. alpar@803: //! \param GR The graph type in which the path is. hegyi@831: //! alpar@803: //! In a sense, the path can be treated as a graph, for is has \c NodeIt alpar@803: //! and \c EdgeIt with the same usage. These types converts to the \c Node alpar@803: //! and \c Edge of the original graph. alpar@803: template alpar@803: class Path { alpar@803: public: hegyi@831: alpar@803: /// Type of the underlying graph. hegyi@818: typedef /*typename*/ GR Graph; alpar@803: /// Edge type of the underlying graph. hegyi@831: typedef typename Graph::Edge GraphEdge; alpar@803: /// Node type of the underlying graph. hegyi@818: typedef typename Graph::Node GraphNode; alpar@803: class NodeIt; alpar@803: class EdgeIt; hegyi@831: alpar@803: /// \param _G The graph in which the path is. alpar@803: /// alpar@803: Path(const Graph &_G) {} hegyi@831: alpar@803: /// Length of the path. hegyi@818: size_t length() const {return 0;} alpar@803: /// Returns whether the path is empty. hegyi@831: bool empty() const { return true;} hegyi@831: alpar@803: /// Resets the path to an empty path. alpar@803: void clear() {} alpar@797: alpar@803: /// \brief Starting point of the path. alpar@803: /// alpar@803: /// Starting point of the path. alpar@803: /// Returns INVALID if the path is empty. hegyi@818: GraphNode/*It*/ head() const {return INVALID;} alpar@803: /// \brief End point of the path. alpar@803: /// alpar@803: /// End point of the path. alpar@803: /// Returns INVALID if the path is empty. hegyi@818: GraphNode/*It*/ tail() const {return INVALID;} alpar@797: alpar@803: /// \brief First NodeIt/EdgeIt. alpar@803: /// alpar@803: /// Initializes node or edge iterator to point to the first alpar@803: /// node or edge. alpar@803: template alpar@803: It& first(It &i) const { return i=It(*this); } alpar@797: alpar@803: /// \brief The head of an edge. alpar@803: /// alpar@803: /// Returns node iterator pointing to the head node of the alpar@803: /// given edge iterator. hegyi@831: NodeIt head(const EdgeIt& e) const {return INVALID;} alpar@797: alpar@803: /// \brief The tail of an edge. alpar@803: /// alpar@803: /// Returns node iterator pointing to the tail node of the alpar@803: /// given edge iterator. hegyi@831: NodeIt tail(const EdgeIt& e) const {return INVALID;} alpar@797: alpar@797: alpar@803: /* Iterator classes */ alpar@797: alpar@803: /** alpar@803: * \brief Iterator class to iterate on the edges of the paths hegyi@831: * alpar@803: * \ingroup skeletons alpar@803: * This class is used to iterate on the edges of the paths alpar@803: * alpar@803: * Of course it converts to Graph::Edge hegyi@831: * alpar@803: */ alpar@803: class EdgeIt { alpar@803: public: alpar@803: /// Default constructor alpar@803: EdgeIt() {} alpar@803: /// Invalid constructor alpar@803: EdgeIt(Invalid) {} alpar@803: /// Constructor with starting point alpar@803: EdgeIt(const Path &_p) {} alpar@797: alpar@803: operator GraphEdge () const {} alpar@797: alpar@803: /// Next edge hegyi@831: EdgeIt& operator++() {return *this;} alpar@797: alpar@803: /// Comparison operator hegyi@823: bool operator==(const EdgeIt& e) const {return true;} alpar@803: /// Comparison operator hegyi@823: bool operator!=(const EdgeIt& e) const {return true;} alpar@803: // /// Comparison operator alpar@803: // /// \todo It is not clear what is the "natural" ordering. alpar@803: // bool operator<(const EdgeIt& e) const {} alpar@797: alpar@803: }; alpar@797: alpar@803: /** alpar@803: * \brief Iterator class to iterate on the nodes of the paths hegyi@831: * alpar@803: * \ingroup skeletons alpar@803: * This class is used to iterate on the nodes of the paths alpar@803: * alpar@803: * Of course it converts to Graph::Node. hegyi@831: * alpar@803: */ alpar@803: class NodeIt { alpar@803: public: alpar@803: /// Default constructor alpar@803: NodeIt() {} alpar@803: /// Invalid constructor alpar@803: NodeIt(Invalid) {} alpar@803: /// Constructor with starting point alpar@803: NodeIt(const Path &_p) {} alpar@797: alpar@803: ///Conversion to Graph::Node alpar@803: operator const GraphNode& () const {} alpar@803: /// Next node hegyi@831: NodeIt& operator++() {return *this;} alpar@797: alpar@803: /// Comparison operator hegyi@831: bool operator==(const NodeIt& e) const {return true;} alpar@803: /// Comparison operator hegyi@831: bool operator!=(const NodeIt& e) const {return true;} alpar@803: // /// Comparison operator alpar@803: // /// \todo It is not clear what is the "natural" ordering. alpar@803: // bool operator<(const NodeIt& e) const {} alpar@797: alpar@803: }; alpar@797: hegyi@831: friend class Builder; alpar@797: alpar@803: /** alpar@803: * \brief Class to build paths hegyi@831: * alpar@803: * \ingroup skeletons alpar@803: * This class is used to fill a path with edges. alpar@803: * alpar@803: * You can push new edges to the front and to the back of the path in alpar@803: * arbitrary order then you should commit these changes to the graph. alpar@803: * alpar@803: * While the builder is active (after the first modifying alpar@803: * operation and until the call of \ref commit()) alpar@803: * the underlining Path is in a alpar@803: * "transitional" state (operations on it have undefined result). alpar@803: */ alpar@803: class Builder { alpar@803: public: hegyi@818: hegyi@818: Path &P; hegyi@818: alpar@803: ///\param _P the path you want to fill in. alpar@803: /// alpar@803: Builder(Path &_P) : P(_P) {} alpar@797: alpar@803: /// Sets the starting node of the path. hegyi@831: alpar@803: /// Sets the starting node of the path. Edge added to the path alpar@803: /// afterwards have to be incident to this node. alpar@803: /// You \em must start building an empry path with this functions. alpar@803: /// (And you \em must \em not use it later). alpar@803: /// \sa pushFront() alpar@803: /// \sa pushBack() alpar@803: void setStartNode(const GraphNode &) {} alpar@797: alpar@803: ///Push a new edge to the front of the path alpar@797: alpar@803: ///Push a new edge to the front of the path. alpar@803: ///If the path is empty, you \em must call \ref setStartNode() before alpar@803: ///the first use of \ref pushFront(). alpar@803: void pushFront(const GraphEdge& e) {} alpar@797: alpar@803: ///Push a new edge to the back of the path alpar@797: alpar@803: ///Push a new edge to the back of the path. alpar@803: ///If the path is empty, you \em must call \ref setStartNode() before alpar@803: ///the first use of \ref pushBack(). alpar@803: void pushBack(const GraphEdge& e) {} alpar@797: alpar@803: ///Commit the changes to the path. alpar@803: void commit() {} alpar@797: alpar@803: ///Reserve (front) storage for the builder in advance. alpar@797: alpar@803: ///If you know an reasonable upper bound of the number of the edges alpar@803: ///to add to the front of the path, alpar@803: ///using this function you may speed up the building. alpar@803: void reserveFront(size_t r) {} alpar@803: ///Reserve (back) storage for the builder in advance. alpar@797: alpar@803: ///If you know an reasonable upper bound of the number of the edges alpar@803: ///to add to the back of the path, alpar@803: ///using this function you may speed up the building. alpar@803: void reserveBack(size_t r) {} alpar@803: }; alpar@797: }; alpar@797: alpar@803: ///@} alpar@797: } hegyi@831: alpar@797: } // namespace hugo alpar@797: hegyi@831: #endif // HUGO_SKELETON_PATH_H