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.
This commit is contained in:
Alberto Aguirre 2020-03-10 11:56:48 -05:00
parent ee2b828b9a
commit a15c81e5ff
2 changed files with 55 additions and 3 deletions

View File

@ -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 <typename Int>
FMT_CONSTEXPR typename std::make_unsigned<Int>::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:

View File

@ -1685,8 +1685,9 @@ template <typename Range> class basic_writer {
handle_int_type_spec(spec.type, int_writer<T, Spec>(*this, value, spec));
}
#if FMT_USE_FLOAT || FMT_USE_DOUBLE || FMT_USE_LONG_DOUBLE
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::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 <typename Range> class basic_writer {
static_cast<int>(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<T, Char,
&specs_, internal::char_specs_checker<decltype(eh)>(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(