- Added stream output for std::map '[key] = value', manipulator
[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
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27
28   /** Print range defined by iterators.
29    * \code
30    * intro [ pfx ITEM [ { sep ITEM }+ ] sfx ] extro
31    * \endcode
32    * The defaults print the range enclosed in \c {}, one item per
33    * line indented by 2 spaces.
34    * \code
35    * {
36    *   item1
37    *   item2
38    * }
39    * {} // on empty rande
40    * \endcode
41    * A comma separated list enclosed in \c () would be
42    * \code
43    * dumpRange( stream, begin, end, "(", "", ", ", "", ")" );
44    * \endcode
45   */
46   template<class _Iterator>
47     std::ostream & dumpRange( std::ostream & str,
48                               _Iterator begin, _Iterator end,
49                               const std::string & intro = "{",
50                               const std::string & pfx   = "\n  ",
51                               const std::string & sep   = "\n  ",
52                               const std::string & sfx   = "\n",
53                               const std::string & extro = "}" )
54     {
55       str << intro;
56       if ( begin != end )
57         {
58           str << pfx << *begin;
59           for (  ++begin; begin != end; ++begin )
60             str << sep << *begin;
61           str << sfx;
62         }
63       return str << extro;
64     }
65
66   template<class _Iterator>
67     std::ostream & dumpRangeLine( std::ostream & str,
68                                   _Iterator begin, _Iterator end )
69     { return dumpRange( str, begin, end, "(", "", ", ", "", ")" ); }
70
71   template<class _Tp>
72     std::ostream & operator<<( std::ostream & str, const std::vector<_Tp> & obj )
73     { return dumpRange( str, obj.begin(), obj.end() ); }
74
75   template<class _Tp>
76     std::ostream & operator<<( std::ostream & str, const std::set<_Tp> & obj )
77     { return dumpRange( str, obj.begin(), obj.end() ); }
78
79   template<class _Tp>
80     std::ostream & operator<<( std::ostream & str, const std::list<_Tp> & obj )
81     { return dumpRange( str, obj.begin(), obj.end() ); }
82
83   ///////////////////////////////////////////////////////////////////
84   namespace _logtoolsdetail
85   { /////////////////////////////////////////////////////////////////
86
87     ///////////////////////////////////////////////////////////////////
88     // dumpMap
89     ///////////////////////////////////////////////////////////////////
90
91     /** std::pair wrapper for std::map output.
92      * Just because we want a special output format for std::pair
93      * used in a std::map.
94     */
95     template<class _Pair>
96       class MapEntry
97       {
98       public:
99         MapEntry( const _Pair & pair_r )
100         : _pair( &pair_r )
101         {}
102
103         const _Pair & pair() const
104         { return *_pair; }
105
106       private:
107         const _Pair *const _pair;
108       };
109
110     /** \relates MapEntry Stream output. */
111     template<class _Pair>
112       std::ostream & operator<<( std::ostream & str, const MapEntry<_Pair> & obj )
113       {
114         return str << '[' << obj.pair().first << "] = " << obj.pair().second;
115       }
116
117     /** Functor transforming std::pair into MapEntry. */
118     template<class _Pair>
119       struct GetMapEntry : public std::unary_function<_Pair, typename zypp::_logtoolsdetail::MapEntry<_Pair> >
120       {
121         typename zypp::_logtoolsdetail::MapEntry<_Pair> operator()( const _Pair & pair_r ) const
122         { return MapEntry<_Pair>( pair_r ); }
123       };
124
125     /** std::map wrapper for stream output.
126      * Provides the transform_iterator used to write std::pair formated as
127      * MapEntry.
128      */
129     template<class _Map>
130       class DumpMap
131       {
132       public:
133         typedef _Map                      MapType;
134         typedef typename _Map::value_type PairType;
135
136         typedef transform_iterator<GetMapEntry<PairType>, typename MapType::const_iterator>
137                 MapEntry_const_iterator;
138
139         DumpMap( const _Map & map_r )
140         : _map( &map_r )
141         {}
142
143         const _Map & map() const
144         { return *_map; }
145
146         MapEntry_const_iterator map_begin() const
147         { return make_transform_iterator( map().begin(), GetMapEntry<PairType>() ); }
148
149         MapEntry_const_iterator map_end() const
150         { return make_transform_iterator( map().end(), GetMapEntry<PairType>() );}
151
152       private:
153         const _Map *const _map;
154       };
155
156     /** \relates DumpMap Stream output. */
157     template<class _Map>
158       std::ostream & operator<<( std::ostream & str, const DumpMap<_Map> & obj )
159       {
160         return dumpRange( str, obj.map_begin(), obj.map_end() );
161       }
162
163     /** \relates DumpMap Convenience function to create DumpMap from std::map. */
164     template<class _Map>
165       DumpMap<_Map> dumpMap( const _Map & map_r )
166       { return DumpMap<_Map>( map_r ); }
167
168     ///////////////////////////////////////////////////////////////////
169     // dumpKeys
170     ///////////////////////////////////////////////////////////////////
171
172     /** std::map wrapper for stream output of keys.
173      * Uses MapKVIterator iterate and write the key values.
174      * \code
175      * std::map<...> mymap;
176      * std::cout << dumpKeys(mymap) << std::endl;
177      * \endcode
178      */
179     template<class _Map>
180       class DumpKeys
181       {
182       public:
183         DumpKeys( const _Map & map_r )
184         : _map( &map_r )
185         {}
186
187         const _Map & map() const
188         { return *_map; }
189
190       private:
191         const _Map *const _map;
192       };
193
194     /** \relates DumpKeys Stream output. */
195     template<class _Map>
196       std::ostream & operator<<( std::ostream & str, const DumpKeys<_Map> & obj )
197       { return dumpRange( str, make_map_key_begin(obj.map()), make_map_key_end(obj.map()) ); }
198
199     /** \relates DumpKeys Convenience function to create DumpKeys from std::map. */
200     template<class _Map>
201       DumpKeys<_Map> dumpKeys( const _Map & map_r )
202       { return DumpKeys<_Map>( map_r ); }
203
204     ///////////////////////////////////////////////////////////////////
205     // dumpValues
206     ///////////////////////////////////////////////////////////////////
207
208     /** std::map wrapper for stream output of values.
209      * Uses MapKVIterator iterate and write the values.
210      * \code
211      * std::map<...> mymap;
212      * std::cout << dumpValues(mymap) << std::endl;
213      * \endcode
214      */
215     template<class _Map>
216       class DumpValues
217       {
218       public:
219         DumpValues( const _Map & map_r )
220         : _map( &map_r )
221         {}
222
223         const _Map & map() const
224         { return *_map; }
225
226       private:
227         const _Map *const _map;
228       };
229
230     /** \relates DumpValues Stream output. */
231     template<class _Map>
232       std::ostream & operator<<( std::ostream & str, const DumpValues<_Map> & obj )
233       { return dumpRange( str, make_map_value_begin(obj.map()), make_map_value_end(obj.map()) ); }
234
235     /** \relates DumpValues Convenience function to create DumpValues from std::map. */
236     template<class _Map>
237       DumpValues<_Map> dumpValues( const _Map & map_r )
238       { return DumpValues<_Map>( map_r ); }
239
240     /////////////////////////////////////////////////////////////////
241   } // namespace _logtoolsdetail
242   ///////////////////////////////////////////////////////////////////
243
244   using _logtoolsdetail::dumpMap;    // dumpRange '[key] = value'
245   using _logtoolsdetail::dumpKeys;   // dumpRange keys
246   using _logtoolsdetail::dumpValues; // dumpRange values
247
248   template<class _Key, class _Tp>
249     std::ostream & operator<<( std::ostream & str, const std::map<_Key, _Tp> & obj )
250     { return str << dumpMap( obj ); }
251
252   /** Print stream status bits.
253    * Prints the values of a streams \c good, \c eof, \c failed and \c bad bit.
254    *
255    * \code
256    *  [g___] - good
257    *  [_eF_] - eof and fail bit set
258    *  [__FB] - fail and bad bit set
259    * \endcode
260   */
261   inline std::ostream & operator<<( std::ostream & str, const std::basic_ios<char> & obj )
262   {
263     std::string ret( "[" );
264     ret += ( obj.good() ? 'g' : '_' );
265     ret += ( obj.eof()  ? 'e' : '_' );
266     ret += ( obj.fail() ? 'F' : '_' );
267     ret += ( obj.bad()  ? 'B' : '_' );
268     ret += "]";
269     return str << ret;
270   }
271
272   /////////////////////////////////////////////////////////////////
273 } // namespace zypp
274 ///////////////////////////////////////////////////////////////////
275 #endif // ZYPP_BASE_LOGTOOLS_H