os/ossrv/ossrv_pub/boost_apis/boost/graph/graph_concepts.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
//
sl@0
     2
//=======================================================================
sl@0
     3
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
sl@0
     4
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
sl@0
     5
//
sl@0
     6
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
     7
// accompanying file LICENSE_1_0.txt or copy at
sl@0
     8
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
     9
//=======================================================================
sl@0
    10
//
sl@0
    11
#ifndef BOOST_GRAPH_CONCEPTS_HPP
sl@0
    12
#define BOOST_GRAPH_CONCEPTS_HPP
sl@0
    13
sl@0
    14
#include <boost/config.hpp>
sl@0
    15
#include <boost/graph/graph_traits.hpp>
sl@0
    16
#include <boost/property_map.hpp>
sl@0
    17
#include <boost/graph/properties.hpp>
sl@0
    18
#include <boost/concept_check.hpp>
sl@0
    19
#include <boost/detail/workaround.hpp>
sl@0
    20
sl@0
    21
namespace boost {
sl@0
    22
sl@0
    23
  template <class T>
sl@0
    24
  struct MultiPassInputIteratorConcept {
sl@0
    25
    void constraints() {
sl@0
    26
      function_requires< InputIteratorConcept<T> >();
sl@0
    27
    }
sl@0
    28
  };
sl@0
    29
sl@0
    30
  template <class G>
sl@0
    31
  struct GraphConcept
sl@0
    32
  {
sl@0
    33
    typedef typename graph_traits<G>::vertex_descriptor vertex_descriptor;
sl@0
    34
    typedef typename graph_traits<G>::directed_category directed_category;
sl@0
    35
    typedef typename graph_traits<G>::edge_parallel_category
sl@0
    36
      edge_parallel_category;
sl@0
    37
    typedef typename graph_traits<G>::traversal_category
sl@0
    38
      traversal_category;
sl@0
    39
    void constraints() {
sl@0
    40
      function_requires< DefaultConstructibleConcept<vertex_descriptor> >();
sl@0
    41
      function_requires< EqualityComparableConcept<vertex_descriptor> >();
sl@0
    42
      function_requires< AssignableConcept<vertex_descriptor> >();
sl@0
    43
    }
sl@0
    44
    G g;
sl@0
    45
  };
sl@0
    46
sl@0
    47
  template <class G>
sl@0
    48
  struct IncidenceGraphConcept
sl@0
    49
  {
sl@0
    50
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
    51
    typedef typename graph_traits<G>::out_edge_iterator
sl@0
    52
      out_edge_iterator;
sl@0
    53
    typedef typename graph_traits<G>::traversal_category
sl@0
    54
      traversal_category;
sl@0
    55
    void constraints() {
sl@0
    56
      function_requires< GraphConcept<G> >();
sl@0
    57
      function_requires< MultiPassInputIteratorConcept<out_edge_iterator> >();
sl@0
    58
      function_requires< DefaultConstructibleConcept<edge_descriptor> >();
sl@0
    59
      function_requires< EqualityComparableConcept<edge_descriptor> >();
sl@0
    60
      function_requires< AssignableConcept<edge_descriptor> >();
sl@0
    61
      function_requires< ConvertibleConcept<traversal_category,
sl@0
    62
        incidence_graph_tag> >();
sl@0
    63
sl@0
    64
      p = out_edges(u, g);
sl@0
    65
      n = out_degree(u, g);
sl@0
    66
      e = *p.first;
sl@0
    67
      u = source(e, g);
sl@0
    68
      v = target(e, g);
sl@0
    69
      const_constraints(g);
sl@0
    70
    }
sl@0
    71
    void const_constraints(const G& cg) {
sl@0
    72
      p = out_edges(u, cg);
sl@0
    73
      n = out_degree(u, cg);
sl@0
    74
      e = *p.first;
sl@0
    75
      u = source(e, cg);
sl@0
    76
      v = target(e, cg);
sl@0
    77
    }
sl@0
    78
    std::pair<out_edge_iterator, out_edge_iterator> p;
sl@0
    79
    typename graph_traits<G>::vertex_descriptor u, v;
sl@0
    80
    typename graph_traits<G>::edge_descriptor e;
sl@0
    81
    typename graph_traits<G>::degree_size_type n;
sl@0
    82
    G g;
sl@0
    83
  };
sl@0
    84
sl@0
    85
  template <class G>
sl@0
    86
  struct BidirectionalGraphConcept
sl@0
    87
  {
sl@0
    88
    typedef typename graph_traits<G>::in_edge_iterator
sl@0
    89
      in_edge_iterator;
sl@0
    90
    typedef typename graph_traits<G>::traversal_category
sl@0
    91
      traversal_category;
sl@0
    92
    void constraints() {
sl@0
    93
      function_requires< IncidenceGraphConcept<G> >();
sl@0
    94
      function_requires< MultiPassInputIteratorConcept<in_edge_iterator> >();
sl@0
    95
      function_requires< ConvertibleConcept<traversal_category,
sl@0
    96
        bidirectional_graph_tag> >();
sl@0
    97
sl@0
    98
      p = in_edges(v, g);
sl@0
    99
      n = in_degree(v, g);
sl@0
   100
      e = *p.first;
sl@0
   101
      const_constraints(g);
sl@0
   102
    }
sl@0
   103
    void const_constraints(const G& cg) {
sl@0
   104
      p = in_edges(v, cg);
sl@0
   105
      n = in_degree(v, cg);
sl@0
   106
      e = *p.first;
sl@0
   107
    }
sl@0
   108
    std::pair<in_edge_iterator, in_edge_iterator> p;
sl@0
   109
    typename graph_traits<G>::vertex_descriptor v;
sl@0
   110
    typename graph_traits<G>::edge_descriptor e;
sl@0
   111
    typename graph_traits<G>::degree_size_type n;
sl@0
   112
    G g;
sl@0
   113
  };
sl@0
   114
sl@0
   115
  template <class G>
sl@0
   116
  struct AdjacencyGraphConcept
sl@0
   117
  {
sl@0
   118
    typedef typename graph_traits<G>::adjacency_iterator
sl@0
   119
      adjacency_iterator;
sl@0
   120
    typedef typename graph_traits<G>::traversal_category
sl@0
   121
      traversal_category;
sl@0
   122
    void constraints() {
sl@0
   123
      function_requires< GraphConcept<G> >();
sl@0
   124
      function_requires< MultiPassInputIteratorConcept<adjacency_iterator> >();
sl@0
   125
      function_requires< ConvertibleConcept<traversal_category,
sl@0
   126
        adjacency_graph_tag> >();
sl@0
   127
sl@0
   128
      p = adjacent_vertices(v, g);
sl@0
   129
      v = *p.first;
sl@0
   130
      const_constraints(g);
sl@0
   131
    }
sl@0
   132
    void const_constraints(const G& cg) {
sl@0
   133
      p = adjacent_vertices(v, cg);
sl@0
   134
    }
sl@0
   135
    std::pair<adjacency_iterator,adjacency_iterator> p;
sl@0
   136
    typename graph_traits<G>::vertex_descriptor v;
sl@0
   137
    G g;
sl@0
   138
  };
sl@0
   139
sl@0
   140
// dwa 2003/7/11 -- This clearly shouldn't be necessary, but if
sl@0
   141
// you want to use vector_as_graph, it is!  I'm sure the graph
sl@0
   142
// library leaves these out all over the place.  Probably a
sl@0
   143
// redesign involving specializing a template with a static
sl@0
   144
// member function is in order :(
sl@0
   145
//
sl@0
   146
// It is needed in order to allow us to write using boost::vertices as
sl@0
   147
// needed for ADL when using vector_as_graph below.
sl@0
   148
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)            \
sl@0
   149
 && !BOOST_WORKAROUND(__GNUC__, <= 2)                       \
sl@0
   150
 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
sl@0
   151
# define BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
sl@0
   152
#endif 
sl@0
   153
sl@0
   154
#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
sl@0
   155
template <class T>
sl@0
   156
typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&);
sl@0
   157
#endif      
sl@0
   158
sl@0
   159
  template <class G>
sl@0
   160
  struct VertexListGraphConcept
sl@0
   161
  {
sl@0
   162
    typedef typename graph_traits<G>::vertex_iterator vertex_iterator;
sl@0
   163
    typedef typename graph_traits<G>::vertices_size_type vertices_size_type;
sl@0
   164
    typedef typename graph_traits<G>::traversal_category
sl@0
   165
      traversal_category;
sl@0
   166
    void constraints() {
sl@0
   167
      function_requires< GraphConcept<G> >();
sl@0
   168
      function_requires< MultiPassInputIteratorConcept<vertex_iterator> >();
sl@0
   169
      function_requires< ConvertibleConcept<traversal_category,
sl@0
   170
        vertex_list_graph_tag> >();
sl@0
   171
sl@0
   172
#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
sl@0
   173
      // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if
sl@0
   174
      // you want to use vector_as_graph, it is!  I'm sure the graph
sl@0
   175
      // library leaves these out all over the place.  Probably a
sl@0
   176
      // redesign involving specializing a template with a static
sl@0
   177
      // member function is in order :(
sl@0
   178
      using boost::vertices;
sl@0
   179
#endif      
sl@0
   180
      p = vertices(g);
sl@0
   181
      v = *p.first;
sl@0
   182
      const_constraints(g);
sl@0
   183
    }
sl@0
   184
    void const_constraints(const G& cg) {
sl@0
   185
#ifdef BOOST_VECTOR_AS_GRAPH_GRAPH_ADL_HACK
sl@0
   186
      // dwa 2003/7/11 -- This clearly shouldn't be necessary, but if
sl@0
   187
      // you want to use vector_as_graph, it is!  I'm sure the graph
sl@0
   188
      // library leaves these out all over the place.  Probably a
sl@0
   189
      // redesign involving specializing a template with a static
sl@0
   190
      // member function is in order :(
sl@0
   191
      using boost::vertices;
sl@0
   192
#endif 
sl@0
   193
      
sl@0
   194
      p = vertices(cg);
sl@0
   195
      v = *p.first;
sl@0
   196
      V = num_vertices(cg);
sl@0
   197
    }
sl@0
   198
    std::pair<vertex_iterator,vertex_iterator> p;
sl@0
   199
    typename graph_traits<G>::vertex_descriptor v;
sl@0
   200
    G g;
sl@0
   201
    vertices_size_type V;
sl@0
   202
  };
sl@0
   203
sl@0
   204
  template <class G>
sl@0
   205
  struct EdgeListGraphConcept
sl@0
   206
  {
sl@0
   207
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   208
    typedef typename graph_traits<G>::edge_iterator edge_iterator;
sl@0
   209
    typedef typename graph_traits<G>::edges_size_type edges_size_type;
sl@0
   210
    typedef typename graph_traits<G>::traversal_category
sl@0
   211
      traversal_category;
sl@0
   212
    void constraints() {
sl@0
   213
      function_requires< GraphConcept<G> >();
sl@0
   214
      function_requires< MultiPassInputIteratorConcept<edge_iterator> >();
sl@0
   215
      function_requires< DefaultConstructibleConcept<edge_descriptor> >();
sl@0
   216
      function_requires< EqualityComparableConcept<edge_descriptor> >();
sl@0
   217
      function_requires< AssignableConcept<edge_descriptor> >();
sl@0
   218
      function_requires< ConvertibleConcept<traversal_category,
sl@0
   219
        edge_list_graph_tag> >();
sl@0
   220
sl@0
   221
      p = edges(g);
sl@0
   222
      e = *p.first;
sl@0
   223
      u = source(e, g);
sl@0
   224
      v = target(e, g);
sl@0
   225
      const_constraints(g);
sl@0
   226
    }
sl@0
   227
    void const_constraints(const G& cg) {
sl@0
   228
      p = edges(cg);
sl@0
   229
      E = num_edges(cg);
sl@0
   230
      e = *p.first;
sl@0
   231
      u = source(e, cg);
sl@0
   232
      v = target(e, cg);
sl@0
   233
    }
sl@0
   234
    std::pair<edge_iterator,edge_iterator> p;
sl@0
   235
    typename graph_traits<G>::vertex_descriptor u, v;
sl@0
   236
    typename graph_traits<G>::edge_descriptor e;
sl@0
   237
    edges_size_type E;
sl@0
   238
    G g;
sl@0
   239
  };
sl@0
   240
sl@0
   241
  template <class G>
sl@0
   242
  struct VertexAndEdgeListGraphConcept
sl@0
   243
  {
sl@0
   244
    void constraints() {
sl@0
   245
      function_requires< VertexListGraphConcept<G> >();    
sl@0
   246
      function_requires< EdgeListGraphConcept<G> >();
sl@0
   247
    }
sl@0
   248
  };
sl@0
   249
sl@0
   250
  // Where to put the requirement for this constructor?
sl@0
   251
  //      G g(n_vertices);
sl@0
   252
  // Not in mutable graph, then LEDA graph's can't be models of
sl@0
   253
  // MutableGraph.
sl@0
   254
sl@0
   255
  template <class G>
sl@0
   256
  struct EdgeMutableGraphConcept
sl@0
   257
  {
sl@0
   258
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   259
    void constraints() {
sl@0
   260
      p = add_edge(u, v, g);
sl@0
   261
      remove_edge(u, v, g);
sl@0
   262
      remove_edge(e, g);
sl@0
   263
      clear_vertex(v, g);
sl@0
   264
    }
sl@0
   265
    G g;
sl@0
   266
    edge_descriptor e;
sl@0
   267
    std::pair<edge_descriptor, bool> p;
sl@0
   268
    typename graph_traits<G>::vertex_descriptor u, v;
sl@0
   269
  };
sl@0
   270
sl@0
   271
  template <class G>
sl@0
   272
  struct VertexMutableGraphConcept
sl@0
   273
  {
sl@0
   274
    void constraints() {
sl@0
   275
      v = add_vertex(g);
sl@0
   276
      remove_vertex(v, g);
sl@0
   277
    }
sl@0
   278
    G g;
sl@0
   279
    typename graph_traits<G>::vertex_descriptor u, v;
sl@0
   280
  };
sl@0
   281
sl@0
   282
  template <class G>
sl@0
   283
  struct MutableGraphConcept
sl@0
   284
  {
sl@0
   285
    void constraints() {
sl@0
   286
      function_requires< EdgeMutableGraphConcept<G> >();
sl@0
   287
      function_requires< VertexMutableGraphConcept<G> >();
sl@0
   288
    }
sl@0
   289
  };
sl@0
   290
sl@0
   291
  template <class edge_descriptor>
sl@0
   292
  struct dummy_edge_predicate {
sl@0
   293
    bool operator()(const edge_descriptor&) const {
sl@0
   294
      return false;
sl@0
   295
    }
sl@0
   296
  };
sl@0
   297
sl@0
   298
  template <class G>
sl@0
   299
  struct MutableIncidenceGraphConcept
sl@0
   300
  {
sl@0
   301
    void constraints() {
sl@0
   302
      function_requires< MutableGraphConcept<G> >();
sl@0
   303
      remove_edge(iter, g);
sl@0
   304
      remove_out_edge_if(u, p, g);
sl@0
   305
    }
sl@0
   306
    G g;
sl@0
   307
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   308
    dummy_edge_predicate<edge_descriptor> p;
sl@0
   309
    typename boost::graph_traits<G>::vertex_descriptor u;
sl@0
   310
    typename boost::graph_traits<G>::out_edge_iterator iter;
sl@0
   311
  };
sl@0
   312
sl@0
   313
  template <class G>
sl@0
   314
  struct MutableBidirectionalGraphConcept
sl@0
   315
  {
sl@0
   316
    void constraints() {
sl@0
   317
      function_requires< MutableIncidenceGraphConcept<G> >();
sl@0
   318
      remove_in_edge_if(u, p, g);
sl@0
   319
    }
sl@0
   320
    G g;
sl@0
   321
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   322
    dummy_edge_predicate<edge_descriptor> p;
sl@0
   323
    typename boost::graph_traits<G>::vertex_descriptor u;
sl@0
   324
  };
sl@0
   325
sl@0
   326
  template <class G>
sl@0
   327
  struct MutableEdgeListGraphConcept
sl@0
   328
  {
sl@0
   329
    void constraints() {
sl@0
   330
      function_requires< EdgeMutableGraphConcept<G> >();
sl@0
   331
      remove_edge_if(p, g);
sl@0
   332
    }
sl@0
   333
    G g;
sl@0
   334
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   335
    dummy_edge_predicate<edge_descriptor> p;
sl@0
   336
  };
sl@0
   337
sl@0
   338
  template <class G>
sl@0
   339
  struct VertexMutablePropertyGraphConcept
sl@0
   340
  {
sl@0
   341
    void constraints() {
sl@0
   342
      function_requires< VertexMutableGraphConcept<G> >();
sl@0
   343
      v = add_vertex(vp, g);
sl@0
   344
    }
sl@0
   345
    G g;
sl@0
   346
    typename graph_traits<G>::vertex_descriptor v;
sl@0
   347
    typename vertex_property<G>::type vp;
sl@0
   348
  };
sl@0
   349
sl@0
   350
  template <class G>
sl@0
   351
  struct EdgeMutablePropertyGraphConcept
sl@0
   352
  {
sl@0
   353
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   354
    void constraints() {
sl@0
   355
      function_requires< EdgeMutableGraphConcept<G> >();
sl@0
   356
      p = add_edge(u, v, ep, g);
sl@0
   357
    }
sl@0
   358
    G g;
sl@0
   359
    std::pair<edge_descriptor, bool> p;
sl@0
   360
    typename graph_traits<G>::vertex_descriptor u, v;
sl@0
   361
    typename edge_property<G>::type ep;
sl@0
   362
  };
sl@0
   363
sl@0
   364
  template <class G>
sl@0
   365
  struct AdjacencyMatrixConcept
sl@0
   366
  {
sl@0
   367
    typedef typename graph_traits<G>::edge_descriptor edge_descriptor;
sl@0
   368
    void constraints() {
sl@0
   369
      function_requires< GraphConcept<G> >();
sl@0
   370
      
sl@0
   371
      p = edge(u, v, g);
sl@0
   372
      const_constraints(g);
sl@0
   373
    }
sl@0
   374
    void const_constraints(const G& cg) {
sl@0
   375
      p = edge(u, v, cg);
sl@0
   376
    }
sl@0
   377
    typename graph_traits<G>::vertex_descriptor u, v;
sl@0
   378
    std::pair<edge_descriptor, bool> p;
sl@0
   379
    G g;
sl@0
   380
  };
sl@0
   381
sl@0
   382
  template <class G, class X, class Property>
sl@0
   383
  struct ReadablePropertyGraphConcept
sl@0
   384
  {
sl@0
   385
    typedef typename property_map<G, Property>::const_type const_Map;
sl@0
   386
    void constraints() {
sl@0
   387
      function_requires< GraphConcept<G> >();
sl@0
   388
      function_requires< ReadablePropertyMapConcept<const_Map, X> >();
sl@0
   389
sl@0
   390
      const_constraints(g);
sl@0
   391
    }
sl@0
   392
    void const_constraints(const G& cg) {
sl@0
   393
      const_Map pmap = get(Property(), cg);
sl@0
   394
      pval = get(Property(), cg, x);
sl@0
   395
      ignore_unused_variable_warning(pmap);
sl@0
   396
    }
sl@0
   397
    G g;
sl@0
   398
    X x;
sl@0
   399
    typename property_traits<const_Map>::value_type pval;
sl@0
   400
  };
sl@0
   401
sl@0
   402
  template <class G, class X, class Property>
sl@0
   403
  struct PropertyGraphConcept
sl@0
   404
  {
sl@0
   405
    typedef typename property_map<G, Property>::type Map;
sl@0
   406
    void constraints() {
sl@0
   407
      function_requires< ReadablePropertyGraphConcept<G, X, Property> >();
sl@0
   408
      function_requires< ReadWritePropertyMapConcept<Map, X> >();
sl@0
   409
sl@0
   410
      Map pmap = get(Property(), g);
sl@0
   411
      pval = get(Property(), g, x);
sl@0
   412
      put(Property(), g, x, pval);
sl@0
   413
      ignore_unused_variable_warning(pmap);
sl@0
   414
    }
sl@0
   415
    G g;
sl@0
   416
    X x;
sl@0
   417
    typename property_traits<Map>::value_type pval;
sl@0
   418
  };
sl@0
   419
sl@0
   420
  template <class G, class X, class Property>
sl@0
   421
  struct LvaluePropertyGraphConcept
sl@0
   422
  {
sl@0
   423
    typedef typename property_map<G, Property>::type Map;
sl@0
   424
    typedef typename property_map<G, Property>::const_type const_Map;
sl@0
   425
    void constraints() {
sl@0
   426
      function_requires< ReadablePropertyGraphConcept<G, X, Property> >();
sl@0
   427
      function_requires< LvaluePropertyMapConcept<const_Map, X> >();
sl@0
   428
sl@0
   429
      pval = get(Property(), g, x);
sl@0
   430
      put(Property(), g, x, pval);
sl@0
   431
    }
sl@0
   432
    G g;
sl@0
   433
    X x;
sl@0
   434
    typename property_traits<Map>::value_type pval;
sl@0
   435
  };
sl@0
   436
sl@0
   437
  // This needs to move out of the graph library
sl@0
   438
  template <class B>
sl@0
   439
  struct BufferConcept
sl@0
   440
  {
sl@0
   441
    void constraints() {
sl@0
   442
      b.push(t);
sl@0
   443
      b.pop();
sl@0
   444
      typename B::value_type& v = b.top();
sl@0
   445
      const_constraints(b);
sl@0
   446
      ignore_unused_variable_warning(v);
sl@0
   447
    }
sl@0
   448
    void const_constraints(const B& cb) {
sl@0
   449
      const typename B::value_type& v = cb.top();
sl@0
   450
      n = cb.size();
sl@0
   451
      bool e = cb.empty();
sl@0
   452
      ignore_unused_variable_warning(v);
sl@0
   453
      ignore_unused_variable_warning(e);
sl@0
   454
    }
sl@0
   455
    typename B::size_type n;
sl@0
   456
    typename B::value_type t;
sl@0
   457
    B b;
sl@0
   458
  };
sl@0
   459
sl@0
   460
  template <class C>
sl@0
   461
  struct ColorValueConcept
sl@0
   462
  {
sl@0
   463
    void constraints() {
sl@0
   464
      function_requires< EqualityComparableConcept<C> >();
sl@0
   465
      function_requires< DefaultConstructibleConcept<C> >();
sl@0
   466
sl@0
   467
      c = color_traits<C>::white();
sl@0
   468
      c = color_traits<C>::gray();
sl@0
   469
      c = color_traits<C>::black();
sl@0
   470
    }
sl@0
   471
    C c;
sl@0
   472
  };
sl@0
   473
sl@0
   474
  template <class M, class I, class V>
sl@0
   475
  struct BasicMatrixConcept
sl@0
   476
  {
sl@0
   477
    void constraints() {
sl@0
   478
      V& elt = A[i][j];
sl@0
   479
      const_constraints(A);
sl@0
   480
      ignore_unused_variable_warning(elt);      
sl@0
   481
    }
sl@0
   482
    void const_constraints(const M& cA) {
sl@0
   483
      const V& elt = cA[i][j];
sl@0
   484
      ignore_unused_variable_warning(elt);      
sl@0
   485
    }
sl@0
   486
    M A;
sl@0
   487
    I i, j;
sl@0
   488
  };
sl@0
   489
sl@0
   490
} // namespace boost
sl@0
   491
sl@0
   492
#endif /* BOOST_GRAPH_CONCEPTS_H */