#include <list>
#include <set>
#include <map>
-#include "zypp/base/Logger.h"
-#include "zypp/base/Iterator.h"
+
+#include <zypp/base/Hash.h>
+#include <zypp/base/Logger.h>
+#include <zypp/base/Iterator.h>
+#include <zypp/APIConfig.h>
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
- /** Print range defined by iterators.
+ using std::endl;
+
+ /** Print range defined by iterators (multiline style).
* \code
* intro [ pfx ITEM [ { sep ITEM }+ ] sfx ] extro
* \endcode
+ *
* The defaults print the range enclosed in \c {}, one item per
* line indented by 2 spaces.
* \code
* }
* {} // on empty range
* \endcode
- * A comma separated list enclosed in \c () would be
+ *
+ * A comma separated list enclosed in \c () would be:
* \code
* dumpRange( stream, begin, end, "(", "", ", ", "", ")" );
+ * // or shorter:
+ * dumpRangeLine( stream, begin, end );
+ * \endcode
+ *
+ * \note Some special handling is required for printing std::maps.
+ * Therefore iomaipulators \ref dumpMap, \ref dumpKeys and \ref dumpValues
+ * are provided.
+ * \code
+ * std::map<string,int> m;
+ * m["a"]=1;
+ * m["b"]=2;
+ * m["c"]=3;
+ *
+ * dumpRange( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
+ * // {
+ * // [a] = 1
+ * // [b] = 2
+ * // [c] = 3
+ * // }
+ * dumpRange( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
+ * // {
+ * // a
+ * // b
+ * // c
+ * // }
+ * dumpRange( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
+ * // {
+ * // 1
+ * // 2
+ * // 3
+ * // }
+ * dumpRangeLine( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
+ * // ([a] = 1, [b] = 2, [c] = 3)
+ * dumpRangeLine( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
+ * // (a, b, c)
+ * dumpRangeLine( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
+ * // (1, 2, 3)
* \endcode
*/
- template<class _Iterator>
+ template<class TIterator>
std::ostream & dumpRange( std::ostream & str,
- _Iterator begin, _Iterator end,
+ TIterator begin, TIterator end,
const std::string & intro = "{",
const std::string & pfx = "\n ",
const std::string & sep = "\n ",
return str << extro;
}
- template<class _Iterator>
+ /** Print range defined by iterators (single line style).
+ * \see dumpRange
+ */
+ template<class TIterator>
std::ostream & dumpRangeLine( std::ostream & str,
- _Iterator begin, _Iterator end )
+ TIterator begin, TIterator end )
{ return dumpRange( str, begin, end, "(", "", ", ", "", ")" ); }
+ /** \overload for container */
+ template<class TContainer>
+ std::ostream & dumpRangeLine( std::ostream & str, const TContainer & cont )
+ { return dumpRangeLine( str, cont.begin(), cont.end() ); }
+
+
+ ///////////////////////////////////////////////////////////////////
+ namespace iomanip
+ {
+ ///////////////////////////////////////////////////////////////////
+ /// \class RangeLine<TIterator>
+ /// \brief Iomanip helper printing dumpRangeLine style
+ ///////////////////////////////////////////////////////////////////
+ template<class TIterator>
+ struct RangeLine
+ {
+ RangeLine( TIterator begin, TIterator end )
+ : _begin( begin )
+ , _end( end )
+ {}
+ TIterator _begin;
+ TIterator _end;
+ };
+
+ /** \relates RangeLine<TIterator> */
+ template<class TIterator>
+ std::ostream & operator<<( std::ostream & str, const RangeLine<TIterator> & obj )
+ { return dumpRangeLine( str, obj._begin, obj._end ); }
+
+ } // namespce iomanip
+ ///////////////////////////////////////////////////////////////////
+
+ /** Iomanip printing dumpRangeLine style
+ * \code
+ * std::vector<int> c( { 1, 1, 2, 3, 5, 8 } );
+ * std::cout << rangeLine(c) << std::endl;
+ * -> (1, 1, 2, 3, 5, 8)
+ * \endcode
+ */
+ template<class TIterator>
+ iomanip::RangeLine<TIterator> rangeLine( TIterator begin, TIterator end )
+ { return iomanip::RangeLine<TIterator>( begin, end ); }
+ /** \overload for container */
+ template<class TContainer>
+ auto rangeLine( const TContainer & cont ) -> decltype( rangeLine( cont.begin(), cont.end() ) )
+ { return rangeLine( cont.begin(), cont.end() ); }
+
+ template<class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::vector<Tp> & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
+
+ template<class Tp, class TCmp, class TAlloc>
+ std::ostream & operator<<( std::ostream & str, const std::set<Tp,TCmp,TAlloc> & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
+
+ template<class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::unordered_set<Tp> & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
- template<class _Tp>
- std::ostream & operator<<( std::ostream & str, const std::vector<_Tp> & obj )
+ template<class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::multiset<Tp> & obj )
{ return dumpRange( str, obj.begin(), obj.end() ); }
- template<class _Tp>
- std::ostream & operator<<( std::ostream & str, const std::set<_Tp> & obj )
+ template<class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::list<Tp> & obj )
{ return dumpRange( str, obj.begin(), obj.end() ); }
- template<class _Tp>
- std::ostream & operator<<( std::ostream & str, const std::list<_Tp> & obj )
+ template<class Tp>
+ std::ostream & operator<<( std::ostream & str, const Iterable<Tp> & obj )
{ return dumpRange( str, obj.begin(), obj.end() ); }
///////////////////////////////////////////////////////////////////
/** std::pair wrapper for std::map output.
* Just because we want a special output format for std::pair
- * used in a std::map.
+ * used in a std::map. The mapped std::pair is printed as
+ * <tt>[key] = value</tt>.
*/
- template<class _Pair>
+ template<class TPair>
class MapEntry
{
public:
- MapEntry( const _Pair & pair_r )
+ MapEntry( const TPair & pair_r )
: _pair( &pair_r )
{}
- const _Pair & pair() const
+ const TPair & pair() const
{ return *_pair; }
private:
- const _Pair *const _pair;
+ const TPair *const _pair;
};
/** \relates MapEntry Stream output. */
- template<class _Pair>
- std::ostream & operator<<( std::ostream & str, const MapEntry<_Pair> & obj )
+ template<class TPair>
+ std::ostream & operator<<( std::ostream & str, const MapEntry<TPair> & obj )
{
return str << '[' << obj.pair().first << "] = " << obj.pair().second;
}
/** \relates MapEntry Convenience function to create MapEntry from std::pair. */
- template<class _Pair>
- MapEntry<_Pair> mapEntry( const _Pair & pair_r )
- { return MapEntry<_Pair>( pair_r ); }
+ template<class TPair>
+ MapEntry<TPair> mapEntry( const TPair & pair_r )
+ { return MapEntry<TPair>( pair_r ); }
///////////////////////////////////////////////////////////////////
// dumpMap
///////////////////////////////////////////////////////////////////
/** std::map wrapper for stream output.
- * Provides the transform_iterator used to write std::pair formated as
- * MapEntry.
+ * Uses a transform_iterator to wrap the std::pair into MapEntry.
+ *
*/
- template<class _Map>
+ template<class TMap>
class DumpMap
{
- private:
- typedef _Map MapType;
- typedef typename _Map::value_type PairType;
+ public:
+ typedef TMap MapType;
+ typedef typename TMap::value_type PairType;
typedef MapEntry<PairType> MapEntryType;
struct Transformer : public std::unary_function<PairType, MapEntryType>
MapEntry_const_iterator;
public:
- DumpMap( const _Map & map_r )
+ DumpMap( const TMap & map_r )
: _map( &map_r )
{}
- const _Map & map() const
+ const TMap & map() const
{ return *_map; }
- MapEntry_const_iterator map_begin() const
+ MapEntry_const_iterator begin() const
{ return make_transform_iterator( map().begin(), Transformer() ); }
- MapEntry_const_iterator map_end() const
+ MapEntry_const_iterator end() const
{ return make_transform_iterator( map().end(), Transformer() );}
private:
- const _Map *const _map;
+ const TMap *const _map;
};
/** \relates DumpMap Stream output. */
- template<class _Map>
- std::ostream & operator<<( std::ostream & str, const DumpMap<_Map> & obj )
- { return dumpRange( str, obj.map_begin(), obj.map_end() ); }
+ template<class TMap>
+ std::ostream & operator<<( std::ostream & str, const DumpMap<TMap> & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
/** \relates DumpMap Convenience function to create DumpMap from std::map. */
- template<class _Map>
- DumpMap<_Map> dumpMap( const _Map & map_r )
- { return DumpMap<_Map>( map_r ); }
+ template<class TMap>
+ DumpMap<TMap> dumpMap( const TMap & map_r )
+ { return DumpMap<TMap>( map_r ); }
///////////////////////////////////////////////////////////////////
// dumpKeys
* std::cout << dumpKeys(mymap) << std::endl;
* \endcode
*/
- template<class _Map>
+ template<class TMap>
class DumpKeys
{
public:
- DumpKeys( const _Map & map_r )
+ typedef typename MapKVIteratorTraits<TMap>::Key_const_iterator MapKey_const_iterator;
+
+ public:
+ DumpKeys( const TMap & map_r )
: _map( &map_r )
{}
- const _Map & map() const
+ const TMap & map() const
{ return *_map; }
+ MapKey_const_iterator begin() const
+ { return make_map_key_begin( map() ); }
+
+ MapKey_const_iterator end() const
+ { return make_map_key_end( map() ); }
+
private:
- const _Map *const _map;
+ const TMap *const _map;
};
/** \relates DumpKeys Stream output. */
- template<class _Map>
- std::ostream & operator<<( std::ostream & str, const DumpKeys<_Map> & obj )
- { return dumpRange( str, make_map_key_begin(obj.map()), make_map_key_end(obj.map()) ); }
+ template<class TMap>
+ std::ostream & operator<<( std::ostream & str, const DumpKeys<TMap> & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
/** \relates DumpKeys Convenience function to create DumpKeys from std::map. */
- template<class _Map>
- DumpKeys<_Map> dumpKeys( const _Map & map_r )
- { return DumpKeys<_Map>( map_r ); }
+ template<class TMap>
+ DumpKeys<TMap> dumpKeys( const TMap & map_r )
+ { return DumpKeys<TMap>( map_r ); }
///////////////////////////////////////////////////////////////////
// dumpValues
* std::cout << dumpValues(mymap) << std::endl;
* \endcode
*/
- template<class _Map>
+ template<class TMap>
class DumpValues
{
public:
- DumpValues( const _Map & map_r )
+ typedef typename MapKVIteratorTraits<TMap>::Value_const_iterator MapValue_const_iterator;
+
+ public:
+ DumpValues( const TMap & map_r )
: _map( &map_r )
{}
- const _Map & map() const
+ const TMap & map() const
{ return *_map; }
+ MapValue_const_iterator begin() const
+ { return make_map_value_begin( map() ); }
+
+ MapValue_const_iterator end() const
+ { return make_map_value_end( map() ); }
+
private:
- const _Map *const _map;
+ const TMap *const _map;
};
/** \relates DumpValues Stream output. */
- template<class _Map>
- std::ostream & operator<<( std::ostream & str, const DumpValues<_Map> & obj )
- { return dumpRange( str, make_map_value_begin(obj.map()), make_map_value_end(obj.map()) ); }
+ template<class TMap>
+ std::ostream & operator<<( std::ostream & str, const DumpValues<TMap> & obj )
+ { return dumpRange( str, obj.begin(), obj.end() ); }
/** \relates DumpValues Convenience function to create DumpValues from std::map. */
- template<class _Map>
- DumpValues<_Map> dumpValues( const _Map & map_r )
- { return DumpValues<_Map>( map_r ); }
+ template<class TMap>
+ DumpValues<TMap> dumpValues( const TMap & map_r )
+ { return DumpValues<TMap>( map_r ); }
/////////////////////////////////////////////////////////////////
} // namespace _logtoolsdetail
using _logtoolsdetail::dumpKeys; // dumpRange keys
using _logtoolsdetail::dumpValues; // dumpRange values
- template<class _Key, class _Tp>
- std::ostream & operator<<( std::ostream & str, const std::map<_Key, _Tp> & obj )
+ template<class TKey, class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::map<TKey, Tp> & obj )
+ { return str << dumpMap( obj ); }
+
+ template<class TKey, class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::unordered_map<TKey, Tp> & obj )
+ { return str << dumpMap( obj ); }
+
+ template<class TKey, class Tp>
+ std::ostream & operator<<( std::ostream & str, const std::multimap<TKey, Tp> & obj )
{ return str << dumpMap( obj ); }
/** Print stream status bits.
return str << ret;
}
+ ///////////////////////////////////////////////////////////////////
+ // iomanipulator: str << dump(val) << ...
+ // calls: std::ostream & dumpOn( std::ostream & str, const Type & obj )
+ ///////////////////////////////////////////////////////////////////
+
+ namespace detail
+ {
+ template<class Tp>
+ struct Dump
+ {
+ Dump( const Tp & obj_r ) : _obj( obj_r ) {}
+ const Tp & _obj;
+ };
+
+ template<class Tp>
+ std::ostream & operator<<( std::ostream & str, const Dump<Tp> & obj )
+ { return dumpOn( str, obj._obj ); }
+ }
+
+ template<class Tp>
+ detail::Dump<Tp> dump( const Tp & obj_r )
+ { return detail::Dump<Tp>(obj_r); }
+
+
/////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////