src/work/klao/path.h
changeset 715 665689d86225
parent 683 3cbf51510180
child 803 c3d832275e69
equal deleted inserted replaced
10:56cb8321e311 11:4f5027e89a22
     1 // -*- c++ -*- //
     1 // -*- c++ -*- //
     2 
     2 
     3 ///\ingroup datas
     3 /**
       
     4 @defgroup paths Path Structures
       
     5 @ingroup datas
       
     6 \brief Path structures implemented in Hugo.
       
     7 
       
     8 Hugolib provides flexible data structures
       
     9 to work with paths.
       
    10 
       
    11 All of them have the same interface, especially they can be built or extended
       
    12 using a standard Builder subclass. This make is easy to have e.g. the Dijkstra
       
    13 algorithm to store its result in any kind of path structure.
       
    14 
       
    15 */
       
    16 
       
    17 ///\ingroup paths
     4 ///\file
    18 ///\file
     5 ///\brief Classes for representing paths in graphs.
    19 ///\brief Classes for representing paths in graphs.
     6 
    20 
     7 #ifndef HUGO_PATH_H
    21 #ifndef HUGO_PATH_H
     8 #define HUGO_PATH_H
    22 #define HUGO_PATH_H
    15 #include <hugo/error.h>
    29 #include <hugo/error.h>
    16 #include <debug.h>
    30 #include <debug.h>
    17 
    31 
    18 namespace hugo {
    32 namespace hugo {
    19 
    33 
    20   /// \addtogroup datas
    34   /// \addtogroup paths
    21   /// @{
    35   /// @{
    22 
    36 
    23 
    37 
    24   //! \brief A structure for representing directed path in a graph.
    38   //! \brief A structure for representing directed path in a graph.
    25   //!
    39   //!
    33   //!
    47   //!
    34   //! \todo Thoroughfully check all the range and consistency tests.
    48   //! \todo Thoroughfully check all the range and consistency tests.
    35   template<typename Graph, typename DM = DefaultDebugMode>
    49   template<typename Graph, typename DM = DefaultDebugMode>
    36   class DirPath {
    50   class DirPath {
    37   public:
    51   public:
    38     typedef typename Graph::Edge GraphEdge;
    52     /// Edge type of the underlying graph.
       
    53     typedef typename Graph::Edge GraphEdge; 
       
    54     /// Node type of the underlying graph.
    39     typedef typename Graph::Node GraphNode;
    55     typedef typename Graph::Node GraphNode;
    40     class NodeIt;
    56     class NodeIt;
    41     class EdgeIt;
    57     class EdgeIt;
    42 
    58 
    43   protected:
    59   protected:
   150 	fault("DirPath::tail() on invalid iterator");
   166 	fault("DirPath::tail() on invalid iterator");
   151       return NodeIt(*this, e.idx);
   167       return NodeIt(*this, e.idx);
   152     }
   168     }
   153 
   169 
   154 
   170 
   155     /*** Iterator classes ***/
   171     /* Iterator classes */
       
   172 
       
   173     /**
       
   174      * \brief Iterator class to iterate on the edges of the paths
       
   175      * 
       
   176      * \ingroup paths
       
   177      * This class is used to iterate on the edges of the paths
       
   178      *
       
   179      * Of course it converts to Graph::Edge
       
   180      * 
       
   181      * \todo Its interface differs from the standard edge iterator.
       
   182      * Yes, it shouldn't.
       
   183      */
   156     class EdgeIt {
   184     class EdgeIt {
   157       friend class DirPath;
   185       friend class DirPath;
   158 
   186 
   159       int idx;
   187       int idx;
   160       const DirPath *p;
   188       const DirPath *p;
   161     public:
   189     public:
       
   190       /// Default constructor
   162       EdgeIt() {}
   191       EdgeIt() {}
       
   192       /// Invalid constructor
   163       EdgeIt(Invalid) : idx(-1), p(0) {}
   193       EdgeIt(Invalid) : idx(-1), p(0) {}
       
   194       /// Constructor with starting point
   164       EdgeIt(const DirPath &_p, int _idx = 0) :
   195       EdgeIt(const DirPath &_p, int _idx = 0) :
   165 	idx(_idx), p(&_p) { validate(); }
   196 	idx(_idx), p(&_p) { validate(); }
   166 
   197 
       
   198       ///Validity check
   167       bool valid() const { return idx!=-1; }
   199       bool valid() const { return idx!=-1; }
   168 
   200 
       
   201       ///Conversion to Graph::Edge
   169       operator GraphEdge () const {
   202       operator GraphEdge () const {
   170 	return valid() ? p->edges[idx] : INVALID;
   203 	return valid() ? p->edges[idx] : INVALID;
   171       }
   204       }
       
   205 
       
   206       /// Next edge
   172       EdgeIt& operator++() { ++idx; validate(); return *this; }
   207       EdgeIt& operator++() { ++idx; validate(); return *this; }
   173 
   208 
       
   209       /// Comparison operator
   174       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
   210       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
       
   211       /// Comparison operator
   175       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
   212       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
       
   213       /// Comparison operator
   176       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
   214       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
   177 
   215 
   178     private:
   216     private:
   179       // FIXME: comparison between signed and unsigned...
   217       // FIXME: comparison between signed and unsigned...
   180       // Jo ez igy? Vagy esetleg legyen a length() int?
   218       // Jo ez igy? Vagy esetleg legyen a length() int?
   181       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   219       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   182     };
   220     };
   183 
   221 
       
   222     /**
       
   223      * \brief Iterator class to iterate on the nodes of the paths
       
   224      * 
       
   225      * \ingroup paths
       
   226      * This class is used to iterate on the nodes of the paths
       
   227      *
       
   228      * Of course it converts to Graph::Node
       
   229      * 
       
   230      * \todo Its interface differs from the standard node iterator.
       
   231      * Yes, it shouldn't.
       
   232      */
   184     class NodeIt {
   233     class NodeIt {
   185       friend class DirPath;
   234       friend class DirPath;
   186 
   235 
   187       int idx;
   236       int idx;
   188       const DirPath *p;
   237       const DirPath *p;
   189     public:
   238     public:
       
   239       /// Default constructor
   190       NodeIt() {}
   240       NodeIt() {}
       
   241       /// Invalid constructor
   191       NodeIt(Invalid) : idx(-1), p(0) {}
   242       NodeIt(Invalid) : idx(-1), p(0) {}
       
   243       /// Constructor with starting point
   192       NodeIt(const DirPath &_p, int _idx = 0) :
   244       NodeIt(const DirPath &_p, int _idx = 0) :
   193 	idx(_idx), p(&_p) { validate(); }
   245 	idx(_idx), p(&_p) { validate(); }
   194 
   246 
       
   247       ///Validity check
   195       bool valid() const { return idx!=-1; }
   248       bool valid() const { return idx!=-1; }
   196 
   249 
       
   250       ///Conversion to Graph::Node
   197       operator const GraphNode& () const {
   251       operator const GraphNode& () const {
   198 	if(idx >= p->length())
   252 	if(idx >= p->length())
   199 	  return p->to();
   253 	  return p->to();
   200 	else if(idx >= 0)
   254 	else if(idx >= 0)
   201 	  return p->gr->tail(p->edges[idx]);
   255 	  return p->gr->tail(p->edges[idx]);
   202 	else
   256 	else
   203 	  return INVALID;
   257 	  return INVALID;
   204       }
   258       }
       
   259       /// Next node
   205       NodeIt& operator++() { ++idx; validate(); return *this; }
   260       NodeIt& operator++() { ++idx; validate(); return *this; }
   206 
   261 
       
   262       /// Comparison operator
   207       bool operator==(const NodeIt& e) const { return idx==e.idx; }
   263       bool operator==(const NodeIt& e) const { return idx==e.idx; }
       
   264       /// Comparison operator
   208       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
   265       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
       
   266       /// Comparison operator
   209       bool operator<(const NodeIt& e) const { return idx<e.idx; }
   267       bool operator<(const NodeIt& e) const { return idx<e.idx; }
   210 
   268 
   211     private:
   269     private:
   212       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   270       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   213     };
   271     };
   215     friend class Builder;    
   273     friend class Builder;    
   216 
   274 
   217     /**
   275     /**
   218      * \brief Class to build paths
   276      * \brief Class to build paths
   219      * 
   277      * 
   220      * \ingroup datas
   278      * \ingroup paths
   221      * This class is used to fill a path with edges.
   279      * This class is used to fill a path with edges.
   222      *
   280      *
   223      * You can push new edges to the front and to the back of the path in
   281      * You can push new edges to the front and to the back of the path in
   224      * arbitrary order then you should commit these changes to the graph.
   282      * arbitrary order then you should commit these changes to the graph.
   225      *
   283      *
   283 	}
   341 	}
   284       }
   342       }
   285 
   343 
   286       // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
   344       // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
   287       // Hogy kenyelmes egy ilyet hasznalni?
   345       // Hogy kenyelmes egy ilyet hasznalni?
       
   346   
       
   347       ///Reserve storage in advance for the builder
       
   348 
       
   349       ///If you know an reasonable upper bound of the number of the edges
       
   350       ///to add, using this function you can speed up the building.
   288       void reserve(size_t r) {
   351       void reserve(size_t r) {
   289 	front.reserve(r);
   352 	front.reserve(r);
   290 	back.reserve(r);
   353 	back.reserve(r);
   291       }
   354       }
   292 
   355 
   347   //!
   410   //!
   348   //! \todo Thoroughfully check all the range and consistency tests.
   411   //! \todo Thoroughfully check all the range and consistency tests.
   349   template<typename Graph, typename DM = DefaultDebugMode>
   412   template<typename Graph, typename DM = DefaultDebugMode>
   350   class UndirPath {
   413   class UndirPath {
   351   public:
   414   public:
       
   415     /// Edge type of the underlying graph.
   352     typedef typename Graph::Edge GraphEdge;
   416     typedef typename Graph::Edge GraphEdge;
   353     typedef typename Graph::Node GraphNode;
   417      /// Node type of the underlying graph.
       
   418    typedef typename Graph::Node GraphNode;
   354     class NodeIt;
   419     class NodeIt;
   355     class EdgeIt;
   420     class EdgeIt;
   356 
   421 
   357   protected:
   422   protected:
   358     const Graph *gr;
   423     const Graph *gr;
   464 	fault("UndirPath::tail() on invalid iterator");
   529 	fault("UndirPath::tail() on invalid iterator");
   465       return NodeIt(*this, e.idx);
   530       return NodeIt(*this, e.idx);
   466     }
   531     }
   467 
   532 
   468 
   533 
   469     /*** Iterator classes ***/
   534 
       
   535     /**
       
   536      * \brief Iterator class to iterate on the edges of the paths
       
   537      * 
       
   538      * \ingroup paths
       
   539      * This class is used to iterate on the edges of the paths
       
   540      *
       
   541      * Of course it converts to Graph::Edge
       
   542      * 
       
   543      * \todo Its interface differs from the standard edge iterator.
       
   544      * Yes, it shouldn't.
       
   545      */
   470     class EdgeIt {
   546     class EdgeIt {
   471       friend class UndirPath;
   547       friend class UndirPath;
   472 
   548 
   473       int idx;
   549       int idx;
   474       const UndirPath *p;
   550       const UndirPath *p;
   475     public:
   551     public:
       
   552       /// Default constructor
   476       EdgeIt() {}
   553       EdgeIt() {}
       
   554       /// Invalid constructor
   477       EdgeIt(Invalid) : idx(-1), p(0) {}
   555       EdgeIt(Invalid) : idx(-1), p(0) {}
       
   556       /// Constructor with starting point
   478       EdgeIt(const UndirPath &_p, int _idx = 0) :
   557       EdgeIt(const UndirPath &_p, int _idx = 0) :
   479 	idx(_idx), p(&_p) { validate(); }
   558 	idx(_idx), p(&_p) { validate(); }
   480 
   559 
       
   560       ///Validity check
   481       bool valid() const { return idx!=-1; }
   561       bool valid() const { return idx!=-1; }
   482 
   562 
       
   563       ///Conversion to Graph::Edge
   483       operator GraphEdge () const {
   564       operator GraphEdge () const {
   484 	return valid() ? p->edges[idx] : INVALID;
   565 	return valid() ? p->edges[idx] : INVALID;
   485       }
   566       }
   486       EdgeIt& operator++() { ++idx; validate(); return *this; }
   567       /// Next edge
   487 
   568      EdgeIt& operator++() { ++idx; validate(); return *this; }
       
   569 
       
   570       /// Comparison operator
   488       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
   571       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
       
   572       /// Comparison operator
   489       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
   573       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
       
   574       /// Comparison operator
   490       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
   575       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
   491 
   576 
   492     private:
   577     private:
   493       // FIXME: comparison between signed and unsigned...
   578       // FIXME: comparison between signed and unsigned...
   494       // Jo ez igy? Vagy esetleg legyen a length() int?
   579       // Jo ez igy? Vagy esetleg legyen a length() int?
   495       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   580       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   496     };
   581     };
   497 
   582 
       
   583     /**
       
   584      * \brief Iterator class to iterate on the nodes of the paths
       
   585      * 
       
   586      * \ingroup paths
       
   587      * This class is used to iterate on the nodes of the paths
       
   588      *
       
   589      * Of course it converts to Graph::Node
       
   590      * 
       
   591      * \todo Its interface differs from the standard node iterator.
       
   592      * Yes, it shouldn't.
       
   593      */
   498     class NodeIt {
   594     class NodeIt {
   499       friend class UndirPath;
   595       friend class UndirPath;
   500 
   596 
   501       int idx;
   597       int idx;
   502       const UndirPath *p;
   598       const UndirPath *p;
   503     public:
   599     public:
       
   600       /// Default constructor
   504       NodeIt() {}
   601       NodeIt() {}
       
   602       /// Invalid constructor
   505       NodeIt(Invalid) : idx(-1), p(0) {}
   603       NodeIt(Invalid) : idx(-1), p(0) {}
       
   604       /// Constructor with starting point
   506       NodeIt(const UndirPath &_p, int _idx = 0) :
   605       NodeIt(const UndirPath &_p, int _idx = 0) :
   507 	idx(_idx), p(&_p) { validate(); }
   606 	idx(_idx), p(&_p) { validate(); }
   508 
   607 
       
   608       ///Validity check
   509       bool valid() const { return idx!=-1; }
   609       bool valid() const { return idx!=-1; }
   510 
   610 
       
   611       ///Conversion to Graph::Node
   511       operator const GraphNode& () const {
   612       operator const GraphNode& () const {
   512 	if(idx >= p->length())
   613 	if(idx >= p->length())
   513 	  return p->to();
   614 	  return p->to();
   514 	else if(idx >= 0)
   615 	else if(idx >= 0)
   515 	  return p->gr->tail(p->edges[idx]);
   616 	  return p->gr->tail(p->edges[idx]);
   516 	else
   617 	else
   517 	  return INVALID;
   618 	  return INVALID;
   518       }
   619       }
       
   620       /// Next node
   519       NodeIt& operator++() { ++idx; validate(); return *this; }
   621       NodeIt& operator++() { ++idx; validate(); return *this; }
   520 
   622 
       
   623       /// Comparison operator
   521       bool operator==(const NodeIt& e) const { return idx==e.idx; }
   624       bool operator==(const NodeIt& e) const { return idx==e.idx; }
       
   625       /// Comparison operator
   522       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
   626       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
   523       bool operator<(const NodeIt& e) const { return idx<e.idx; }
   627        /// Comparison operator
       
   628      bool operator<(const NodeIt& e) const { return idx<e.idx; }
   524 
   629 
   525     private:
   630     private:
   526       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   631       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   527     };
   632     };
   528 
   633 
   529     friend class Builder;    
   634     friend class Builder;    
   530 
   635 
   531     /**
   636     /**
   532      * \brief Class to build paths
   637      * \brief Class to build paths
   533      * 
   638      * 
   534      * \ingroup datas
   639      * \ingroup paths
   535      * This class is used to fill a path with edges.
   640      * This class is used to fill a path with edges.
   536      *
   641      *
   537      * You can push new edges to the front and to the back of the path in
   642      * You can push new edges to the front and to the back of the path in
   538      * arbitrary order then you should commit these changes to the graph.
   643      * arbitrary order then you should commit these changes to the graph.
   539      *
   644      *
   597 	}
   702 	}
   598       }
   703       }
   599 
   704 
   600       // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
   705       // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
   601       // Hogy kenyelmes egy ilyet hasznalni?
   706       // Hogy kenyelmes egy ilyet hasznalni?
   602       void reserve(size_t r) {
   707 
       
   708       ///Reserve storage in advance for the builder
       
   709 
       
   710       ///If you know an reasonable upper bound of the number of the edges
       
   711       ///to add, using this function you can speed up the building.
       
   712        void reserve(size_t r) {
   603 	front.reserve(r);
   713 	front.reserve(r);
   604 	back.reserve(r);
   714 	back.reserve(r);
   605       }
   715       }
   606 
   716 
   607     private:
   717     private: