Update for 1.4.18
[xapian.git] / xapian-core / common / pretty.h
blobf3ad3846df617b9f990e3fdf0ce752219b4a42a1
1 /** @file
2 * @brief Convert types to pretty representations
3 */
4 /* Copyright (C) 2010,2011,2012,2014,2016 Olly Betts
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef XAPIAN_INCLUDED_PRETTY_H
22 #define XAPIAN_INCLUDED_PRETTY_H
24 #include <list>
25 #include <map>
26 #include <ostream>
27 #include <string>
28 #include <vector>
30 #include "xapian/intrusive_ptr.h"
31 #include "xapian/types.h"
33 template<class S>
34 struct PrettyOStream {
35 /// The std::ostream object we're outputting to.
36 S & os;
38 PrettyOStream(S & os_) : os(os_) { }
39 template<typename T> PrettyOStream & operator|(const T & t) {
40 os << ", ";
41 return *this << t;
45 struct Literal {
46 const char * _lit;
47 explicit Literal(const char * lit) : _lit(lit) { }
48 explicit Literal(const std::string & s) : _lit(s.c_str()) { }
51 /// Default is to output as std::ostream would.
52 template<class S, class T>
53 inline PrettyOStream<S> &
54 operator<<(PrettyOStream<S> &ps, const T & t)
56 ps.os << t;
57 return ps;
60 /** Allow writing literal strings.
62 * For example:
64 * PrettyOStream<std::ostream> ps(std::cout);
65 * ps << Literal("x = ") << x << Literal(", y = ") << y << endl;
67 template<class S>
68 inline PrettyOStream<S> &
69 operator<<(PrettyOStream<S> &ps, const Literal & t)
71 ps.os << t._lit;
72 return ps;
75 template<class S, class T>
76 inline PrettyOStream<S> &
77 operator<<(PrettyOStream<S> &ps, const T * t)
79 if (!t) {
80 ps.os << "NULL";
81 return ps;
83 ps.os << '&';
84 return ps << *t;
87 template<class S, class T>
88 inline PrettyOStream<S> &
89 operator<<(PrettyOStream<S> &ps, const T ** t)
91 ps.os << (void*)t;
92 return ps;
95 template<class S>
96 inline PrettyOStream<S> &
97 operator<<(PrettyOStream<S> &ps, const void * t)
99 ps.os << "(void*)" << t;
100 return ps;
103 // FIXME: We probably don't want to inline this, but need to arrange to
104 // put it somewhere sane out-of-line.
105 inline void write_ch(std::ostream & os, unsigned char ch)
107 if (ch < 32 || ch >= 127) {
108 os << '\\';
109 if (ch >= 7 && ch <= 13) {
110 os << "abtnvfr"[ch - 7];
111 } else {
112 os << char('0' | (ch >> 6));
113 os << char('0' | ((ch >> 3) & 7));
114 os << char('0' | (ch & 7));
116 } else if (ch == '\\') {
117 os << "\\\\";
118 } else if (ch == '"') {
119 os << "\\\"";
120 } else {
121 os << ch;
125 template<class S>
126 inline PrettyOStream<S> &
127 operator<<(PrettyOStream<S> &ps, const char * str)
129 ps.os << '"';
130 while (*str) {
131 write_ch(ps.os, *str++);
133 ps.os << '"';
134 return ps;
137 template<class S>
138 inline PrettyOStream<S> &
139 operator<<(PrettyOStream<S> &ps, const std::string & str)
141 ps.os << '"';
142 for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) {
143 write_ch(ps.os, *i);
145 ps.os << '"';
146 return ps;
149 template<class S>
150 inline PrettyOStream<S> &
151 operator<<(PrettyOStream<S> &ps, std::string &)
153 ps.os << "std::string&";
154 return ps;
157 template<class S>
158 inline PrettyOStream<S> &
159 operator<<(PrettyOStream<S> &ps, std::string *)
161 ps.os << "std::string*";
162 return ps;
165 template<class S>
166 inline PrettyOStream<S> &
167 operator<<(PrettyOStream<S> &ps, unsigned char ch)
169 ps.os << '\'';
170 if (ch < 32 || ch >= 127) {
171 ps.os << '\\';
172 if (ch >= 7 && ch <= 13) {
173 ps.os << "abtnvfr"[ch - 7];
174 } else if (ch == '\0') {
175 ps.os << "\\0";
176 } else {
177 ps.os << "0123456789abcdef"[ch >> 4];
178 ps.os << "0123456789abcdef"[ch & 0x0f];
180 } else if (ch == '\\') {
181 ps.os << "\\\\";
182 } else if (ch == '\'') {
183 ps.os << "\\'";
184 } else {
185 ps.os << ch;
187 ps.os << '\'';
188 return ps;
191 template<class S>
192 inline PrettyOStream<S> &
193 operator<<(PrettyOStream<S> &ps, bool b)
195 ps.os << (b ? "true" : "false");
196 return ps;
200 template<class S>
201 inline PrettyOStream<S> &
202 operator<<(PrettyOStream<S> &ps, bool &)
204 ps.os << "bool&";
205 return ps;
209 template<class S>
210 inline PrettyOStream<S> &
211 operator<<(PrettyOStream<S> &ps, Xapian::termcount * p)
213 ps.os << "(Xapian::termcount*)" << (void*)p;
214 return ps;
217 template<class S, typename T>
218 inline PrettyOStream<S> &
219 operator<<(PrettyOStream<S> &ps, std::list<T> &) {
220 ps.os << "std::list&";
221 return ps;
224 template<class S, typename T>
225 inline PrettyOStream<S> &
226 operator<<(PrettyOStream<S> &ps, const std::list<T> &) {
227 ps.os << "std::list";
228 // FIXME: could show first up to N elements.
229 return ps;
232 template<class S, typename K, typename V>
233 inline PrettyOStream<S> &
234 operator<<(PrettyOStream<S> &ps, std::map<K, V> *) {
235 ps.os << "std::map*";
236 return ps;
239 template<class S, typename K, typename V>
240 inline PrettyOStream<S> &
241 operator<<(PrettyOStream<S> &ps, std::map<K, V> &) {
242 ps.os << "std::map&";
243 return ps;
246 template<class S, typename K, typename V>
247 inline PrettyOStream<S> &
248 operator<<(PrettyOStream<S> &ps, const std::map<K, V> & m) {
249 ps.os << "std::map(" << m.size() << ')';
250 // FIXME: could show first up to N elements.
251 return ps;
254 template<class S, typename T>
255 inline PrettyOStream<S> &
256 operator<<(PrettyOStream<S> &ps, const std::vector<T> & v) {
257 ps.os << "std::vector(" << v.size() << ')';
258 // FIXME: could show first up to N elements.
259 return ps;
262 namespace Xapian {
263 class ExpandDecider;
264 class LatLongMetric;
265 class MatchDecider;
266 class Registry;
267 class Weight;
268 namespace Internal {
269 class AndContext;
270 class ExpandStats;
271 class ExpandWeight;
272 class OrContext;
276 namespace Glass {
277 class RootInfo;
280 class ChertCursor;
281 class ChertDatabase;
282 class ChertTable;
283 class GlassCursor;
284 class GlassDatabase;
285 class GlassFreeListChecker;
286 class GlassTable;
288 #define XAPIAN_PRETTY_AS_CLASSNAME(C)\
289 template<class S>\
290 inline PrettyOStream<S> &\
291 operator<<(PrettyOStream<S> &ps, const C &) {\
292 ps.os << #C;\
293 return ps;\
296 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::ExpandDecider)
297 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::LatLongMetric)
298 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::MatchDecider)
299 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::Registry)
300 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::Weight)
301 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::Internal::AndContext)
302 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::Internal::ExpandStats)
303 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::Internal::ExpandWeight)
304 XAPIAN_PRETTY_AS_CLASSNAME(Xapian::Internal::OrContext)
305 XAPIAN_PRETTY_AS_CLASSNAME(ChertCursor)
306 XAPIAN_PRETTY_AS_CLASSNAME(ChertDatabase)
307 XAPIAN_PRETTY_AS_CLASSNAME(ChertTable)
308 XAPIAN_PRETTY_AS_CLASSNAME(Glass::RootInfo)
309 XAPIAN_PRETTY_AS_CLASSNAME(GlassCursor)
310 XAPIAN_PRETTY_AS_CLASSNAME(GlassFreeListChecker)
311 XAPIAN_PRETTY_AS_CLASSNAME(GlassDatabase)
312 XAPIAN_PRETTY_AS_CLASSNAME(GlassTable)
314 template<class S>
315 inline PrettyOStream<S> &
316 operator<<(PrettyOStream<S> &ps, const Xapian::Weight *p) {
317 ps.os << "(Xapian:Weight*)" << (const void*)p;
318 return ps;
321 class RemoteConnection;
323 template<class S>
324 inline PrettyOStream<S> &
325 operator<<(PrettyOStream<S> &ps, const RemoteConnection &) {
326 ps.os << "RemoteConnection";
327 return ps;
330 #include "backends/database.h"
332 template<class S>
333 inline PrettyOStream<S> &
334 operator<<(PrettyOStream<S> &ps, const Xapian::Database::Internal *p) {
335 ps.os << "(Database::Internal*)" << (const void*)p;
336 return ps;
339 template<class S, class T>
340 inline PrettyOStream<S> &
341 operator<<(PrettyOStream<S> &ps, Xapian::Internal::intrusive_ptr<const T> t) {
342 ps.os << "intrusive_ptr->";
343 return ps << t;
346 #endif // XAPIAN_INCLUDED_PRETTY_H