Skip to content
Draft
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ set(FlatBuffers_Tests_SRCS
tests/alignment_test.cpp
tests/64bit/offset64_test.h
tests/64bit/offset64_test.cpp
tests/float_to_string_test.cpp
include/flatbuffers/code_generators.h
src/code_generators.cpp
)
Expand Down Expand Up @@ -543,7 +544,11 @@ if(FLATBUFFERS_BUILD_TESTS)
)

# Have tests load data from the source directory, not the build directory.
add_definitions(-DFLATBUFFERS_TEST_PATH_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/)
target_compile_definitions(flattests
PRIVATE
-DFLATBUFFERS_TEST_PATH_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/
# -DFLATBUFFERS_PREFER_OLD_FLOATTOSTRING
)

# The flattest target needs some generated files
SET(FLATC_OPT_COMP --cpp --gen-compare --gen-mutable --gen-object-api --reflect-names)
Expand Down
45 changes: 29 additions & 16 deletions include/flatbuffers/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,33 +155,46 @@ inline std::string NumToString<char>(char t) {
return NumToString(static_cast<int>(t));
}

// definitions in util.cpp
template <typename Float>
std::string FloatToStringImpl(Float value);

// Special versions for floats/doubles.
template <typename T>
std::string FloatToString(T t, int precision) {
// clang-format off

#ifndef FLATBUFFERS_PREFER_PRINTF
// to_string() prints different numbers of digits for floats depending on
// platform and isn't available on Android, so we use stringstream
std::stringstream ss;
// Use std::fixed to suppress scientific notation.
ss << std::fixed;
// Default precision is 6, we want that to be higher for doubles.
ss << std::setprecision(precision);
ss << t;
auto s = ss.str();
#ifndef FLATBUFFERS_PREFER_OLD_FLOATTOSTRING
(void)precision; // unused, can't use [[maybe_unused]]
return FloatToStringImpl(t);
#else // FLATBUFFERS_PREFER_OLD_FLOATTOSTRING
// to_string() prints different numbers of digits for floats depending on
// platform and isn't available on Android, so we use stringstream
std::stringstream ss;
// Use std::fixed to suppress scientific notation.
ss << std::fixed;
// Default precision is 6, we want that to be higher for doubles.
ss << std::setprecision(precision);
ss << t;
auto s = ss.str();
#endif // FLATBUFFERS_PREFER_OLD_FLOATTOSTRING
#else // FLATBUFFERS_PREFER_PRINTF
auto v = static_cast<double>(t);
auto s = NumToStringImplWrapper(v, "%0.*f", precision);
#endif // FLATBUFFERS_PREFER_PRINTF

#if defined(FLATBUFFERS_PREFER_OLD_FLOATTOSTRING) || defined(FLATBUFFERS_PREFER_PRINTF)
// Sadly, std::fixed turns "1" into "1.00000", so here we undo that.
auto p = s.find_last_not_of('0');
if (p != std::string::npos) {
// Strip trailing zeroes. If it is a whole number, keep one zero.
s.resize(p + (s[p] == '.' ? 2 : 1));
}

return s;
#endif
// clang-format on
// Sadly, std::fixed turns "1" into "1.00000", so here we undo that.
auto p = s.find_last_not_of('0');
if (p != std::string::npos) {
// Strip trailing zeroes. If it is a whole number, keep one zero.
s.resize(p + (s[p] == '.' ? 2 : 1));
}
return s;
}

template <>
Expand Down
2 changes: 2 additions & 0 deletions src/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ cc_library(
"idl_parser.cpp",
"reflection.cpp",
"util.cpp",
"dragonbox.h"
],
hdrs = [
"//:public_headers",
Expand Down Expand Up @@ -141,6 +142,7 @@ cc_library(
"idl_namer.h",
"namer.h",
"util.cpp",
"dragonbox.h",
],
hdrs = [
"//:flatc_headers",
Expand Down
Loading
Loading