liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (C) 2013 Eurodecision
// Authors: Guillaume Pinot
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/property_map for documentation.
 
#ifndef BOOST_PROPERTY_MAP_COMPOSE_PROPERTY_MAP_HPP
#define BOOST_PROPERTY_MAP_COMPOSE_PROPERTY_MAP_HPP
 
#include <boost/property_map/property_map.hpp>
#include <boost/type_traits.hpp>
 
namespace boost {
 
// A compose property map: make_compose_property_map(f, g)[x] == f[g[x]]
//
// g must be a readable property map.
// The category of compose_property_map(f, g) is the category of f.
 
template <typename FPMap, typename GPMap>
class compose_property_map
{
public:
    typedef typename boost::property_traits<FPMap>::category category;
    typedef typename boost::property_traits<GPMap>::key_type key_type; 
    typedef typename boost::property_traits<FPMap>::value_type value_type;
    typedef typename boost::property_traits<FPMap>::reference reference;
 
    inline compose_property_map(const FPMap &f_p, const GPMap &g_p):
        f(f_p), g(g_p)
    {}
 
    inline compose_property_map() {}
 
    inline reference
    operator[](const key_type &v) const {
        return f[get(g, v)];
    }
 
    // return type of get():
    // if (reference is not a ref)
    //     value_type
    // else if (reference is const)
    //     reference
    // else
    //     const value_type&
    inline friend typename boost::mpl::if_<
        boost::mpl::not_< boost::is_reference<reference> >,
        value_type,
        typename boost::mpl::if_<
            boost::is_const<reference>,
            reference,
            const value_type&
            >::type
        >::type
    get(const compose_property_map &m, const key_type &k) {
        return get(m.f, get(m.g, k));
    }
 
    inline friend void
    put(const compose_property_map &m, const key_type &k, const value_type &v) {
        put(m.f, get(m.g, k), v);
    }
 
private:
    FPMap f;
    GPMap g;
};
 
template <class FPMap, class GPMap>
inline compose_property_map<FPMap, GPMap>
make_compose_property_map(const FPMap &f, const GPMap &g) {
    return compose_property_map<FPMap, GPMap>(f, g);
}
 
} // namespace boost
 
#endif // BOOST_PROPERTY_MAP_COMPOSE_PROPERTY_MAP_HPP