1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/Iterator.h
12 #ifndef ZYPP_BASE_ITERATOR_H
13 #define ZYPP_BASE_ITERATOR_H
18 #include <boost/functional.hpp>
19 #include <boost/iterator/filter_iterator.hpp>
20 #include <boost/iterator/transform_iterator.hpp>
21 #include <boost/function_output_iterator.hpp>
23 ///////////////////////////////////////////////////////////////////
25 { /////////////////////////////////////////////////////////////////
27 /** \defgroup ITERATOR Boost.Iterator Library
29 * \see http://www.boost.org/libs/iterator/doc/index.html
31 * \li \b counting_iterator: an iterator over a sequence of
32 * consecutive values. Implements a "lazy sequence"
33 * \li \b filter_iterator: an iterator over the subset of elements
34 * of some sequence which satisfy a given predicate
35 * \li \b function_output_iterator: an output iterator wrapping a
36 * unary function object; each time an element is written into
37 * the dereferenced iterator, it is passed as a parameter to
38 * the function object.
39 * \li \b indirect_iterator: an iterator over the objects pointed-to
40 * by the elements of some sequence.
41 * \li \b permutation_iterator: an iterator over the elements of
42 * some random-access sequence, rearranged according to some
43 * sequence of integer indices.
44 * \li \b reverse_iterator: an iterator which traverses the elements
45 * of some bidirectional sequence in reverse. Corrects many of the shortcomings of C++98's std::reverse_iterator.
46 * \li \b shared_container_iterator: an iterator over elements of
47 * a container whose lifetime is maintained by a shared_ptr
48 * stored in the iterator.
49 * \li \b transform_iterator: an iterator over elements which are
50 * the result of applying some functional transformation to
51 * the elements of an underlying sequence. This component
52 * also replaces the old projection_iterator_adaptor.
53 * \li \b zip_iterator: an iterator over tuples of the elements
54 * at corresponding positions of heterogeneous underlying
57 * There are in fact more interesting iterator concepts
58 * available than the ones listed above. Have a look at them.
60 * Some of the iterator types are already dragged into namespace
61 * zypp. Feel free to add what's missing.
63 * \todo Separate them into individual zypp header files.
67 /** \class filter_iterator
68 * An iterator over the subset of elements of some sequence
69 * which satisfy a given predicate.
71 * Provides boost::filter_iterator and boost::make_filter_iterator
72 * convenience function.
73 * \see http://www.boost.org/libs/iterator/doc/filter_iterator.html
75 * template <class Predicate, class Iterator>
76 * filter_iterator<Predicate,Iterator>
77 * make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
79 * template <class Predicate, class Iterator>
80 * filter_iterator<Predicate,Iterator>
81 * make_filter_iterator(Iterator x, Iterator end = Iterator());
83 * Remember the deduction rules for template arguments.
85 * struct MyDefaultConstructibleFilter;
86 * make_filter_iterator<MyDefaultConstructibleFilter>( c.begin(), c.end() );
87 * make_filter_iterator( MyDefaultConstructibleFilter(), c.begin(), c.end() );
89 * make_filter_iterator( resfilter::ByName("foo"), c.begin(), c.end() );
93 using boost::filter_iterator;
94 using boost::make_filter_iterator;
96 /** Convenience to create filter_iterator from container::begin(). */
97 template<class _Filter, class _Container>
98 filter_iterator<_Filter, typename _Container::const_iterator>
99 make_filter_begin( _Filter f, const _Container & c )
101 return make_filter_iterator( f, c.begin(), c.end() );
104 /** Convenience to create filter_iterator from container::begin(). */
105 template<class _Filter, class _Container>
106 filter_iterator<_Filter, typename _Container::const_iterator>
107 make_filter_begin( const _Container & c )
109 return make_filter_iterator( _Filter(), c.begin(), c.end() );
112 /** Convenience to create filter_iterator from container::end(). */
113 template<class _Filter, class _Container>
114 filter_iterator<_Filter, typename _Container::const_iterator>
115 make_filter_end( _Filter f, const _Container & c )
117 return make_filter_iterator( f, c.end(), c.end() );
120 /** Convenience to create filter_iterator from container::end(). */
121 template<class _Filter, class _Container>
122 filter_iterator<_Filter, typename _Container::const_iterator>
123 make_filter_end( const _Container & c )
125 return make_filter_iterator( _Filter(), c.end(), c.end() );
128 /** \class transform_iterator
129 * An iterator over elements which are the result of applying
130 * some functional transformation to the elements of an underlying
133 * Provides boost::transform_iterator and boost::make_transform_iterator
134 * convenience function.
135 * \see http://www.boost.org/libs/iterator/doc/transform_iterator.html
137 * template <class UnaryFunction, class Iterator>
138 * transform_iterator<UnaryFunction, Iterator>
139 * make_transform_iterator(Iterator it, UnaryFunction fun);
141 * template <class UnaryFunction, class Iterator>
142 * transform_iterator<UnaryFunction, Iterator>
143 * make_transform_iterator(Iterator it);
146 using boost::transform_iterator;
147 using boost::make_transform_iterator;
149 /** Functor taking a \c std::pair returning \c std::pair.first.
150 * \see MapKVIteratorTraits
152 template<class _Pair>
153 struct GetPairFirst : public std::unary_function<_Pair, const typename _Pair::first_type &>
155 const typename _Pair::first_type & operator()( const _Pair & pair_r ) const
156 { return pair_r.first; }
159 /** Functor taking a \c std::pair returning \c std::pair.second .
160 * \see MapKVIteratorTraits
162 template<class _Pair>
163 struct GetPairSecond : public std::unary_function<_Pair, const typename _Pair::second_type &>
165 const typename _Pair::second_type & operator()( const _Pair & pair_r ) const
166 { return pair_r.second; }
169 /** Traits for std::map key and value iterators.
171 * \ref GetPairFirst and \ref GetPairSecond help building a transform_iterator
172 * that iterates over keys or values of a std::map. Class MapKVIteratorTraits
173 * provides some typedefs, you usg. do not want to write explicitly.
177 * typedef std::map<K,V> MapType;
179 * // transform_iterator<GetPairFirst<MapType::value_type>, MapType::const_iterator>
180 * typedef MapKVIteratorTraits<MapType>::Key_const_iterator MapTypeKey_iterator;
181 * // transform_iterator<GetPairSecond<MapType::value_type>, MapType::const_iterator>
182 * typedef MapKVIteratorTraits<MapType>::Value_const_iterator MapTypeValue_iterator;
187 * MapTypeKey_const_iterator keyBegin( make_map_key_begin( mymap ) );
188 * MapTypeKey_const_iterator keyEnd ( make_map_key_end( mymap ) );
190 * MapTypeValue_const_iterator valBegin( make_map_value_begin( mymap ) );
191 * MapTypeValue_const_iterator valEnd ( make_map_value_end( mymap ) );
193 * std::for_each( keyBegin, keyEnd, DoSomething() );
194 * std::for_each( valBegin, valEnd, DoSomething() );
200 * typedef std::map<K,V> MapType;
203 * std::for_each( make_map_key_begin( mymap ), make_map_key_end( mymap ), DoSomething() );
204 * std::for_each( make_map_value_begin( mymap ), make_map_value_end( mymap ), DoSomething() );
208 struct MapKVIteratorTraits
211 typedef _Map MapType;
212 /** The maps key type */
213 typedef typename _Map::key_type KeyType;
214 /** The key iterator type */
215 typedef transform_iterator<GetPairFirst<typename MapType::value_type>,
216 typename MapType::const_iterator> Key_const_iterator;
217 /** The maps value (mapped) type */
218 typedef typename _Map::mapped_type ValueType;
219 /** The value iterator type */
220 typedef transform_iterator<GetPairSecond<typename MapType::value_type>,
221 typename MapType::const_iterator> Value_const_iterator;
224 /** Convenience to create the key iterator from container::begin() */
226 inline typename MapKVIteratorTraits<_Map>::Key_const_iterator make_map_key_begin( const _Map & map_r )
227 { return make_transform_iterator( map_r.begin(), GetPairFirst<typename _Map::value_type>() ); }
229 /** Convenience to create the key iterator from container::end() */
231 inline typename MapKVIteratorTraits<_Map>::Key_const_iterator make_map_key_end( const _Map & map_r )
232 { return make_transform_iterator( map_r.end(), GetPairFirst<typename _Map::value_type>() ); }
234 /** Convenience to create the value iterator from container::begin() */
236 inline typename MapKVIteratorTraits<_Map>::Value_const_iterator make_map_value_begin( const _Map & map_r )
237 { return make_transform_iterator( map_r.begin(), GetPairSecond<typename _Map::value_type>() ); }
239 /** Convenience to create the value iterator from container::end() */
241 inline typename MapKVIteratorTraits<_Map>::Value_const_iterator make_map_value_end( const _Map & map_r )
242 { return make_transform_iterator( map_r.end(), GetPairSecond<typename _Map::value_type>() ); }
244 /** Convenience to create the key iterator from container::lower_bound() */
246 inline typename MapKVIteratorTraits<_Map>::Key_const_iterator make_map_key_lower_bound( const _Map & map_r, const typename _Map::key_type & key_r )
247 { return make_transform_iterator( map_r.lower_bound( key_r ), GetPairFirst<typename _Map::value_type>() ); }
249 /** Convenience to create the key iterator from container::upper_bound() */
251 inline typename MapKVIteratorTraits<_Map>::Key_const_iterator make_map_key_upper_bound( const _Map & map_r, const typename _Map::key_type & key_r )
252 { return make_transform_iterator( map_r.upper_bound( key_r ), GetPairFirst<typename _Map::value_type>() ); }
254 /** Convenience to create the value iterator from container::lower_bound() */
256 inline typename MapKVIteratorTraits<_Map>::Value_const_iterator make_map_value_lower_bound( const _Map & map_r, const typename _Map::key_type & key_r )
257 { return make_transform_iterator( map_r.lower_bound( key_r ), GetPairSecond<typename _Map::value_type>() ); }
259 /** Convenience to create the value iterator from container::upper_bound() */
261 inline typename MapKVIteratorTraits<_Map>::Value_const_iterator make_map_value_upper_bound( const _Map & map_r, const typename _Map::key_type & key_r )
262 { return make_transform_iterator( map_r.upper_bound( key_r ), GetPairSecond<typename _Map::value_type>() ); }
264 /** \class function_output_iterator
265 * An output iterator wrapping a unary function object; each time an
266 * element is written into the dereferenced iterator, it is passed as
267 * a parameter to the function object.
269 * Provides boost::function_output_iterator and boost::make_function_output_iterator
270 * convenience function.
271 * \see http://www.boost.org/libs/iterator/doc/function_output_iterator.html
273 * template <class UnaryFunction>
274 * function_output_iterator<UnaryFunction>
275 * make_function_output_iterator(const UnaryFunction& f = UnaryFunction());
278 using boost::function_output_iterator;
279 using boost::make_function_output_iterator;
282 /////////////////////////////////////////////////////////////////
284 ///////////////////////////////////////////////////////////////////
285 #endif // ZYPP_BASE_ITERATOR_H