os/ossrv/ossrv_pub/boost_apis/boost/graph/visitors.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
//=======================================================================
sl@0
     2
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
sl@0
     3
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
sl@0
     4
//
sl@0
     5
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     6
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     7
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     8
//=======================================================================
sl@0
     9
//
sl@0
    10
// Revision History:
sl@0
    11
//   01 April 2001: Modified to use new <boost/limits.hpp> header. (JMaddock)
sl@0
    12
//
sl@0
    13
#ifndef BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
sl@0
    14
#define BOOST_GRAPH_GRAPH_SEARCH_VISITORS_HPP
sl@0
    15
sl@0
    16
#include <iosfwd>
sl@0
    17
#include <boost/config.hpp>
sl@0
    18
#include <boost/property_map.hpp>
sl@0
    19
#include <boost/graph/graph_traits.hpp>
sl@0
    20
#include <boost/limits.hpp>
sl@0
    21
#include <boost/graph/detail/is_same.hpp>
sl@0
    22
sl@0
    23
namespace boost {
sl@0
    24
sl@0
    25
  // This is a bit more convenient than std::numeric_limits because
sl@0
    26
  // you don't have to explicitly provide type T.
sl@0
    27
  template <class T>
sl@0
    28
  inline T numeric_limits_max(T) { return (std::numeric_limits<T>::max)(); }
sl@0
    29
sl@0
    30
  //========================================================================
sl@0
    31
  // Event Tags
sl@0
    32
sl@0
    33
  namespace detail {
sl@0
    34
    // For partial specialization workaround
sl@0
    35
    enum event_visitor_enum
sl@0
    36
    { on_no_event_num,
sl@0
    37
      on_initialize_vertex_num, on_start_vertex_num,
sl@0
    38
      on_discover_vertex_num, on_finish_vertex_num, on_examine_vertex_num,
sl@0
    39
      on_examine_edge_num, on_tree_edge_num, on_non_tree_edge_num,
sl@0
    40
      on_gray_target_num, on_black_target_num,
sl@0
    41
      on_forward_or_cross_edge_num, on_back_edge_num,
sl@0
    42
      on_edge_relaxed_num, on_edge_not_relaxed_num,
sl@0
    43
      on_edge_minimized_num, on_edge_not_minimized_num
sl@0
    44
    };
sl@0
    45
sl@0
    46
    template<typename Event, typename Visitor>
sl@0
    47
    struct functor_to_visitor : Visitor
sl@0
    48
    {
sl@0
    49
      typedef Event event_filter;
sl@0
    50
      functor_to_visitor(const Visitor& visitor) : Visitor(visitor) {}
sl@0
    51
    };
sl@0
    52
sl@0
    53
  } // namespace detail
sl@0
    54
sl@0
    55
  struct on_no_event { enum { num = detail::on_no_event_num }; };
sl@0
    56
sl@0
    57
  struct on_initialize_vertex {
sl@0
    58
    enum { num = detail::on_initialize_vertex_num }; };
sl@0
    59
  struct on_start_vertex { enum { num = detail::on_start_vertex_num }; };
sl@0
    60
  struct on_discover_vertex { enum { num = detail::on_discover_vertex_num }; };
sl@0
    61
  struct on_examine_vertex { enum { num = detail::on_examine_vertex_num }; };
sl@0
    62
  struct on_finish_vertex { enum { num = detail::on_finish_vertex_num }; };
sl@0
    63
sl@0
    64
  struct on_examine_edge { enum { num = detail::on_examine_edge_num }; };
sl@0
    65
  struct on_tree_edge { enum { num = detail::on_tree_edge_num }; };
sl@0
    66
  struct on_non_tree_edge { enum { num = detail::on_non_tree_edge_num }; };
sl@0
    67
  struct on_gray_target { enum { num = detail::on_gray_target_num }; };
sl@0
    68
  struct on_black_target { enum { num = detail::on_black_target_num }; };
sl@0
    69
  struct on_forward_or_cross_edge {
sl@0
    70
    enum { num = detail::on_forward_or_cross_edge_num }; };
sl@0
    71
  struct on_back_edge { enum { num = detail::on_back_edge_num }; };
sl@0
    72
sl@0
    73
  struct on_edge_relaxed { enum { num = detail::on_edge_relaxed_num }; };
sl@0
    74
  struct on_edge_not_relaxed {
sl@0
    75
    enum { num = detail::on_edge_not_relaxed_num }; };
sl@0
    76
  struct on_edge_minimized { enum { num = detail::on_edge_minimized_num }; };
sl@0
    77
  struct on_edge_not_minimized {
sl@0
    78
    enum { num = detail::on_edge_not_minimized_num }; };
sl@0
    79
sl@0
    80
  struct true_tag { enum { num = true }; };
sl@0
    81
  struct false_tag { enum { num = false }; };
sl@0
    82
sl@0
    83
  //========================================================================
sl@0
    84
  // base_visitor and null_visitor
sl@0
    85
sl@0
    86
  // needed for MSVC workaround
sl@0
    87
  template <class Visitor>
sl@0
    88
  struct base_visitor {
sl@0
    89
    typedef on_no_event event_filter;
sl@0
    90
    template <class T, class Graph>
sl@0
    91
    void operator()(T, Graph&) { }
sl@0
    92
  };
sl@0
    93
sl@0
    94
  struct null_visitor : public base_visitor<null_visitor> {
sl@0
    95
    typedef on_no_event event_filter;
sl@0
    96
    template <class T, class Graph>
sl@0
    97
    void operator()(T, Graph&) { }
sl@0
    98
  };
sl@0
    99
sl@0
   100
  //========================================================================
sl@0
   101
  // The invoke_visitors() function
sl@0
   102
sl@0
   103
  namespace detail {
sl@0
   104
    template <class Visitor, class T, class Graph>
sl@0
   105
    inline void
sl@0
   106
    invoke_dispatch(Visitor& v, T x, Graph& g, true_tag) {
sl@0
   107
       v(x, g);
sl@0
   108
    }
sl@0
   109
    template <class Visitor, class T, class Graph>
sl@0
   110
    inline void
sl@0
   111
    invoke_dispatch(Visitor&, T, Graph&, false_tag) { }
sl@0
   112
  } // namespace detail
sl@0
   113
sl@0
   114
  template <class Visitor, class Rest, class T, class Graph, class Tag>
sl@0
   115
  inline void
sl@0
   116
  invoke_visitors(std::pair<Visitor, Rest>& vlist, T x, Graph& g, Tag tag) {
sl@0
   117
    typedef typename Visitor::event_filter Category;
sl@0
   118
    typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
sl@0
   119
      IsSameTag;
sl@0
   120
    detail::invoke_dispatch(vlist.first, x, g, IsSameTag());
sl@0
   121
    invoke_visitors(vlist.second, x, g, tag);
sl@0
   122
  }
sl@0
   123
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
sl@0
   124
  template <class Visitor, class T, class Graph, class Tag>
sl@0
   125
  inline void
sl@0
   126
  invoke_visitors(base_visitor<Visitor>& vis, T x, Graph& g, Tag) {
sl@0
   127
    typedef typename Visitor::event_filter Category;
sl@0
   128
    typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
sl@0
   129
      IsSameTag;
sl@0
   130
    Visitor& v = static_cast<Visitor&>(vis);
sl@0
   131
    detail::invoke_dispatch(v, x, g, IsSameTag());
sl@0
   132
  }
sl@0
   133
#else
sl@0
   134
  template <class Visitor, class T, class Graph, class Tag>
sl@0
   135
  inline void
sl@0
   136
  invoke_visitors(Visitor& v, T x, Graph& g, Tag) {
sl@0
   137
    typedef typename Visitor::event_filter Category;
sl@0
   138
    typedef typename graph_detail::is_same<Category, Tag>::is_same_tag
sl@0
   139
      IsSameTag;
sl@0
   140
    detail::invoke_dispatch(v, x, g, IsSameTag());
sl@0
   141
  }
sl@0
   142
#endif
sl@0
   143
sl@0
   144
  //========================================================================
sl@0
   145
  // predecessor_recorder
sl@0
   146
sl@0
   147
  template <class PredecessorMap, class Tag>
sl@0
   148
  struct predecessor_recorder
sl@0
   149
    : public base_visitor<predecessor_recorder<PredecessorMap, Tag> >
sl@0
   150
  {
sl@0
   151
    typedef Tag event_filter;
sl@0
   152
    predecessor_recorder(PredecessorMap pa) : m_predecessor(pa) { }
sl@0
   153
    template <class Edge, class Graph>
sl@0
   154
    void operator()(Edge e, const Graph& g) {
sl@0
   155
      put(m_predecessor, target(e, g), source(e, g));
sl@0
   156
    }
sl@0
   157
    PredecessorMap m_predecessor;
sl@0
   158
  };
sl@0
   159
  template <class PredecessorMap, class Tag>
sl@0
   160
  predecessor_recorder<PredecessorMap, Tag>
sl@0
   161
  record_predecessors(PredecessorMap pa, Tag) {
sl@0
   162
    return predecessor_recorder<PredecessorMap, Tag> (pa);
sl@0
   163
  }
sl@0
   164
sl@0
   165
  //========================================================================
sl@0
   166
  // edge_predecessor_recorder
sl@0
   167
sl@0
   168
  template <class PredEdgeMap, class Tag>
sl@0
   169
  struct edge_predecessor_recorder
sl@0
   170
    : public base_visitor<edge_predecessor_recorder<PredEdgeMap, Tag> >
sl@0
   171
  {
sl@0
   172
    typedef Tag event_filter;
sl@0
   173
    edge_predecessor_recorder(PredEdgeMap pa) : m_predecessor(pa) { }
sl@0
   174
    template <class Edge, class Graph>
sl@0
   175
    void operator()(Edge e, const Graph& g) {
sl@0
   176
      put(m_predecessor, target(e, g), e);
sl@0
   177
    }
sl@0
   178
    PredEdgeMap m_predecessor;
sl@0
   179
  };
sl@0
   180
  template <class PredEdgeMap, class Tag>
sl@0
   181
  edge_predecessor_recorder<PredEdgeMap, Tag>
sl@0
   182
  record_edge_predecessors(PredEdgeMap pa, Tag) {
sl@0
   183
    return edge_predecessor_recorder<PredEdgeMap, Tag> (pa);
sl@0
   184
  }
sl@0
   185
sl@0
   186
  //========================================================================
sl@0
   187
  // distance_recorder
sl@0
   188
sl@0
   189
  template <class DistanceMap, class Tag>
sl@0
   190
  struct distance_recorder
sl@0
   191
    : public base_visitor<distance_recorder<DistanceMap, Tag> >
sl@0
   192
  {
sl@0
   193
    typedef Tag event_filter;
sl@0
   194
    distance_recorder(DistanceMap pa) : m_distance(pa) { }
sl@0
   195
    template <class Edge, class Graph>
sl@0
   196
    void operator()(Edge e, const Graph& g) {
sl@0
   197
      typename graph_traits<Graph>::vertex_descriptor
sl@0
   198
        u = source(e, g), v = target(e, g);
sl@0
   199
      put(m_distance, v, get(m_distance, u) + 1);
sl@0
   200
    }
sl@0
   201
    DistanceMap m_distance;
sl@0
   202
  };
sl@0
   203
  template <class DistanceMap, class Tag>
sl@0
   204
  distance_recorder<DistanceMap, Tag>
sl@0
   205
  record_distances(DistanceMap pa, Tag) {
sl@0
   206
    return distance_recorder<DistanceMap, Tag> (pa);
sl@0
   207
  }
sl@0
   208
sl@0
   209
  //========================================================================
sl@0
   210
  // time_stamper
sl@0
   211
sl@0
   212
sl@0
   213
  template <class TimeMap, class TimeT, class Tag>
sl@0
   214
  struct time_stamper
sl@0
   215
    : public base_visitor<time_stamper<TimeMap, TimeT, Tag> >
sl@0
   216
  {
sl@0
   217
    typedef Tag event_filter;
sl@0
   218
    time_stamper(TimeMap pa, TimeT& t) : m_time_pa(pa), m_time(t) { }
sl@0
   219
    template <class Vertex, class Graph>
sl@0
   220
    void operator()(Vertex u, const Graph&) {
sl@0
   221
      put(m_time_pa, u, ++m_time);
sl@0
   222
    }
sl@0
   223
    TimeMap m_time_pa;
sl@0
   224
    TimeT& m_time;
sl@0
   225
  };
sl@0
   226
  template <class TimeMap, class TimeT, class Tag>
sl@0
   227
  time_stamper<TimeMap, TimeT, Tag>
sl@0
   228
  stamp_times(TimeMap pa, TimeT& time_counter, Tag) {
sl@0
   229
    return time_stamper<TimeMap, TimeT, Tag>(pa, time_counter);
sl@0
   230
  }
sl@0
   231
sl@0
   232
  //========================================================================
sl@0
   233
  // property_writer
sl@0
   234
sl@0
   235
  template <class PA, class OutputIterator, class Tag>
sl@0
   236
  struct property_writer
sl@0
   237
    : public base_visitor<property_writer<PA, OutputIterator, Tag> >
sl@0
   238
  {
sl@0
   239
    typedef Tag event_filter;
sl@0
   240
sl@0
   241
    property_writer(PA pa, OutputIterator out) : m_pa(pa), m_out(out) { }
sl@0
   242
sl@0
   243
    template <class T, class Graph>
sl@0
   244
    void operator()(T x, Graph&) { *m_out++ = get(m_pa, x); }
sl@0
   245
    PA m_pa;
sl@0
   246
    OutputIterator m_out;
sl@0
   247
  };
sl@0
   248
  template <class PA, class OutputIterator, class Tag>
sl@0
   249
  property_writer<PA, OutputIterator, Tag>
sl@0
   250
  write_property(PA pa, OutputIterator out, Tag) {
sl@0
   251
    return property_writer<PA, OutputIterator, Tag>(pa, out);
sl@0
   252
  }
sl@0
   253
sl@0
   254
#define BOOST_GRAPH_EVENT_STUB(Event,Kind)                                 \
sl@0
   255
    typedef ::boost::Event Event##_type;                                   \
sl@0
   256
    template<typename Visitor>                                             \
sl@0
   257
    Kind##_visitor<std::pair<detail::functor_to_visitor<Event##_type,      \
sl@0
   258
                                                     Visitor>, Visitors> > \
sl@0
   259
    do_##Event(Visitor visitor)                                            \
sl@0
   260
    {                                                                      \
sl@0
   261
      typedef std::pair<detail::functor_to_visitor<Event##_type, Visitor>, \
sl@0
   262
                        Visitors> visitor_list;                            \
sl@0
   263
      typedef Kind##_visitor<visitor_list> result_type;                    \
sl@0
   264
      return result_type(visitor_list(visitor, m_vis));                    \
sl@0
   265
    }
sl@0
   266
sl@0
   267
} /* namespace boost */
sl@0
   268
sl@0
   269
#endif