Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / base / Iterator.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/Iterator.h
10  *
11 */
12 #ifndef ZYPP_BASE_ITERATOR_H
13 #define ZYPP_BASE_ITERATOR_H
14
15 #include <iterator>
16 #include <utility>
17
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>
22
23 ///////////////////////////////////////////////////////////////////
24 namespace zypp
25 { /////////////////////////////////////////////////////////////////
26
27   /** \defgroup ITERATOR Boost.Iterator Library
28    *
29    * \see http://www.boost.org/libs/iterator/doc/index.html
30    *
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
55    *        iterators.
56    *
57    * There are in fact more interesting iterator concepts
58    * available than the ones listed above. Have a look at them.
59    *
60    * Some of the iterator types are already dragged into namespace
61    * zypp. Feel free to add what's missing.
62    *
63    * \todo Separate them into individual zypp header files.
64   */
65   //@{
66
67   /** \class filter_iterator
68    * An iterator over the subset of elements of some sequence
69    * which satisfy a given predicate.
70    *
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
74    * \code
75    * template <class Predicate, class Iterator>
76    *   filter_iterator<Predicate,Iterator>
77    *   make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
78    *
79    * template <class Predicate, class Iterator>
80    *   filter_iterator<Predicate,Iterator>
81    *   make_filter_iterator(Iterator x, Iterator end = Iterator());
82    * \endcode
83    * Remember the deduction rules for template arguments.
84    * \code
85    * struct MyDefaultConstructibleFilter;
86    * make_filter_iterator<MyDefaultConstructibleFilter>( c.begin(), c.end() );
87    * make_filter_iterator( MyDefaultConstructibleFilter(), c.begin(), c.end() );
88    * ...
89    * make_filter_iterator( resfilter::ByName("foo"), c.begin(), c.end() );
90    *
91    * \endcode
92   */
93   using boost::filter_iterator;
94   using boost::make_filter_iterator;
95
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 )
100     {
101       return make_filter_iterator( f, c.begin(), c.end() );
102     }
103
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 )
108     {
109       return make_filter_iterator( _Filter(), c.begin(), c.end() );
110     }
111
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 )
116     {
117       return make_filter_iterator( f, c.end(), c.end() );
118     }
119
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 )
124     {
125       return make_filter_iterator( _Filter(), c.end(), c.end() );
126     }
127
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
131    * sequence.
132    *
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
136    * \code
137    * template <class UnaryFunction, class Iterator>
138    *   transform_iterator<UnaryFunction, Iterator>
139    *   make_transform_iterator(Iterator it, UnaryFunction fun);
140    *
141    * template <class UnaryFunction, class Iterator>
142    *   transform_iterator<UnaryFunction, Iterator>
143    *   make_transform_iterator(Iterator it);
144    * \endcode
145   */
146   using boost::transform_iterator;
147   using boost::make_transform_iterator;
148
149   /** Functor taking a \c std::pair returning \c std::pair.first.
150    * \see MapKVIteratorTraits
151   */
152   template<class _Pair>
153     struct GetPairFirst : public std::unary_function<_Pair, const typename _Pair::first_type &>
154     {
155       const typename _Pair::first_type & operator()( const _Pair & pair_r ) const
156       { return pair_r.first; }
157     };
158
159   /** Functor taking a \c std::pair returning \c std::pair.second .
160    * \see MapKVIteratorTraits
161   */
162   template<class _Pair>
163     struct GetPairSecond : public std::unary_function<_Pair, const typename _Pair::second_type &>
164     {
165       const typename _Pair::second_type & operator()( const _Pair & pair_r ) const
166       { return pair_r.second; }
167     };
168
169   /** Traits for std::map key and value iterators.
170    *
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.
174    *
175    * \code
176    * // typedefs
177    * typedef std::map<K,V> MapType;
178    *
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;
183    *
184    * // usage
185    * MapType mymap;
186    *
187    * MapTypeKey_const_iterator keyBegin( make_map_key_begin( mymap ) );
188    * MapTypeKey_const_iterator keyEnd  ( make_map_key_end( mymap ) );
189    *
190    * MapTypeValue_const_iterator valBegin( make_map_value_begin( mymap ) );
191    * MapTypeValue_const_iterator valEnd  ( make_map_value_end( mymap ) );
192    *
193    * std::for_each( keyBegin, keyEnd, DoSomething() );
194    * std::for_each( valBegin, valEnd, DoSomething() );
195    * \endcode
196    *
197    * Or short:
198    *
199    * \code
200    * typedef std::map<K,V> MapType;
201    * MapType mymap;
202    *
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() );
205    * \endcode
206    */
207   template<class _Map>
208     struct MapKVIteratorTraits
209     {
210       /** The map type */
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;
222     };
223
224   /** Convenience to create the key iterator from container::begin() */
225   template<class _Map>
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>() ); }
228
229   /** Convenience to create the key iterator from container::end() */
230   template<class _Map>
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>() ); }
233
234   /** Convenience to create the value iterator from container::begin() */
235   template<class _Map>
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>() ); }
238
239   /** Convenience to create the value iterator from container::end() */
240   template<class _Map>
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>() ); }
243
244   /** Convenience to create the key iterator from container::lower_bound() */
245   template<class _Map>
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>() ); }
248
249   /** Convenience to create the key iterator from container::upper_bound() */
250   template<class _Map>
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>() ); }
253
254   /** Convenience to create the value iterator from container::lower_bound() */
255   template<class _Map>
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>() ); }
258
259   /** Convenience to create the value iterator from container::upper_bound() */
260   template<class _Map>
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>() ); }
263
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.
268    *
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
272    * \code
273    * template <class UnaryFunction>
274    *   function_output_iterator<UnaryFunction>
275    *   make_function_output_iterator(const UnaryFunction& f = UnaryFunction());
276    * \endcode
277   */
278   using boost::function_output_iterator;
279   using boost::make_function_output_iterator;
280
281   //@}
282   /////////////////////////////////////////////////////////////////
283 } // namespace zypp
284 ///////////////////////////////////////////////////////////////////
285 #endif // ZYPP_BASE_ITERATOR_H