From a15c81e5ff405144ae88f665fb8ad9419338b068 Mon Sep 17 00:00:00 2001 From: Alberto Aguirre Date: Tue, 10 Mar 2020 11:56:48 -0500 Subject: [PATCH] Allow disabling floating point support Add FMT_USE_FLOAT, FMT_USE_DOUBLE and FMT_USE_LONG_DOUBLE to allow a user of the library to configure the float types they want to allow. This is specially useful in embedded environements where code size is important. --- include/fmt/core.h | 24 ++++++++++++++++++++++++ include/fmt/format.h | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 72bbddad..4bf6d310 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -296,6 +296,18 @@ struct int128_t {}; struct uint128_t {}; #endif +#ifndef FMT_USE_FLOAT +# define FMT_USE_FLOAT 1 +#endif + +#ifndef FMT_USE_DOUBLE +# define FMT_USE_DOUBLE 1 +#endif + +#ifndef FMT_USE_LONG_DOUBLE +# define FMT_USE_LONG_DOUBLE 1 +#endif + // Casts a nonnegative integer to unsigned. template FMT_CONSTEXPR typename std::make_unsigned::type to_unsigned(Int value) { @@ -1083,11 +1095,23 @@ FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, case internal::type::char_type: return vis(arg.value_.char_value); case internal::type::float_type: +#if FMT_USE_FLOAT return vis(arg.value_.float_value); +#else + break; +#endif case internal::type::double_type: +#if FMT_USE_DOUBLE return vis(arg.value_.double_value); +#else + break; +#endif case internal::type::long_double_type: +#if FMT_USE_LONG_DOUBLE return vis(arg.value_.long_double_value); +#else + break; +#endif case internal::type::cstring_type: return vis(arg.value_.string.data); case internal::type::string_type: diff --git a/include/fmt/format.h b/include/fmt/format.h index 16b77fa5..f1f8aed8 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -1685,8 +1685,9 @@ template class basic_writer { handle_int_type_spec(spec.type, int_writer(*this, value, spec)); } +#if FMT_USE_FLOAT || FMT_USE_DOUBLE || FMT_USE_LONG_DOUBLE template ::value)> - void write(T value, format_specs specs = {}) { + void write_float(T value, format_specs specs = {}) { float_specs fspecs = parse_float_type_spec(specs); fspecs.sign = specs.sign; if (std::signbit(value)) { // value < 0 is false for NaN so use signbit. @@ -1743,6 +1744,17 @@ template class basic_writer { static_cast(buffer.size()), exp, fspecs, point)); } +#endif + +#if FMT_USE_FLOAT + void write(float value, format_specs specs = {}) { write_float(value, specs); } +#endif +#if FMT_USE_DOUBLE + void write(double value, format_specs specs = {}) { write_float(value, specs); } +#endif +#if FMT_USE_LONG_DOUBLE + void write(long double value, format_specs specs = {}) { write_float(value, specs); } +#endif void write(char value) { auto&& it = reserve(1); @@ -2925,9 +2937,25 @@ struct formatter(specs_.type, eh)); break; case internal::type::float_type: - case internal::type::double_type: - case internal::type::long_double_type: +#if FMT_USE_FLOAT internal::parse_float_type_spec(specs_, eh); +#else + FMT_ASSERT(false, "float support disabled"); +#endif + break; + case internal::type::double_type: +#if FMT_USE_DOUBLE + internal::parse_float_type_spec(specs_, eh); +#else + FMT_ASSERT(false, "double support disabled"); +#endif + break; + case internal::type::long_double_type: +#if FMT_USE_LONG_DOUBLE + internal::parse_float_type_spec(specs_, eh); +#else + FMT_ASSERT(false, "long double support disabled"); +#endif break; case internal::type::cstring_type: internal::handle_cstring_type_spec(