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 #include "zypp/base/Iterable.h"
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
29 /** \defgroup ITERATOR Boost.Iterator Library
31 * \see http://www.boost.org/libs/iterator/doc/index.html
33 * \li \b counting_iterator: an iterator over a sequence of
34 * consecutive values. Implements a "lazy sequence"
35 * \li \b filter_iterator: an iterator over the subset of elements
36 * of some sequence which satisfy a given predicate
37 * \li \b function_output_iterator: an output iterator wrapping a
38 * unary function object; each time an element is written into
39 * the dereferenced iterator, it is passed as a parameter to
40 * the function object.
41 * \li \b indirect_iterator: an iterator over the objects pointed-to
42 * by the elements of some sequence.
43 * \li \b permutation_iterator: an iterator over the elements of
44 * some random-access sequence, rearranged according to some
45 * sequence of integer indices.
46 * \li \b reverse_iterator: an iterator which traverses the elements
47 * of some bidirectional sequence in reverse. Corrects many of the shortcomings of C++98's std::reverse_iterator.
48 * \li \b shared_container_iterator: an iterator over elements of
49 * a container whose lifetime is maintained by a shared_ptr
50 * stored in the iterator.
51 * \li \b transform_iterator: an iterator over elements which are
52 * the result of applying some functional transformation to
53 * the elements of an underlying sequence. This component
54 * also replaces the old projection_iterator_adaptor.
55 * \li \b zip_iterator: an iterator over tuples of the elements
56 * at corresponding positions of heterogeneous underlying
59 * There are in fact more interesting iterator concepts
60 * available than the ones listed above. Have a look at them.
62 * Some of the iterator types are already dragged into namespace
63 * zypp. Feel free to add what's missing.
65 * \todo Separate them into individual zypp header files.
69 /** \class filter_iterator
70 * An iterator over the subset of elements of some sequence
71 * which satisfy a given predicate.
73 * Provides boost::filter_iterator and boost::make_filter_iterator
74 * convenience function.
75 * \see http://www.boost.org/libs/iterator/doc/filter_iterator.html
77 * template <class Predicate, class Iterator>
78 * filter_iterator<Predicate,Iterator>
79 * make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
81 * template <class Predicate, class Iterator>
82 * filter_iterator<Predicate,Iterator>
83 * make_filter_iterator(Iterator x, Iterator end = Iterator());
85 * Remember the deduction rules for template arguments.
87 * struct MyDefaultConstructibleFilter;
88 * make_filter_iterator<MyDefaultConstructibleFilter>( c.begin(), c.end() );
89 * make_filter_iterator( MyDefaultConstructibleFilter(), c.begin(), c.end() );
91 * make_filter_iterator( resfilter::ByName("foo"), c.begin(), c.end() );
95 using boost::filter_iterator;
96 using boost::make_filter_iterator;
98 /** Convenience to create filter_iterator from container::begin(). */
99 template<class TFilter, class TContainer>
100 filter_iterator<TFilter, typename TContainer::const_iterator>
101 make_filter_begin( TFilter f, const TContainer & c )
103 return make_filter_iterator( f, c.begin(), c.end() );
106 /** Convenience to create filter_iterator from container::begin(). */
107 template<class TFilter, class TContainer>
108 filter_iterator<TFilter, typename TContainer::const_iterator>
109 make_filter_begin( const TContainer & c )
111 return make_filter_iterator( TFilter(), c.begin(), c.end() );
114 /** Convenience to create filter_iterator from container::end(). */
115 template<class TFilter, class TContainer>
116 filter_iterator<TFilter, typename TContainer::const_iterator>
117 make_filter_end( TFilter f, const TContainer & c )
119 return make_filter_iterator( f, c.end(), c.end() );
122 /** Convenience to create filter_iterator from container::end(). */
123 template<class TFilter, class TContainer>
124 filter_iterator<TFilter, typename TContainer::const_iterator>
125 make_filter_end( const TContainer & c )
127 return make_filter_iterator( TFilter(), c.end(), c.end() );
130 /** \class transform_iterator
131 * An iterator over elements which are the result of applying
132 * some functional transformation to the elements of an underlying
135 * Provides boost::transform_iterator and boost::make_transform_iterator
136 * convenience function.
137 * \see http://www.boost.org/libs/iterator/doc/transform_iterator.html
139 * template <class UnaryFunction, class Iterator>
140 * transform_iterator<UnaryFunction, Iterator>
141 * make_transform_iterator(Iterator it, UnaryFunction fun);
143 * template <class UnaryFunction, class Iterator>
144 * transform_iterator<UnaryFunction, Iterator>
145 * make_transform_iterator(Iterator it);
148 using boost::transform_iterator;
149 using boost::make_transform_iterator;
151 /** Functor taking a \c std::pair returning \c std::pair.first.
152 * \see MapKVIteratorTraits
154 template<class TPair>
155 struct GetPairFirst : public std::unary_function<TPair, const typename TPair::first_type &>
157 const typename TPair::first_type & operator()( const TPair & pair_r ) const
158 { return pair_r.first; }
161 /** Functor taking a \c std::pair returning \c std::pair.second .
162 * \see MapKVIteratorTraits
164 template<class TPair>
165 struct GetPairSecond : public std::unary_function<TPair, const typename TPair::second_type &>
167 const typename TPair::second_type & operator()( const TPair & pair_r ) const
168 { return pair_r.second; }
171 /** Traits for std::map key and value iterators.
173 * \ref GetPairFirst and \ref GetPairSecond help building a transform_iterator
174 * that iterates over keys or values of a std::map. Class MapKVIteratorTraits
175 * provides some typedefs, you usg. do not want to write explicitly.
179 * typedef std::map<K,V> MapType;
181 * // transform_iterator<GetPairFirst<MapType::value_type>, MapType::const_iterator>
182 * typedef MapKVIteratorTraits<MapType>::Key_const_iterator MapTypeKey_iterator;
183 * // transform_iterator<GetPairSecond<MapType::value_type>, MapType::const_iterator>
184 * typedef MapKVIteratorTraits<MapType>::Value_const_iterator MapTypeValue_iterator;
189 * MapTypeKey_const_iterator keyBegin( make_map_key_begin( mymap ) );
190 * MapTypeKey_const_iterator keyEnd ( make_map_key_end( mymap ) );
192 * MapTypeValue_const_iterator valBegin( make_map_value_begin( mymap ) );
193 * MapTypeValue_const_iterator valEnd ( make_map_value_end( mymap ) );
195 * std::for_each( keyBegin, keyEnd, DoSomething() );
196 * std::for_each( valBegin, valEnd, DoSomething() );
202 * typedef std::map<K,V> MapType;
205 * std::for_each( make_map_key_begin( mymap ), make_map_key_end( mymap ), DoSomething() );
206 * std::for_each( make_map_value_begin( mymap ), make_map_value_end( mymap ), DoSomething() );
210 struct MapKVIteratorTraits
213 typedef TMap MapType;
214 /** The maps key type */
215 typedef typename TMap::key_type KeyType;
216 /** The key iterator type */
217 typedef transform_iterator<GetPairFirst<typename MapType::value_type>,
218 typename MapType::const_iterator> Key_const_iterator;
219 /** The maps value (mapped) type */
220 typedef typename TMap::mapped_type ValueType;
221 /** The value iterator type */
222 typedef transform_iterator<GetPairSecond<typename MapType::value_type>,
223 typename MapType::const_iterator> Value_const_iterator;
226 /** Convenience to create the key iterator from container::begin() */
228 inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_begin( const TMap & map_r )
229 { return make_transform_iterator( map_r.begin(), GetPairFirst<typename TMap::value_type>() ); }
231 /** Convenience to create the key iterator from container::end() */
233 inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_end( const TMap & map_r )
234 { return make_transform_iterator( map_r.end(), GetPairFirst<typename TMap::value_type>() ); }
236 /** Convenience to create the value iterator from container::begin() */
238 inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_begin( const TMap & map_r )
239 { return make_transform_iterator( map_r.begin(), GetPairSecond<typename TMap::value_type>() ); }
241 /** Convenience to create the value iterator from container::end() */
243 inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_end( const TMap & map_r )
244 { return make_transform_iterator( map_r.end(), GetPairSecond<typename TMap::value_type>() ); }
246 /** Convenience to create the key iterator from container::lower_bound() */
248 inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_lower_bound( const TMap & map_r, const typename TMap::key_type & key_r )
249 { return make_transform_iterator( map_r.lower_bound( key_r ), GetPairFirst<typename TMap::value_type>() ); }
251 /** Convenience to create the key iterator from container::upper_bound() */
253 inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_upper_bound( const TMap & map_r, const typename TMap::key_type & key_r )
254 { return make_transform_iterator( map_r.upper_bound( key_r ), GetPairFirst<typename TMap::value_type>() ); }
256 /** Convenience to create the value iterator from container::lower_bound() */
258 inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_lower_bound( const TMap & map_r, const typename TMap::key_type & key_r )
259 { return make_transform_iterator( map_r.lower_bound( key_r ), GetPairSecond<typename TMap::value_type>() ); }
261 /** Convenience to create the value iterator from container::upper_bound() */
263 inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_upper_bound( const TMap & map_r, const typename TMap::key_type & key_r )
264 { return make_transform_iterator( map_r.upper_bound( key_r ), GetPairSecond<typename TMap::value_type>() ); }
266 /** \class function_output_iterator
267 * An output iterator wrapping a unary function object; each time an
268 * element is written into the dereferenced iterator, it is passed as
269 * a parameter to the function object.
271 * Provides boost::function_output_iterator and boost::make_function_output_iterator
272 * convenience function.
273 * \see http://www.boost.org/libs/iterator/doc/function_output_iterator.html
275 * template <class UnaryFunction>
276 * function_output_iterator<UnaryFunction>
277 * make_function_output_iterator(const UnaryFunction& f = UnaryFunction());
280 using boost::function_output_iterator;
281 using boost::make_function_output_iterator;
284 /////////////////////////////////////////////////////////////////
286 ///////////////////////////////////////////////////////////////////
287 #endif // ZYPP_BASE_ITERATOR_H