Gemmi C++ API
Loading...
Searching...
No Matches
sprintf.hpp
Go to the documentation of this file.
1// Copyright 2017 Global Phasing Ltd.
2//
3// interface to stb_sprintf: snprintf_z, to_str(float|double)
4
5#ifndef GEMMI_SPRINTF_HPP_
6#define GEMMI_SPRINTF_HPP_
7
8#include <string>
9#ifdef __has_include
10# if __has_include(<charconv>) && !(defined(_MSVC_LANG) && _MSVC_LANG < 201703L)
11# include <charconv>
12# endif
13#endif
14
15#if __cpp_lib_to_chars < 201611L
16# include <algorithm> // for min
17#endif
18
19#include "fail.hpp" // for GEMMI_DLL
20
21namespace gemmi {
22
23// On MinGW format(printf) doesn't support %zu.
24#if (defined(__GNUC__) && !defined(__MINGW32__)) || defined(__clang__)
25# define GEMMI_ATTRIBUTE_FORMAT(fmt,va) __attribute__((format(printf,fmt,va)))
26#else
27# define GEMMI_ATTRIBUTE_FORMAT(fmt,va)
28#endif
31GEMMI_DLL int snprintf_z(char *buf, int count, char const *fmt, ...)
34GEMMI_DLL int sprintf_z(char *buf, char const *fmt, ...) GEMMI_ATTRIBUTE_FORMAT(2,3);
35
36inline std::string to_str(double d) {
37 char buf[24];
38 int len = sprintf_z(buf, "%.9g", d);
39 return std::string(buf, len > 0 ? len : 0);
40}
41
42inline std::string to_str(float d) {
43 char buf[16];
44 int len = sprintf_z(buf, "%.6g", d);
45 return std::string(buf, len > 0 ? len : 0);
46}
47
48template<int Prec>
49std::string to_str_prec(double d) {
50 static_assert(Prec >= 0 && Prec < 7, "unsupported precision");
51 char buf[16];
52 int len = d > -1e8 && d < 1e8 ? sprintf_z(buf, "%.*f", Prec, d)
53 : sprintf_z(buf, "%g", d);
54 return std::string(buf, len > 0 ? len : 0);
55}
56
58inline char* to_chars_z(char* first, char* last, int value) {
59#if __cpp_lib_to_chars >= 201611L
60 auto result = std::to_chars(first, last-1, value);
61 *result.ptr = '\0';
62 return result.ptr;
63#else
64 int n = snprintf_z(first, int(last - first), "%d", value);
65 return std::min(first + n, last - 1);
66#endif
67}
68inline char* to_chars_z(char* first, char* last, size_t value) {
69#if __cpp_lib_to_chars >= 201611L
70 auto result = std::to_chars(first, last-1, value);
71 *result.ptr = '\0';
72 return result.ptr;
73#else
74 int n = snprintf_z(first, int(last - first), "%zu", value);
75 return std::min(first + n, last - 1);
76#endif
77}
78
79} // namespace gemmi
80#endif
#define GEMMI_DLL
Definition fail.hpp:53
char * to_chars_z(char *first, char *last, int value)
zero-terminated to_chars()
Definition sprintf.hpp:58
GEMMI_DLL int GEMMI_DLL int sprintf_z(char *buf, char const *fmt,...) GEMMI_ATTRIBUTE_FORMAT(2
stb_sprintf in gemmi namespace
GEMMI_DLL int GEMMI_DLL int std::string to_str(double d)
Definition sprintf.hpp:36
GEMMI_DLL int snprintf_z(char *buf, int count, char const *fmt,...) GEMMI_ATTRIBUTE_FORMAT(3
stb_snprintf in gemmi namespace - like snprintf, but ignores locale and is always zero-terminated (he...
std::string to_str_prec(double d)
Definition sprintf.hpp:49
Definition seqid.hpp:149
#define GEMMI_ATTRIBUTE_FORMAT(fmt, va)
Definition sprintf.hpp:27