1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/LogTools.h
12 #ifndef ZYPP_BASE_LOGTOOLS_H
13 #define ZYPP_BASE_LOGTOOLS_H
22 #include "zypp/base/Hash.h"
23 #include "zypp/base/Logger.h"
24 #include "zypp/base/Iterator.h"
25 #include "zypp/APIConfig.h"
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
33 /** Print range defined by iterators (multiline style).
35 * intro [ pfx ITEM [ { sep ITEM }+ ] sfx ] extro
38 * The defaults print the range enclosed in \c {}, one item per
39 * line indented by 2 spaces.
45 * {} // on empty range
48 * A comma separated list enclosed in \c () would be:
50 * dumpRange( stream, begin, end, "(", "", ", ", "", ")" );
52 * dumpRangeLine( stream, begin, end );
55 * \note Some special handling is required for printing std::maps.
56 * Therefore iomaipulators \ref dumpMap, \ref dumpKeys and \ref dumpValues
59 * std::map<string,int> m;
64 * dumpRange( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
70 * dumpRange( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
76 * dumpRange( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
82 * dumpRangeLine( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
83 * // ([a] = 1, [b] = 2, [c] = 3)
84 * dumpRangeLine( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
86 * dumpRangeLine( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
90 template<class TIterator>
91 std::ostream & dumpRange( std::ostream & str,
92 TIterator begin, TIterator end,
93 const std::string & intro = "{",
94 const std::string & pfx = "\n ",
95 const std::string & sep = "\n ",
96 const std::string & sfx = "\n",
97 const std::string & extro = "}" )
102 str << pfx << *begin;
103 for ( ++begin; begin != end; ++begin )
104 str << sep << *begin;
110 /** Print range defined by iterators (single line style).
113 template<class TIterator>
114 std::ostream & dumpRangeLine( std::ostream & str,
115 TIterator begin, TIterator end )
116 { return dumpRange( str, begin, end, "(", "", ", ", "", ")" ); }
117 /** \overload for container */
118 template<class TContainer>
119 std::ostream & dumpRangeLine( std::ostream & str, const TContainer & cont )
120 { return dumpRangeLine( str, cont.begin(), cont.end() ); }
123 ///////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////
127 /// \class RangeLine<TIterator>
128 /// \brief Iomanip helper printing dumpRangeLine style
129 ///////////////////////////////////////////////////////////////////
130 template<class TIterator>
133 RangeLine( TIterator begin, TIterator end )
141 /** \relates RangeLine<TIterator> */
142 template<class TIterator>
143 std::ostream & operator<<( std::ostream & str, const RangeLine<TIterator> & obj )
144 { return dumpRangeLine( str, obj._begin, obj._end ); }
146 } // namespce iomanip
147 ///////////////////////////////////////////////////////////////////
149 /** Iomanip printing dumpRangeLine style
151 * std::vector<int> c( { 1, 1, 2, 3, 5, 8 } );
152 * std::cout << rangeLine(c) << std::endl;
153 * -> (1, 1, 2, 3, 5, 8)
156 template<class TIterator>
157 iomanip::RangeLine<TIterator> rangeLine( TIterator begin, TIterator end )
158 { return iomanip::RangeLine<TIterator>( begin, end ); }
159 /** \overload for container */
160 template<class TContainer>
161 auto rangeLine( const TContainer & cont ) -> decltype( rangeLine( cont.begin(), cont.end() ) )
162 { return rangeLine( cont.begin(), cont.end() ); }
165 std::ostream & operator<<( std::ostream & str, const std::vector<Tp> & obj )
166 { return dumpRange( str, obj.begin(), obj.end() ); }
168 template<class Tp, class TCmp, class TAlloc>
169 std::ostream & operator<<( std::ostream & str, const std::set<Tp,TCmp,TAlloc> & obj )
170 { return dumpRange( str, obj.begin(), obj.end() ); }
173 std::ostream & operator<<( std::ostream & str, const std::unordered_set<Tp> & obj )
174 { return dumpRange( str, obj.begin(), obj.end() ); }
177 std::ostream & operator<<( std::ostream & str, const std::multiset<Tp> & obj )
178 { return dumpRange( str, obj.begin(), obj.end() ); }
181 std::ostream & operator<<( std::ostream & str, const std::list<Tp> & obj )
182 { return dumpRange( str, obj.begin(), obj.end() ); }
185 std::ostream & operator<<( std::ostream & str, const Iterable<Tp> & obj )
186 { return dumpRange( str, obj.begin(), obj.end() ); }
188 ///////////////////////////////////////////////////////////////////
189 namespace _logtoolsdetail
190 { /////////////////////////////////////////////////////////////////
192 ///////////////////////////////////////////////////////////////////
194 ///////////////////////////////////////////////////////////////////
196 /** std::pair wrapper for std::map output.
197 * Just because we want a special output format for std::pair
198 * used in a std::map. The mapped std::pair is printed as
199 * <tt>[key] = value</tt>.
201 template<class TPair>
205 MapEntry( const TPair & pair_r )
209 const TPair & pair() const
213 const TPair *const _pair;
216 /** \relates MapEntry Stream output. */
217 template<class TPair>
218 std::ostream & operator<<( std::ostream & str, const MapEntry<TPair> & obj )
220 return str << '[' << obj.pair().first << "] = " << obj.pair().second;
223 /** \relates MapEntry Convenience function to create MapEntry from std::pair. */
224 template<class TPair>
225 MapEntry<TPair> mapEntry( const TPair & pair_r )
226 { return MapEntry<TPair>( pair_r ); }
228 ///////////////////////////////////////////////////////////////////
230 ///////////////////////////////////////////////////////////////////
232 /** std::map wrapper for stream output.
233 * Uses a transform_iterator to wrap the std::pair into MapEntry.
240 typedef TMap MapType;
241 typedef typename TMap::value_type PairType;
242 typedef MapEntry<PairType> MapEntryType;
244 struct Transformer : public std::unary_function<PairType, MapEntryType>
246 MapEntryType operator()( const PairType & pair_r ) const
247 { return mapEntry( pair_r ); }
250 typedef transform_iterator<Transformer, typename MapType::const_iterator>
251 MapEntry_const_iterator;
254 DumpMap( const TMap & map_r )
258 const TMap & map() const
261 MapEntry_const_iterator begin() const
262 { return make_transform_iterator( map().begin(), Transformer() ); }
264 MapEntry_const_iterator end() const
265 { return make_transform_iterator( map().end(), Transformer() );}
268 const TMap *const _map;
271 /** \relates DumpMap Stream output. */
273 std::ostream & operator<<( std::ostream & str, const DumpMap<TMap> & obj )
274 { return dumpRange( str, obj.begin(), obj.end() ); }
276 /** \relates DumpMap Convenience function to create DumpMap from std::map. */
278 DumpMap<TMap> dumpMap( const TMap & map_r )
279 { return DumpMap<TMap>( map_r ); }
281 ///////////////////////////////////////////////////////////////////
283 ///////////////////////////////////////////////////////////////////
285 /** std::map wrapper for stream output of keys.
286 * Uses MapKVIterator iterate and write the key values.
288 * std::map<...> mymap;
289 * std::cout << dumpKeys(mymap) << std::endl;
296 typedef typename MapKVIteratorTraits<TMap>::Key_const_iterator MapKey_const_iterator;
299 DumpKeys( const TMap & map_r )
303 const TMap & map() const
306 MapKey_const_iterator begin() const
307 { return make_map_key_begin( map() ); }
309 MapKey_const_iterator end() const
310 { return make_map_key_end( map() ); }
313 const TMap *const _map;
316 /** \relates DumpKeys Stream output. */
318 std::ostream & operator<<( std::ostream & str, const DumpKeys<TMap> & obj )
319 { return dumpRange( str, obj.begin(), obj.end() ); }
321 /** \relates DumpKeys Convenience function to create DumpKeys from std::map. */
323 DumpKeys<TMap> dumpKeys( const TMap & map_r )
324 { return DumpKeys<TMap>( map_r ); }
326 ///////////////////////////////////////////////////////////////////
328 ///////////////////////////////////////////////////////////////////
330 /** std::map wrapper for stream output of values.
331 * Uses MapKVIterator iterate and write the values.
333 * std::map<...> mymap;
334 * std::cout << dumpValues(mymap) << std::endl;
341 typedef typename MapKVIteratorTraits<TMap>::Value_const_iterator MapValue_const_iterator;
344 DumpValues( const TMap & map_r )
348 const TMap & map() const
351 MapValue_const_iterator begin() const
352 { return make_map_value_begin( map() ); }
354 MapValue_const_iterator end() const
355 { return make_map_value_end( map() ); }
358 const TMap *const _map;
361 /** \relates DumpValues Stream output. */
363 std::ostream & operator<<( std::ostream & str, const DumpValues<TMap> & obj )
364 { return dumpRange( str, obj.begin(), obj.end() ); }
366 /** \relates DumpValues Convenience function to create DumpValues from std::map. */
368 DumpValues<TMap> dumpValues( const TMap & map_r )
369 { return DumpValues<TMap>( map_r ); }
371 /////////////////////////////////////////////////////////////////
372 } // namespace _logtoolsdetail
373 ///////////////////////////////////////////////////////////////////
376 using _logtoolsdetail::mapEntry; // std::pair as '[key] = value'
377 using _logtoolsdetail::dumpMap; // dumpRange '[key] = value'
378 using _logtoolsdetail::dumpKeys; // dumpRange keys
379 using _logtoolsdetail::dumpValues; // dumpRange values
381 template<class TKey, class Tp>
382 std::ostream & operator<<( std::ostream & str, const std::map<TKey, Tp> & obj )
383 { return str << dumpMap( obj ); }
385 template<class TKey, class Tp>
386 std::ostream & operator<<( std::ostream & str, const std::unordered_map<TKey, Tp> & obj )
387 { return str << dumpMap( obj ); }
389 template<class TKey, class Tp>
390 std::ostream & operator<<( std::ostream & str, const std::multimap<TKey, Tp> & obj )
391 { return str << dumpMap( obj ); }
393 /** Print stream status bits.
394 * Prints the values of a streams \c good, \c eof, \c failed and \c bad bit.
398 * [_eF_] - eof and fail bit set
399 * [__FB] - fail and bad bit set
402 inline std::ostream & operator<<( std::ostream & str, const std::basic_ios<char> & obj )
404 std::string ret( "[" );
405 ret += ( obj.good() ? 'g' : '_' );
406 ret += ( obj.eof() ? 'e' : '_' );
407 ret += ( obj.fail() ? 'F' : '_' );
408 ret += ( obj.bad() ? 'B' : '_' );
413 ///////////////////////////////////////////////////////////////////
414 // iomanipulator: str << dump(val) << ...
415 // calls: std::ostream & dumpOn( std::ostream & str, const Type & obj )
416 ///////////////////////////////////////////////////////////////////
423 Dump( const Tp & obj_r ) : _obj( obj_r ) {}
428 std::ostream & operator<<( std::ostream & str, const Dump<Tp> & obj )
429 { return dumpOn( str, obj._obj ); }
433 detail::Dump<Tp> dump( const Tp & obj_r )
434 { return detail::Dump<Tp>(obj_r); }
437 /////////////////////////////////////////////////////////////////
439 ///////////////////////////////////////////////////////////////////
440 #endif // ZYPP_BASE_LOGTOOLS_H