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