YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
LogStream.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#ifndef YARP_OS_LOGSTREAM_H
7#define YARP_OS_LOGSTREAM_H
8
9#include <yarp/os/api.h>
10
11#include <yarp/os/Log.h>
13#include <yarp/os/Os.h>
14#include <yarp/os/SystemClock.h>
15#include <yarp/os/Time.h>
16
17#include <cstdio>
18#include <cstdlib>
19#include <iosfwd>
20#include <sstream>
21#include <string>
22#include <tuple>
23#include <type_traits>
24#include <utility>
25
26namespace yarp::os {
27
29{
30 struct Stream
31 {
32 Stream(Log::LogType t,
33 const char* fn,
34 unsigned int l,
35 const char* f,
36 const char* id,
37 const double ct,
38 const yarp::os::Log::Predicate pred,
39 const LogComponent& c) :
40 type(t),
41 file(fn),
42 line(l),
43 func(f),
44 id(id),
47 externaltime(ct),
48 pred(pred),
49 comp(c),
50 ref(1)
51 {
52 }
53 std::ostringstream oss;
54 Log::LogType type;
55 const char* file;
56 unsigned int line;
57 const char* func;
58 const char* id;
59 double systemtime;
60 double networktime;
61 double externaltime;
62 const yarp::os::Log::Predicate pred;
63 const LogComponent& comp;
64 int ref;
65 bool nospace {false};
66 } * stream;
67
68public:
70 const char* file,
71 unsigned int line,
72 const char* func,
73 const char* id,
74 const double externaltime,
75 const yarp::os::Log::Predicate pred = nullptr,
76 const LogComponent& comp = Log::defaultLogComponent()) :
77 stream(new Stream(type, file, line, func, id, externaltime, pred, comp))
78 {
79 }
80
81 inline LogStream(const LogStream& o) :
82 stream(o.stream)
83 {
84 ++stream->ref;
85 }
86
87 inline ~LogStream()
88 {
89 if (!--stream->ref) {
90 if (!stream->pred || stream->pred()) {
91 std::string s = stream->oss.str();
92 if (!s.empty())
93 {
94 // remove the last character if it an empty space (i.e.
95 // always unless the user defined an operator<< that
96 // does not add an empty space.
97 if (s.back() == ' ') {
98 s.pop_back();
99 } else {
100 yarp::os::Log(stream->file, stream->line, stream->func, nullptr, yarp::os::Log::logInternalComponent()).warning(
101 "' ' was expected. Some `operator<<` does not add an extra space at the end");
102 }
103 // remove the last character if it is a \n
104 if (!s.empty() && s.back() == '\n') {
105 yarp::os::Log(stream->file, stream->line, stream->func, nullptr, yarp::os::Log::logInternalComponent()).warning(
106 "Removing extra \\n (stream-style)");
107 s.pop_back();
108 }
109 }
110 Log::do_log(stream->type,
111 s.c_str(),
112 stream->file,
113 stream->line,
114 stream->func,
115 stream->systemtime,
116 stream->networktime,
117 stream->externaltime,
118 stream->comp,
119 stream->id);
120 }
121
122 if (stream->type == yarp::os::Log::FatalType) {
123 yarp_print_trace(stderr, stream->file, stream->line);
124 delete stream;
125 std::exit(-1);
126 }
127 delete stream;
128 }
129 }
130
131 inline LogStream& operator<<(bool t)
132 {
133 stream->oss << (t ? "true" : "false");
134 if (!stream->nospace) {
135 stream->oss << ' ';
136 }
137 return *this;
138 }
139 inline LogStream& operator<<(char t)
140 {
141 stream->oss << t;
142 if (!stream->nospace) {
143 stream->oss << ' ';
144 }
145 return *this;
146 }
147 inline LogStream& operator<<(signed short t)
148 {
149 stream->oss << t;
150 if (!stream->nospace) {
151 stream->oss << ' ';
152 }
153 return *this;
154 }
155 inline LogStream& operator<<(unsigned short t)
156 {
157 stream->oss << t;
158 if (!stream->nospace) {
159 stream->oss << ' ';
160 }
161 return *this;
162 }
163 inline LogStream& operator<<(signed int t)
164 {
165 stream->oss << t;
166 if (!stream->nospace) {
167 stream->oss << ' ';
168 }
169 return *this;
170 }
171 inline LogStream& operator<<(unsigned int t)
172 {
173 stream->oss << t;
174 if (!stream->nospace) {
175 stream->oss << ' ';
176 }
177 return *this;
178 }
179 inline LogStream& operator<<(signed long t)
180 {
181 stream->oss << t;
182 if (!stream->nospace) {
183 stream->oss << ' ';
184 }
185 return *this;
186 }
187 inline LogStream& operator<<(unsigned long t)
188 {
189 stream->oss << t;
190 if (!stream->nospace) {
191 stream->oss << ' ';
192 }
193 return *this;
194 }
195 inline LogStream& operator<<(signed long long t)
196 {
197 stream->oss << t;
198 if (!stream->nospace) {
199 stream->oss << ' ';
200 }
201 return *this;
202 }
203 inline LogStream& operator<<(unsigned long long t)
204 {
205 stream->oss << t;
206 if (!stream->nospace) {
207 stream->oss << ' ';
208 }
209 return *this;
210 }
211 inline LogStream& operator<<(float t)
212 {
213 stream->oss << t;
214 if (!stream->nospace) {
215 stream->oss << ' ';
216 }
217 return *this;
218 }
219 inline LogStream& operator<<(double t)
220 {
221 stream->oss << t;
222 if (!stream->nospace) {
223 stream->oss << ' ';
224 }
225 return *this;
226 }
227 inline LogStream& operator<<(const char* t)
228 {
229 stream->oss << t;
230 if (!stream->nospace) {
231 stream->oss << ' ';
232 }
233 return *this;
234 }
235 inline LogStream& operator<<(const void* t)
236 {
237 stream->oss << t;
238 if (!stream->nospace) {
239 stream->oss << ' ';
240 }
241 return *this;
242 }
243
244 inline LogStream& operator<<(const std::string& t)
245 {
246 stream->oss << t.c_str();
247 if (!stream->nospace) {
248 stream->oss << ' ';
249 }
250 return *this;
251 }
252
253#if !defined(SWIG)
254 template <typename T1, typename T2>
255 inline LogStream& operator<<(const std::pair<T1, T2>& t)
256 {
257 bool nospace = stream->nospace;
258 stream->nospace = true;
259 stream->oss << '{';
260 *this << t.first;
261 stream->oss << ", ";
262 *this << t.second << '}';
263 stream->nospace = nospace;
264 if (!stream->nospace) {
265 stream->oss << ' ';
266 }
267 return *this;
268 }
269
270 template <typename Container, typename = typename Container::value_type>
272 {
273 return streamInternal(cont);
274 }
275
276 template <typename Arr, typename std::enable_if_t<std::is_array_v<Arr>, bool> = true>
277 inline LogStream& operator<<(const Arr& arr)
278 {
279 return streamInternal(arr);
280 }
281
282 template <typename... Args>
283 inline LogStream& operator<<(const std::tuple<Args...>& t)
284 {
285 bool nospace = stream->nospace;
286 stream->nospace = true;
287 return tupleInternal<0>(t, nospace);
288 }
289
290private:
291 template <typename C>
292 inline LogStream& streamInternal(const C& c)
293 {
294 bool nospace = stream->nospace;
295 stream->nospace = true;
296 stream->oss << '[';
297 for (auto it = std::begin(c); it != std::end(c); ++it) {
298 if (it != std::begin(c)) {
299 stream->oss << ", ";
300 }
301 *this << *it;
302 }
303 stream->oss << ']';
304 stream->nospace = nospace;
305 if (!stream->nospace) {
306 stream->oss << ' ';
307 }
308 return *this;
309 }
310
311 template <std::size_t I, typename... Args>
312 inline LogStream& tupleInternal(const std::tuple<Args...>& t, bool nospace)
313 {
314 if constexpr (I == 0) {
315 stream->oss << '{';
316 }
317 if constexpr (I < sizeof...(Args)) {
318 if constexpr (I != 0) {
319 stream->oss << ", ";
320 }
321 *this << std::get<I>(t);
322 return tupleInternal<I + 1>(t, nospace);
323 } else {
324 stream->oss << '}';
325 stream->nospace = nospace;
326 if (!stream->nospace) {
327 stream->oss << ' ';
328 }
329 }
330 return *this;
331 }
332#endif // !defined(SWIG)
333
334}; // class LogStream
335
336} // namespace yarp::os
337
338#endif // YARP_OS_LOGSTREAM_H
float t
void yarp_print_trace(FILE *out, const char *file, unsigned int line)
Low level function for printing a stack trace, if implemented (ACE or gcc/Linux).
Definition Log.cpp:1119
A mini-server for performing network communication in the background.
LogStream & operator<<(const std::pair< T1, T2 > &t)
Definition LogStream.h:255
LogStream & operator<<(signed short t)
Definition LogStream.h:147
LogStream & operator<<(const Arr &arr)
Definition LogStream.h:277
LogStream & operator<<(bool t)
Definition LogStream.h:131
LogStream & operator<<(double t)
Definition LogStream.h:219
LogStream & operator<<(const std::tuple< Args... > &t)
Definition LogStream.h:283
LogStream & operator<<(signed long long t)
Definition LogStream.h:195
LogStream(Log::LogType type, const char *file, unsigned int line, const char *func, const char *id, const double externaltime, const yarp::os::Log::Predicate pred=nullptr, const LogComponent &comp=Log::defaultLogComponent())
Definition LogStream.h:69
LogStream & operator<<(unsigned short t)
Definition LogStream.h:155
LogStream & operator<<(const char *t)
Definition LogStream.h:227
LogStream & operator<<(float t)
Definition LogStream.h:211
LogStream & operator<<(unsigned int t)
Definition LogStream.h:171
LogStream(const LogStream &o)
Definition LogStream.h:81
LogStream & operator<<(char t)
Definition LogStream.h:139
LogStream & operator<<(unsigned long long t)
Definition LogStream.h:203
LogStream & operator<<(const void *t)
Definition LogStream.h:235
LogStream & operator<<(signed long t)
Definition LogStream.h:179
LogStream & operator<<(const std::string &t)
Definition LogStream.h:244
LogStream & operator<<(unsigned long t)
Definition LogStream.h:187
LogStream & operator<<(signed int t)
Definition LogStream.h:163
LogStream & operator<<(const Container &cont)
Definition LogStream.h:271
void warning(const char *msg,...) const
Definition Log.cpp:1056
@ FatalType
Definition Log.h:97
static double nowSystem()
bool isClockInitialized()
Check if YARP clock is initialized.
Definition Time.cpp:250
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition Time.cpp:121
bool isSystemClock()
Check if YARP is providing system time.
Definition Time.cpp:255
An interface to the operating system, including Port based communication.
#define YARP_os_API
Definition api.h:18