map.hpp 6.09 KB
Newer Older
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
// Boost.Range library
//
//  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
//  distribution is subject to 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)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_ADAPTOR_MAP_HPP
#define BOOST_RANGE_ADAPTOR_MAP_HPP

#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/value_type.hpp>

namespace boost
{
    namespace range_detail
    {
        struct map_keys_forwarder {};
        struct map_values_forwarder {};

        template< class Map >
        struct select_first
        {
28 29 30
            typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type pair_t;
            typedef const BOOST_DEDUCED_TYPENAME pair_t::first_type&
                result_type;
31 32 33 34 35 36 37 38 39 40

            result_type operator()( const pair_t& r ) const
            {
                return r.first;
            }
        };

        template< class Map >
        struct select_second_mutable
        {
41 42
            typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type pair_t;
            typedef BOOST_DEDUCED_TYPENAME pair_t::second_type& result_type;
43 44 45 46 47 48 49 50 51 52

            result_type operator()( pair_t& r ) const
            {
                return r.second;
            }
        };

        template< class Map >
        struct select_second_const
        {
53 54 55 56
            typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type pair_t;
            typedef const BOOST_DEDUCED_TYPENAME pair_t::second_type&
                result_type;

57 58 59 60 61
            result_type operator()( const pair_t& r ) const
            {
                return r.second;
            }
        };
62

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
        template<class StdPairRng>
        class select_first_range
            : public transform_range<
                        select_first<StdPairRng>,
                        const StdPairRng>
        {
            typedef transform_range<select_first<StdPairRng>, const StdPairRng> base;
        public:
            typedef select_first<StdPairRng> transform_fn_type;
            typedef const StdPairRng source_range_type;

            select_first_range(transform_fn_type fn, source_range_type& rng)
                : base(fn, rng)
            {
            }

            select_first_range(const base& other) : base(other) {}
        };
81

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        template<class StdPairRng>
        class select_second_mutable_range
            : public transform_range<
                        select_second_mutable<StdPairRng>,
                        StdPairRng>
        {
            typedef transform_range<select_second_mutable<StdPairRng>, StdPairRng> base;
        public:
            typedef select_second_mutable<StdPairRng> transform_fn_type;
            typedef StdPairRng source_range_type;

            select_second_mutable_range(transform_fn_type fn, source_range_type& rng)
                : base(fn, rng)
            {
            }

            select_second_mutable_range(const base& other) : base(other) {}
        };
100

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
        template<class StdPairRng>
        class select_second_const_range
            : public transform_range<
                        select_second_const<StdPairRng>,
                        const StdPairRng>
        {
            typedef transform_range<select_second_const<StdPairRng>, const StdPairRng> base;
        public:
            typedef select_second_const<StdPairRng> transform_fn_type;
            typedef const StdPairRng source_range_type;

            select_second_const_range(transform_fn_type fn, source_range_type& rng)
                : base(fn, rng)
            {
            }

            select_second_const_range(const base& other) : base(other) {}
        };
119

120
        template< class StdPairRng >
121
        inline select_first_range<StdPairRng>
122 123
        operator|( const StdPairRng& r, map_keys_forwarder )
        {
124
            return operator|( r,
125 126 127 128
              boost::adaptors::transformed( select_first<StdPairRng>() ) );
        }

        template< class StdPairRng >
129
        inline select_second_mutable_range<StdPairRng>
130 131
        operator|( StdPairRng& r, map_values_forwarder )
        {
132
            return operator|( r,
133 134 135 136 137 138 139
          boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
        }

        template< class StdPairRng >
        inline select_second_const_range<StdPairRng>
        operator|( const StdPairRng& r, map_values_forwarder )
        {
140 141
            return operator|( r,
           boost::adaptors::transformed( select_second_const<StdPairRng>() ) );
142
        }
143

144
    } // 'range_detail'
145

146 147 148 149 150
    using range_detail::select_first_range;
    using range_detail::select_second_mutable_range;
    using range_detail::select_second_const_range;

    namespace adaptors
151
    {
152 153
        namespace
        {
154
            const range_detail::map_keys_forwarder map_keys =
155 156
                                            range_detail::map_keys_forwarder();

157
            const range_detail::map_values_forwarder map_values =
158 159
                                           range_detail::map_values_forwarder();
        }
160

161 162 163 164 165 166 167
        template<class StdPairRange>
        inline select_first_range<StdPairRange>
        keys(const StdPairRange& rng)
        {
            return select_first_range<StdPairRange>(
                range_detail::select_first<StdPairRange>(), rng );
        }
168

169 170 171 172 173 174 175
        template<class StdPairRange>
        inline select_second_const_range<StdPairRange>
        values(const StdPairRange& rng)
        {
            return select_second_const_range<StdPairRange>(
                range_detail::select_second_const<StdPairRange>(), rng );
        }
176

177 178 179 180 181 182 183 184
        template<class StdPairRange>
        inline select_second_mutable_range<StdPairRange>
        values(StdPairRange& rng)
        {
            return select_second_mutable_range<StdPairRange>(
                range_detail::select_second_mutable<StdPairRange>(), rng );
        }
    } // 'adaptors'
185

186 187 188
}

#endif