Adding custom IOSTREAM for libtest.
[m6w6/libmemcached] / libtest / stream.h
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2 *
3 * uTest, libtest
4 *
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * * The names of its contributors may not be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36
37 #pragma once
38
39 #include <iostream>
40 #include <cassert>
41 #include <sstream>
42 #include <ctime>
43 #include <ostream>
44
45 namespace libtest {
46 namespace stream {
47
48 namespace detail {
49
50 template<class Ch, class Tr, class A>
51 class cerr {
52 private:
53
54 public:
55 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
56
57 public:
58 void operator()(const stream_buffer &s)
59 {
60 std::cerr << std::endl << s.str() << std::endl;
61 }
62 };
63
64 template<class Ch, class Tr, class A>
65 class cout {
66 private:
67
68 public:
69 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
70
71 public:
72 void operator()(const stream_buffer &s)
73 {
74 std::cout << s.str() << std::endl;
75 }
76 };
77
78 template<class Ch, class Tr, class A>
79 class clog {
80 private:
81
82 public:
83 typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
84
85 public:
86 void operator()(const stream_buffer &s)
87 {
88 std::cerr << s.str() << std::endl;
89 }
90 };
91
92 template<template <class Ch, class Tr, class A> class OutputPolicy, class Ch = char, class Tr = std::char_traits<Ch>, class A = std::allocator<Ch> >
93 class log {
94 private:
95 typedef OutputPolicy<Ch, Tr, A> output_policy;
96 const char *_filename;
97 int _line_number;
98
99 public:
100 log(const char *filename, int line_number) :
101 _filename(filename),
102 _line_number(line_number)
103 {
104 if (_filename)
105 {
106 arg << _filename << ":" << _line_number << " ";
107 }
108 }
109
110 ~log()
111 {
112 output_policy()(arg);
113 }
114
115 public:
116 template<class T>
117 log &operator<<(const T &x)
118 {
119 arg << x;
120 return *this;
121 }
122
123 private:
124 typename output_policy::stream_buffer arg;
125 };
126 }
127
128 class cerr : public detail::log<detail::cerr> {
129 public:
130 cerr(const char *filename, int line_number) :
131 log(filename, line_number)
132 { }
133 };
134
135 class clog : public detail::log<detail::clog> {
136 public:
137 clog(const char *filename, int line_number) :
138 log(filename, line_number)
139 { }
140 };
141
142 class cout : public detail::log<detail::cout> {
143 public:
144 cout(const char *filename, int line_number) :
145 log(filename, line_number)
146 { }
147 };
148
149
150 } // namespace stream
151
152 #define Error stream::cerr(__FILE__, __LINE__)
153
154 #define Out stream::cout(NULL, __LINE__)
155
156 #define Log stream::clog(NULL, __LINE__)
157
158 } // namespace libtest