unify syntax for prointing std::map
[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 #include "zypp/base/Logger.h"
22 #include "zypp/base/Iterator.h"
23 #include "zypp/base/Deprecated.h"
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28
29   /** Print range defined by iterators (multiline style).
30    * \code
31    * intro [ pfx ITEM [ { sep ITEM }+ ] sfx ] extro
32    * \endcode
33    *
34    * The defaults print the range enclosed in \c {}, one item per
35    * line indented by 2 spaces.
36    * \code
37    * {
38    *   item1
39    *   item2
40    * }
41    * {} // on empty range
42    * \endcode
43    *
44    * A comma separated list enclosed in \c () would be:
45    * \code
46    * dumpRange( stream, begin, end, "(", "", ", ", "", ")" );
47    * // or shorter:
48    * dumpRangeLine( stream, begin, end );
49    * \endcode
50    *
51    * \note Some special handling is required for printing std::maps.
52    * Therefore iomaipulators \ref dumpMap, \ref dumpKeys and \ref dumpValues
53    * are provided.
54    * \code
55    * std::map<string,int> m;
56    * m["a"]=1;
57    * m["b"]=2;
58    * m["c"]=3;
59    *
60    * dumpRange( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
61    * // {
62    * //   [a] = 1
63    * //   [b] = 2
64    * //   [c] = 3
65    * // }
66    * dumpRange( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
67    * // {
68    * //   a
69    * //   b
70    * //   c
71    * // }
72    * dumpRange( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
73    * // {
74    * //   1
75    * //   2
76    * //   3
77    * // }
78    * dumpRangeLine( DBG, dumpMap(m).begin(), dumpMap(m).end() ) << endl;
79    * // ([a] = 1, [b] = 2, [c] = 3)
80    * dumpRangeLine( DBG, dumpKeys(m).begin(), dumpKeys(m).end() ) << endl;
81    * // (a, b, c)
82    * dumpRangeLine( DBG, dumpValues(m).begin(), dumpValues(m).end() ) << endl;
83    * // (1, 2, 3)
84    * \endcode
85   */
86   template<class _Iterator>
87     std::ostream & dumpRange( std::ostream & str,
88                               _Iterator begin, _Iterator end,
89                               const std::string & intro = "{",
90                               const std::string & pfx   = "\n  ",
91                               const std::string & sep   = "\n  ",
92                               const std::string & sfx   = "\n",
93                               const std::string & extro = "}" )
94     {
95       str << intro;
96       if ( begin != end )
97         {
98           str << pfx << *begin;
99           for (  ++begin; begin != end; ++begin )
100             str << sep << *begin;
101           str << sfx;
102         }
103       return str << extro;
104     }
105
106   /** Print range defined by iterators (single line style).
107    * \see dumpRange
108    */
109   template<class _Iterator>
110     std::ostream & dumpRangeLine( std::ostream & str,
111                                   _Iterator begin, _Iterator end )
112     { return dumpRange( str, begin, end, "(", "", ", ", "", ")" ); }
113
114
115   template<class _Tp>
116     std::ostream & operator<<( std::ostream & str, const std::vector<_Tp> & obj )
117     { return dumpRange( str, obj.begin(), obj.end() ); }
118
119   template<class _Tp>
120     std::ostream & operator<<( std::ostream & str, const std::set<_Tp> & obj )
121     { return dumpRange( str, obj.begin(), obj.end() ); }
122
123   template<class _Tp>
124     std::ostream & operator<<( std::ostream & str, const std::list<_Tp> & obj )
125     { return dumpRange( str, obj.begin(), obj.end() ); }
126
127   ///////////////////////////////////////////////////////////////////
128   namespace _logtoolsdetail
129   { /////////////////////////////////////////////////////////////////
130
131     ///////////////////////////////////////////////////////////////////
132     // mapEntry
133     ///////////////////////////////////////////////////////////////////
134
135     /** std::pair wrapper for std::map output.
136      * Just because we want a special output format for std::pair
137      * used in a std::map. The mapped std::pair is printed as
138      * <tt>[key] = value</tt>.
139     */
140     template<class _Pair>
141       class MapEntry
142       {
143       public:
144         MapEntry( const _Pair & pair_r )
145         : _pair( &pair_r )
146         {}
147
148         const _Pair & pair() const
149         { return *_pair; }
150
151       private:
152         const _Pair *const _pair;
153       };
154
155     /** \relates MapEntry Stream output. */
156     template<class _Pair>
157       std::ostream & operator<<( std::ostream & str, const MapEntry<_Pair> & obj )
158       {
159         return str << '[' << obj.pair().first << "] = " << obj.pair().second;
160       }
161
162     /** \relates MapEntry Convenience function to create MapEntry from std::pair. */
163     template<class _Pair>
164       MapEntry<_Pair> mapEntry( const _Pair & pair_r )
165       { return MapEntry<_Pair>( pair_r ); }
166
167     ///////////////////////////////////////////////////////////////////
168     // dumpMap
169     ///////////////////////////////////////////////////////////////////
170
171     /** std::map wrapper for stream output.
172      * Uses a transform_iterator to wrap the std::pair into MapEntry.
173      *
174      */
175     template<class _Map>
176       class DumpMap
177       {
178       public:
179         typedef _Map                        MapType;
180         typedef typename _Map::value_type   PairType;
181         typedef MapEntry<PairType>          MapEntryType;
182
183         struct Transformer : public std::unary_function<PairType, MapEntryType>
184         {
185           MapEntryType operator()( const PairType & pair_r ) const
186           { return mapEntry( pair_r ); }
187         };
188
189         typedef transform_iterator<Transformer, typename MapType::const_iterator>
190                 MapEntry_const_iterator;
191
192       public:
193         DumpMap( const _Map & map_r )
194         : _map( &map_r )
195         {}
196
197         const _Map & map() const
198         { return *_map; }
199
200         MapEntry_const_iterator begin() const
201         { return make_transform_iterator( map().begin(), Transformer() ); }
202
203         MapEntry_const_iterator end() const
204         { return make_transform_iterator( map().end(), Transformer() );}
205
206         /** \deprecated Use begin. */
207         ZYPP_DEPRECATED MapEntry_const_iterator map_begin() const
208         { return make_transform_iterator( map().begin(), Transformer() ); }
209
210         /** \deprecated Use end. */
211         ZYPP_DEPRECATED MapEntry_const_iterator map_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   /** Print stream status bits.
333    * Prints the values of a streams \c good, \c eof, \c failed and \c bad bit.
334    *
335    * \code
336    *  [g___] - good
337    *  [_eF_] - eof and fail bit set
338    *  [__FB] - fail and bad bit set
339    * \endcode
340   */
341   inline std::ostream & operator<<( std::ostream & str, const std::basic_ios<char> & obj )
342   {
343     std::string ret( "[" );
344     ret += ( obj.good() ? 'g' : '_' );
345     ret += ( obj.eof()  ? 'e' : '_' );
346     ret += ( obj.fail() ? 'F' : '_' );
347     ret += ( obj.bad()  ? 'B' : '_' );
348     ret += "]";
349     return str << ret;
350   }
351
352   /////////////////////////////////////////////////////////////////
353 } // namespace zypp
354 ///////////////////////////////////////////////////////////////////
355 #endif // ZYPP_BASE_LOGTOOLS_H