map.hpp 6.05 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 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
// 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>
#include <boost/range/reference.hpp>

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

        template< class Map >
        struct select_first
        {
            typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
            typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type;

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

        template< class Map >
        struct select_second_mutable
        {
            typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type;
            typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type;

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

        template< class Map >
        struct select_second_const
        {
            typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type;
            typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type;

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

        template<class StdPairRng>
        class select_first_range
            : public transformed_range<
                        select_first<StdPairRng>,
                        const StdPairRng>
        {
            typedef transformed_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) {}
        };

        template<class StdPairRng>
        class select_second_mutable_range
            : public transformed_range<
                        select_second_mutable<StdPairRng>,
                        StdPairRng>
        {
            typedef transformed_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) {}
        };

        template<class StdPairRng>
        class select_second_const_range
            : public transformed_range<
                        select_second_const<StdPairRng>,
                        const StdPairRng>
        {
            typedef transformed_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) {}
        };

        template< class StdPairRng >
        inline select_first_range<StdPairRng>
        operator|( const StdPairRng& r, map_keys_forwarder )
        {
            return operator|( r,
                boost::adaptors::transformed( select_first<StdPairRng>() ) );
        }

        template< class StdPairRng >
        inline select_second_mutable_range<StdPairRng>
        operator|( StdPairRng& r, map_values_forwarder )
        {
            return operator|( r,
                boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) );
        }

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

    } // 'range_detail'

    using range_detail::select_first_range;
    using range_detail::select_second_mutable_range;
    using range_detail::select_second_const_range;

    namespace adaptors
    {
        namespace
        {
            const range_detail::map_keys_forwarder map_keys =
                                            range_detail::map_keys_forwarder();

            const range_detail::map_values_forwarder map_values =
                                           range_detail::map_values_forwarder();
        }

        template<class StdPairRange>
        inline select_first_range<StdPairRange>
        keys(const StdPairRange& rng)
        {
            return select_first_range<StdPairRange>(
                range_detail::select_first<StdPairRange>(), rng );
        }

        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 );
        }

        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'

}

#endif