guanaqo main
Utilities for scientific software
Loading...
Searching...
No Matches
print.cpp
Go to the documentation of this file.
1#include <guanaqo/export.h>
3
4#include <charconv>
5#include <concepts>
6#ifdef __has_include
7#if __has_include(<stdfloat>)
8#include <stdfloat>
9#endif
10#endif
11
12namespace guanaqo {
13
14namespace {
15
16std::string_view float_to_str_vw_snprintf(auto &&print, auto &buf,
17 std::floating_point auto value,
18 int precision, const char *fmt) {
19 int n = print(buf.data(), buf.size(), fmt, precision, value);
20 assert((size_t)n < buf.size());
21 return {buf.data(), (size_t)n};
22}
23#if __cpp_lib_to_chars
24template <std::floating_point F>
25#ifdef GUANAQO_WITH_QUAD_PRECISION
26 requires(!std::same_as<F, __float128>)
27#endif
28std::string_view float_to_str_vw_impl(std::span<char> buf, F value,
29 int precision) {
30 auto begin = buf.data(), buf_end = begin + buf.size();
31 if (!std::signbit(value) && !std::isnan(value))
32 *begin++ = '+';
33 auto fmt = std::chars_format::scientific;
34 // GCC to_chars support for std::float128_t depends on glibc version,
35 // so first check if to_chars is available at all.
36 constexpr bool print_chars_available =
37 requires { std::to_chars(begin, buf_end, value, fmt, precision); };
38 if constexpr (print_chars_available) {
39 auto [end, _] = std::to_chars(begin, buf_end, value, fmt, precision);
40 return std::string_view{buf.data(), end};
41 } else {
42 auto value_ld = static_cast<long double>(value);
43 auto [end, _] = std::to_chars(begin, buf_end, value_ld, fmt, precision);
44 return std::string_view{buf.data(), end};
45 }
46}
47#else
48#pragma message("Using std::snprintf as a fallback to replace std::to_chars")
49
50std::string_view float_to_str_vw_impl(std::span<char> buf, double value,
51 int precision) {
52 return float_to_str_vw_snprintf(std::snprintf, buf, value, precision,
53 "%+-#.*e");
54}
55std::string_view float_to_str_vw_impl(std::span<char> buf, float value,
56 int precision) {
57 return float_to_str_vw_impl(buf, static_cast<double>(value), precision);
58}
59std::string_view float_to_str_vw_impl(std::span<char> buf, long double value,
60 int precision) {
61 return float_to_str_vw_snprintf(std::snprintf, buf, value, precision,
62 "%+-#.*Le");
63}
64#endif
65
66#ifdef GUANAQO_WITH_QUAD_PRECISION
67std::string_view float_to_str_vw_impl(std::span<char> buf, __float128 value,
68 int precision) {
69 return float_to_str_vw_snprintf(quadmath_snprintf, buf, value, precision,
70 "%+-#.*Qe");
71}
72#endif
73
74} // namespace
75
76template <std::floating_point F>
77std::string_view float_to_str_vw(std::span<char> buf, F value, int precision) {
78 return float_to_str_vw_impl(buf, value, precision);
79}
80
81#ifndef DOXYGEN
82// clang-format off
83// NOLINTBEGIN(*-parentheses)
84#define GUANAQO_PRINT_INSTANTIATE_F(type) \
85 template GUANAQO_EXPORT std::string_view float_to_str_vw(std::span<char>, type value, int precision); \
86 template GUANAQO_EXPORT std::string float_to_str(type value, int precision); \
87 template GUANAQO_EXPORT std::ostream &detail::print_csv_impl(std::ostream &os, PrintMatrixView<const type>, PrintOpts); \
88 template GUANAQO_EXPORT std::ostream &detail::print_matlab_impl(std::ostream &os, PrintMatrixView<const type>, std::string_view); \
89 template GUANAQO_EXPORT std::ostream &detail::print_python_impl(std::ostream &os, PrintMatrixView<const type>, std::string_view, bool); \
90 template GUANAQO_EXPORT std::ostream &detail::print_csv_impl(std::ostream &os, PrintMatrixView<const std::complex<type>>, PrintOpts); \
91 template GUANAQO_EXPORT std::ostream &detail::print_matlab_impl(std::ostream &os, PrintMatrixView<const std::complex<type>>, std::string_view); \
92 template GUANAQO_EXPORT std::ostream &detail::print_python_impl(std::ostream &os, PrintMatrixView<const std::complex<type>>, std::string_view, bool)
93// NOLINTEND(*-parentheses)
94// clang-format on
95
96GUANAQO_PRINT_INSTANTIATE_F(float);
97GUANAQO_PRINT_INSTANTIATE_F(double);
98GUANAQO_PRINT_INSTANTIATE_F(long double);
99#if defined(__STDCPP_FLOAT16_T__) && __STDCPP_FLOAT16_T__ == 1
100GUANAQO_PRINT_INSTANTIATE_F(std::float16_t);
101#endif
102#if defined(__STDCPP_FLOAT32_T__) && __STDCPP_FLOAT32_T__ == 1
103GUANAQO_PRINT_INSTANTIATE_F(std::float32_t);
104#endif
105#if defined(__STDCPP_FLOAT64_T__) && __STDCPP_FLOAT64_T__ == 1
106GUANAQO_PRINT_INSTANTIATE_F(std::float64_t);
107#endif
108#if defined(__STDCPP_FLOAT128_T__) && __STDCPP_FLOAT128_T__ == 1
109GUANAQO_PRINT_INSTANTIATE_F(std::float128_t);
110#endif
111#if defined(__STDCPP_BFLOAT16_T__) && __STDCPP_BFLOAT16_T__ == 1
112GUANAQO_PRINT_INSTANTIATE_F(std::bfloat16_t);
113#endif
114#ifdef GUANAQO_WITH_QUAD_PRECISION
115GUANAQO_PRINT_INSTANTIATE_F(__float128);
116#endif
117
118// clang-format off
119#define GUANAQO_PRINT_INSTANTIATE_I(type) \
120 template GUANAQO_EXPORT std::ostream &detail::print_csv_impl(std::ostream &os, PrintMatrixView<const type>, PrintOpts); \
121 template GUANAQO_EXPORT std::ostream &detail::print_matlab_impl(std::ostream &os, PrintMatrixView<const type>, std::string_view); \
122 template GUANAQO_EXPORT std::ostream &detail::print_python_impl(std::ostream &os, PrintMatrixView<const type>, std::string_view, bool)
123// clang-format on
124
125GUANAQO_PRINT_INSTANTIATE_I(char);
126GUANAQO_PRINT_INSTANTIATE_I(signed char);
127GUANAQO_PRINT_INSTANTIATE_I(short);
128GUANAQO_PRINT_INSTANTIATE_I(int);
129GUANAQO_PRINT_INSTANTIATE_I(long);
130GUANAQO_PRINT_INSTANTIATE_I(long long);
131GUANAQO_PRINT_INSTANTIATE_I(unsigned char);
132GUANAQO_PRINT_INSTANTIATE_I(unsigned short);
133GUANAQO_PRINT_INSTANTIATE_I(unsigned int);
134GUANAQO_PRINT_INSTANTIATE_I(unsigned long);
135GUANAQO_PRINT_INSTANTIATE_I(unsigned long long);
136
137#endif // DOXYGEN
138
139} // namespace guanaqo
std::string_view float_to_str_vw(std::span< char > buf, F value, int precision=std::numeric_limits< F >::max_digits10)
Definition print.cpp:77