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