Merge in util update
[awesomized/libmemcached] / libtest / stream.h
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * libtest
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #pragma once
23
24 #include <iostream>
25 #include <cassert>
26 #include <sstream>
27 #include <ctime>
28 #include <ostream>
29
30 namespace libtest {
31 namespace stream {
32
33 namespace detail {
34
35 template<class Ch, class Tr, class A>
36 class cerr {
37 private:
38
39 public:
40 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
41
42 public:
43 void operator()(const stream_buffer &s)
44 {
45 std::cerr << s.str() << std::endl;
46 }
47 };
48
49 template<class Ch, class Tr, class A>
50 class make_cerr {
51 private:
52
53 public:
54 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
55
56 public:
57 void operator()(const stream_buffer &s)
58 {
59 std::cerr << std::endl << s.str() << std::endl;
60 }
61 };
62
63 template<class Ch, class Tr, class A>
64 class cout {
65 private:
66
67 public:
68 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
69
70 public:
71 void operator()(const stream_buffer &s)
72 {
73 std::cout << s.str() << std::endl;
74 }
75 };
76
77 template<class Ch, class Tr, class A>
78 class clog {
79 private:
80
81 public:
82 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
83
84 public:
85 void operator()(const stream_buffer &s)
86 {
87 std::cerr<< s.str() << std::endl;
88 }
89 };
90
91 template<template <class Ch, class Tr, class A> class OutputPolicy, class Ch = char, class Tr = std::char_traits<Ch>, class A = std::allocator<Ch> >
92 class log {
93 private:
94 typedef OutputPolicy<Ch, Tr, A> output_policy;
95 const char *_filename;
96 int _line_number;
97 const char *_func;
98
99 public:
100 log() :
101 _filename(NULL),
102 _line_number(0)
103 { }
104
105 void set_filename(const char *filename, int line_number, const char *func)
106 {
107 _filename= filename;
108 _line_number= line_number;
109 _func= func;
110 }
111
112 ~log()
113 {
114 output_policy()(arg);
115 }
116
117 public:
118 template<class T>
119 log &operator<<(const T &x)
120 {
121 if (_filename)
122 {
123 arg << _filename << ":" << _line_number << ": in " << _func << "() ";
124 _filename= NULL;
125 }
126 arg << x;
127 return *this;
128 }
129
130 private:
131 typename output_policy::stream_buffer arg;
132 };
133 }
134
135 class make_cerr : public detail::log<detail::make_cerr> {
136 public:
137 make_cerr(const char *filename, int line_number, const char *func)
138 {
139 set_filename(filename, line_number, func);
140 }
141 };
142
143 class cerr : public detail::log<detail::cerr> {
144 public:
145 cerr(const char *filename, int line_number, const char *func)
146 {
147 set_filename(filename, line_number, func);
148 }
149 };
150
151 class clog : public detail::log<detail::clog> {
152 public:
153 clog(const char *, int, const char*)
154 { }
155 };
156
157 class cout : public detail::log<detail::cout> {
158 public:
159 cout(const char *, int, const char *)
160 { }
161 };
162
163
164 } // namespace stream
165
166 #define Error stream::cerr(__FILE__, __LINE__, __func__)
167
168 #define Out stream::cout(NULL, __LINE__, __func__)
169
170 #define Outn() stream::cout(NULL, __LINE__, __func__) << " "
171
172 #define Log stream::clog(NULL, __LINE__, __func__)
173
174 #define Logn() stream::clog(NULL, __LINE__, __func__) << " "
175
176 } // namespace libtest