Imported Upstream version 16.3.2
[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/Hash.h"
23 #include "zypp/base/Logger.h"
24 #include "zypp/base/Iterator.h"
25 #include "zypp/APIConfig.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 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 = "}" )
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 TIterator>
114     std::ostream & dumpRangeLine( std::ostream & str,
115                                   TIterator begin, TIterator 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, class TCmp, class TAlloc>
124     std::ostream & operator<<( std::ostream & str, const std::set<Tp,TCmp,TAlloc> & obj )
125     { return dumpRange( str, obj.begin(), obj.end() ); }
126
127   template<class Tp>
128     std::ostream & operator<<( std::ostream & str, const std::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::multiset<Tp> & obj )
133     { return dumpRange( str, obj.begin(), obj.end() ); }
134
135   template<class Tp>
136     std::ostream & operator<<( std::ostream & str, const std::list<Tp> & obj )
137     { return dumpRange( str, obj.begin(), obj.end() ); }
138
139   ///////////////////////////////////////////////////////////////////
140   namespace _logtoolsdetail
141   { /////////////////////////////////////////////////////////////////
142
143     ///////////////////////////////////////////////////////////////////
144     // mapEntry
145     ///////////////////////////////////////////////////////////////////
146
147     /** std::pair wrapper for std::map output.
148      * Just because we want a special output format for std::pair
149      * used in a std::map. The mapped std::pair is printed as
150      * <tt>[key] = value</tt>.
151     */
152     template<class TPair>
153       class MapEntry
154       {
155       public:
156         MapEntry( const TPair & pair_r )
157         : _pair( &pair_r )
158         {}
159
160         const TPair & pair() const
161         { return *_pair; }
162
163       private:
164         const TPair *const _pair;
165       };
166
167     /** \relates MapEntry Stream output. */
168     template<class TPair>
169       std::ostream & operator<<( std::ostream & str, const MapEntry<TPair> & obj )
170       {
171         return str << '[' << obj.pair().first << "] = " << obj.pair().second;
172       }
173
174     /** \relates MapEntry Convenience function to create MapEntry from std::pair. */
175     template<class TPair>
176       MapEntry<TPair> mapEntry( const TPair & pair_r )
177       { return MapEntry<TPair>( pair_r ); }
178
179     ///////////////////////////////////////////////////////////////////
180     // dumpMap
181     ///////////////////////////////////////////////////////////////////
182
183     /** std::map wrapper for stream output.
184      * Uses a transform_iterator to wrap the std::pair into MapEntry.
185      *
186      */
187     template<class TMap>
188       class DumpMap
189       {
190       public:
191         typedef TMap                        MapType;
192         typedef typename TMap::value_type   PairType;
193         typedef MapEntry<PairType>          MapEntryType;
194
195         struct Transformer : public std::unary_function<PairType, MapEntryType>
196         {
197           MapEntryType operator()( const PairType & pair_r ) const
198           { return mapEntry( pair_r ); }
199         };
200
201         typedef transform_iterator<Transformer, typename MapType::const_iterator>
202                 MapEntry_const_iterator;
203
204       public:
205         DumpMap( const TMap & map_r )
206         : _map( &map_r )
207         {}
208
209         const TMap & map() const
210         { return *_map; }
211
212         MapEntry_const_iterator begin() const
213         { return make_transform_iterator( map().begin(), Transformer() ); }
214
215         MapEntry_const_iterator end() const
216         { return make_transform_iterator( map().end(), Transformer() );}
217
218       private:
219         const TMap *const _map;
220       };
221
222     /** \relates DumpMap Stream output. */
223     template<class TMap>
224       std::ostream & operator<<( std::ostream & str, const DumpMap<TMap> & obj )
225       { return dumpRange( str, obj.begin(), obj.end() ); }
226
227     /** \relates DumpMap Convenience function to create DumpMap from std::map. */
228     template<class TMap>
229       DumpMap<TMap> dumpMap( const TMap & map_r )
230       { return DumpMap<TMap>( map_r ); }
231
232     ///////////////////////////////////////////////////////////////////
233     // dumpKeys
234     ///////////////////////////////////////////////////////////////////
235
236     /** std::map wrapper for stream output of keys.
237      * Uses MapKVIterator iterate and write the key values.
238      * \code
239      * std::map<...> mymap;
240      * std::cout << dumpKeys(mymap) << std::endl;
241      * \endcode
242      */
243     template<class TMap>
244       class DumpKeys
245       {
246       public:
247         typedef typename MapKVIteratorTraits<TMap>::Key_const_iterator MapKey_const_iterator;
248
249       public:
250         DumpKeys( const TMap & map_r )
251         : _map( &map_r )
252         {}
253
254         const TMap & map() const
255         { return *_map; }
256
257         MapKey_const_iterator begin() const
258         { return make_map_key_begin( map() ); }
259
260         MapKey_const_iterator end() const
261         { return make_map_key_end( map() ); }
262
263       private:
264         const TMap *const _map;
265       };
266
267     /** \relates DumpKeys Stream output. */
268     template<class TMap>
269       std::ostream & operator<<( std::ostream & str, const DumpKeys<TMap> & obj )
270       { return dumpRange( str, obj.begin(), obj.end() ); }
271
272     /** \relates DumpKeys Convenience function to create DumpKeys from std::map. */
273     template<class TMap>
274       DumpKeys<TMap> dumpKeys( const TMap & map_r )
275       { return DumpKeys<TMap>( map_r ); }
276
277     ///////////////////////////////////////////////////////////////////
278     // dumpValues
279     ///////////////////////////////////////////////////////////////////
280
281     /** std::map wrapper for stream output of values.
282      * Uses MapKVIterator iterate and write the values.
283      * \code
284      * std::map<...> mymap;
285      * std::cout << dumpValues(mymap) << std::endl;
286      * \endcode
287      */
288     template<class TMap>
289       class DumpValues
290       {
291       public:
292         typedef typename MapKVIteratorTraits<TMap>::Value_const_iterator MapValue_const_iterator;
293
294       public:
295         DumpValues( const TMap & map_r )
296         : _map( &map_r )
297         {}
298
299         const TMap & map() const
300         { return *_map; }
301
302         MapValue_const_iterator begin() const
303         { return make_map_value_begin( map() ); }
304
305         MapValue_const_iterator end() const
306         { return make_map_value_end( map() ); }
307
308       private:
309         const TMap *const _map;
310       };
311
312     /** \relates DumpValues Stream output. */
313     template<class TMap>
314       std::ostream & operator<<( std::ostream & str, const DumpValues<TMap> & obj )
315       { return dumpRange( str, obj.begin(), obj.end() ); }
316
317     /** \relates DumpValues Convenience function to create DumpValues from std::map. */
318     template<class TMap>
319       DumpValues<TMap> dumpValues( const TMap & map_r )
320       { return DumpValues<TMap>( map_r ); }
321
322     /////////////////////////////////////////////////////////////////
323   } // namespace _logtoolsdetail
324   ///////////////////////////////////////////////////////////////////
325
326   // iomanipulator
327   using _logtoolsdetail::mapEntry;   // std::pair as '[key] = value'
328   using _logtoolsdetail::dumpMap;    // dumpRange '[key] = value'
329   using _logtoolsdetail::dumpKeys;   // dumpRange keys
330   using _logtoolsdetail::dumpValues; // dumpRange values
331
332   template<class TKey, class Tp>
333     std::ostream & operator<<( std::ostream & str, const std::map<TKey, Tp> & obj )
334     { return str << dumpMap( obj ); }
335
336   template<class TKey, class Tp>
337     std::ostream & operator<<( std::ostream & str, const std::unordered_map<TKey, Tp> & obj )
338     { return str << dumpMap( obj ); }
339
340   template<class TKey, class Tp>
341     std::ostream & operator<<( std::ostream & str, const std::multimap<TKey, Tp> & obj )
342     { return str << dumpMap( obj ); }
343
344   /** Print stream status bits.
345    * Prints the values of a streams \c good, \c eof, \c failed and \c bad bit.
346    *
347    * \code
348    *  [g___] - good
349    *  [_eF_] - eof and fail bit set
350    *  [__FB] - fail and bad bit set
351    * \endcode
352   */
353   inline std::ostream & operator<<( std::ostream & str, const std::basic_ios<char> & obj )
354   {
355     std::string ret( "[" );
356     ret += ( obj.good() ? 'g' : '_' );
357     ret += ( obj.eof()  ? 'e' : '_' );
358     ret += ( obj.fail() ? 'F' : '_' );
359     ret += ( obj.bad()  ? 'B' : '_' );
360     ret += "]";
361     return str << ret;
362   }
363
364   ///////////////////////////////////////////////////////////////////
365   // iomanipulator: str << dump(val) << ...
366   // calls:         std::ostream & dumpOn( std::ostream & str, const Type & obj )
367   ///////////////////////////////////////////////////////////////////
368
369   namespace detail
370   {
371     template<class Tp>
372     struct Dump
373     {
374       Dump( const Tp & obj_r ) : _obj( obj_r ) {}
375       const Tp & _obj;
376     };
377
378     template<class Tp>
379     std::ostream & operator<<( std::ostream & str, const Dump<Tp> & obj )
380     { return dumpOn( str, obj._obj ); }
381   }
382
383   template<class Tp>
384   detail::Dump<Tp> dump( const Tp & obj_r )
385   { return detail::Dump<Tp>(obj_r); }
386
387
388   /////////////////////////////////////////////////////////////////
389 } // namespace zypp
390 ///////////////////////////////////////////////////////////////////
391 #endif // ZYPP_BASE_LOGTOOLS_H