gravatar
deba@inf.elte.hu
deba@inf.elte.hu
MSVC 2005 compatible path structure (ticket #87)
0 1 0
default
1 file changed with 25 insertions and 18 deletions:
↑ Collapse diff ↑
Show white space 192 line context
... ...
@@ -810,242 +810,249 @@
810 810
      ///Conversion to Digraph::Arc
811 811
      operator const Arc&() const {
812 812
        return path->nth(idx);
813 813
      }
814 814

	
815 815
      /// Next arc
816 816
      ArcIt& operator++() { 
817 817
        ++idx;
818 818
        if (idx >= path->length()) idx = -1; 
819 819
        return *this; 
820 820
      }
821 821

	
822 822
      /// Comparison operator
823 823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824 824
      /// Comparison operator
825 825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826 826
      /// Comparison operator
827 827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828 828

	
829 829
    private:
830 830
      const StaticPath *path;
831 831
      int idx;
832 832
    };
833 833

	
834 834
    /// \brief The nth arc.
835 835
    ///
836 836
    /// \pre n is in the [0..length() - 1] range
837 837
    const Arc& nth(int n) const {
838 838
      return arcs[n];
839 839
    }
840 840

	
841 841
    /// \brief The arc iterator pointing to the nth arc.
842 842
    ArcIt nthIt(int n) const {
843 843
      return ArcIt(*this, n);
844 844
    }
845 845

	
846 846
    /// \brief The length of the path.
847 847
    int length() const { return len; }
848 848

	
849 849
    /// \brief Return true when the path is empty.
850 850
    int empty() const { return len == 0; }
851 851

	
852 852
    /// \break Erase all arcs in the digraph.
853 853
    void clear() {
854 854
      len = 0;
855 855
      if (arcs) delete[] arcs;
856 856
      arcs = 0;
857 857
    }
858 858

	
859 859
    /// \brief The first arc of the path.
860 860
    const Arc& front() const {
861 861
      return arcs[0];
862 862
    }
863 863

	
864 864
    /// \brief The last arc of the path.
865 865
    const Arc& back() const {
866 866
      return arcs[len - 1];
867 867
    }
868 868

	
869 869

	
870 870
    typedef True BuildTag;
871 871

	
872 872
    template <typename CPath>
873 873
    void build(const CPath& path) {
874 874
      len = path.length();
875 875
      arcs = new Arc[len];
876 876
      int index = 0;
877 877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878 878
        arcs[index] = it;
879 879
        ++index;
880 880
      }
881 881
    }
882 882

	
883 883
    template <typename CPath>
884 884
    void buildRev(const CPath& path) {
885 885
      len = path.length();
886 886
      arcs = new Arc[len];
887 887
      int index = len;
888 888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889 889
        --index;
890 890
        arcs[index] = it;
891 891
      }
892 892
    }
893 893

	
894 894
  private:
895 895
    int len;
896 896
    Arc* arcs;
897 897
  };
898 898

	
899 899
  ///////////////////////////////////////////////////////////////////////
900 900
  // Additional utilities
901 901
  ///////////////////////////////////////////////////////////////////////
902 902

	
903 903
  namespace _path_bits {
904 904

	
905 905
    template <typename Path, typename Enable = void>
906
    struct RevTagIndicator {
906
    struct RevPathTagIndicator {
907 907
      static const bool value = false;
908 908
    };
909 909

	
910
    template <typename Digraph>
911
    struct RevTagIndicator<
912
      Digraph, 
913
      typename enable_if<typename Digraph::RevTag, void>::type
910
    template <typename Path>
911
    struct RevPathTagIndicator<
912
      Path, 
913
      typename enable_if<typename Path::RevPathTag, void>::type
914
      > {
915
      static const bool value = true;
916
    };
917

	
918
    template <typename Path, typename Enable = void>
919
    struct BuildTagIndicator {
920
      static const bool value = false;
921
    };
922

	
923
    template <typename Path>
924
    struct BuildTagIndicator<
925
      Path, 
926
      typename enable_if<typename Path::BuildTag, void>::type
914 927
    > {
915 928
      static const bool value = true;
916 929
    };
917 930

	
918 931
    template <typename Target, typename Source,
919
              typename BuildEnable = void, typename RevEnable = void>
932
	      bool buildEnable = BuildTagIndicator<Target>::value, 
933
	      bool revEnable = RevPathTagIndicator<Source>::value>
920 934
    struct PathCopySelector {
921 935
      static void copy(Target& target, const Source& source) {
922 936
        target.clear();
923 937
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
924 938
          target.addBack(it);
925 939
        }
926 940
      }
927 941
    };
928 942

	
929
    template <typename Target, typename Source, typename BuildEnable>
930
    struct PathCopySelector<
931
      Target, Source, BuildEnable, 
932
      typename enable_if<typename Source::RevPathTag, void>::type> {
943
    template <typename Target, typename Source>
944
    struct PathCopySelector<Target, Source, false, true> {
933 945
      static void copy(Target& target, const Source& source) {
934 946
        target.clear();
935 947
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
936 948
          target.addFront(it);
937 949
        }
938 950
      }
939 951
    };
940 952

	
941
    template <typename Target, typename Source, typename RevEnable>
942
    struct PathCopySelector<
943
      Target, Source, 
944
      typename enable_if<typename Target::BuildTag, void>::type, RevEnable> {
953
    template <typename Target, typename Source>
954
    struct PathCopySelector<Target, Source, true, false> {
945 955
      static void copy(Target& target, const Source& source) {
946 956
        target.clear();
947 957
        target.build(source);
948 958
      }
949 959
    };
950 960

	
951 961
    template <typename Target, typename Source>
952
    struct PathCopySelector<
953
      Target, Source, 
954
      typename enable_if<typename Target::BuildTag, void>::type,
955
      typename enable_if<typename Source::RevPathTag, void>::type> {
962
    struct PathCopySelector<Target, Source, true, true> {
956 963
      static void copy(Target& target, const Source& source) {
957 964
        target.clear();
958 965
        target.buildRev(source);
959 966
      }
960 967
    };
961 968

	
962 969
  }
963 970

	
964 971

	
965 972
  /// \brief Make a copy of a path.
966 973
  ///
967 974
  ///  This function makes a copy of a path.
968 975
  template <typename Target, typename Source>
969 976
  void copyPath(Target& target, const Source& source) {
970 977
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
971 978
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
972 979
  }
973 980

	
974 981
  /// \brief Check the consistency of a path.
975 982
  ///
976 983
  /// This function checks that the target of each arc is the same
977 984
  /// as the source of the next one. 
978 985
  /// 
979 986
  template <typename Digraph, typename Path>
980 987
  bool checkPath(const Digraph& digraph, const Path& path) {
981 988
    typename Path::ArcIt it(path);
982 989
    if (it == INVALID) return true;
983 990
    typename Digraph::Node node = digraph.target(it);
984 991
    ++it;
985 992
    while (it != INVALID) {
986 993
      if (digraph.source(it) != node) return false;
987 994
      node = digraph.target(it);
988 995
      ++it;
989 996
    }
990 997
    return true;
991 998
  }
992 999

	
993 1000
  /// \brief The source of a path
994 1001
  ///
995 1002
  /// This function returns the source of the given path.
996 1003
  template <typename Digraph, typename Path>
997 1004
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
998 1005
    return digraph.source(path.front());
999 1006
  }
1000 1007

	
1001 1008
  /// \brief The target of a path
1002 1009
  ///
1003 1010
  /// This function returns the target of the given path.
1004 1011
  template <typename Digraph, typename Path>
1005 1012
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1006 1013
    return digraph.target(path.back());
1007 1014
  }
1008 1015

	
1009 1016
  /// \brief Class which helps to iterate through the nodes of a path
1010 1017
  ///
1011 1018
  /// In a sense, the path can be treated as a list of arcs. The
1012 1019
  /// lemon path type stores only this list. As a consequence, it
1013 1020
  /// cannot enumerate the nodes in the path and the zero length paths
1014 1021
  /// cannot have a source node.
1015 1022
  ///
1016 1023
  /// This class implements the node iterator of a path structure. To
1017 1024
  /// provide this feature, the underlying digraph should be passed to
1018 1025
  /// the constructor of the iterator.
1019 1026
  template <typename Path>
1020 1027
  class PathNodeIt {
1021 1028
  private:
1022 1029
    const typename Path::Digraph *_digraph;
1023 1030
    typename Path::ArcIt _it;
1024 1031
    typename Path::Digraph::Node _nd;
1025 1032

	
1026 1033
  public:
1027 1034

	
1028 1035
    typedef typename Path::Digraph Digraph;
1029 1036
    typedef typename Digraph::Node Node;
1030 1037
    
1031 1038
    /// Default constructor
1032 1039
    PathNodeIt() {}
1033 1040
    /// Invalid constructor
1034 1041
    PathNodeIt(Invalid) 
1035 1042
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1036 1043
    /// Constructor
1037 1044
    PathNodeIt(const Digraph& digraph, const Path& path) 
1038 1045
      : _digraph(&digraph), _it(path) {
1039 1046
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1040 1047
    }
1041 1048
    /// Constructor
1042 1049
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src) 
1043 1050
      : _digraph(&digraph), _it(path), _nd(src) {}
1044 1051

	
1045 1052
    ///Conversion to Digraph::Node
1046 1053
    operator Node() const {
1047 1054
      return _nd;
1048 1055
    }
1049 1056

	
1050 1057
    /// Next node
1051 1058
    PathNodeIt& operator++() {
0 comments (0 inline)