graph_adaptor.hh 24.6 KB
Newer Older
Tiago Peixoto's avatar
Tiago Peixoto committed
1
2
// graph-tool -- a general graph modification and manipulation thingy
//
Tiago Peixoto's avatar
Tiago Peixoto committed
3
// Copyright (C) 2006-2017 Tiago de Paula Peixoto <tiago@skewed.de>
Tiago Peixoto's avatar
Tiago Peixoto committed
4
5
6
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
Tiago Peixoto's avatar
Tiago Peixoto committed
7
// as published by the Free Software Foundation; either version 3
Tiago Peixoto's avatar
Tiago Peixoto committed
8
9
10
11
12
13
14
15
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
Tiago Peixoto's avatar
Tiago Peixoto committed
17
18
19
20

#ifndef GRAPH_ADAPTOR_HH
#define GRAPH_ADAPTOR_HH

21
22
#include <list>

Tiago Peixoto's avatar
Tiago Peixoto committed
23
24
25
26
27
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>

28
29
#include "transform_iterator.hh"

Tiago Peixoto's avatar
Tiago Peixoto committed
30
31
32
namespace boost {

//==============================================================================
33
// undirected_adaptor
34
// This class encapsulates a directed graph with parallel edges and provides a
Tiago Peixoto's avatar
Tiago Peixoto committed
35
36
// view of the graph as undirected with parallel edges.
//==============================================================================
37
template <class Graph> class undirected_adaptor
Tiago Peixoto's avatar
Tiago Peixoto committed
38
39
{
public:
40
    undirected_adaptor(const Graph& g) : _g(const_cast<Graph&>(g)){}
Tiago Peixoto's avatar
Tiago Peixoto committed
41

42
43
    typedef typename vertex_property_type<Graph>::type vertex_property_type;
    typedef typename edge_property_type<Graph>::type edge_property_type;
44
    typedef typename Graph::graph_tag graph_tag;
45
    typedef Graph graph_type;
46

Tiago Peixoto's avatar
Tiago Peixoto committed
47
    typedef Graph original_graph_t;
48

49
    typedef typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor
50
        vertex_descriptor;
51
    typedef typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor
52
53
        edge_descriptor;

54
55
56
    typedef undirected_tag directed_category;
    typedef allow_parallel_edge_tag edge_parallel_category;
    typedef typename graph_traits<Graph>::traversal_category traversal_category;
57

58
59
    const Graph& original_graph() const {return _g;}
    Graph& original_graph() {return _g;}
60

61
62
    static vertex_descriptor null_vertex() {graph_traits<Graph>::null_vertex();}

Tiago Peixoto's avatar
Tiago Peixoto committed
63
private:
64
    Graph& _g;
Tiago Peixoto's avatar
Tiago Peixoto committed
65
66
};

67
template <class Graph>
68
struct get_iterator_category
69
{
70
71
    typedef typename graph_traits<Graph>::out_edge_iterator iter_t;
    typedef typename std::iterator_traits<iter_t>::iterator_category type;
72
};
73

Tiago Peixoto's avatar
Tiago Peixoto committed
74
75

//==============================================================================
76
77
// graph_traits<undirected_adaptor>
// this defines all the necessary types associated with undirected_adaptor
Tiago Peixoto's avatar
Tiago Peixoto committed
78
79
//==============================================================================
template <class Graph>
80
struct graph_traits<undirected_adaptor<Graph> > {
Tiago Peixoto's avatar
Tiago Peixoto committed
81
    typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
82
    typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
Tiago Peixoto's avatar
Tiago Peixoto committed
83

84
85
86
    typedef typename graph_traits<Graph>::adjacency_iterator adjacency_iterator;
    typedef typename graph_traits<Graph>::out_edge_iterator out_edge_iterator;
    typedef typename graph_traits<Graph>::in_edge_iterator in_edge_iterator;
Tiago Peixoto's avatar
Tiago Peixoto committed
87
    typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
88
    typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
89

90

Tiago Peixoto's avatar
Tiago Peixoto committed
91
    typedef undirected_tag directed_category;
92
    typedef allow_parallel_edge_tag edge_parallel_category;
93
    typedef typename graph_traits<Graph>::traversal_category traversal_category;
Tiago Peixoto's avatar
Tiago Peixoto committed
94
95
96
    typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
    typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
    typedef typename graph_traits<Graph>::degree_size_type degree_size_type;
97
98
99
100
101

    static vertex_descriptor null_vertex()
    {
        return graph_traits<Graph>::null_vertex();
    }
102
103
104
105
106
107
108

private:
    typedef is_convertible<typename std::iterator_traits<typename graph_traits<Graph>::out_edge_iterator>::iterator_category,
                           std::random_access_iterator_tag> is_orig_ra;
    typedef is_convertible<typename std::iterator_traits<out_edge_iterator>::iterator_category,
                           std::random_access_iterator_tag> is_ra;
    BOOST_STATIC_ASSERT((!is_orig_ra::value || is_ra::value));
Tiago Peixoto's avatar
Tiago Peixoto committed
109
110
};

111
template <class Graph>
112
113
struct graph_traits< const undirected_adaptor<Graph> >:
    public graph_traits<undirected_adaptor<Graph> > {};
114

Tiago Peixoto's avatar
Tiago Peixoto committed
115
116
//==============================================================================
// Nonmember functions
117
// these provide manipulation of the graph
Tiago Peixoto's avatar
Tiago Peixoto committed
118
119
120
121
122
123
//==============================================================================

//==============================================================================
// source(e,g)
//==============================================================================
template <class Graph>
124
inline  __attribute__((always_inline)) __attribute__((flatten))
125
126
127
auto
source(const typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor& e,
       const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
128
{
129
    return source(e, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
130
131
132
133
134
135
}

//==============================================================================
// target(e,g)
//==============================================================================
template <class Graph>
136
inline  __attribute__((always_inline)) __attribute__((flatten))
137
138
139
auto
target(const typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor& e,
       const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
140
{
141
    return target(e, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
142
143
144
145
146
147
}

//==============================================================================
// vertex(n,g)
//==============================================================================
template <class Graph>
148
inline  __attribute__((always_inline)) __attribute__((flatten))
149
150
151
auto
vertex(typename graph_traits<undirected_adaptor<Graph> >::vertices_size_type n,
       const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
152
{
153
    return vertex(n, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
154
155
156
157
158
159
}

//==============================================================================
// vertices(g)
//==============================================================================
template <class Graph>
160
inline  __attribute__((always_inline)) __attribute__((flatten))
161
162
auto
vertices(const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
163
{
164
    return vertices(g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
165
166
167
168
169
170
}

//==============================================================================
// edges(g)
//==============================================================================
template <class Graph>
171
inline  __attribute__((always_inline)) __attribute__((flatten))
172
173
auto
edges(const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
174
{
175
    return edges(g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
176
177
}

178
179
180
181
//==============================================================================
// edge(u, v, g)
//==============================================================================
template <class Graph>
182
inline __attribute__((always_inline)) __attribute__((flatten))
183
184
185
186
auto
edge(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
     typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
     const undirected_adaptor<Graph>& g)
187
{
188
    auto res = edge(u, v, g.original_graph());
189
190
191

    if (!res.second)
    {
192
        res = edge(v, u, g.original_graph());
193
        std::swap(res.first.s, res.first.t);
194
    }
195
196

    return res;
197
198
}

Tiago Peixoto's avatar
Tiago Peixoto committed
199
200
201
202
//==============================================================================
// out_edges(u,g)
//==============================================================================
template <class Graph>
203
inline __attribute__((always_inline)) __attribute__((flatten))
204
205
206
auto
out_edges(typename graph_traits<undirected_adaptor<Graph>>::vertex_descriptor u,
          const undirected_adaptor<Graph>& g)
207
{
208
    return _all_edges_out(u, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
209
210
}

211
212
213
214
//==============================================================================
// in_edges(u,g)
//==============================================================================
template <class Graph>
215
inline __attribute__((always_inline)) __attribute__((flatten))
216
217
218
auto
in_edges(typename graph_traits<undirected_adaptor<Graph>>::vertex_descriptor u,
         const undirected_adaptor<Graph>& g)
219
{
220
    return _all_edges_in(u, g.original_graph());
221
222
223
224
225
226
}

//==============================================================================
// out_neighbours(u, g)
//==============================================================================
template <class Graph>
227
inline  __attribute__((always_inline)) __attribute__((flatten))
228
229
230
auto
out_neighbours(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
               const undirected_adaptor<Graph>& g)
231
{
232
    return all_neighbours(u, g.original_graph());
233
234
235
236
237
238
}

//==============================================================================
// in_neighbours(u, g)
//==============================================================================
template <class Graph>
239
inline  __attribute__((always_inline)) __attribute__((flatten))
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
auto
in_neighbours(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
              const undirected_adaptor<Graph>& g)
{
    return out_neighbours(u, g);
}

//==============================================================================
// all_neighbours(u, g)
//==============================================================================
template <class Graph>
inline  __attribute__((always_inline)) __attribute__((flatten))
auto
all_neighbours(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
               const undirected_adaptor<Graph>& g)
255
256
{
    return out_neighbours(u, g);
257
258
}

Tiago Peixoto's avatar
Tiago Peixoto committed
259
260
261
262
//==============================================================================
// adjacent_vertices(u,g)
//==============================================================================
template <class Graph>
263
inline  __attribute__((always_inline)) __attribute__((flatten))
264
auto
265
adjacent_vertices
266
267
    (typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
     const undirected_adaptor<Graph>& g)
268
{
269
    return out_neighbours(u, g);
Tiago Peixoto's avatar
Tiago Peixoto committed
270
271
272
273
274
275
}

//==============================================================================
// num_vertices(g)
//==============================================================================
template <class Graph>
276
inline __attribute__((always_inline)) __attribute__((flatten))
277
278
auto
num_vertices(const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
279
{
280
    return num_vertices(g.original_graph());
281
}
Tiago Peixoto's avatar
Tiago Peixoto committed
282
283
284
285
286

//==============================================================================
// num_edges(g)
//==============================================================================
template <class Graph>
287
inline __attribute__((always_inline)) __attribute__((flatten))
288
289
auto
num_edges(const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
290
{
291
    return num_edges(g.original_graph());
292
}
Tiago Peixoto's avatar
Tiago Peixoto committed
293
294
295
296
297

//==============================================================================
// out_degree(u,g)
//==============================================================================
template <class Graph>
298
inline __attribute__((always_inline)) __attribute__((flatten))
299
300
301
auto
out_degree(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
           const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
302
{
303
    return degree(u, g.original_graph());
304
305
306
307
308
309
}

//==============================================================================
// in_degree(u,g)
//==============================================================================
template <class Graph>
310
inline __attribute__((always_inline)) __attribute__((flatten))
311
312
313
auto
in_degree(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
          const undirected_adaptor<Graph>& g)
314
315
{
    return out_degree(u, g);
Tiago Peixoto's avatar
Tiago Peixoto committed
316
317
318
319
320
321
}

//==============================================================================
// degree(u,g)
//==============================================================================
template <class Graph>
322
inline __attribute__((always_inline)) __attribute__((flatten))
323
324
325
auto
degree(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
       const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
326
327
328
329
330
331
332
333
{
    return out_degree(u, g);
}


//==============================================================================
// add_vertex(g)
//==============================================================================
334
template <class Graph>
335
inline __attribute__((always_inline))
336
337
auto
add_vertex(undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
338
{
339
    return add_vertex(g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
340
341
342
343
344
345
}

//==============================================================================
// add_vertex(vp,g)
//==============================================================================
template <class Graph, class VertexProperties>
346
inline __attribute__((always_inline))
347
348
auto
add_vertex(const VertexProperties& p, undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
349
{
350
    return add_vertex(p, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
351
352
353
354
355
356
}

//==============================================================================
// clear_vertex(u,g)
//==============================================================================
template <class Graph>
357
inline __attribute__((always_inline))
358
359
void clear_vertex(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
                  undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
360
{
361
    clear_vertex(u, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
362
363
}

364
365
366
367
368
369
370
371
372
373
374
//==============================================================================
// clear_vertex(u,g,pred)
//==============================================================================
template <class Graph, class Pred>
inline __attribute__((always_inline))
void clear_vertex(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
                  undirected_adaptor<Graph>& g, Pred&& pred)
{
    clear_vertex(u, g.original_graph(), pred);
}

Tiago Peixoto's avatar
Tiago Peixoto committed
375
376
377
378
//==============================================================================
// remove_vertex(u,g)
//==============================================================================
template <class Graph>
379
inline __attribute__((always_inline))
380
381
void remove_vertex(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
                   undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
382
{
383
    remove_vertex(u, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
384
385
}

386
387
388
389
//==============================================================================
// remove_vertex_fast(u,g)
//==============================================================================
template <class Graph>
390
inline __attribute__((always_inline))
391
392
void remove_vertex_fast(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
                        undirected_adaptor<Graph>& g)
393
{
394
    remove_vertex_fast(u, g.original_graph());
395
396
}

Tiago Peixoto's avatar
Tiago Peixoto committed
397
398
399
400
//==============================================================================
// add_edge(u,v,g)
//==============================================================================
template <class Graph>
401
inline __attribute__((always_inline))
402
std::pair<typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor,
403
          bool>
404
405
406
add_edge(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
         typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
         undirected_adaptor<Graph>& g)
407
{
408
    return add_edge(u, v, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
409
410
411
412
413
414
}

//==============================================================================
// add_edge(u,v,ep,g)
//==============================================================================
template <class Graph, class EdgeProperties>
415
inline __attribute__((always_inline))
416
417
418
419
auto
add_edge(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
         typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
         const EdgeProperties& ep, undirected_adaptor<Graph>& g)
420
{
421
    return add_edge(u, v, ep, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
422
423
424
425
426
427
}

//==============================================================================
// remove_edge(u,v,g)
//==============================================================================
template <class Graph>
428
inline __attribute__((always_inline))
429
430
431
void remove_edge(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor u,
                 typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
                 undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
432
{
433
434
435
    auto e = edge(u, v, g);
    if (e.second)
        remove_edge(e.first, g);
Tiago Peixoto's avatar
Tiago Peixoto committed
436
437
438
439
440
441
}

//==============================================================================
// remove_edge(e,g)
//==============================================================================
template <class Graph>
442
inline __attribute__((always_inline))
443
444
void remove_edge(typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor e,
                 undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
445
{
446
447
448
449
    auto& u = g.original_graph();
    remove_edge(e, u);
    std::swap(e.s, e.t);
    remove_edge(e, u);
Tiago Peixoto's avatar
Tiago Peixoto committed
450
451
452
453
454
455
}

//==============================================================================
// remove_edge(e_iter,g)
//==============================================================================
template <class Graph>
456
inline __attribute__((always_inline))
457
458
void remove_edge(const typename graph_traits<undirected_adaptor<Graph> >::out_edge_iterator& iter,
                 undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
459
460
461
462
463
464
465
466
{
    remove_edge(*iter, g);
}

//==============================================================================
// remove_out_edge_if(v,predicate,g)
//==============================================================================
template <class Graph, class Predicate>
467
inline
468
469
void remove_out_edge_if(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
                        Predicate predicate, undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
470
{
471
    std::vector<typename undirected_adaptor<Graph>::EdgeDescriptor> removed_edges;
472
473
    auto edge_range = out_edges(v,g);
    for(auto iter = edge_range.first; iter != edge_range.second; ++iter)
Tiago Peixoto's avatar
Tiago Peixoto committed
474
        if (predicate(*iter))
475
476
477
            removed_edges.push_back(*iter);
    for(auto& e : removed_edges)
        remove_edge(e, g);
Tiago Peixoto's avatar
Tiago Peixoto committed
478
479
}

480
481
482
483
//==============================================================================
// remove_in_edge_if(v,predicate,g)
//==============================================================================
template <class Graph, class Predicate>
484
inline
485
486
void remove_in_edge_if(typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
                       Predicate predicate, undirected_adaptor<Graph>& g)
487
{
488
    std::vector<typename undirected_adaptor<Graph>::EdgeDescriptor> removed_edges;
489
490
    auto edge_range = in_edges(v,g);
    for(auto iter = edge_range.first; iter != edge_range.second; ++iter)
491
        if (predicate(*iter))
492
493
494
            removed_edges.push_back(*iter);
    for(auto& e : removed_edges)
        remove_edge(e, g);
495
496
}

Tiago Peixoto's avatar
Tiago Peixoto committed
497
498

//==============================================================================
499
// Property maps
Tiago Peixoto's avatar
Tiago Peixoto committed
500
501
502
//==============================================================================

//==============================================================================
503
// vertex_property<undirected_adaptor>
Tiago Peixoto's avatar
Tiago Peixoto committed
504
505
//==============================================================================
template <class Graph>
506
class vertex_property<undirected_adaptor<Graph> >
Tiago Peixoto's avatar
Tiago Peixoto committed
507
508
509
510
511
512
{
public:
    typedef typename vertex_property<Graph>::type type;
};

//==============================================================================
513
// vertex_property_type<undirected_adaptor>
Tiago Peixoto's avatar
Tiago Peixoto committed
514
515
//==============================================================================
template <class Graph>
516
class vertex_property_type<undirected_adaptor<Graph> >
Tiago Peixoto's avatar
Tiago Peixoto committed
517
518
519
520
521
522
{
public:
    typedef typename vertex_property_type<Graph>::type type;
};

//==============================================================================
523
// edge_property<undirected_adaptor>
Tiago Peixoto's avatar
Tiago Peixoto committed
524
525
//==============================================================================
template <class Graph>
526
class edge_property<undirected_adaptor<Graph> >
Tiago Peixoto's avatar
Tiago Peixoto committed
527
528
529
530
531
532
{
public:
    typedef typename edge_property<Graph>::type type;
};

//==============================================================================
533
// edge_property_type<undirected_adaptor>
Tiago Peixoto's avatar
Tiago Peixoto committed
534
535
//==============================================================================
template <class Graph>
536
class edge_property_type<undirected_adaptor<Graph> >
Tiago Peixoto's avatar
Tiago Peixoto committed
537
538
539
540
541
542
543
544
545
{
public:
    typedef typename edge_property_type<Graph>::type type;
};

//==============================================================================
// property_map<UndirecterdAdaptor, PropertyTag>
//==============================================================================
template <class Graph, class PropertyTag>
546
class property_map<undirected_adaptor<Graph>, PropertyTag>
Tiago Peixoto's avatar
Tiago Peixoto committed
547
548
549
{
public:
    typedef typename property_map<Graph, PropertyTag>::type type;
550
    typedef typename property_map<Graph, PropertyTag>::const_type const_type;
Tiago Peixoto's avatar
Tiago Peixoto committed
551
552
553
};

//==============================================================================
554
// property_map<undirected_adaptor, T Bundle::*>
Tiago Peixoto's avatar
Tiago Peixoto committed
555
556
//==============================================================================
template <typename Graph, typename T, typename Bundle>
557
class property_map<undirected_adaptor<Graph>, T Bundle::*>
Tiago Peixoto's avatar
Tiago Peixoto committed
558
559
560
561
562
563
564
565
566
567
568
{
public:
    typedef typename property_map<Graph, T Bundle::*>::type type;
    typedef typename property_map<Graph, T Bundle::*>::const_type const_type;
};


//==============================================================================
// get(tag,g)
//==============================================================================
template <class PropertyTag, class Graph>
569
inline
570
571
typename property_map<undirected_adaptor<Graph>, PropertyTag>::type
get(PropertyTag tag, undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
572
{
573
    return get(tag, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
574
575
576
}

//==============================================================================
577
// const get(tag,g)
Tiago Peixoto's avatar
Tiago Peixoto committed
578
579
//==============================================================================
template <class PropertyTag, class Graph>
580
inline
581
582
typename property_map<undirected_adaptor<Graph>, PropertyTag>::const_type
get(PropertyTag tag, const undirected_adaptor<Graph>& g)
Tiago Peixoto's avatar
Tiago Peixoto committed
583
{
584
    return get(tag, g.original_graph());
Tiago Peixoto's avatar
Tiago Peixoto committed
585
586
587
588
589
590
}

//==============================================================================
// get(tag,g,v)
//==============================================================================
template <class PropertyTag, class Graph>
591
inline
592
typename property_traits
593
    <typename property_map<undirected_adaptor<Graph>,
594
                           PropertyTag>::const_type >::value_type
595
596
get(PropertyTag tag, const undirected_adaptor<Graph>& g,
    typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v)
Tiago Peixoto's avatar
Tiago Peixoto committed
597
{
598
    return get(tag, g.original_graph(), v);
Tiago Peixoto's avatar
Tiago Peixoto committed
599
600
601
602
603
604
}

//==============================================================================
// get(tag,g,e)
//==============================================================================
template <class PropertyTag, class Graph>
605
inline
606
typename property_traits
607
    <typename property_map<undirected_adaptor<Graph>,
608
                           PropertyTag>::const_type >::value_type
609
610
get(PropertyTag tag, const undirected_adaptor<Graph>& g,
    const typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor& e)
Tiago Peixoto's avatar
Tiago Peixoto committed
611
{
612
    return get(tag, g.original_graph(), e);
Tiago Peixoto's avatar
Tiago Peixoto committed
613
614
615
616
617
618
}

//==============================================================================
// put(tag, g, v, value)
//==============================================================================
template <class Graph, class PropertyTag, class Value>
619
inline
620
621
void put(PropertyTag tag, undirected_adaptor<Graph>& g,
         typename graph_traits<undirected_adaptor<Graph> >::vertex_descriptor v,
622
         const Value& value)
Tiago Peixoto's avatar
Tiago Peixoto committed
623
{
624
    put(tag, g.original_graph(), v, value);
Tiago Peixoto's avatar
Tiago Peixoto committed
625
626
627
628
629
630
}

//==============================================================================
// put(tag, g, e, value)
//==============================================================================
template <class Graph, class PropertyTag, class X, class Value>
631
inline
632
633
void put(PropertyTag tag, const undirected_adaptor<Graph>& g,
         const typename graph_traits<undirected_adaptor<Graph> >::edge_descriptor& e,
634
         const Value &value)
Tiago Peixoto's avatar
Tiago Peixoto committed
635
{
636
    put(tag, g.original_graph(), e, value);
Tiago Peixoto's avatar
Tiago Peixoto committed
637
638
639
640
641
642
}

//==============================================================================
// get_property(g,tag)
//==============================================================================
template <class Graph, class GraphProperties, class GraphPropertyTag>
643
inline
Tiago Peixoto's avatar
Tiago Peixoto committed
644
typename property_value<GraphProperties, GraphPropertyTag>::type&
645
get_property(undirected_adaptor<Graph>& g, GraphPropertyTag tag)
Tiago Peixoto's avatar
Tiago Peixoto committed
646
{
647
    get_property(g.original_graph(), tag);
Tiago Peixoto's avatar
Tiago Peixoto committed
648
649
650
651
652
653
}

//==============================================================================
// const get_property(g,tag)
//==============================================================================
template <class Graph, class GraphProperties, class GraphPropertyTag>
654
inline
Tiago Peixoto's avatar
Tiago Peixoto committed
655
const typename property_value<GraphProperties, GraphPropertyTag>::type&
656
get_property(const undirected_adaptor<Graph>& g, GraphPropertyTag tag)
Tiago Peixoto's avatar
Tiago Peixoto committed
657
{
658
    get_property(g.original_graph(), tag);
Tiago Peixoto's avatar
Tiago Peixoto committed
659
660
661
662
663
664
}

} // namespace boost


#endif // GRAPH_ADAPTOR_HH