epoc32/include/stdapis/boost/graph/reverse_graph.hpp
branchSymbian2
changeset 2 2fe1408b6811
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
       
     1 //  (C) Copyright David Abrahams 2000.
       
     2 // Distributed under the Boost Software License, Version 1.0. (See
       
     3 // accompanying file LICENSE_1_0.txt or copy at
       
     4 // http://www.boost.org/LICENSE_1_0.txt)
       
     5 
       
     6 #ifndef REVERSE_GRAPH_DWA092300_H_
       
     7 # define REVERSE_GRAPH_DWA092300_H_
       
     8 
       
     9 #include <boost/graph/adjacency_iterator.hpp>
       
    10 #include <boost/graph/properties.hpp>
       
    11 #include <boost/tuple/tuple.hpp>
       
    12 
       
    13 namespace boost {
       
    14 
       
    15 struct reverse_graph_tag { };
       
    16 
       
    17   namespace detail {
       
    18 
       
    19     template <bool isEdgeList> struct choose_rev_edge_iter { };
       
    20     template <> struct choose_rev_edge_iter<true> {
       
    21       template <class G> struct bind_ {
       
    22         typedef typename graph_traits<G>::edge_iterator type;
       
    23       };
       
    24     };
       
    25     template <> struct choose_rev_edge_iter<false> {
       
    26       template <class G> struct bind_ {
       
    27         typedef void type;
       
    28       };
       
    29     };
       
    30 
       
    31   } // namespace detail
       
    32 
       
    33 template <class BidirectionalGraph, class GraphRef = const BidirectionalGraph&>
       
    34 class reverse_graph {
       
    35     typedef reverse_graph<BidirectionalGraph, GraphRef> Self;
       
    36     typedef graph_traits<BidirectionalGraph> Traits;
       
    37  public:
       
    38     typedef BidirectionalGraph base_type;
       
    39 
       
    40     // Constructor
       
    41     reverse_graph(GraphRef g) : m_g(g) {}
       
    42 
       
    43     // Graph requirements
       
    44     typedef typename Traits::vertex_descriptor vertex_descriptor;
       
    45     typedef typename Traits::edge_descriptor edge_descriptor;
       
    46     typedef typename Traits::directed_category directed_category;
       
    47     typedef typename Traits::edge_parallel_category edge_parallel_category;
       
    48     typedef typename Traits::traversal_category traversal_category;
       
    49 
       
    50     // IncidenceGraph requirements
       
    51     typedef typename Traits::in_edge_iterator out_edge_iterator;
       
    52     typedef typename Traits::degree_size_type degree_size_type;
       
    53 
       
    54     // BidirectionalGraph requirements
       
    55     typedef typename Traits::out_edge_iterator in_edge_iterator;
       
    56 
       
    57     // AdjacencyGraph requirements
       
    58   typedef typename adjacency_iterator_generator<Self,
       
    59     vertex_descriptor, out_edge_iterator>::type adjacency_iterator;
       
    60 
       
    61     // VertexListGraph requirements
       
    62     typedef typename Traits::vertex_iterator vertex_iterator;
       
    63 
       
    64     // EdgeListGraph requirements
       
    65     enum { is_edge_list = is_convertible<traversal_category,
       
    66            edge_list_graph_tag>::value };
       
    67     typedef detail::choose_rev_edge_iter<is_edge_list> ChooseEdgeIter;
       
    68     typedef typename ChooseEdgeIter::
       
    69       template bind_<BidirectionalGraph>::type   edge_iterator;
       
    70     typedef typename Traits::vertices_size_type vertices_size_type;
       
    71     typedef typename Traits::edges_size_type edges_size_type;
       
    72 
       
    73     // More typedefs used by detail::edge_property_map, vertex_property_map
       
    74     typedef typename BidirectionalGraph::edge_property_type
       
    75       edge_property_type;
       
    76     typedef typename BidirectionalGraph::vertex_property_type
       
    77       vertex_property_type;
       
    78     typedef reverse_graph_tag graph_tag;
       
    79 
       
    80 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
    81     // Bundled properties support
       
    82     template<typename Descriptor>
       
    83     typename graph::detail::bundled_result<BidirectionalGraph, 
       
    84                                            Descriptor>::type&
       
    85     operator[](Descriptor x)
       
    86     { return m_g[x]; }
       
    87 
       
    88     template<typename Descriptor>
       
    89     typename graph::detail::bundled_result<BidirectionalGraph, 
       
    90                                            Descriptor>::type const&
       
    91     operator[](Descriptor x) const
       
    92     { return m_g[x]; }
       
    93 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
    94 
       
    95     static vertex_descriptor null_vertex()
       
    96     { return Traits::null_vertex(); }
       
    97 
       
    98     // would be private, but template friends aren't portable enough.
       
    99  // private:
       
   100     GraphRef m_g;
       
   101 };
       
   102 
       
   103 #ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
   104   template<typename Graph, typename GraphRef>
       
   105   struct vertex_bundle_type<reverse_graph<Graph, GraphRef> > 
       
   106     : vertex_bundle_type<Graph> { };
       
   107 
       
   108   template<typename Graph, typename GraphRef>
       
   109   struct edge_bundle_type<reverse_graph<Graph, GraphRef> > 
       
   110     : edge_bundle_type<Graph> { };
       
   111 #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
       
   112 
       
   113 template <class BidirectionalGraph>
       
   114 inline reverse_graph<BidirectionalGraph>
       
   115 make_reverse_graph(const BidirectionalGraph& g)
       
   116 {
       
   117     return reverse_graph<BidirectionalGraph>(g);
       
   118 }
       
   119 
       
   120 template <class BidirectionalGraph>
       
   121 inline reverse_graph<BidirectionalGraph, BidirectionalGraph&>
       
   122 make_reverse_graph(BidirectionalGraph& g)
       
   123 {
       
   124     return reverse_graph<BidirectionalGraph, BidirectionalGraph&>(g);
       
   125 }
       
   126 
       
   127 template <class BidirectionalGraph, class GRef>
       
   128 std::pair<typename reverse_graph<BidirectionalGraph>::vertex_iterator,
       
   129           typename reverse_graph<BidirectionalGraph>::vertex_iterator>
       
   130 vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
       
   131 {
       
   132     return vertices(g.m_g);
       
   133 }
       
   134 
       
   135 template <class BidirectionalGraph, class GRef>
       
   136 std::pair<typename reverse_graph<BidirectionalGraph>::edge_iterator,
       
   137           typename reverse_graph<BidirectionalGraph>::edge_iterator>
       
   138 edges(const reverse_graph<BidirectionalGraph,GRef>& g)
       
   139 {
       
   140     return edges(g.m_g);
       
   141 }
       
   142 
       
   143 template <class BidirectionalGraph, class GRef>
       
   144 inline std::pair<typename BidirectionalGraph::in_edge_iterator,
       
   145                  typename BidirectionalGraph::in_edge_iterator>
       
   146 out_edges(const typename BidirectionalGraph::vertex_descriptor u,
       
   147           const reverse_graph<BidirectionalGraph,GRef>& g)
       
   148 {
       
   149     return in_edges(u, g.m_g);
       
   150 }
       
   151 
       
   152 template <class BidirectionalGraph, class GRef>
       
   153 inline typename BidirectionalGraph::vertices_size_type
       
   154 num_vertices(const reverse_graph<BidirectionalGraph,GRef>& g)
       
   155 {
       
   156     return num_vertices(g.m_g);
       
   157 }
       
   158 
       
   159 template <class BidirectionalGraph, class GRef>
       
   160 inline typename reverse_graph<BidirectionalGraph>::edges_size_type
       
   161 num_edges(const reverse_graph<BidirectionalGraph,GRef>& g)
       
   162 {
       
   163     return num_edges(g.m_g);
       
   164 }
       
   165 
       
   166 template <class BidirectionalGraph, class GRef>
       
   167 inline typename BidirectionalGraph::degree_size_type
       
   168 out_degree(const typename BidirectionalGraph::vertex_descriptor u,
       
   169            const reverse_graph<BidirectionalGraph,GRef>& g)
       
   170 {
       
   171     return in_degree(u, g.m_g);
       
   172 }
       
   173 
       
   174 template <class BidirectionalGraph, class GRef>
       
   175 inline std::pair<typename BidirectionalGraph::edge_descriptor, bool>
       
   176 edge(const typename BidirectionalGraph::vertex_descriptor u,
       
   177      const typename BidirectionalGraph::vertex_descriptor v,
       
   178      const reverse_graph<BidirectionalGraph,GRef>& g)
       
   179 {
       
   180     return edge(v, u, g.m_g);
       
   181 }
       
   182 
       
   183 template <class BidirectionalGraph, class GRef>
       
   184 inline std::pair<typename BidirectionalGraph::out_edge_iterator,
       
   185     typename BidirectionalGraph::out_edge_iterator>
       
   186 in_edges(const typename BidirectionalGraph::vertex_descriptor u,
       
   187          const reverse_graph<BidirectionalGraph,GRef>& g)
       
   188 {
       
   189     return out_edges(u, g.m_g);
       
   190 }
       
   191 
       
   192 template <class BidirectionalGraph, class GRef>
       
   193 inline std::pair<typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator,
       
   194     typename reverse_graph<BidirectionalGraph,GRef>::adjacency_iterator>
       
   195 adjacent_vertices(const typename BidirectionalGraph::vertex_descriptor u,
       
   196                   const reverse_graph<BidirectionalGraph,GRef>& g)
       
   197 {
       
   198     typedef reverse_graph<BidirectionalGraph,GRef> Graph;
       
   199     typename Graph::out_edge_iterator first, last;
       
   200     tie(first, last) = out_edges(u, g);
       
   201     typedef typename Graph::adjacency_iterator adjacency_iterator;
       
   202     return std::make_pair(adjacency_iterator(first, const_cast<Graph*>(&g)),
       
   203                           adjacency_iterator(last, const_cast<Graph*>(&g)));
       
   204 }
       
   205 
       
   206 template <class BidirectionalGraph, class GRef>
       
   207 inline typename BidirectionalGraph::degree_size_type
       
   208 in_degree(const typename BidirectionalGraph::vertex_descriptor u,
       
   209           const reverse_graph<BidirectionalGraph,GRef>& g)
       
   210 {
       
   211     return out_degree(u, g.m_g);
       
   212 }
       
   213 
       
   214 template <class Edge, class BidirectionalGraph, class GRef>
       
   215 inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
       
   216 source(const Edge& e, const reverse_graph<BidirectionalGraph,GRef>& g)
       
   217 {
       
   218     return target(e, g.m_g);
       
   219 }
       
   220 
       
   221 template <class Edge, class BidirectionalGraph, class GRef>
       
   222 inline typename graph_traits<BidirectionalGraph>::vertex_descriptor
       
   223 target(const Edge& e, const reverse_graph<BidirectionalGraph,GRef>& g)
       
   224 {
       
   225     return source(e, g.m_g);
       
   226 }
       
   227 
       
   228 
       
   229 namespace detail {
       
   230 
       
   231   struct reverse_graph_vertex_property_selector {
       
   232     template <class ReverseGraph, class Property, class Tag>
       
   233     struct bind_ {
       
   234       typedef typename ReverseGraph::base_type Graph;
       
   235       typedef property_map<Graph, Tag> PMap;
       
   236       typedef typename PMap::type type;
       
   237       typedef typename PMap::const_type const_type;
       
   238     };
       
   239   };
       
   240 
       
   241   struct reverse_graph_edge_property_selector {
       
   242     template <class ReverseGraph, class Property, class Tag>
       
   243     struct bind_ {
       
   244       typedef typename ReverseGraph::base_type Graph;
       
   245       typedef property_map<Graph, Tag> PMap;
       
   246       typedef typename PMap::type type;
       
   247       typedef typename PMap::const_type const_type;
       
   248     };
       
   249   };
       
   250 
       
   251 } // namespace detail
       
   252 
       
   253 template <>
       
   254 struct vertex_property_selector<reverse_graph_tag> {
       
   255   typedef detail::reverse_graph_vertex_property_selector type;
       
   256 };
       
   257 
       
   258 template <>
       
   259 struct edge_property_selector<reverse_graph_tag> {
       
   260   typedef detail::reverse_graph_edge_property_selector type;
       
   261 };
       
   262 
       
   263 template <class BidirGraph, class GRef, class Property>
       
   264 typename property_map<BidirGraph, Property>::type
       
   265 get(Property p, reverse_graph<BidirGraph,GRef>& g)
       
   266 {
       
   267   return get(p, g.m_g);
       
   268 }
       
   269 
       
   270 template <class BidirGraph, class GRef, class Property>
       
   271 typename property_map<BidirGraph, Property>::const_type
       
   272 get(Property p, const reverse_graph<BidirGraph,GRef>& g)
       
   273 {
       
   274   const BidirGraph& gref = g.m_g; // in case GRef is non-const
       
   275   return get(p, gref);
       
   276 }
       
   277 
       
   278 template <class BidirectionalGraph, class GRef, class Property, class Key>
       
   279 typename property_traits<
       
   280   typename property_map<BidirectionalGraph, Property>::const_type
       
   281 >::value_type
       
   282 get(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k)
       
   283 {
       
   284   return get(p, g.m_g, k);
       
   285 }
       
   286 
       
   287 template <class BidirectionalGraph, class GRef, class Property, class Key, class Value>
       
   288 void
       
   289 put(Property p, const reverse_graph<BidirectionalGraph,GRef>& g, const Key& k,
       
   290     const Value& val)
       
   291 {
       
   292   put(p, g.m_g, k, val);
       
   293 }
       
   294 
       
   295 template<typename BidirectionalGraph, typename GRef, typename Tag,
       
   296          typename Value>
       
   297 inline void
       
   298 set_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag, 
       
   299              const Value& value)
       
   300 {
       
   301   set_property(g.m_g, tag, value);
       
   302 }
       
   303 
       
   304 template<typename BidirectionalGraph, typename GRef, typename Tag>
       
   305 inline
       
   306 typename graph_property<BidirectionalGraph, Tag>::type
       
   307 get_property(const reverse_graph<BidirectionalGraph,GRef>& g, Tag tag)
       
   308 {
       
   309   return get_property(g.m_g, tag);
       
   310 }
       
   311 
       
   312 } // namespace boost
       
   313 
       
   314 #endif