MCPcopy Create free account
hub / github.com/ObEngine/ObEngine / snprintf_float

Function snprintf_float

extlibs/fmt/include/fmt/format-inl.h:1115–1215  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1113
1114template <typename T>
1115int snprintf_float(T value, int precision, float_specs specs,
1116 buffer<char>& buf) {
1117 // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
1118 FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
1119 static_assert(!std::is_same<T, float>::value, "");
1120
1121 // Subtract 1 to account for the difference in precision since we use %e for
1122 // both general and exponent format.
1123 if (specs.format == float_format::general ||
1124 specs.format == float_format::exp)
1125 precision = (precision >= 0 ? precision : 6) - 1;
1126
1127 // Build the format string.
1128 enum { max_format_size = 7 }; // Ths longest format is "%#.*Le".
1129 char format[max_format_size];
1130 char* format_ptr = format;
1131 *format_ptr++ = '%';
1132 if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#';
1133 if (precision >= 0) {
1134 *format_ptr++ = '.';
1135 *format_ptr++ = '*';
1136 }
1137 if (std::is_same<T, long double>()) *format_ptr++ = 'L';
1138 *format_ptr++ = specs.format != float_format::hex
1139 ? (specs.format == float_format::fixed ? 'f' : 'e')
1140 : (specs.upper ? 'A' : 'a');
1141 *format_ptr = '\0';
1142
1143 // Format using snprintf.
1144 auto offset = buf.size();
1145 for (;;) {
1146 auto begin = buf.data() + offset;
1147 auto capacity = buf.capacity() - offset;
1148#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1149 if (precision > 100000)
1150 throw std::runtime_error(
1151 "fuzz mode - avoid large allocation inside snprintf");
1152#endif
1153 // Suppress the warning about a nonliteral format string.
1154 // Cannot use auto becase of a bug in MinGW (#1532).
1155 int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
1156 int result = precision >= 0
1157 ? snprintf_ptr(begin, capacity, format, precision, value)
1158 : snprintf_ptr(begin, capacity, format, value);
1159 if (result < 0) {
1160 buf.reserve(buf.capacity() + 1); // The buffer will grow exponentially.
1161 continue;
1162 }
1163 auto size = to_unsigned(result);
1164 // Size equal to capacity means that the last character was truncated.
1165 if (size >= capacity) {
1166 buf.reserve(size + offset + 1); // Add 1 for the terminating '\0'.
1167 continue;
1168 }
1169 auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
1170 if (specs.format == float_format::fixed) {
1171 if (precision == 0) {
1172 buf.resize(size);

Callers 2

format_floatFunction · 0.85
writeMethod · 0.85

Calls 5

capacityMethod · 0.80
resizeMethod · 0.80
sizeMethod · 0.45
dataMethod · 0.45
reserveMethod · 0.45

Tested by

no test coverage detected