2 * @brief Convert types to pretty representations
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
30 #include "xapian/intrusive_ptr.h"
31 #include "xapian/types.h"
34 struct PrettyOStream
{
35 /// The std::ostream object we're outputting to.
38 PrettyOStream(S
& os_
) : os(os_
) { }
39 template<typename T
> PrettyOStream
& operator|(const T
& t
) {
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
)
60 /** Allow writing literal strings.
64 * PrettyOStream<std::ostream> ps(std::cout);
65 * ps << Literal("x = ") << x << Literal(", y = ") << y << endl;
68 inline PrettyOStream
<S
> &
69 operator<<(PrettyOStream
<S
> &ps
, const Literal
& t
)
75 template<class S
, class T
>
76 inline PrettyOStream
<S
> &
77 operator<<(PrettyOStream
<S
> &ps
, const T
* t
)
87 template<class S
, class T
>
88 inline PrettyOStream
<S
> &
89 operator<<(PrettyOStream
<S
> &ps
, const T
** t
)
96 inline PrettyOStream
<S
> &
97 operator<<(PrettyOStream
<S
> &ps
, const void * t
)
99 ps
.os
<< "(void*)" << t
;
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) {
109 if (ch
>= 7 && ch
<= 13) {
110 os
<< "abtnvfr"[ch
- 7];
112 os
<< char('0' | (ch
>> 6));
113 os
<< char('0' | ((ch
>> 3) & 7));
114 os
<< char('0' | (ch
& 7));
116 } else if (ch
== '\\') {
118 } else if (ch
== '"') {
126 inline PrettyOStream
<S
> &
127 operator<<(PrettyOStream
<S
> &ps
, const char * str
)
131 write_ch(ps
.os
, *str
++);
138 inline PrettyOStream
<S
> &
139 operator<<(PrettyOStream
<S
> &ps
, const std::string
& str
)
142 for (std::string::const_iterator i
= str
.begin(); i
!= str
.end(); ++i
) {
150 inline PrettyOStream
<S
> &
151 operator<<(PrettyOStream
<S
> &ps
, std::string
&)
153 ps
.os
<< "std::string&";
158 inline PrettyOStream
<S
> &
159 operator<<(PrettyOStream
<S
> &ps
, std::string
*)
161 ps
.os
<< "std::string*";
166 inline PrettyOStream
<S
> &
167 operator<<(PrettyOStream
<S
> &ps
, unsigned char ch
)
170 if (ch
< 32 || ch
>= 127) {
172 if (ch
>= 7 && ch
<= 13) {
173 ps
.os
<< "abtnvfr"[ch
- 7];
174 } else if (ch
== '\0') {
177 ps
.os
<< "0123456789abcdef"[ch
>> 4];
178 ps
.os
<< "0123456789abcdef"[ch
& 0x0f];
180 } else if (ch
== '\\') {
182 } else if (ch
== '\'') {
192 inline PrettyOStream
<S
> &
193 operator<<(PrettyOStream
<S
> &ps
, bool b
)
195 ps
.os
<< (b
? "true" : "false");
201 inline PrettyOStream<S> &
202 operator<<(PrettyOStream<S> &ps, bool &)
210 inline PrettyOStream
<S
> &
211 operator<<(PrettyOStream
<S
> &ps
, Xapian::termcount
* p
)
213 ps
.os
<< "(Xapian::termcount*)" << (void*)p
;
217 template<class S
, typename T
>
218 inline PrettyOStream
<S
> &
219 operator<<(PrettyOStream
<S
> &ps
, std::list
<T
> &) {
220 ps
.os
<< "std::list&";
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.
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*";
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&";
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.
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.
285 class GlassFreeListChecker
;
288 #define XAPIAN_PRETTY_AS_CLASSNAME(C)\
290 inline PrettyOStream<S> &\
291 operator<<(PrettyOStream<S> &ps, const C &) {\
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
)
315 inline PrettyOStream
<S
> &
316 operator<<(PrettyOStream
<S
> &ps
, const Xapian::Weight
*p
) {
317 ps
.os
<< "(Xapian:Weight*)" << (const void*)p
;
321 class RemoteConnection
;
324 inline PrettyOStream
<S
> &
325 operator<<(PrettyOStream
<S
> &ps
, const RemoteConnection
&) {
326 ps
.os
<< "RemoteConnection";
330 #include "backends/database.h"
333 inline PrettyOStream
<S
> &
334 operator<<(PrettyOStream
<S
> &ps
, const Xapian::Database::Internal
*p
) {
335 ps
.os
<< "(Database::Internal*)" << (const void*)p
;
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->";
346 #endif // XAPIAN_INCLUDED_PRETTY_H