Imported Upstream version 15.19.0
[platform/upstream/libzypp.git] / zypp / base / Iterator.h
index a978dcd..f4deb90 100644 (file)
 #ifndef ZYPP_BASE_ITERATOR_H
 #define ZYPP_BASE_ITERATOR_H
 
+#include <iterator>
+#include <utility>
+
+#include <boost/functional.hpp>
 #include <boost/iterator/filter_iterator.hpp>
 #include <boost/iterator/transform_iterator.hpp>
 #include <boost/function_output_iterator.hpp>
 
+#include "zypp/base/Iterable.h"
+
 ///////////////////////////////////////////////////////////////////
 namespace zypp
 { /////////////////////////////////////////////////////////////////
@@ -89,6 +95,38 @@ namespace zypp
   using boost::filter_iterator;
   using boost::make_filter_iterator;
 
+  /** Convenience to create filter_iterator from container::begin(). */
+  template<class TFilter, class TContainer>
+    filter_iterator<TFilter, typename TContainer::const_iterator>
+    make_filter_begin( TFilter f, const TContainer & c )
+    {
+      return make_filter_iterator( f, c.begin(), c.end() );
+    }
+
+  /** Convenience to create filter_iterator from container::begin(). */
+  template<class TFilter, class TContainer>
+    filter_iterator<TFilter, typename TContainer::const_iterator>
+    make_filter_begin( const TContainer & c )
+    {
+      return make_filter_iterator( TFilter(), c.begin(), c.end() );
+    }
+
+  /** Convenience to create filter_iterator from container::end(). */
+  template<class TFilter, class TContainer>
+    filter_iterator<TFilter, typename TContainer::const_iterator>
+    make_filter_end( TFilter f, const TContainer & c )
+    {
+      return make_filter_iterator( f, c.end(), c.end() );
+    }
+
+  /** Convenience to create filter_iterator from container::end(). */
+  template<class TFilter, class TContainer>
+    filter_iterator<TFilter, typename TContainer::const_iterator>
+    make_filter_end( const TContainer & c )
+    {
+      return make_filter_iterator( TFilter(), c.end(), c.end() );
+    }
+
   /** \class transform_iterator
    * An iterator over elements which are the result of applying
    * some functional transformation to the elements of an underlying
@@ -107,9 +145,124 @@ namespace zypp
    *   make_transform_iterator(Iterator it);
    * \endcode
   */
-  using boost::function_output_iterator;
+  using boost::transform_iterator;
   using boost::make_transform_iterator;
 
+  /** Functor taking a \c std::pair returning \c std::pair.first.
+   * \see MapKVIteratorTraits
+  */
+  template<class TPair>
+    struct GetPairFirst : public std::unary_function<TPair, const typename TPair::first_type &>
+    {
+      const typename TPair::first_type & operator()( const TPair & pair_r ) const
+      { return pair_r.first; }
+    };
+
+  /** Functor taking a \c std::pair returning \c std::pair.second .
+   * \see MapKVIteratorTraits
+  */
+  template<class TPair>
+    struct GetPairSecond : public std::unary_function<TPair, const typename TPair::second_type &>
+    {
+      const typename TPair::second_type & operator()( const TPair & pair_r ) const
+      { return pair_r.second; }
+    };
+
+  /** Traits for std::map key and value iterators.
+   *
+   * \ref GetPairFirst and \ref GetPairSecond help building a transform_iterator
+   * that iterates over keys or values of a std::map. Class MapKVIteratorTraits
+   * provides some typedefs, you usg. do not want to write explicitly.
+   *
+   * \code
+   * // typedefs
+   * typedef std::map<K,V> MapType;
+   *
+   * // transform_iterator<GetPairFirst<MapType::value_type>,  MapType::const_iterator>
+   * typedef MapKVIteratorTraits<MapType>::Key_const_iterator MapTypeKey_iterator;
+   * // transform_iterator<GetPairSecond<MapType::value_type>, MapType::const_iterator>
+   * typedef MapKVIteratorTraits<MapType>::Value_const_iterator  MapTypeValue_iterator;
+   *
+   * // usage
+   * MapType mymap;
+   *
+   * MapTypeKey_const_iterator keyBegin( make_map_key_begin( mymap ) );
+   * MapTypeKey_const_iterator keyEnd  ( make_map_key_end( mymap ) );
+   *
+   * MapTypeValue_const_iterator valBegin( make_map_value_begin( mymap ) );
+   * MapTypeValue_const_iterator valEnd  ( make_map_value_end( mymap ) );
+   *
+   * std::for_each( keyBegin, keyEnd, DoSomething() );
+   * std::for_each( valBegin, valEnd, DoSomething() );
+   * \endcode
+   *
+   * Or short:
+   *
+   * \code
+   * typedef std::map<K,V> MapType;
+   * MapType mymap;
+   *
+   * std::for_each( make_map_key_begin( mymap ),   make_map_key_end( mymap ),   DoSomething() );
+   * std::for_each( make_map_value_begin( mymap ), make_map_value_end( mymap ), DoSomething() );
+   * \endcode
+   */
+  template<class TMap>
+    struct MapKVIteratorTraits
+    {
+      /** The map type */
+      typedef TMap                       MapType;
+      /** The maps key type */
+      typedef typename TMap::key_type    KeyType;
+      /** The key iterator type */
+      typedef transform_iterator<GetPairFirst<typename MapType::value_type>,
+                                 typename MapType::const_iterator> Key_const_iterator;
+      /** The maps value (mapped) type */
+      typedef typename TMap::mapped_type ValueType;
+      /** The value iterator type */
+      typedef transform_iterator<GetPairSecond<typename MapType::value_type>,
+                                 typename MapType::const_iterator> Value_const_iterator;
+    };
+
+  /** Convenience to create the key iterator from container::begin() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_begin( const TMap & map_r )
+    { return make_transform_iterator( map_r.begin(), GetPairFirst<typename TMap::value_type>() ); }
+
+  /** Convenience to create the key iterator from container::end() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_end( const TMap & map_r )
+    { return make_transform_iterator( map_r.end(), GetPairFirst<typename TMap::value_type>() ); }
+
+  /** Convenience to create the value iterator from container::begin() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_begin( const TMap & map_r )
+    { return make_transform_iterator( map_r.begin(), GetPairSecond<typename TMap::value_type>() ); }
+
+  /** Convenience to create the value iterator from container::end() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_end( const TMap & map_r )
+    { return make_transform_iterator( map_r.end(), GetPairSecond<typename TMap::value_type>() ); }
+
+  /** Convenience to create the key iterator from container::lower_bound() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_lower_bound( const TMap & map_r, const typename TMap::key_type & key_r )
+    { return make_transform_iterator( map_r.lower_bound( key_r ), GetPairFirst<typename TMap::value_type>() ); }
+
+  /** Convenience to create the key iterator from container::upper_bound() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Key_const_iterator make_map_key_upper_bound( const TMap & map_r, const typename TMap::key_type & key_r )
+    { return make_transform_iterator( map_r.upper_bound( key_r ), GetPairFirst<typename TMap::value_type>() ); }
+
+  /** Convenience to create the value iterator from container::lower_bound() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_lower_bound( const TMap & map_r, const typename TMap::key_type & key_r )
+    { return make_transform_iterator( map_r.lower_bound( key_r ), GetPairSecond<typename TMap::value_type>() ); }
+
+  /** Convenience to create the value iterator from container::upper_bound() */
+  template<class TMap>
+    inline typename MapKVIteratorTraits<TMap>::Value_const_iterator make_map_value_upper_bound( const TMap & map_r, const typename TMap::key_type & key_r )
+    { return make_transform_iterator( map_r.upper_bound( key_r ), GetPairSecond<typename TMap::value_type>() ); }
+
   /** \class function_output_iterator
    * An output iterator wrapping a unary function object; each time an
    * element is written into the dereferenced iterator, it is passed as