convenience added
[platform/upstream/libzypp.git] / zypp / base / LogTools.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/LogTools.h
10  *
11 */
12 #ifndef ZYPP_BASE_LOGTOOLS_H
13 #define ZYPP_BASE_LOGTOOLS_H
14
15 #include <iostream>
16 #include <string>
17 #include <vector>
18 #include <list>
19 #include <set>
20 #include <map>
21
22 #include "zypp/base/Tr1hash.h"
23 #include "zypp/base/Logger.h"
24 #include "zypp/base/Iterator.h"
25 #include "zypp/base/Deprecated.h"
26
27 ///////////////////////////////////////////////////////////////////
28 namespace zypp
29 { /////////////////////////////////////////////////////////////////
30   
31   using std::endl;
32
33   /** Print range defined by iterators (multiline style).
34    * \code
35    * intro [ pfx ITEM [ { sep ITEM }+ ] sfx ] extro
36    * \endcode
37    *
38    * The defaults print the range enclosed in \c {}, one item per
39    * line indented by 2 spaces.
40    * \code
41    * {
42    *   item1
43    *   item2
44    * }
45    * {} // on empty range
46    * \endcode
47    *
48    * A comma separated list enclosed in \c () would be:
49    * \code
50    * dumpRange( stream, begin, end, "(", "", ", ", "", ")" );
51    * // or shorter:
52    * dumpRangeLine( stream, begin, end );
53    * \endcode
54    *
55    * \note Some special handling is required for printing std::maps.
56    * Therefore iomaipulators \ref dumpMap, \ref dumpKeys and \ref dumpValues
57    * are provided.
58    * \code
59    * std::map<string,int> m;
60    * m["a"]=1;
61    * m["b"]=2;
62    * m["c"]=3;
63    *
64    * dumpRange( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
65    * // {
66    * //   [a] = 1
67    * //   [b] = 2
68    * //   [c] = 3
69    * // }
70    * dumpRange( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
71    * // {
72    * //   a
73    * //   b
74    * //   c
75    * // }
76    * dumpRange( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
77    * // {
78    * //   1
79    * //   2
80    * //   3
81    * // }
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;
85    * // (a, b, c)
86    * dumpRangeLine( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
87    * // (1, 2, 3)
88    * \endcode
89   */
90   template<class _Iterator>
91     std::ostream & dumpRange( std::ostream & str,
92                               _Iterator begin, _Iterator 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 = "}" )
98     {
99       str << intro;
100       if ( begin != end )
101         {
102           str << pfx << *begin;
103           for (  ++begin; begin != end; ++begin )
104             str << sep << *begin;
105           str << sfx;
106         }
107       return str << extro;
108     }
109
110   /** Print range defined by iterators (single line style).
111    * \see dumpRange
112    */
113   template<class _Iterator>
114     std::ostream & dumpRangeLine( std::ostream & str,
115                                   _Iterator begin, _Iterator end )
116     { return dumpRange( str, begin, end, "(", "", ", ", "", ")" ); }
117
118
119   template<class _Tp>
120     std::ostream & operator<<( std::ostream & str, const std::vector<_Tp> & obj )
121     { return dumpRange( str, obj.begin(), obj.end() ); }
122
123   template<class _Tp>
124     std::ostream & operator<<( std::ostream & str, const std::set<_Tp> & obj )
125     { return dumpRange( str, obj.begin(), obj.end() ); }
126
127   template<class _Tp>
128     std::ostream & operator<<( std::ostream & str, const std::tr1::unordered_set<_Tp> & obj )
129     { return dumpRange( str, obj.begin(), obj.end() ); }
130
131   template<class _Tp>
132     std::ostream & operator<<( std::ostream & str, const std::list<_Tp> & obj )
133     { return dumpRange( str, obj.begin(), obj.end() ); }
134
135   ///////////////////////////////////////////////////////////////////
136   namespace _logtoolsdetail
137   { /////////////////////////////////////////////////////////////////
138
139     ///////////////////////////////////////////////////////////////////
140     // mapEntry
141     ///////////////////////////////////////////////////////////////////
142
143     /** std::pair wrapper for std::map output.
144      * Just because we want a special output format for std::pair
145      * used in a std::map. The mapped std::pair is printed as
146      * <tt>[key] = value</tt>.
147     */
148     template<class _Pair>
149       class MapEntry
150       {
151       public:
152         MapEntry( const _Pair & pair_r )
153         : _pair( &pair_r )
154         {}
155
156         const _Pair & pair() const
157         { return *_pair; }
158
159       private:
160         const _Pair *const _pair;
161       };
162
163     /** \relates MapEntry Stream output. */
164     template<class _Pair>
165       std::ostream & operator<<( std::ostream & str, const MapEntry<_Pair> & obj )
166       {
167         return str << '[' << obj.pair().first << "] = " << obj.pair().second;
168       }
169
170     /** \relates MapEntry Convenience function to create MapEntry from std::pair. */
171     template<class _Pair>
172       MapEntry<_Pair> mapEntry( const _Pair & pair_r )
173       { return MapEntry<_Pair>( pair_r ); }
174
175     ///////////////////////////////////////////////////////////////////
176     // dumpMap
177     ///////////////////////////////////////////////////////////////////
178
179     /** std::map wrapper for stream output.
180      * Uses a transform_iterator to wrap the std::pair into MapEntry.
181      *
182      */
183     template<class _Map>
184       class DumpMap
185       {
186       public:
187         typedef _Map                        MapType;
188         typedef typename _Map::value_type   PairType;
189         typedef MapEntry<PairType>          MapEntryType;
190
191         struct Transformer : public std::unary_function<PairType, MapEntryType>
192         {
193           MapEntryType operator()( const PairType & pair_r ) const
194           { return mapEntry( pair_r ); }
195         };
196
197         typedef transform_iterator<Transformer, typename MapType::const_iterator>
198                 MapEntry_const_iterator;
199
200       public:
201         DumpMap( const _Map & map_r )
202         : _map( &map_r )
203         {}
204
205         const _Map & map() const
206         { return *_map; }
207
208         MapEntry_const_iterator begin() const
209         { return make_transform_iterator( map().begin(), Transformer() ); }
210
211         MapEntry_const_iterator end() const
212         { return make_transform_iterator( map().end(), Transformer() );}
213
214       private:
215         const _Map *const _map;
216       };
217
218     /** \relates DumpMap Stream output. */
219     template<class _Map>
220       std::ostream & operator<<( std::ostream & str, const DumpMap<_Map> & obj )
221       { return dumpRange( str, obj.begin(), obj.end() ); }
222
223     /** \relates DumpMap Convenience function to create DumpMap from std::map. */
224     template<class _Map>
225       DumpMap<_Map> dumpMap( const _Map & map_r )
226       { return DumpMap<_Map>( map_r ); }
227
228     ///////////////////////////////////////////////////////////////////
229     // dumpKeys
230     ///////////////////////////////////////////////////////////////////
231
232     /** std::map wrapper for stream output of keys.
233      * Uses MapKVIterator iterate and write the key values.
234      * \code
235      * std::map<...> mymap;
236      * std::cout << dumpKeys(mymap) << std::endl;
237      * \endcode
238      */
239     template<class _Map>
240       class DumpKeys
241       {
242       public:
243         typedef typename MapKVIteratorTraits<_Map>::Key_const_iterator MapKey_const_iterator;
244
245       public:
246         DumpKeys( const _Map & map_r )
247         : _map( &map_r )
248         {}
249
250         const _Map & map() const
251         { return *_map; }
252
253         MapKey_const_iterator begin() const
254         { return make_map_key_begin( map() ); }
255
256         MapKey_const_iterator end() const
257         { return make_map_key_end( map() ); }
258
259       private:
260         const _Map *const _map;
261       };
262
263     /** \relates DumpKeys Stream output. */
264     template<class _Map>
265       std::ostream & operator<<( std::ostream & str, const DumpKeys<_Map> & obj )
266       { return dumpRange( str, obj.begin(), obj.end() ); }
267
268     /** \relates DumpKeys Convenience function to create DumpKeys from std::map. */
269     template<class _Map>
270       DumpKeys<_Map> dumpKeys( const _Map & map_r )
271       { return DumpKeys<_Map>( map_r ); }
272
273     ///////////////////////////////////////////////////////////////////
274     // dumpValues
275     ///////////////////////////////////////////////////////////////////
276
277     /** std::map wrapper for stream output of values.
278      * Uses MapKVIterator iterate and write the values.
279      * \code
280      * std::map<...> mymap;
281      * std::cout << dumpValues(mymap) << std::endl;
282      * \endcode
283      */
284     template<class _Map>
285       class DumpValues
286       {
287       public:
288         typedef typename MapKVIteratorTraits<_Map>::Value_const_iterator MapValue_const_iterator;
289
290       public:
291         DumpValues( const _Map & map_r )
292         : _map( &map_r )
293         {}
294
295         const _Map & map() const
296         { return *_map; }
297
298         MapValue_const_iterator begin() const
299         { return make_map_value_begin( map() ); }
300
301         MapValue_const_iterator end() const
302         { return make_map_value_end( map() ); }
303
304       private:
305         const _Map *const _map;
306       };
307
308     /** \relates DumpValues Stream output. */
309     template<class _Map>
310       std::ostream & operator<<( std::ostream & str, const DumpValues<_Map> & obj )
311       { return dumpRange( str, obj.begin(), obj.end() ); }
312
313     /** \relates DumpValues Convenience function to create DumpValues from std::map. */
314     template<class _Map>
315       DumpValues<_Map> dumpValues( const _Map & map_r )
316       { return DumpValues<_Map>( map_r ); }
317
318     /////////////////////////////////////////////////////////////////
319   } // namespace _logtoolsdetail
320   ///////////////////////////////////////////////////////////////////
321
322   // iomanipulator
323   using _logtoolsdetail::mapEntry;   // std::pair as '[key] = value'
324   using _logtoolsdetail::dumpMap;    // dumpRange '[key] = value'
325   using _logtoolsdetail::dumpKeys;   // dumpRange keys
326   using _logtoolsdetail::dumpValues; // dumpRange values
327
328   template<class _Key, class _Tp>
329     std::ostream & operator<<( std::ostream & str, const std::map<_Key, _Tp> & obj )
330     { return str << dumpMap( obj ); }
331
332   template<class _Key, class _Tp>
333     std::ostream & operator<<( std::ostream & str, const std::tr1::unordered_map<_Key, _Tp> & obj )
334     { return str << dumpMap( obj ); }
335
336   /** Print stream status bits.
337    * Prints the values of a streams \c good, \c eof, \c failed and \c bad bit.
338    *
339    * \code
340    *  [g___] - good
341    *  [_eF_] - eof and fail bit set
342    *  [__FB] - fail and bad bit set
343    * \endcode
344   */
345   inline std::ostream & operator<<( std::ostream & str, const std::basic_ios<char> & obj )
346   {
347     std::string ret( "[" );
348     ret += ( obj.good() ? 'g' : '_' );
349     ret += ( obj.eof()  ? 'e' : '_' );
350     ret += ( obj.fail() ? 'F' : '_' );
351     ret += ( obj.bad()  ? 'B' : '_' );
352     ret += "]";
353     return str << ret;
354   }
355
356   ///////////////////////////////////////////////////////////////////
357   // iomanipulator: str << dump(val) << ...
358   // calls:         std::ostream & dumpOn( std::ostream & str, const Type & obj )
359   ///////////////////////////////////////////////////////////////////
360
361   namespace detail
362   {
363     template<class _Tp>
364     struct Dump
365     {
366       Dump( const _Tp & obj_r ) : _obj( obj_r ) {}
367       const _Tp & _obj;
368     };
369
370     template<class _Tp>
371     std::ostream & operator<<( std::ostream & str, const Dump<_Tp> & obj )
372     { return dumpOn( str, obj._obj ); }
373   }
374
375   template<class _Tp>
376   detail::Dump<_Tp> dump( const _Tp & obj_r )
377   { return detail::Dump<_Tp>(obj_r); }
378
379
380   /////////////////////////////////////////////////////////////////
381 } // namespace zypp
382 ///////////////////////////////////////////////////////////////////
383 #endif // ZYPP_BASE_LOGTOOLS_H