epoc32/include/stdapis/boost/graph/neighbor_bfs.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
williamr@2
     1
//
williamr@2
     2
//=======================================================================
williamr@2
     3
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
williamr@2
     4
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
williamr@2
     5
//
williamr@2
     6
// Distributed under the Boost Software License, Version 1.0. (See
williamr@2
     7
// accompanying file LICENSE_1_0.txt or copy at
williamr@2
     8
// http://www.boost.org/LICENSE_1_0.txt)
williamr@2
     9
//=======================================================================
williamr@2
    10
//
williamr@2
    11
#ifndef BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
williamr@2
    12
#define BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
williamr@2
    13
williamr@2
    14
/*
williamr@2
    15
  Neighbor Breadth First Search
williamr@2
    16
  Like BFS, but traverses in-edges as well as out-edges.
williamr@2
    17
  (for directed graphs only. use normal BFS for undirected graphs)
williamr@2
    18
*/
williamr@2
    19
#include <boost/config.hpp>
williamr@2
    20
#include <vector>
williamr@2
    21
#include <boost/pending/queue.hpp>
williamr@2
    22
#include <boost/graph/graph_traits.hpp>
williamr@2
    23
#include <boost/graph/graph_concepts.hpp>
williamr@2
    24
#include <boost/graph/visitors.hpp>
williamr@2
    25
#include <boost/graph/named_function_params.hpp>
williamr@2
    26
williamr@2
    27
namespace boost {
williamr@2
    28
williamr@2
    29
  template <class Visitor, class Graph>
williamr@2
    30
  struct NeighborBFSVisitorConcept {
williamr@2
    31
    void constraints() {
williamr@2
    32
      function_requires< CopyConstructibleConcept<Visitor> >();
williamr@2
    33
      vis.initialize_vertex(u, g);
williamr@2
    34
      vis.discover_vertex(u, g);
williamr@2
    35
      vis.examine_vertex(u, g);
williamr@2
    36
      vis.examine_out_edge(e, g);
williamr@2
    37
      vis.examine_in_edge(e, g);
williamr@2
    38
      vis.tree_out_edge(e, g);
williamr@2
    39
      vis.tree_in_edge(e, g);
williamr@2
    40
      vis.non_tree_out_edge(e, g);
williamr@2
    41
      vis.non_tree_in_edge(e, g);
williamr@2
    42
      vis.gray_target(e, g);
williamr@2
    43
      vis.black_target(e, g);
williamr@2
    44
      vis.gray_source(e, g);
williamr@2
    45
      vis.black_source(e, g);
williamr@2
    46
      vis.finish_vertex(u, g);
williamr@2
    47
    }
williamr@2
    48
    Visitor vis;
williamr@2
    49
    Graph g;
williamr@2
    50
    typename graph_traits<Graph>::vertex_descriptor u;
williamr@2
    51
    typename graph_traits<Graph>::edge_descriptor e;
williamr@2
    52
  };
williamr@2
    53
williamr@2
    54
  template <class Visitors = null_visitor>
williamr@2
    55
  class neighbor_bfs_visitor {
williamr@2
    56
  public:
williamr@2
    57
    neighbor_bfs_visitor(Visitors vis = Visitors()) : m_vis(vis) { }
williamr@2
    58
williamr@2
    59
    template <class Vertex, class Graph>
williamr@2
    60
    void initialize_vertex(Vertex u, Graph& g) {
williamr@2
    61
      invoke_visitors(m_vis, u, g, on_initialize_vertex());      
williamr@2
    62
    }
williamr@2
    63
    template <class Vertex, class Graph>
williamr@2
    64
    void discover_vertex(Vertex u, Graph& g) {
williamr@2
    65
      invoke_visitors(m_vis, u, g, on_discover_vertex());      
williamr@2
    66
    }
williamr@2
    67
    template <class Vertex, class Graph>
williamr@2
    68
    void examine_vertex(Vertex u, Graph& g) {
williamr@2
    69
      invoke_visitors(m_vis, u, g, on_examine_vertex());
williamr@2
    70
    }
williamr@2
    71
    template <class Edge, class Graph>
williamr@2
    72
    void examine_out_edge(Edge e, Graph& g) {
williamr@2
    73
      invoke_visitors(m_vis, e, g, on_examine_edge());
williamr@2
    74
    }
williamr@2
    75
    template <class Edge, class Graph>
williamr@2
    76
    void tree_out_edge(Edge e, Graph& g) {
williamr@2
    77
      invoke_visitors(m_vis, e, g, on_tree_edge());      
williamr@2
    78
    }
williamr@2
    79
    template <class Edge, class Graph>
williamr@2
    80
    void non_tree_out_edge(Edge e, Graph& g) {
williamr@2
    81
      invoke_visitors(m_vis, e, g, on_non_tree_edge());
williamr@2
    82
    }
williamr@2
    83
    template <class Edge, class Graph>
williamr@2
    84
    void gray_target(Edge e, Graph& g) {
williamr@2
    85
      invoke_visitors(m_vis, e, g, on_gray_target());
williamr@2
    86
    }
williamr@2
    87
    template <class Edge, class Graph>
williamr@2
    88
    void black_target(Edge e, Graph& g) {
williamr@2
    89
      invoke_visitors(m_vis, e, g, on_black_target());
williamr@2
    90
    }
williamr@2
    91
    template <class Edge, class Graph>
williamr@2
    92
    void examine_in_edge(Edge e, Graph& g) {
williamr@2
    93
      invoke_visitors(m_vis, e, g, on_examine_edge());
williamr@2
    94
    }
williamr@2
    95
    template <class Edge, class Graph>
williamr@2
    96
    void tree_in_edge(Edge e, Graph& g) {
williamr@2
    97
      invoke_visitors(m_vis, e, g, on_tree_edge());      
williamr@2
    98
    }
williamr@2
    99
    template <class Edge, class Graph>
williamr@2
   100
    void non_tree_in_edge(Edge e, Graph& g) {
williamr@2
   101
      invoke_visitors(m_vis, e, g, on_non_tree_edge());
williamr@2
   102
    }
williamr@2
   103
    template <class Edge, class Graph>
williamr@2
   104
    void gray_source(Edge e, Graph& g) {
williamr@2
   105
      invoke_visitors(m_vis, e, g, on_gray_target());
williamr@2
   106
    }
williamr@2
   107
    template <class Edge, class Graph>
williamr@2
   108
    void black_source(Edge e, Graph& g) {
williamr@2
   109
      invoke_visitors(m_vis, e, g, on_black_target());
williamr@2
   110
    }
williamr@2
   111
    template <class Vertex, class Graph>
williamr@2
   112
    void finish_vertex(Vertex u, Graph& g) {
williamr@2
   113
      invoke_visitors(m_vis, u, g, on_finish_vertex());      
williamr@2
   114
    }
williamr@2
   115
  protected:
williamr@2
   116
    Visitors m_vis;
williamr@2
   117
  };
williamr@2
   118
williamr@2
   119
  template <class Visitors>
williamr@2
   120
  neighbor_bfs_visitor<Visitors>
williamr@2
   121
  make_neighbor_bfs_visitor(Visitors vis) {
williamr@2
   122
    return neighbor_bfs_visitor<Visitors>(vis);
williamr@2
   123
  }
williamr@2
   124
williamr@2
   125
  namespace detail {
williamr@2
   126
williamr@2
   127
    template <class BidirectionalGraph, class Buffer, class BFSVisitor, 
williamr@2
   128
              class ColorMap>
williamr@2
   129
    void neighbor_bfs_impl
williamr@2
   130
      (const BidirectionalGraph& g, 
williamr@2
   131
       typename graph_traits<BidirectionalGraph>::vertex_descriptor s, 
williamr@2
   132
       Buffer& Q, BFSVisitor vis, ColorMap color)
williamr@2
   133
williamr@2
   134
    {
williamr@2
   135
      function_requires< BidirectionalGraphConcept<BidirectionalGraph> >();
williamr@2
   136
      typedef graph_traits<BidirectionalGraph> GTraits;
williamr@2
   137
      typedef typename GTraits::vertex_descriptor Vertex;
williamr@2
   138
      typedef typename GTraits::edge_descriptor Edge;
williamr@2
   139
      function_requires< 
williamr@2
   140
        NeighborBFSVisitorConcept<BFSVisitor, BidirectionalGraph> >();
williamr@2
   141
      function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
williamr@2
   142
      typedef typename property_traits<ColorMap>::value_type ColorValue;
williamr@2
   143
      typedef color_traits<ColorValue> Color;
williamr@2
   144
      
williamr@2
   145
      put(color, s, Color::gray());
williamr@2
   146
      vis.discover_vertex(s, g);
williamr@2
   147
      Q.push(s);
williamr@2
   148
      while (! Q.empty()) {
williamr@2
   149
        Vertex u = Q.top();
williamr@2
   150
        Q.pop(); // pop before push to avoid problem if Q is priority_queue.
williamr@2
   151
        vis.examine_vertex(u, g);
williamr@2
   152
williamr@2
   153
        typename GTraits::out_edge_iterator ei, ei_end;
williamr@2
   154
        for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
williamr@2
   155
          Edge e = *ei;
williamr@2
   156
          vis.examine_out_edge(e, g);
williamr@2
   157
          Vertex v = target(e, g);
williamr@2
   158
          ColorValue v_color = get(color, v);
williamr@2
   159
          if (v_color == Color::white()) {
williamr@2
   160
            vis.tree_out_edge(e, g);
williamr@2
   161
            put(color, v, Color::gray());
williamr@2
   162
            vis.discover_vertex(v, g);
williamr@2
   163
            Q.push(v);
williamr@2
   164
          } else {
williamr@2
   165
            vis.non_tree_out_edge(e, g);
williamr@2
   166
            if (v_color == Color::gray())
williamr@2
   167
              vis.gray_target(e, g);
williamr@2
   168
            else
williamr@2
   169
              vis.black_target(e, g);
williamr@2
   170
          }
williamr@2
   171
        } // for out-edges
williamr@2
   172
williamr@2
   173
        typename GTraits::in_edge_iterator in_ei, in_ei_end;
williamr@2
   174
        for (tie(in_ei, in_ei_end) = in_edges(u, g); 
williamr@2
   175
             in_ei != in_ei_end; ++in_ei) {
williamr@2
   176
          Edge e = *in_ei;
williamr@2
   177
          vis.examine_in_edge(e, g);
williamr@2
   178
          Vertex v = source(e, g);
williamr@2
   179
          ColorValue v_color = get(color, v);
williamr@2
   180
          if (v_color == Color::white()) {
williamr@2
   181
            vis.tree_in_edge(e, g);
williamr@2
   182
            put(color, v, Color::gray());
williamr@2
   183
            vis.discover_vertex(v, g);
williamr@2
   184
            Q.push(v);
williamr@2
   185
          } else {
williamr@2
   186
            vis.non_tree_in_edge(e, g);
williamr@2
   187
            if (v_color == Color::gray())
williamr@2
   188
              vis.gray_source(e, g);
williamr@2
   189
            else
williamr@2
   190
              vis.black_source(e, g);
williamr@2
   191
          }
williamr@2
   192
        } // for in-edges
williamr@2
   193
williamr@2
   194
        put(color, u, Color::black());
williamr@2
   195
        vis.finish_vertex(u, g);
williamr@2
   196
      } // while
williamr@2
   197
    }
williamr@2
   198
williamr@2
   199
    
williamr@2
   200
    template <class VertexListGraph, class ColorMap, class BFSVisitor,
williamr@2
   201
      class P, class T, class R>
williamr@2
   202
    void neighbor_bfs_helper
williamr@2
   203
      (VertexListGraph& g,
williamr@2
   204
       typename graph_traits<VertexListGraph>::vertex_descriptor s,
williamr@2
   205
       ColorMap color, 
williamr@2
   206
       BFSVisitor vis,
williamr@2
   207
       const bgl_named_params<P, T, R>& params)
williamr@2
   208
    {
williamr@2
   209
      typedef graph_traits<VertexListGraph> Traits;
williamr@2
   210
      // Buffer default
williamr@2
   211
      typedef typename Traits::vertex_descriptor Vertex;
williamr@2
   212
      typedef boost::queue<Vertex> queue_t;
williamr@2
   213
      queue_t Q;
williamr@2
   214
      detail::wrap_ref<queue_t> Qref(Q);
williamr@2
   215
      // Initialization
williamr@2
   216
      typedef typename property_traits<ColorMap>::value_type ColorValue;
williamr@2
   217
      typedef color_traits<ColorValue> Color;
williamr@2
   218
      typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
williamr@2
   219
      for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
williamr@2
   220
        put(color, *i, Color::white());
williamr@2
   221
        vis.initialize_vertex(*i, g);
williamr@2
   222
      }
williamr@2
   223
      neighbor_bfs_impl
williamr@2
   224
        (g, s, 
williamr@2
   225
         choose_param(get_param(params, buffer_param_t()), Qref).ref,
williamr@2
   226
         vis, color);
williamr@2
   227
    }
williamr@2
   228
williamr@2
   229
    //-------------------------------------------------------------------------
williamr@2
   230
    // Choose between default color and color parameters. Using
williamr@2
   231
    // function dispatching so that we don't require vertex index if
williamr@2
   232
    // the color default is not being used.
williamr@2
   233
williamr@2
   234
    template <class ColorMap>
williamr@2
   235
    struct neighbor_bfs_dispatch {
williamr@2
   236
      template <class VertexListGraph, class P, class T, class R>
williamr@2
   237
      static void apply
williamr@2
   238
      (VertexListGraph& g,
williamr@2
   239
       typename graph_traits<VertexListGraph>::vertex_descriptor s,
williamr@2
   240
       const bgl_named_params<P, T, R>& params,
williamr@2
   241
       ColorMap color)
williamr@2
   242
      {
williamr@2
   243
        neighbor_bfs_helper
williamr@2
   244
          (g, s, color,
williamr@2
   245
           choose_param(get_param(params, graph_visitor),
williamr@2
   246
                        make_neighbor_bfs_visitor(null_visitor())),
williamr@2
   247
           params);
williamr@2
   248
      }
williamr@2
   249
    };
williamr@2
   250
williamr@2
   251
    template <>
williamr@2
   252
    struct neighbor_bfs_dispatch<detail::error_property_not_found> {
williamr@2
   253
      template <class VertexListGraph, class P, class T, class R>
williamr@2
   254
      static void apply
williamr@2
   255
      (VertexListGraph& g,
williamr@2
   256
       typename graph_traits<VertexListGraph>::vertex_descriptor s,
williamr@2
   257
       const bgl_named_params<P, T, R>& params,
williamr@2
   258
       detail::error_property_not_found)
williamr@2
   259
      {
williamr@2
   260
        std::vector<default_color_type> color_vec(num_vertices(g));
williamr@2
   261
        null_visitor null_vis;
williamr@2
   262
        
williamr@2
   263
        neighbor_bfs_helper
williamr@2
   264
          (g, s, 
williamr@2
   265
           make_iterator_property_map
williamr@2
   266
           (color_vec.begin(), 
williamr@2
   267
            choose_const_pmap(get_param(params, vertex_index), 
williamr@2
   268
                              g, vertex_index), color_vec[0]),
williamr@2
   269
           choose_param(get_param(params, graph_visitor),
williamr@2
   270
                        make_neighbor_bfs_visitor(null_vis)),
williamr@2
   271
           params);
williamr@2
   272
      }
williamr@2
   273
    };
williamr@2
   274
williamr@2
   275
  } // namespace detail
williamr@2
   276
williamr@2
   277
williamr@2
   278
  // Named Parameter Variant
williamr@2
   279
  template <class VertexListGraph, class P, class T, class R>
williamr@2
   280
  void neighbor_breadth_first_search
williamr@2
   281
    (const VertexListGraph& g,
williamr@2
   282
     typename graph_traits<VertexListGraph>::vertex_descriptor s,
williamr@2
   283
     const bgl_named_params<P, T, R>& params)
williamr@2
   284
  {
williamr@2
   285
    // The graph is passed by *const* reference so that graph adaptors
williamr@2
   286
    // (temporaries) can be passed into this function. However, the
williamr@2
   287
    // graph is not really const since we may write to property maps
williamr@2
   288
    // of the graph.
williamr@2
   289
    VertexListGraph& ng = const_cast<VertexListGraph&>(g);
williamr@2
   290
    typedef typename property_value< bgl_named_params<P,T,R>, 
williamr@2
   291
      vertex_color_t>::type C;
williamr@2
   292
    detail::neighbor_bfs_dispatch<C>::apply(ng, s, params, 
williamr@2
   293
                                            get_param(params, vertex_color));
williamr@2
   294
  }
williamr@2
   295
williamr@2
   296
williamr@2
   297
  // This version does not initialize colors, user has to.
williamr@2
   298
williamr@2
   299
  template <class IncidenceGraph, class P, class T, class R>
williamr@2
   300
  void neighbor_breadth_first_visit
williamr@2
   301
    (IncidenceGraph& g,
williamr@2
   302
     typename graph_traits<IncidenceGraph>::vertex_descriptor s,
williamr@2
   303
     const bgl_named_params<P, T, R>& params)
williamr@2
   304
  {
williamr@2
   305
    typedef graph_traits<IncidenceGraph> Traits;
williamr@2
   306
    // Buffer default
williamr@2
   307
    typedef boost::queue<typename Traits::vertex_descriptor> queue_t;
williamr@2
   308
    queue_t Q;
williamr@2
   309
    detail::wrap_ref<queue_t> Qref(Q);
williamr@2
   310
williamr@2
   311
    detail::neighbor_bfs_impl
williamr@2
   312
      (g, s,
williamr@2
   313
       choose_param(get_param(params, buffer_param_t()), Qref).ref,
williamr@2
   314
       choose_param(get_param(params, graph_visitor),
williamr@2
   315
                    make_neighbor_bfs_visitor(null_visitor())),
williamr@2
   316
       choose_pmap(get_param(params, vertex_color), g, vertex_color)
williamr@2
   317
       );
williamr@2
   318
  }
williamr@2
   319
williamr@2
   320
} // namespace boost
williamr@2
   321
williamr@2
   322
#endif // BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
williamr@2
   323