rclcpp  master
C++ ROS Client Library API
logging.hpp
Go to the documentation of this file.
1 // generated from rclcpp/resource/logging.hpp.em
2 
3 // Copyright 2017 Open Source Robotics Foundation, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef RCLCPP__LOGGING_HPP_
18 #define RCLCPP__LOGGING_HPP_
19 
20 #include <type_traits>
21 
22 #include "rclcpp/logger.hpp"
23 #include "rcutils/logging_macros.h"
24 #include "rclcpp/utilities.hpp"
25 
26 // These are used for compiling out logging macros lower than a minimum severity.
27 #define RCLCPP_LOG_MIN_SEVERITY_DEBUG 0
28 #define RCLCPP_LOG_MIN_SEVERITY_INFO 1
29 #define RCLCPP_LOG_MIN_SEVERITY_WARN 2
30 #define RCLCPP_LOG_MIN_SEVERITY_ERROR 3
31 #define RCLCPP_LOG_MIN_SEVERITY_FATAL 4
32 #define RCLCPP_LOG_MIN_SEVERITY_NONE 5
33 
34 #define RCLCPP_FIRST_ARG(N, ...) N
35 #define RCLCPP_ALL_BUT_FIRST_ARGS(N, ...) __VA_ARGS__
36 
43 #ifndef RCLCPP_LOG_MIN_SEVERITY
44 #define RCLCPP_LOG_MIN_SEVERITY RCLCPP_LOG_MIN_SEVERITY_DEBUG
45 #endif
46 
49 #if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_DEBUG)
51 // empty logging macros for severity DEBUG when being disabled at compile time
53 #define RCLCPP_DEBUG(...)
54 #define RCLCPP_DEBUG_ONCE(...)
56 #define RCLCPP_DEBUG_EXPRESSION(...)
58 #define RCLCPP_DEBUG_FUNCTION(...)
60 #define RCLCPP_DEBUG_SKIPFIRST(...)
62 #define RCLCPP_DEBUG_THROTTLE(...)
64 #define RCLCPP_DEBUG_SKIPFIRST_THROTTLE(...)
66 #define RCLCPP_DEBUG_STREAM(...)
68 #define RCLCPP_DEBUG_STREAM_ONCE(...)
70 #define RCLCPP_DEBUG_STREAM_EXPRESSION(...)
72 #define RCLCPP_DEBUG_STREAM_FUNCTION(...)
74 #define RCLCPP_DEBUG_STREAM_SKIPFIRST(...)
76 #define RCLCPP_DEBUG_STREAM_THROTTLE(...)
78 #define RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE(...)
80 
81 #else
82 // The RCLCPP_DEBUG macro is surrounded by do { .. } while (0)
83 // to implement the standard C macro idiom to make the macro safe in all
84 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
92 #define RCLCPP_DEBUG(logger, ...) \
93  do { \
94  static_assert( \
95  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
96  typename ::rclcpp::Logger>::value, \
97  "First argument to logging macros must be an rclcpp::Logger"); \
98  \
99  RCUTILS_LOG_DEBUG_NAMED( \
100  logger.get_name(), \
101  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
102  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
103  } while (0)
104 
105 // The RCLCPP_DEBUG_ONCE macro is surrounded by do { .. } while (0)
106 // to implement the standard C macro idiom to make the macro safe in all
107 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
116 #define RCLCPP_DEBUG_ONCE(logger, ...) \
117  do { \
118  static_assert( \
119  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
120  typename ::rclcpp::Logger>::value, \
121  "First argument to logging macros must be an rclcpp::Logger"); \
122  \
123  RCUTILS_LOG_DEBUG_ONCE_NAMED( \
124  logger.get_name(), \
125  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
126  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
127  } while (0)
128 
129 // The RCLCPP_DEBUG_EXPRESSION macro is surrounded by do { .. } while (0)
130 // to implement the standard C macro idiom to make the macro safe in all
131 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
141 #define RCLCPP_DEBUG_EXPRESSION(logger, expression, ...) \
142  do { \
143  static_assert( \
144  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
145  typename ::rclcpp::Logger>::value, \
146  "First argument to logging macros must be an rclcpp::Logger"); \
147  \
148  RCUTILS_LOG_DEBUG_EXPRESSION_NAMED( \
149  expression, \
150  logger.get_name(), \
151  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
152  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
153  } while (0)
154 
155 // The RCLCPP_DEBUG_FUNCTION macro is surrounded by do { .. } while (0)
156 // to implement the standard C macro idiom to make the macro safe in all
157 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
167 #define RCLCPP_DEBUG_FUNCTION(logger, function, ...) \
168  do { \
169  static_assert( \
170  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
171  typename ::rclcpp::Logger>::value, \
172  "First argument to logging macros must be an rclcpp::Logger"); \
173  \
174  RCUTILS_LOG_DEBUG_FUNCTION_NAMED( \
175  function, \
176  logger.get_name(), \
177  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
178  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
179  } while (0)
180 
181 // The RCLCPP_DEBUG_SKIPFIRST macro is surrounded by do { .. } while (0)
182 // to implement the standard C macro idiom to make the macro safe in all
183 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
192 #define RCLCPP_DEBUG_SKIPFIRST(logger, ...) \
193  do { \
194  static_assert( \
195  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
196  typename ::rclcpp::Logger>::value, \
197  "First argument to logging macros must be an rclcpp::Logger"); \
198  \
199  RCUTILS_LOG_DEBUG_SKIPFIRST_NAMED( \
200  logger.get_name(), \
201  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
202  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
203  } while (0)
204 
205 // The RCLCPP_DEBUG_THROTTLE macro is surrounded by do { .. } while (0)
206 // to implement the standard C macro idiom to make the macro safe in all
207 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
218 #define RCLCPP_DEBUG_THROTTLE(logger, clock, duration, ...) \
219  do { \
220  static_assert( \
221  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
222  typename ::rclcpp::Logger>::value, \
223  "First argument to logging macros must be an rclcpp::Logger"); \
224 \
225  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
226  try { \
227  *time_point = clock.now().nanoseconds(); \
228  } catch (...) { \
229  RCUTILS_SAFE_FWRITE_TO_STDERR( \
230  "[rclcpp|logging.hpp] RCLCPP_DEBUG_THROTTLE could not get current time stamp\n"); \
231  return RCUTILS_RET_ERROR; \
232  } \
233  return RCUTILS_RET_OK; \
234  }; \
235  \
236  RCUTILS_LOG_DEBUG_THROTTLE_NAMED( \
237  get_time_point, \
238  duration, \
239  logger.get_name(), \
240  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
241  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
242  } while (0)
243 
244 // The RCLCPP_DEBUG_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
245 // to implement the standard C macro idiom to make the macro safe in all
246 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
258 #define RCLCPP_DEBUG_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
259  do { \
260  static_assert( \
261  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
262  typename ::rclcpp::Logger>::value, \
263  "First argument to logging macros must be an rclcpp::Logger"); \
264 \
265  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
266  try { \
267  *time_point = clock.now().nanoseconds(); \
268  } catch (...) { \
269  RCUTILS_SAFE_FWRITE_TO_STDERR( \
270  "[rclcpp|logging.hpp] RCLCPP_DEBUG_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
271  return RCUTILS_RET_ERROR; \
272  } \
273  return RCUTILS_RET_OK; \
274  }; \
275  \
276  RCUTILS_LOG_DEBUG_SKIPFIRST_THROTTLE_NAMED( \
277  get_time_point, \
278  duration, \
279  logger.get_name(), \
280  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
281  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
282  } while (0)
283 
284 // The RCLCPP_DEBUG_STREAM macro is surrounded by do { .. } while (0)
285 // to implement the standard C macro idiom to make the macro safe in all
286 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
293 #define RCLCPP_DEBUG_STREAM(logger, stream_arg) \
294  do { \
295  static_assert( \
296  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
297  typename ::rclcpp::Logger>::value, \
298  "First argument to logging macros must be an rclcpp::Logger"); \
299  \
300  std::stringstream ss; \
301  ss << stream_arg; \
302  RCUTILS_LOG_DEBUG_NAMED( \
303  logger.get_name(), \
304  "%s", rclcpp::get_c_string(ss.str())); \
305  } while (0)
306 
307 // The RCLCPP_DEBUG_STREAM_ONCE macro is surrounded by do { .. } while (0)
308 // to implement the standard C macro idiom to make the macro safe in all
309 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
317 #define RCLCPP_DEBUG_STREAM_ONCE(logger, stream_arg) \
318  do { \
319  static_assert( \
320  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
321  typename ::rclcpp::Logger>::value, \
322  "First argument to logging macros must be an rclcpp::Logger"); \
323  \
324  std::stringstream ss; \
325  ss << stream_arg; \
326  RCUTILS_LOG_DEBUG_ONCE_NAMED( \
327  logger.get_name(), \
328  "%s", rclcpp::get_c_string(ss.str())); \
329  } while (0)
330 
331 // The RCLCPP_DEBUG_STREAM_EXPRESSION macro is surrounded by do { .. } while (0)
332 // to implement the standard C macro idiom to make the macro safe in all
333 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
342 #define RCLCPP_DEBUG_STREAM_EXPRESSION(logger, expression, stream_arg) \
343  do { \
344  static_assert( \
345  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
346  typename ::rclcpp::Logger>::value, \
347  "First argument to logging macros must be an rclcpp::Logger"); \
348  \
349  std::stringstream ss; \
350  ss << stream_arg; \
351  RCUTILS_LOG_DEBUG_EXPRESSION_NAMED( \
352  expression, \
353  logger.get_name(), \
354  "%s", rclcpp::get_c_string(ss.str())); \
355  } while (0)
356 
357 // The RCLCPP_DEBUG_STREAM_FUNCTION macro is surrounded by do { .. } while (0)
358 // to implement the standard C macro idiom to make the macro safe in all
359 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
368 #define RCLCPP_DEBUG_STREAM_FUNCTION(logger, function, stream_arg) \
369  do { \
370  static_assert( \
371  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
372  typename ::rclcpp::Logger>::value, \
373  "First argument to logging macros must be an rclcpp::Logger"); \
374  \
375  std::stringstream ss; \
376  ss << stream_arg; \
377  RCUTILS_LOG_DEBUG_FUNCTION_NAMED( \
378  function, \
379  logger.get_name(), \
380  "%s", rclcpp::get_c_string(ss.str())); \
381  } while (0)
382 
383 // The RCLCPP_DEBUG_STREAM_SKIPFIRST macro is surrounded by do { .. } while (0)
384 // to implement the standard C macro idiom to make the macro safe in all
385 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
393 #define RCLCPP_DEBUG_STREAM_SKIPFIRST(logger, stream_arg) \
394  do { \
395  static_assert( \
396  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
397  typename ::rclcpp::Logger>::value, \
398  "First argument to logging macros must be an rclcpp::Logger"); \
399  \
400  std::stringstream ss; \
401  ss << stream_arg; \
402  RCUTILS_LOG_DEBUG_SKIPFIRST_NAMED( \
403  logger.get_name(), \
404  "%s", rclcpp::get_c_string(ss.str())); \
405  } while (0)
406 
407 // The RCLCPP_DEBUG_STREAM_THROTTLE macro is surrounded by do { .. } while (0)
408 // to implement the standard C macro idiom to make the macro safe in all
409 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
419 #define RCLCPP_DEBUG_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
420  do { \
421  static_assert( \
422  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
423  typename ::rclcpp::Logger>::value, \
424  "First argument to logging macros must be an rclcpp::Logger"); \
425 \
426  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
427  try { \
428  *time_point = clock.now().nanoseconds(); \
429  } catch (...) { \
430  RCUTILS_SAFE_FWRITE_TO_STDERR( \
431  "[rclcpp|logging.hpp] RCLCPP_DEBUG_STREAM_THROTTLE could not get current time stamp\n"); \
432  return RCUTILS_RET_ERROR; \
433  } \
434  return RCUTILS_RET_OK; \
435  }; \
436  \
437  std::stringstream ss; \
438  ss << stream_arg; \
439  RCUTILS_LOG_DEBUG_THROTTLE_NAMED( \
440  get_time_point, \
441  duration, \
442  logger.get_name(), \
443  "%s", rclcpp::get_c_string(ss.str())); \
444  } while (0)
445 
446 // The RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
447 // to implement the standard C macro idiom to make the macro safe in all
448 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
459 #define RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
460  do { \
461  static_assert( \
462  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
463  typename ::rclcpp::Logger>::value, \
464  "First argument to logging macros must be an rclcpp::Logger"); \
465 \
466  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
467  try { \
468  *time_point = clock.now().nanoseconds(); \
469  } catch (...) { \
470  RCUTILS_SAFE_FWRITE_TO_STDERR( \
471  "[rclcpp|logging.hpp] RCLCPP_DEBUG_STREAM_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
472  return RCUTILS_RET_ERROR; \
473  } \
474  return RCUTILS_RET_OK; \
475  }; \
476  \
477  std::stringstream ss; \
478  ss << stream_arg; \
479  RCUTILS_LOG_DEBUG_SKIPFIRST_THROTTLE_NAMED( \
480  get_time_point, \
481  duration, \
482  logger.get_name(), \
483  "%s", rclcpp::get_c_string(ss.str())); \
484  } while (0)
485 
486 #endif
487 
491 #if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_INFO)
493 // empty logging macros for severity INFO when being disabled at compile time
495 #define RCLCPP_INFO(...)
496 #define RCLCPP_INFO_ONCE(...)
498 #define RCLCPP_INFO_EXPRESSION(...)
500 #define RCLCPP_INFO_FUNCTION(...)
502 #define RCLCPP_INFO_SKIPFIRST(...)
504 #define RCLCPP_INFO_THROTTLE(...)
506 #define RCLCPP_INFO_SKIPFIRST_THROTTLE(...)
508 #define RCLCPP_INFO_STREAM(...)
510 #define RCLCPP_INFO_STREAM_ONCE(...)
512 #define RCLCPP_INFO_STREAM_EXPRESSION(...)
514 #define RCLCPP_INFO_STREAM_FUNCTION(...)
516 #define RCLCPP_INFO_STREAM_SKIPFIRST(...)
518 #define RCLCPP_INFO_STREAM_THROTTLE(...)
520 #define RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE(...)
522 
523 #else
524 // The RCLCPP_INFO macro is surrounded by do { .. } while (0)
525 // to implement the standard C macro idiom to make the macro safe in all
526 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
534 #define RCLCPP_INFO(logger, ...) \
535  do { \
536  static_assert( \
537  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
538  typename ::rclcpp::Logger>::value, \
539  "First argument to logging macros must be an rclcpp::Logger"); \
540  \
541  RCUTILS_LOG_INFO_NAMED( \
542  logger.get_name(), \
543  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
544  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
545  } while (0)
546 
547 // The RCLCPP_INFO_ONCE macro is surrounded by do { .. } while (0)
548 // to implement the standard C macro idiom to make the macro safe in all
549 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
558 #define RCLCPP_INFO_ONCE(logger, ...) \
559  do { \
560  static_assert( \
561  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
562  typename ::rclcpp::Logger>::value, \
563  "First argument to logging macros must be an rclcpp::Logger"); \
564  \
565  RCUTILS_LOG_INFO_ONCE_NAMED( \
566  logger.get_name(), \
567  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
568  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
569  } while (0)
570 
571 // The RCLCPP_INFO_EXPRESSION macro is surrounded by do { .. } while (0)
572 // to implement the standard C macro idiom to make the macro safe in all
573 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
583 #define RCLCPP_INFO_EXPRESSION(logger, expression, ...) \
584  do { \
585  static_assert( \
586  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
587  typename ::rclcpp::Logger>::value, \
588  "First argument to logging macros must be an rclcpp::Logger"); \
589  \
590  RCUTILS_LOG_INFO_EXPRESSION_NAMED( \
591  expression, \
592  logger.get_name(), \
593  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
594  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
595  } while (0)
596 
597 // The RCLCPP_INFO_FUNCTION macro is surrounded by do { .. } while (0)
598 // to implement the standard C macro idiom to make the macro safe in all
599 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
609 #define RCLCPP_INFO_FUNCTION(logger, function, ...) \
610  do { \
611  static_assert( \
612  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
613  typename ::rclcpp::Logger>::value, \
614  "First argument to logging macros must be an rclcpp::Logger"); \
615  \
616  RCUTILS_LOG_INFO_FUNCTION_NAMED( \
617  function, \
618  logger.get_name(), \
619  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
620  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
621  } while (0)
622 
623 // The RCLCPP_INFO_SKIPFIRST macro is surrounded by do { .. } while (0)
624 // to implement the standard C macro idiom to make the macro safe in all
625 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
634 #define RCLCPP_INFO_SKIPFIRST(logger, ...) \
635  do { \
636  static_assert( \
637  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
638  typename ::rclcpp::Logger>::value, \
639  "First argument to logging macros must be an rclcpp::Logger"); \
640  \
641  RCUTILS_LOG_INFO_SKIPFIRST_NAMED( \
642  logger.get_name(), \
643  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
644  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
645  } while (0)
646 
647 // The RCLCPP_INFO_THROTTLE macro is surrounded by do { .. } while (0)
648 // to implement the standard C macro idiom to make the macro safe in all
649 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
660 #define RCLCPP_INFO_THROTTLE(logger, clock, duration, ...) \
661  do { \
662  static_assert( \
663  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
664  typename ::rclcpp::Logger>::value, \
665  "First argument to logging macros must be an rclcpp::Logger"); \
666 \
667  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
668  try { \
669  *time_point = clock.now().nanoseconds(); \
670  } catch (...) { \
671  RCUTILS_SAFE_FWRITE_TO_STDERR( \
672  "[rclcpp|logging.hpp] RCLCPP_INFO_THROTTLE could not get current time stamp\n"); \
673  return RCUTILS_RET_ERROR; \
674  } \
675  return RCUTILS_RET_OK; \
676  }; \
677  \
678  RCUTILS_LOG_INFO_THROTTLE_NAMED( \
679  get_time_point, \
680  duration, \
681  logger.get_name(), \
682  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
683  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
684  } while (0)
685 
686 // The RCLCPP_INFO_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
687 // to implement the standard C macro idiom to make the macro safe in all
688 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
700 #define RCLCPP_INFO_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
701  do { \
702  static_assert( \
703  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
704  typename ::rclcpp::Logger>::value, \
705  "First argument to logging macros must be an rclcpp::Logger"); \
706 \
707  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
708  try { \
709  *time_point = clock.now().nanoseconds(); \
710  } catch (...) { \
711  RCUTILS_SAFE_FWRITE_TO_STDERR( \
712  "[rclcpp|logging.hpp] RCLCPP_INFO_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
713  return RCUTILS_RET_ERROR; \
714  } \
715  return RCUTILS_RET_OK; \
716  }; \
717  \
718  RCUTILS_LOG_INFO_SKIPFIRST_THROTTLE_NAMED( \
719  get_time_point, \
720  duration, \
721  logger.get_name(), \
722  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
723  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
724  } while (0)
725 
726 // The RCLCPP_INFO_STREAM macro is surrounded by do { .. } while (0)
727 // to implement the standard C macro idiom to make the macro safe in all
728 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
735 #define RCLCPP_INFO_STREAM(logger, stream_arg) \
736  do { \
737  static_assert( \
738  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
739  typename ::rclcpp::Logger>::value, \
740  "First argument to logging macros must be an rclcpp::Logger"); \
741  \
742  std::stringstream ss; \
743  ss << stream_arg; \
744  RCUTILS_LOG_INFO_NAMED( \
745  logger.get_name(), \
746  "%s", rclcpp::get_c_string(ss.str())); \
747  } while (0)
748 
749 // The RCLCPP_INFO_STREAM_ONCE macro is surrounded by do { .. } while (0)
750 // to implement the standard C macro idiom to make the macro safe in all
751 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
759 #define RCLCPP_INFO_STREAM_ONCE(logger, stream_arg) \
760  do { \
761  static_assert( \
762  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
763  typename ::rclcpp::Logger>::value, \
764  "First argument to logging macros must be an rclcpp::Logger"); \
765  \
766  std::stringstream ss; \
767  ss << stream_arg; \
768  RCUTILS_LOG_INFO_ONCE_NAMED( \
769  logger.get_name(), \
770  "%s", rclcpp::get_c_string(ss.str())); \
771  } while (0)
772 
773 // The RCLCPP_INFO_STREAM_EXPRESSION macro is surrounded by do { .. } while (0)
774 // to implement the standard C macro idiom to make the macro safe in all
775 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
784 #define RCLCPP_INFO_STREAM_EXPRESSION(logger, expression, stream_arg) \
785  do { \
786  static_assert( \
787  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
788  typename ::rclcpp::Logger>::value, \
789  "First argument to logging macros must be an rclcpp::Logger"); \
790  \
791  std::stringstream ss; \
792  ss << stream_arg; \
793  RCUTILS_LOG_INFO_EXPRESSION_NAMED( \
794  expression, \
795  logger.get_name(), \
796  "%s", rclcpp::get_c_string(ss.str())); \
797  } while (0)
798 
799 // The RCLCPP_INFO_STREAM_FUNCTION macro is surrounded by do { .. } while (0)
800 // to implement the standard C macro idiom to make the macro safe in all
801 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
810 #define RCLCPP_INFO_STREAM_FUNCTION(logger, function, stream_arg) \
811  do { \
812  static_assert( \
813  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
814  typename ::rclcpp::Logger>::value, \
815  "First argument to logging macros must be an rclcpp::Logger"); \
816  \
817  std::stringstream ss; \
818  ss << stream_arg; \
819  RCUTILS_LOG_INFO_FUNCTION_NAMED( \
820  function, \
821  logger.get_name(), \
822  "%s", rclcpp::get_c_string(ss.str())); \
823  } while (0)
824 
825 // The RCLCPP_INFO_STREAM_SKIPFIRST macro is surrounded by do { .. } while (0)
826 // to implement the standard C macro idiom to make the macro safe in all
827 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
835 #define RCLCPP_INFO_STREAM_SKIPFIRST(logger, stream_arg) \
836  do { \
837  static_assert( \
838  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
839  typename ::rclcpp::Logger>::value, \
840  "First argument to logging macros must be an rclcpp::Logger"); \
841  \
842  std::stringstream ss; \
843  ss << stream_arg; \
844  RCUTILS_LOG_INFO_SKIPFIRST_NAMED( \
845  logger.get_name(), \
846  "%s", rclcpp::get_c_string(ss.str())); \
847  } while (0)
848 
849 // The RCLCPP_INFO_STREAM_THROTTLE macro is surrounded by do { .. } while (0)
850 // to implement the standard C macro idiom to make the macro safe in all
851 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
861 #define RCLCPP_INFO_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
862  do { \
863  static_assert( \
864  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
865  typename ::rclcpp::Logger>::value, \
866  "First argument to logging macros must be an rclcpp::Logger"); \
867 \
868  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
869  try { \
870  *time_point = clock.now().nanoseconds(); \
871  } catch (...) { \
872  RCUTILS_SAFE_FWRITE_TO_STDERR( \
873  "[rclcpp|logging.hpp] RCLCPP_INFO_STREAM_THROTTLE could not get current time stamp\n"); \
874  return RCUTILS_RET_ERROR; \
875  } \
876  return RCUTILS_RET_OK; \
877  }; \
878  \
879  std::stringstream ss; \
880  ss << stream_arg; \
881  RCUTILS_LOG_INFO_THROTTLE_NAMED( \
882  get_time_point, \
883  duration, \
884  logger.get_name(), \
885  "%s", rclcpp::get_c_string(ss.str())); \
886  } while (0)
887 
888 // The RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
889 // to implement the standard C macro idiom to make the macro safe in all
890 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
901 #define RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
902  do { \
903  static_assert( \
904  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
905  typename ::rclcpp::Logger>::value, \
906  "First argument to logging macros must be an rclcpp::Logger"); \
907 \
908  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
909  try { \
910  *time_point = clock.now().nanoseconds(); \
911  } catch (...) { \
912  RCUTILS_SAFE_FWRITE_TO_STDERR( \
913  "[rclcpp|logging.hpp] RCLCPP_INFO_STREAM_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
914  return RCUTILS_RET_ERROR; \
915  } \
916  return RCUTILS_RET_OK; \
917  }; \
918  \
919  std::stringstream ss; \
920  ss << stream_arg; \
921  RCUTILS_LOG_INFO_SKIPFIRST_THROTTLE_NAMED( \
922  get_time_point, \
923  duration, \
924  logger.get_name(), \
925  "%s", rclcpp::get_c_string(ss.str())); \
926  } while (0)
927 
928 #endif
929 
933 #if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_WARN)
935 // empty logging macros for severity WARN when being disabled at compile time
937 #define RCLCPP_WARN(...)
938 #define RCLCPP_WARN_ONCE(...)
940 #define RCLCPP_WARN_EXPRESSION(...)
942 #define RCLCPP_WARN_FUNCTION(...)
944 #define RCLCPP_WARN_SKIPFIRST(...)
946 #define RCLCPP_WARN_THROTTLE(...)
948 #define RCLCPP_WARN_SKIPFIRST_THROTTLE(...)
950 #define RCLCPP_WARN_STREAM(...)
952 #define RCLCPP_WARN_STREAM_ONCE(...)
954 #define RCLCPP_WARN_STREAM_EXPRESSION(...)
956 #define RCLCPP_WARN_STREAM_FUNCTION(...)
958 #define RCLCPP_WARN_STREAM_SKIPFIRST(...)
960 #define RCLCPP_WARN_STREAM_THROTTLE(...)
962 #define RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE(...)
964 
965 #else
966 // The RCLCPP_WARN macro is surrounded by do { .. } while (0)
967 // to implement the standard C macro idiom to make the macro safe in all
968 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
976 #define RCLCPP_WARN(logger, ...) \
977  do { \
978  static_assert( \
979  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
980  typename ::rclcpp::Logger>::value, \
981  "First argument to logging macros must be an rclcpp::Logger"); \
982  \
983  RCUTILS_LOG_WARN_NAMED( \
984  logger.get_name(), \
985  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
986  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
987  } while (0)
988 
989 // The RCLCPP_WARN_ONCE macro is surrounded by do { .. } while (0)
990 // to implement the standard C macro idiom to make the macro safe in all
991 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1000 #define RCLCPP_WARN_ONCE(logger, ...) \
1001  do { \
1002  static_assert( \
1003  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1004  typename ::rclcpp::Logger>::value, \
1005  "First argument to logging macros must be an rclcpp::Logger"); \
1006  \
1007  RCUTILS_LOG_WARN_ONCE_NAMED( \
1008  logger.get_name(), \
1009  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1010  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1011  } while (0)
1012 
1013 // The RCLCPP_WARN_EXPRESSION macro is surrounded by do { .. } while (0)
1014 // to implement the standard C macro idiom to make the macro safe in all
1015 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1025 #define RCLCPP_WARN_EXPRESSION(logger, expression, ...) \
1026  do { \
1027  static_assert( \
1028  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1029  typename ::rclcpp::Logger>::value, \
1030  "First argument to logging macros must be an rclcpp::Logger"); \
1031  \
1032  RCUTILS_LOG_WARN_EXPRESSION_NAMED( \
1033  expression, \
1034  logger.get_name(), \
1035  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1036  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1037  } while (0)
1038 
1039 // The RCLCPP_WARN_FUNCTION macro is surrounded by do { .. } while (0)
1040 // to implement the standard C macro idiom to make the macro safe in all
1041 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1051 #define RCLCPP_WARN_FUNCTION(logger, function, ...) \
1052  do { \
1053  static_assert( \
1054  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1055  typename ::rclcpp::Logger>::value, \
1056  "First argument to logging macros must be an rclcpp::Logger"); \
1057  \
1058  RCUTILS_LOG_WARN_FUNCTION_NAMED( \
1059  function, \
1060  logger.get_name(), \
1061  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1062  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1063  } while (0)
1064 
1065 // The RCLCPP_WARN_SKIPFIRST macro is surrounded by do { .. } while (0)
1066 // to implement the standard C macro idiom to make the macro safe in all
1067 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1076 #define RCLCPP_WARN_SKIPFIRST(logger, ...) \
1077  do { \
1078  static_assert( \
1079  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1080  typename ::rclcpp::Logger>::value, \
1081  "First argument to logging macros must be an rclcpp::Logger"); \
1082  \
1083  RCUTILS_LOG_WARN_SKIPFIRST_NAMED( \
1084  logger.get_name(), \
1085  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1086  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1087  } while (0)
1088 
1089 // The RCLCPP_WARN_THROTTLE macro is surrounded by do { .. } while (0)
1090 // to implement the standard C macro idiom to make the macro safe in all
1091 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1102 #define RCLCPP_WARN_THROTTLE(logger, clock, duration, ...) \
1103  do { \
1104  static_assert( \
1105  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1106  typename ::rclcpp::Logger>::value, \
1107  "First argument to logging macros must be an rclcpp::Logger"); \
1108 \
1109  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1110  try { \
1111  *time_point = clock.now().nanoseconds(); \
1112  } catch (...) { \
1113  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1114  "[rclcpp|logging.hpp] RCLCPP_WARN_THROTTLE could not get current time stamp\n"); \
1115  return RCUTILS_RET_ERROR; \
1116  } \
1117  return RCUTILS_RET_OK; \
1118  }; \
1119  \
1120  RCUTILS_LOG_WARN_THROTTLE_NAMED( \
1121  get_time_point, \
1122  duration, \
1123  logger.get_name(), \
1124  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1125  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1126  } while (0)
1127 
1128 // The RCLCPP_WARN_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
1129 // to implement the standard C macro idiom to make the macro safe in all
1130 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1142 #define RCLCPP_WARN_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
1143  do { \
1144  static_assert( \
1145  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1146  typename ::rclcpp::Logger>::value, \
1147  "First argument to logging macros must be an rclcpp::Logger"); \
1148 \
1149  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1150  try { \
1151  *time_point = clock.now().nanoseconds(); \
1152  } catch (...) { \
1153  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1154  "[rclcpp|logging.hpp] RCLCPP_WARN_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
1155  return RCUTILS_RET_ERROR; \
1156  } \
1157  return RCUTILS_RET_OK; \
1158  }; \
1159  \
1160  RCUTILS_LOG_WARN_SKIPFIRST_THROTTLE_NAMED( \
1161  get_time_point, \
1162  duration, \
1163  logger.get_name(), \
1164  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1165  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1166  } while (0)
1167 
1168 // The RCLCPP_WARN_STREAM macro is surrounded by do { .. } while (0)
1169 // to implement the standard C macro idiom to make the macro safe in all
1170 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1177 #define RCLCPP_WARN_STREAM(logger, stream_arg) \
1178  do { \
1179  static_assert( \
1180  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1181  typename ::rclcpp::Logger>::value, \
1182  "First argument to logging macros must be an rclcpp::Logger"); \
1183  \
1184  std::stringstream ss; \
1185  ss << stream_arg; \
1186  RCUTILS_LOG_WARN_NAMED( \
1187  logger.get_name(), \
1188  "%s", rclcpp::get_c_string(ss.str())); \
1189  } while (0)
1190 
1191 // The RCLCPP_WARN_STREAM_ONCE macro is surrounded by do { .. } while (0)
1192 // to implement the standard C macro idiom to make the macro safe in all
1193 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1201 #define RCLCPP_WARN_STREAM_ONCE(logger, stream_arg) \
1202  do { \
1203  static_assert( \
1204  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1205  typename ::rclcpp::Logger>::value, \
1206  "First argument to logging macros must be an rclcpp::Logger"); \
1207  \
1208  std::stringstream ss; \
1209  ss << stream_arg; \
1210  RCUTILS_LOG_WARN_ONCE_NAMED( \
1211  logger.get_name(), \
1212  "%s", rclcpp::get_c_string(ss.str())); \
1213  } while (0)
1214 
1215 // The RCLCPP_WARN_STREAM_EXPRESSION macro is surrounded by do { .. } while (0)
1216 // to implement the standard C macro idiom to make the macro safe in all
1217 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1226 #define RCLCPP_WARN_STREAM_EXPRESSION(logger, expression, stream_arg) \
1227  do { \
1228  static_assert( \
1229  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1230  typename ::rclcpp::Logger>::value, \
1231  "First argument to logging macros must be an rclcpp::Logger"); \
1232  \
1233  std::stringstream ss; \
1234  ss << stream_arg; \
1235  RCUTILS_LOG_WARN_EXPRESSION_NAMED( \
1236  expression, \
1237  logger.get_name(), \
1238  "%s", rclcpp::get_c_string(ss.str())); \
1239  } while (0)
1240 
1241 // The RCLCPP_WARN_STREAM_FUNCTION macro is surrounded by do { .. } while (0)
1242 // to implement the standard C macro idiom to make the macro safe in all
1243 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1252 #define RCLCPP_WARN_STREAM_FUNCTION(logger, function, stream_arg) \
1253  do { \
1254  static_assert( \
1255  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1256  typename ::rclcpp::Logger>::value, \
1257  "First argument to logging macros must be an rclcpp::Logger"); \
1258  \
1259  std::stringstream ss; \
1260  ss << stream_arg; \
1261  RCUTILS_LOG_WARN_FUNCTION_NAMED( \
1262  function, \
1263  logger.get_name(), \
1264  "%s", rclcpp::get_c_string(ss.str())); \
1265  } while (0)
1266 
1267 // The RCLCPP_WARN_STREAM_SKIPFIRST macro is surrounded by do { .. } while (0)
1268 // to implement the standard C macro idiom to make the macro safe in all
1269 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1277 #define RCLCPP_WARN_STREAM_SKIPFIRST(logger, stream_arg) \
1278  do { \
1279  static_assert( \
1280  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1281  typename ::rclcpp::Logger>::value, \
1282  "First argument to logging macros must be an rclcpp::Logger"); \
1283  \
1284  std::stringstream ss; \
1285  ss << stream_arg; \
1286  RCUTILS_LOG_WARN_SKIPFIRST_NAMED( \
1287  logger.get_name(), \
1288  "%s", rclcpp::get_c_string(ss.str())); \
1289  } while (0)
1290 
1291 // The RCLCPP_WARN_STREAM_THROTTLE macro is surrounded by do { .. } while (0)
1292 // to implement the standard C macro idiom to make the macro safe in all
1293 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1303 #define RCLCPP_WARN_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
1304  do { \
1305  static_assert( \
1306  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1307  typename ::rclcpp::Logger>::value, \
1308  "First argument to logging macros must be an rclcpp::Logger"); \
1309 \
1310  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1311  try { \
1312  *time_point = clock.now().nanoseconds(); \
1313  } catch (...) { \
1314  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1315  "[rclcpp|logging.hpp] RCLCPP_WARN_STREAM_THROTTLE could not get current time stamp\n"); \
1316  return RCUTILS_RET_ERROR; \
1317  } \
1318  return RCUTILS_RET_OK; \
1319  }; \
1320  \
1321  std::stringstream ss; \
1322  ss << stream_arg; \
1323  RCUTILS_LOG_WARN_THROTTLE_NAMED( \
1324  get_time_point, \
1325  duration, \
1326  logger.get_name(), \
1327  "%s", rclcpp::get_c_string(ss.str())); \
1328  } while (0)
1329 
1330 // The RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
1331 // to implement the standard C macro idiom to make the macro safe in all
1332 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1343 #define RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
1344  do { \
1345  static_assert( \
1346  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1347  typename ::rclcpp::Logger>::value, \
1348  "First argument to logging macros must be an rclcpp::Logger"); \
1349 \
1350  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1351  try { \
1352  *time_point = clock.now().nanoseconds(); \
1353  } catch (...) { \
1354  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1355  "[rclcpp|logging.hpp] RCLCPP_WARN_STREAM_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
1356  return RCUTILS_RET_ERROR; \
1357  } \
1358  return RCUTILS_RET_OK; \
1359  }; \
1360  \
1361  std::stringstream ss; \
1362  ss << stream_arg; \
1363  RCUTILS_LOG_WARN_SKIPFIRST_THROTTLE_NAMED( \
1364  get_time_point, \
1365  duration, \
1366  logger.get_name(), \
1367  "%s", rclcpp::get_c_string(ss.str())); \
1368  } while (0)
1369 
1370 #endif
1371 
1375 #if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_ERROR)
1377 // empty logging macros for severity ERROR when being disabled at compile time
1379 #define RCLCPP_ERROR(...)
1380 #define RCLCPP_ERROR_ONCE(...)
1382 #define RCLCPP_ERROR_EXPRESSION(...)
1384 #define RCLCPP_ERROR_FUNCTION(...)
1386 #define RCLCPP_ERROR_SKIPFIRST(...)
1388 #define RCLCPP_ERROR_THROTTLE(...)
1390 #define RCLCPP_ERROR_SKIPFIRST_THROTTLE(...)
1392 #define RCLCPP_ERROR_STREAM(...)
1394 #define RCLCPP_ERROR_STREAM_ONCE(...)
1396 #define RCLCPP_ERROR_STREAM_EXPRESSION(...)
1398 #define RCLCPP_ERROR_STREAM_FUNCTION(...)
1400 #define RCLCPP_ERROR_STREAM_SKIPFIRST(...)
1402 #define RCLCPP_ERROR_STREAM_THROTTLE(...)
1404 #define RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE(...)
1406 
1407 #else
1408 // The RCLCPP_ERROR macro is surrounded by do { .. } while (0)
1409 // to implement the standard C macro idiom to make the macro safe in all
1410 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1418 #define RCLCPP_ERROR(logger, ...) \
1419  do { \
1420  static_assert( \
1421  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1422  typename ::rclcpp::Logger>::value, \
1423  "First argument to logging macros must be an rclcpp::Logger"); \
1424  \
1425  RCUTILS_LOG_ERROR_NAMED( \
1426  logger.get_name(), \
1427  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1428  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1429  } while (0)
1430 
1431 // The RCLCPP_ERROR_ONCE macro is surrounded by do { .. } while (0)
1432 // to implement the standard C macro idiom to make the macro safe in all
1433 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1442 #define RCLCPP_ERROR_ONCE(logger, ...) \
1443  do { \
1444  static_assert( \
1445  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1446  typename ::rclcpp::Logger>::value, \
1447  "First argument to logging macros must be an rclcpp::Logger"); \
1448  \
1449  RCUTILS_LOG_ERROR_ONCE_NAMED( \
1450  logger.get_name(), \
1451  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1452  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1453  } while (0)
1454 
1455 // The RCLCPP_ERROR_EXPRESSION macro is surrounded by do { .. } while (0)
1456 // to implement the standard C macro idiom to make the macro safe in all
1457 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1467 #define RCLCPP_ERROR_EXPRESSION(logger, expression, ...) \
1468  do { \
1469  static_assert( \
1470  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1471  typename ::rclcpp::Logger>::value, \
1472  "First argument to logging macros must be an rclcpp::Logger"); \
1473  \
1474  RCUTILS_LOG_ERROR_EXPRESSION_NAMED( \
1475  expression, \
1476  logger.get_name(), \
1477  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1478  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1479  } while (0)
1480 
1481 // The RCLCPP_ERROR_FUNCTION macro is surrounded by do { .. } while (0)
1482 // to implement the standard C macro idiom to make the macro safe in all
1483 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1493 #define RCLCPP_ERROR_FUNCTION(logger, function, ...) \
1494  do { \
1495  static_assert( \
1496  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1497  typename ::rclcpp::Logger>::value, \
1498  "First argument to logging macros must be an rclcpp::Logger"); \
1499  \
1500  RCUTILS_LOG_ERROR_FUNCTION_NAMED( \
1501  function, \
1502  logger.get_name(), \
1503  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1504  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1505  } while (0)
1506 
1507 // The RCLCPP_ERROR_SKIPFIRST macro is surrounded by do { .. } while (0)
1508 // to implement the standard C macro idiom to make the macro safe in all
1509 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1518 #define RCLCPP_ERROR_SKIPFIRST(logger, ...) \
1519  do { \
1520  static_assert( \
1521  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1522  typename ::rclcpp::Logger>::value, \
1523  "First argument to logging macros must be an rclcpp::Logger"); \
1524  \
1525  RCUTILS_LOG_ERROR_SKIPFIRST_NAMED( \
1526  logger.get_name(), \
1527  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1528  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1529  } while (0)
1530 
1531 // The RCLCPP_ERROR_THROTTLE macro is surrounded by do { .. } while (0)
1532 // to implement the standard C macro idiom to make the macro safe in all
1533 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1544 #define RCLCPP_ERROR_THROTTLE(logger, clock, duration, ...) \
1545  do { \
1546  static_assert( \
1547  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1548  typename ::rclcpp::Logger>::value, \
1549  "First argument to logging macros must be an rclcpp::Logger"); \
1550 \
1551  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1552  try { \
1553  *time_point = clock.now().nanoseconds(); \
1554  } catch (...) { \
1555  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1556  "[rclcpp|logging.hpp] RCLCPP_ERROR_THROTTLE could not get current time stamp\n"); \
1557  return RCUTILS_RET_ERROR; \
1558  } \
1559  return RCUTILS_RET_OK; \
1560  }; \
1561  \
1562  RCUTILS_LOG_ERROR_THROTTLE_NAMED( \
1563  get_time_point, \
1564  duration, \
1565  logger.get_name(), \
1566  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1567  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1568  } while (0)
1569 
1570 // The RCLCPP_ERROR_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
1571 // to implement the standard C macro idiom to make the macro safe in all
1572 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1584 #define RCLCPP_ERROR_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
1585  do { \
1586  static_assert( \
1587  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1588  typename ::rclcpp::Logger>::value, \
1589  "First argument to logging macros must be an rclcpp::Logger"); \
1590 \
1591  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1592  try { \
1593  *time_point = clock.now().nanoseconds(); \
1594  } catch (...) { \
1595  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1596  "[rclcpp|logging.hpp] RCLCPP_ERROR_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
1597  return RCUTILS_RET_ERROR; \
1598  } \
1599  return RCUTILS_RET_OK; \
1600  }; \
1601  \
1602  RCUTILS_LOG_ERROR_SKIPFIRST_THROTTLE_NAMED( \
1603  get_time_point, \
1604  duration, \
1605  logger.get_name(), \
1606  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1607  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1608  } while (0)
1609 
1610 // The RCLCPP_ERROR_STREAM macro is surrounded by do { .. } while (0)
1611 // to implement the standard C macro idiom to make the macro safe in all
1612 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1619 #define RCLCPP_ERROR_STREAM(logger, stream_arg) \
1620  do { \
1621  static_assert( \
1622  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1623  typename ::rclcpp::Logger>::value, \
1624  "First argument to logging macros must be an rclcpp::Logger"); \
1625  \
1626  std::stringstream ss; \
1627  ss << stream_arg; \
1628  RCUTILS_LOG_ERROR_NAMED( \
1629  logger.get_name(), \
1630  "%s", rclcpp::get_c_string(ss.str())); \
1631  } while (0)
1632 
1633 // The RCLCPP_ERROR_STREAM_ONCE macro is surrounded by do { .. } while (0)
1634 // to implement the standard C macro idiom to make the macro safe in all
1635 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1643 #define RCLCPP_ERROR_STREAM_ONCE(logger, stream_arg) \
1644  do { \
1645  static_assert( \
1646  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1647  typename ::rclcpp::Logger>::value, \
1648  "First argument to logging macros must be an rclcpp::Logger"); \
1649  \
1650  std::stringstream ss; \
1651  ss << stream_arg; \
1652  RCUTILS_LOG_ERROR_ONCE_NAMED( \
1653  logger.get_name(), \
1654  "%s", rclcpp::get_c_string(ss.str())); \
1655  } while (0)
1656 
1657 // The RCLCPP_ERROR_STREAM_EXPRESSION macro is surrounded by do { .. } while (0)
1658 // to implement the standard C macro idiom to make the macro safe in all
1659 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1668 #define RCLCPP_ERROR_STREAM_EXPRESSION(logger, expression, stream_arg) \
1669  do { \
1670  static_assert( \
1671  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1672  typename ::rclcpp::Logger>::value, \
1673  "First argument to logging macros must be an rclcpp::Logger"); \
1674  \
1675  std::stringstream ss; \
1676  ss << stream_arg; \
1677  RCUTILS_LOG_ERROR_EXPRESSION_NAMED( \
1678  expression, \
1679  logger.get_name(), \
1680  "%s", rclcpp::get_c_string(ss.str())); \
1681  } while (0)
1682 
1683 // The RCLCPP_ERROR_STREAM_FUNCTION macro is surrounded by do { .. } while (0)
1684 // to implement the standard C macro idiom to make the macro safe in all
1685 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1694 #define RCLCPP_ERROR_STREAM_FUNCTION(logger, function, stream_arg) \
1695  do { \
1696  static_assert( \
1697  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1698  typename ::rclcpp::Logger>::value, \
1699  "First argument to logging macros must be an rclcpp::Logger"); \
1700  \
1701  std::stringstream ss; \
1702  ss << stream_arg; \
1703  RCUTILS_LOG_ERROR_FUNCTION_NAMED( \
1704  function, \
1705  logger.get_name(), \
1706  "%s", rclcpp::get_c_string(ss.str())); \
1707  } while (0)
1708 
1709 // The RCLCPP_ERROR_STREAM_SKIPFIRST macro is surrounded by do { .. } while (0)
1710 // to implement the standard C macro idiom to make the macro safe in all
1711 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1719 #define RCLCPP_ERROR_STREAM_SKIPFIRST(logger, stream_arg) \
1720  do { \
1721  static_assert( \
1722  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1723  typename ::rclcpp::Logger>::value, \
1724  "First argument to logging macros must be an rclcpp::Logger"); \
1725  \
1726  std::stringstream ss; \
1727  ss << stream_arg; \
1728  RCUTILS_LOG_ERROR_SKIPFIRST_NAMED( \
1729  logger.get_name(), \
1730  "%s", rclcpp::get_c_string(ss.str())); \
1731  } while (0)
1732 
1733 // The RCLCPP_ERROR_STREAM_THROTTLE macro is surrounded by do { .. } while (0)
1734 // to implement the standard C macro idiom to make the macro safe in all
1735 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1745 #define RCLCPP_ERROR_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
1746  do { \
1747  static_assert( \
1748  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1749  typename ::rclcpp::Logger>::value, \
1750  "First argument to logging macros must be an rclcpp::Logger"); \
1751 \
1752  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1753  try { \
1754  *time_point = clock.now().nanoseconds(); \
1755  } catch (...) { \
1756  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1757  "[rclcpp|logging.hpp] RCLCPP_ERROR_STREAM_THROTTLE could not get current time stamp\n"); \
1758  return RCUTILS_RET_ERROR; \
1759  } \
1760  return RCUTILS_RET_OK; \
1761  }; \
1762  \
1763  std::stringstream ss; \
1764  ss << stream_arg; \
1765  RCUTILS_LOG_ERROR_THROTTLE_NAMED( \
1766  get_time_point, \
1767  duration, \
1768  logger.get_name(), \
1769  "%s", rclcpp::get_c_string(ss.str())); \
1770  } while (0)
1771 
1772 // The RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
1773 // to implement the standard C macro idiom to make the macro safe in all
1774 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1785 #define RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
1786  do { \
1787  static_assert( \
1788  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1789  typename ::rclcpp::Logger>::value, \
1790  "First argument to logging macros must be an rclcpp::Logger"); \
1791 \
1792  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1793  try { \
1794  *time_point = clock.now().nanoseconds(); \
1795  } catch (...) { \
1796  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1797  "[rclcpp|logging.hpp] RCLCPP_ERROR_STREAM_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
1798  return RCUTILS_RET_ERROR; \
1799  } \
1800  return RCUTILS_RET_OK; \
1801  }; \
1802  \
1803  std::stringstream ss; \
1804  ss << stream_arg; \
1805  RCUTILS_LOG_ERROR_SKIPFIRST_THROTTLE_NAMED( \
1806  get_time_point, \
1807  duration, \
1808  logger.get_name(), \
1809  "%s", rclcpp::get_c_string(ss.str())); \
1810  } while (0)
1811 
1812 #endif
1813 
1817 #if (RCLCPP_LOG_MIN_SEVERITY > RCLCPP_LOG_MIN_SEVERITY_FATAL)
1819 // empty logging macros for severity FATAL when being disabled at compile time
1821 #define RCLCPP_FATAL(...)
1822 #define RCLCPP_FATAL_ONCE(...)
1824 #define RCLCPP_FATAL_EXPRESSION(...)
1826 #define RCLCPP_FATAL_FUNCTION(...)
1828 #define RCLCPP_FATAL_SKIPFIRST(...)
1830 #define RCLCPP_FATAL_THROTTLE(...)
1832 #define RCLCPP_FATAL_SKIPFIRST_THROTTLE(...)
1834 #define RCLCPP_FATAL_STREAM(...)
1836 #define RCLCPP_FATAL_STREAM_ONCE(...)
1838 #define RCLCPP_FATAL_STREAM_EXPRESSION(...)
1840 #define RCLCPP_FATAL_STREAM_FUNCTION(...)
1842 #define RCLCPP_FATAL_STREAM_SKIPFIRST(...)
1844 #define RCLCPP_FATAL_STREAM_THROTTLE(...)
1846 #define RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE(...)
1848 
1849 #else
1850 // The RCLCPP_FATAL macro is surrounded by do { .. } while (0)
1851 // to implement the standard C macro idiom to make the macro safe in all
1852 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1860 #define RCLCPP_FATAL(logger, ...) \
1861  do { \
1862  static_assert( \
1863  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1864  typename ::rclcpp::Logger>::value, \
1865  "First argument to logging macros must be an rclcpp::Logger"); \
1866  \
1867  RCUTILS_LOG_FATAL_NAMED( \
1868  logger.get_name(), \
1869  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1870  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1871  } while (0)
1872 
1873 // The RCLCPP_FATAL_ONCE macro is surrounded by do { .. } while (0)
1874 // to implement the standard C macro idiom to make the macro safe in all
1875 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1884 #define RCLCPP_FATAL_ONCE(logger, ...) \
1885  do { \
1886  static_assert( \
1887  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1888  typename ::rclcpp::Logger>::value, \
1889  "First argument to logging macros must be an rclcpp::Logger"); \
1890  \
1891  RCUTILS_LOG_FATAL_ONCE_NAMED( \
1892  logger.get_name(), \
1893  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1894  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1895  } while (0)
1896 
1897 // The RCLCPP_FATAL_EXPRESSION macro is surrounded by do { .. } while (0)
1898 // to implement the standard C macro idiom to make the macro safe in all
1899 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1909 #define RCLCPP_FATAL_EXPRESSION(logger, expression, ...) \
1910  do { \
1911  static_assert( \
1912  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1913  typename ::rclcpp::Logger>::value, \
1914  "First argument to logging macros must be an rclcpp::Logger"); \
1915  \
1916  RCUTILS_LOG_FATAL_EXPRESSION_NAMED( \
1917  expression, \
1918  logger.get_name(), \
1919  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1920  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1921  } while (0)
1922 
1923 // The RCLCPP_FATAL_FUNCTION macro is surrounded by do { .. } while (0)
1924 // to implement the standard C macro idiom to make the macro safe in all
1925 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1935 #define RCLCPP_FATAL_FUNCTION(logger, function, ...) \
1936  do { \
1937  static_assert( \
1938  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1939  typename ::rclcpp::Logger>::value, \
1940  "First argument to logging macros must be an rclcpp::Logger"); \
1941  \
1942  RCUTILS_LOG_FATAL_FUNCTION_NAMED( \
1943  function, \
1944  logger.get_name(), \
1945  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1946  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1947  } while (0)
1948 
1949 // The RCLCPP_FATAL_SKIPFIRST macro is surrounded by do { .. } while (0)
1950 // to implement the standard C macro idiom to make the macro safe in all
1951 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1960 #define RCLCPP_FATAL_SKIPFIRST(logger, ...) \
1961  do { \
1962  static_assert( \
1963  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1964  typename ::rclcpp::Logger>::value, \
1965  "First argument to logging macros must be an rclcpp::Logger"); \
1966  \
1967  RCUTILS_LOG_FATAL_SKIPFIRST_NAMED( \
1968  logger.get_name(), \
1969  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
1970  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
1971  } while (0)
1972 
1973 // The RCLCPP_FATAL_THROTTLE macro is surrounded by do { .. } while (0)
1974 // to implement the standard C macro idiom to make the macro safe in all
1975 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
1986 #define RCLCPP_FATAL_THROTTLE(logger, clock, duration, ...) \
1987  do { \
1988  static_assert( \
1989  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
1990  typename ::rclcpp::Logger>::value, \
1991  "First argument to logging macros must be an rclcpp::Logger"); \
1992 \
1993  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
1994  try { \
1995  *time_point = clock.now().nanoseconds(); \
1996  } catch (...) { \
1997  RCUTILS_SAFE_FWRITE_TO_STDERR( \
1998  "[rclcpp|logging.hpp] RCLCPP_FATAL_THROTTLE could not get current time stamp\n"); \
1999  return RCUTILS_RET_ERROR; \
2000  } \
2001  return RCUTILS_RET_OK; \
2002  }; \
2003  \
2004  RCUTILS_LOG_FATAL_THROTTLE_NAMED( \
2005  get_time_point, \
2006  duration, \
2007  logger.get_name(), \
2008  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
2009  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
2010  } while (0)
2011 
2012 // The RCLCPP_FATAL_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
2013 // to implement the standard C macro idiom to make the macro safe in all
2014 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2026 #define RCLCPP_FATAL_SKIPFIRST_THROTTLE(logger, clock, duration, ...) \
2027  do { \
2028  static_assert( \
2029  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2030  typename ::rclcpp::Logger>::value, \
2031  "First argument to logging macros must be an rclcpp::Logger"); \
2032 \
2033  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
2034  try { \
2035  *time_point = clock.now().nanoseconds(); \
2036  } catch (...) { \
2037  RCUTILS_SAFE_FWRITE_TO_STDERR( \
2038  "[rclcpp|logging.hpp] RCLCPP_FATAL_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
2039  return RCUTILS_RET_ERROR; \
2040  } \
2041  return RCUTILS_RET_OK; \
2042  }; \
2043  \
2044  RCUTILS_LOG_FATAL_SKIPFIRST_THROTTLE_NAMED( \
2045  get_time_point, \
2046  duration, \
2047  logger.get_name(), \
2048  rclcpp::get_c_string(RCLCPP_FIRST_ARG(__VA_ARGS__, "")), \
2049  RCLCPP_ALL_BUT_FIRST_ARGS(__VA_ARGS__,"")); \
2050  } while (0)
2051 
2052 // The RCLCPP_FATAL_STREAM macro is surrounded by do { .. } while (0)
2053 // to implement the standard C macro idiom to make the macro safe in all
2054 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2061 #define RCLCPP_FATAL_STREAM(logger, stream_arg) \
2062  do { \
2063  static_assert( \
2064  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2065  typename ::rclcpp::Logger>::value, \
2066  "First argument to logging macros must be an rclcpp::Logger"); \
2067  \
2068  std::stringstream ss; \
2069  ss << stream_arg; \
2070  RCUTILS_LOG_FATAL_NAMED( \
2071  logger.get_name(), \
2072  "%s", rclcpp::get_c_string(ss.str())); \
2073  } while (0)
2074 
2075 // The RCLCPP_FATAL_STREAM_ONCE macro is surrounded by do { .. } while (0)
2076 // to implement the standard C macro idiom to make the macro safe in all
2077 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2085 #define RCLCPP_FATAL_STREAM_ONCE(logger, stream_arg) \
2086  do { \
2087  static_assert( \
2088  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2089  typename ::rclcpp::Logger>::value, \
2090  "First argument to logging macros must be an rclcpp::Logger"); \
2091  \
2092  std::stringstream ss; \
2093  ss << stream_arg; \
2094  RCUTILS_LOG_FATAL_ONCE_NAMED( \
2095  logger.get_name(), \
2096  "%s", rclcpp::get_c_string(ss.str())); \
2097  } while (0)
2098 
2099 // The RCLCPP_FATAL_STREAM_EXPRESSION macro is surrounded by do { .. } while (0)
2100 // to implement the standard C macro idiom to make the macro safe in all
2101 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2110 #define RCLCPP_FATAL_STREAM_EXPRESSION(logger, expression, stream_arg) \
2111  do { \
2112  static_assert( \
2113  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2114  typename ::rclcpp::Logger>::value, \
2115  "First argument to logging macros must be an rclcpp::Logger"); \
2116  \
2117  std::stringstream ss; \
2118  ss << stream_arg; \
2119  RCUTILS_LOG_FATAL_EXPRESSION_NAMED( \
2120  expression, \
2121  logger.get_name(), \
2122  "%s", rclcpp::get_c_string(ss.str())); \
2123  } while (0)
2124 
2125 // The RCLCPP_FATAL_STREAM_FUNCTION macro is surrounded by do { .. } while (0)
2126 // to implement the standard C macro idiom to make the macro safe in all
2127 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2136 #define RCLCPP_FATAL_STREAM_FUNCTION(logger, function, stream_arg) \
2137  do { \
2138  static_assert( \
2139  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2140  typename ::rclcpp::Logger>::value, \
2141  "First argument to logging macros must be an rclcpp::Logger"); \
2142  \
2143  std::stringstream ss; \
2144  ss << stream_arg; \
2145  RCUTILS_LOG_FATAL_FUNCTION_NAMED( \
2146  function, \
2147  logger.get_name(), \
2148  "%s", rclcpp::get_c_string(ss.str())); \
2149  } while (0)
2150 
2151 // The RCLCPP_FATAL_STREAM_SKIPFIRST macro is surrounded by do { .. } while (0)
2152 // to implement the standard C macro idiom to make the macro safe in all
2153 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2161 #define RCLCPP_FATAL_STREAM_SKIPFIRST(logger, stream_arg) \
2162  do { \
2163  static_assert( \
2164  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2165  typename ::rclcpp::Logger>::value, \
2166  "First argument to logging macros must be an rclcpp::Logger"); \
2167  \
2168  std::stringstream ss; \
2169  ss << stream_arg; \
2170  RCUTILS_LOG_FATAL_SKIPFIRST_NAMED( \
2171  logger.get_name(), \
2172  "%s", rclcpp::get_c_string(ss.str())); \
2173  } while (0)
2174 
2175 // The RCLCPP_FATAL_STREAM_THROTTLE macro is surrounded by do { .. } while (0)
2176 // to implement the standard C macro idiom to make the macro safe in all
2177 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2187 #define RCLCPP_FATAL_STREAM_THROTTLE(logger, clock, duration, stream_arg) \
2188  do { \
2189  static_assert( \
2190  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2191  typename ::rclcpp::Logger>::value, \
2192  "First argument to logging macros must be an rclcpp::Logger"); \
2193 \
2194  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
2195  try { \
2196  *time_point = clock.now().nanoseconds(); \
2197  } catch (...) { \
2198  RCUTILS_SAFE_FWRITE_TO_STDERR( \
2199  "[rclcpp|logging.hpp] RCLCPP_FATAL_STREAM_THROTTLE could not get current time stamp\n"); \
2200  return RCUTILS_RET_ERROR; \
2201  } \
2202  return RCUTILS_RET_OK; \
2203  }; \
2204  \
2205  std::stringstream ss; \
2206  ss << stream_arg; \
2207  RCUTILS_LOG_FATAL_THROTTLE_NAMED( \
2208  get_time_point, \
2209  duration, \
2210  logger.get_name(), \
2211  "%s", rclcpp::get_c_string(ss.str())); \
2212  } while (0)
2213 
2214 // The RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE macro is surrounded by do { .. } while (0)
2215 // to implement the standard C macro idiom to make the macro safe in all
2216 // contexts; see http://c-faq.com/cpp/multistmt.html for more information.
2227 #define RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE(logger, clock, duration, stream_arg) \
2228  do { \
2229  static_assert( \
2230  ::std::is_same<typename std::remove_cv<typename std::remove_reference<decltype(logger)>::type>::type, \
2231  typename ::rclcpp::Logger>::value, \
2232  "First argument to logging macros must be an rclcpp::Logger"); \
2233 \
2234  auto get_time_point = [&clock](rcutils_time_point_value_t * time_point) -> rcutils_ret_t { \
2235  try { \
2236  *time_point = clock.now().nanoseconds(); \
2237  } catch (...) { \
2238  RCUTILS_SAFE_FWRITE_TO_STDERR( \
2239  "[rclcpp|logging.hpp] RCLCPP_FATAL_STREAM_SKIPFIRST_THROTTLE could not get current time stamp\n"); \
2240  return RCUTILS_RET_ERROR; \
2241  } \
2242  return RCUTILS_RET_OK; \
2243  }; \
2244  \
2245  std::stringstream ss; \
2246  ss << stream_arg; \
2247  RCUTILS_LOG_FATAL_SKIPFIRST_THROTTLE_NAMED( \
2248  get_time_point, \
2249  duration, \
2250  logger.get_name(), \
2251  "%s", rclcpp::get_c_string(ss.str())); \
2252  } while (0)
2253 
2254 #endif
2255 
2257 
2258 #endif // RCLCPP__LOGGING_HPP_