1 // Boost.Range library 2 // 3 // Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and 4 // distribution is subject to the Boost Software License, Version 5 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // For more information, see http://www.boost.org/libs/range/ 9 // 10 11 #ifndef BOOST_RANGE_ADAPTOR_MAP_HPP 12 #define BOOST_RANGE_ADAPTOR_MAP_HPP 13 14 #include <boost/range/adaptor/transformed.hpp> 15 #include <boost/range/iterator_range.hpp> 16 #include <boost/range/value_type.hpp> 17 #include <boost/range/reference.hpp> 18 #include <boost/range/concepts.hpp> 19 20 namespace boost 21 { 22 namespace range_detail 23 { 24 struct map_keys_forwarder {}; 25 struct map_values_forwarder {}; 26 27 template< class Map > 28 struct select_first 29 { 30 typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type; 31 typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::first_type& result_type; 32 operator ()boost::range_detail::select_first33 result_type operator()( argument_type r ) const 34 { 35 return r.first; 36 } 37 }; 38 39 template< class Map > 40 struct select_second_mutable 41 { 42 typedef BOOST_DEDUCED_TYPENAME range_reference<Map>::type argument_type; 43 typedef BOOST_DEDUCED_TYPENAME range_value<Map>::type::second_type& result_type; 44 operator ()boost::range_detail::select_second_mutable45 result_type operator()( argument_type r ) const 46 { 47 return r.second; 48 } 49 }; 50 51 template< class Map > 52 struct select_second_const 53 { 54 typedef BOOST_DEDUCED_TYPENAME range_reference<const Map>::type argument_type; 55 typedef const BOOST_DEDUCED_TYPENAME range_value<const Map>::type::second_type& result_type; 56 operator ()boost::range_detail::select_second_const57 result_type operator()( argument_type r ) const 58 { 59 return r.second; 60 } 61 }; 62 63 template<class StdPairRng> 64 class select_first_range 65 : public transformed_range< 66 select_first<StdPairRng>, 67 const StdPairRng> 68 { 69 typedef transformed_range<select_first<StdPairRng>, const StdPairRng> base; 70 public: 71 typedef select_first<StdPairRng> transform_fn_type; 72 typedef const StdPairRng source_range_type; 73 select_first_range(transform_fn_type fn,source_range_type & rng)74 select_first_range(transform_fn_type fn, source_range_type& rng) 75 : base(fn, rng) 76 { 77 } 78 select_first_range(const base & other)79 select_first_range(const base& other) : base(other) {} 80 }; 81 82 template<class StdPairRng> 83 class select_second_mutable_range 84 : public transformed_range< 85 select_second_mutable<StdPairRng>, 86 StdPairRng> 87 { 88 typedef transformed_range<select_second_mutable<StdPairRng>, StdPairRng> base; 89 public: 90 typedef select_second_mutable<StdPairRng> transform_fn_type; 91 typedef StdPairRng source_range_type; 92 select_second_mutable_range(transform_fn_type fn,source_range_type & rng)93 select_second_mutable_range(transform_fn_type fn, source_range_type& rng) 94 : base(fn, rng) 95 { 96 } 97 select_second_mutable_range(const base & other)98 select_second_mutable_range(const base& other) : base(other) {} 99 }; 100 101 template<class StdPairRng> 102 class select_second_const_range 103 : public transformed_range< 104 select_second_const<StdPairRng>, 105 const StdPairRng> 106 { 107 typedef transformed_range<select_second_const<StdPairRng>, const StdPairRng> base; 108 public: 109 typedef select_second_const<StdPairRng> transform_fn_type; 110 typedef const StdPairRng source_range_type; 111 select_second_const_range(transform_fn_type fn,source_range_type & rng)112 select_second_const_range(transform_fn_type fn, source_range_type& rng) 113 : base(fn, rng) 114 { 115 } 116 select_second_const_range(const base & other)117 select_second_const_range(const base& other) : base(other) {} 118 }; 119 120 template< class StdPairRng > 121 inline select_first_range<StdPairRng> operator |(const StdPairRng & r,map_keys_forwarder)122 operator|( const StdPairRng& r, map_keys_forwarder ) 123 { 124 BOOST_RANGE_CONCEPT_ASSERT(( 125 SinglePassRangeConcept<const StdPairRng>)); 126 127 return operator|( r, 128 boost::adaptors::transformed( select_first<StdPairRng>() ) ); 129 } 130 131 template< class StdPairRng > 132 inline select_second_mutable_range<StdPairRng> operator |(StdPairRng & r,map_values_forwarder)133 operator|( StdPairRng& r, map_values_forwarder ) 134 { 135 BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRng>)); 136 137 return operator|( r, 138 boost::adaptors::transformed( select_second_mutable<StdPairRng>() ) ); 139 } 140 141 template< class StdPairRng > 142 inline select_second_const_range<StdPairRng> operator |(const StdPairRng & r,map_values_forwarder)143 operator|( const StdPairRng& r, map_values_forwarder ) 144 { 145 BOOST_RANGE_CONCEPT_ASSERT(( 146 SinglePassRangeConcept<const StdPairRng>)); 147 148 return operator|( r, 149 boost::adaptors::transformed( select_second_const<StdPairRng>() ) ); 150 } 151 152 } // 'range_detail' 153 154 using range_detail::select_first_range; 155 using range_detail::select_second_mutable_range; 156 using range_detail::select_second_const_range; 157 158 namespace adaptors 159 { 160 namespace 161 { 162 const range_detail::map_keys_forwarder map_keys = 163 range_detail::map_keys_forwarder(); 164 165 const range_detail::map_values_forwarder map_values = 166 range_detail::map_values_forwarder(); 167 } 168 169 template<class StdPairRange> 170 inline select_first_range<StdPairRange> keys(const StdPairRange & rng)171 keys(const StdPairRange& rng) 172 { 173 BOOST_RANGE_CONCEPT_ASSERT(( 174 SinglePassRangeConcept<const StdPairRange>)); 175 176 return select_first_range<StdPairRange>( 177 range_detail::select_first<StdPairRange>(), rng ); 178 } 179 180 template<class StdPairRange> 181 inline select_second_const_range<StdPairRange> values(const StdPairRange & rng)182 values(const StdPairRange& rng) 183 { 184 BOOST_RANGE_CONCEPT_ASSERT(( 185 SinglePassRangeConcept<const StdPairRange>)); 186 187 return select_second_const_range<StdPairRange>( 188 range_detail::select_second_const<StdPairRange>(), rng ); 189 } 190 191 template<class StdPairRange> 192 inline select_second_mutable_range<StdPairRange> values(StdPairRange & rng)193 values(StdPairRange& rng) 194 { 195 BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<StdPairRange>)); 196 197 return select_second_mutable_range<StdPairRange>( 198 range_detail::select_second_mutable<StdPairRange>(), rng ); 199 } 200 } // 'adaptors' 201 202 } 203 204 #endif 205