Printf.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines Parallel::printf for writing to stdout
6 
7 #pragma once
8 
9 #include <charm++.h>
10 #include <iomanip>
11 #include <sstream>
12 #include <string>
13 #include <type_traits>
14 
16 #include "Utilities/Requires.hpp"
17 #include "Utilities/TypeTraits.hpp"
18 
19 namespace Parallel {
20 namespace detail {
21 /*!
22  * Fundamentals and pointers are already printable so there is no conversion
23  * to a std::string necessary.
24  */
25 template <typename T,
29  std::is_pointer<std::decay_t<T>>::value> = nullptr>
30 inline constexpr T stream_object_to_string(T&& t) {
31  return t;
32 }
33 
34 /*!
35  * Stream an object of type `T` into a std::stringstream and return it as a
36  * std::string so that it is printable by calling `.c_str()` on it.
37  * We need a 2-phase call so that the std::string doesn't go out of scope before
38  * the C-style string is passed to printf.
39  */
40 template <typename T,
42  std::is_enum<std::decay_t<T>>::value> = nullptr>
43 inline std::string stream_object_to_string(T&& t) {
45  "Cannot stream type and therefore it cannot be printed. Please "
46  "define a stream operator for the type.");
48  ss << std::setprecision(std::numeric_limits<long double>::digits10 + 1)
49  << std::scientific << t;
50  return ss.str();
51 }
52 
53 /*!
54  * Fundamentals are already printable, so nothing to do.
55  */
56 template <typename T,
58  std::remove_pointer_t<std::decay_t<T>>>>::value> = nullptr>
59 inline constexpr T get_printable_type(T&& t) {
60  return t;
61 }
62 
63 /*!
64  * Get the pointer of the std::string so it can be passed to CkPrintf which
65  * only works on fundamentals
66  */
67 inline const typename std::string::value_type* get_printable_type(
68  const std::string& t) {
69  return t.c_str();
70 }
71 
72 template <typename Printer, typename... Ts>
73 inline void print_helper(Printer&& printer, const std::string& format,
74  Ts&&... t) {
75  printer(format.c_str(), get_printable_type(std::forward<Ts>(t))...);
76 }
77 
78 template <typename Printer, typename... Args>
79 inline void call_printer(Printer&& printer, const std::string& format,
80  Args&&... args) {
82  print_helper(printer, format,
83  stream_object_to_string(std::forward<Args>(args))...);
85 }
86 } // namespace detail
87 
88 /*!
89  * \ingroup ParallelGroup
90  * \brief Print an atomic message to stdout with C printf usage.
91  *
92  * Similar to Python, you can print any object that's streamable by passing it
93  * in as an argument and using the formatter "%s". For example,
94  * \code
95  * std::vector<double> a{0.8, 73, 9.8};
96  * Parallel::printf("%s\n", a);
97  * \endcode
98  */
99 template <typename... Args>
100 inline void printf(const std::string& format, Args&&... args) {
101  detail::call_printer([](auto... a) noexcept { CkPrintf(a...); }, format,
102  std::forward<Args>(args)...);
103 }
104 
105 /*!
106  * \ingroup ParallelGroup
107  * \brief Print an atomic message to stderr with C printf usage.
108  *
109  * See Parallel::printf for details.
110  */
111 template <typename... Args>
112 inline void printf_error(const std::string& format, Args&&... args) {
113  detail::call_printer([](auto... a) noexcept { CkError(a...); }, format,
114  std::forward<Args>(args)...);
115 }
116 } // namespace Parallel
void disable_floating_point_exceptions()
After a call to this function, the code will NOT terminate with a floating point exception on overflo...
Definition: FloatingPointExceptions.cpp:37
Contains functions that forward to Charm++ parallel functions.
Definition: Abort.hpp:13
Check if type T has operator<<(S, T) defined.
Definition: StlStreamDeclarations.hpp:32
Defines the type alias Requires.
void printf_error(const std::string &format, Args &&... args)
Print an atomic message to stderr with C printf usage.
Definition: Printf.hpp:112
Definition: Determinant.hpp:11
void enable_floating_point_exceptions()
After a call to this function, the code will terminate with a floating point exception on overflow...
Definition: FloatingPointExceptions.cpp:27
Functions to enable/disable termination on floating point exceptions.
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t ...
Definition: Requires.hpp:67
Defines type traits, some of which are future STL type_traits header.
void printf(const std::string &format, Args &&... args)
Print an atomic message to stdout with C printf usage.
Definition: Printf.hpp:100