Skip to content

Commit

Permalink
version based on 8.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
moiwi committed Jan 19, 2022
1 parent 64dc8fb commit 1dcbdf8
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 21 deletions.
30 changes: 21 additions & 9 deletions include/fmt/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include <string>
#include <type_traits>

#undef FMT_EXCEPTIONS
#define FMT_EXCEPTIONS 0

// The fmt library version in the form major * 10000 + minor * 100 + patch.
#define FMT_VERSION 80100

Expand Down Expand Up @@ -2059,7 +2062,8 @@ enum class presentation_type : unsigned char {
general_upper, // 'G'
chr, // 'c'
string, // 's'
pointer // 'p'
pointer, // 'p'
any // 'y'
};

// Format specifiers for built-in and string types.
Expand Down Expand Up @@ -2475,6 +2479,8 @@ FMT_CONSTEXPR auto parse_presentation_type(Char type) -> presentation_type {
return presentation_type::string;
case 'p':
return presentation_type::pointer;
case 'y':
return presentation_type::any;
default:
return presentation_type::none;
}
Expand Down Expand Up @@ -2695,16 +2701,16 @@ class compile_parse_context
template <typename ErrorHandler>
FMT_CONSTEXPR void check_int_type_spec(presentation_type type,
ErrorHandler&& eh) {
if (type > presentation_type::bin_upper && type != presentation_type::chr)
if (type > presentation_type::bin_upper && type != presentation_type::chr && type != presentation_type::any)
eh.on_error("invalid type specifier");
}

// Checks char specs and returns true if the type spec is char (and not int).
template <typename Char, typename ErrorHandler = error_handler>
FMT_CONSTEXPR auto check_char_specs(const basic_format_specs<Char>& specs,
ErrorHandler&& eh = {}) -> bool {
if (specs.type != presentation_type::none &&
specs.type != presentation_type::chr) {
if (specs.type != presentation_type::none && specs.type != presentation_type::chr &&
specs.type != presentation_type::string && specs.type != presentation_type::any) {
check_int_type_spec(specs.type, eh);
return false;
}
Expand Down Expand Up @@ -2747,6 +2753,7 @@ FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs,
result.upper = true;
FMT_FALLTHROUGH;
case presentation_type::general_lower:
case presentation_type::any:
result.format = float_format::general;
break;
case presentation_type::exp_upper:
Expand All @@ -2771,6 +2778,7 @@ FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs,
break;
default:
eh.on_error("invalid type specifier");
result.format = float_format::general;
break;
}
return result;
Expand All @@ -2779,23 +2787,27 @@ FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs,
template <typename ErrorHandler = error_handler>
FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type,
ErrorHandler&& eh = {}) -> bool {
if (type == presentation_type::none || type == presentation_type::string)
if (type == presentation_type::none || type == presentation_type::string ||
type == presentation_type::any)
return true;
if (type != presentation_type::pointer) eh.on_error("invalid type specifier");
return false;
if (type != presentation_type::pointer)
eh.on_error("invalid type specifier");
return true;
}

template <typename ErrorHandler = error_handler>
FMT_CONSTEXPR void check_string_type_spec(presentation_type type,
ErrorHandler&& eh = {}) {
if (type != presentation_type::none && type != presentation_type::string)
if (type != presentation_type::none && type != presentation_type::string &&
type != presentation_type::any)
eh.on_error("invalid type specifier");
}

template <typename ErrorHandler>
FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type,
ErrorHandler&& eh) {
if (type != presentation_type::none && type != presentation_type::pointer)
if (type != presentation_type::none && type != presentation_type::pointer &&
type != presentation_type::any)
eh.on_error("invalid type specifier");
}

Expand Down
5 changes: 1 addition & 4 deletions include/fmt/format-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ namespace detail {
FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
// Use unchecked std::fprintf to avoid triggering another assertion when
// writing to stderr fails
std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
// Chosen instead of std::abort to satisfy Clang in CUDA mode during device
// code pass.
std::terminate();
std::fprintf(stderr, "%s:%d: assertion failed: %s\n", file, line, message);
}

FMT_FUNC void throw_format_error(const char* message) {
Expand Down
47 changes: 41 additions & 6 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <stdexcept> // std::runtime_error
#include <system_error> // std::system_error
#include <utility> // std::swap
#include <cfloat> // DBL_DIG

#ifdef __cpp_lib_bit_cast
# include <bit> // std::bitcast
Expand Down Expand Up @@ -95,10 +96,17 @@ FMT_END_NAMESPACE
# define FMT_THROW(x) throw x
# endif
# else
# define FMT_THROW(x) \
do { \
FMT_ASSERT(false, (x).what()); \
} while (false)
# ifdef _DEBUG
# define FMT_THROW(x) \
do { \
::printf("%s\n", x.what()); \
} while (false)
# else
# define FMT_THROW(x) \
do { \
static_cast<void>(x); \
} while (false)
# endif
# endif
#endif

Expand Down Expand Up @@ -1573,6 +1581,10 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
auto abs_value = arg.abs_value;
auto prefix = arg.prefix;
switch (specs.type) {
default:
throw_format_error("invalid type specifier");
FMT_FALLTHROUGH;
case presentation_type::any:
case presentation_type::none:
case presentation_type::dec: {
if (specs.localized &&
Expand Down Expand Up @@ -1621,8 +1633,6 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
}
case presentation_type::chr:
return write_char(out, static_cast<Char>(abs_value), specs);
default:
throw_format_error("invalid type specifier");
}
return out;
}
Expand Down Expand Up @@ -1993,6 +2003,31 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value,
if (const_check(!is_supported_floating_point(value))) return out;
float_specs fspecs = parse_float_type_spec(specs);
fspecs.sign = specs.sign;

if (specs.type == presentation_type::fixed_lower) {
static const double prevPowerOfTen[17] = {1e-1, 1, 1e1, 1e2, 1e3, 1e4,
1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
1e11, 1e12, 1e13, 1e14, 1e15};
if (specs.precision < 0) {
specs.precision = 6;
}
if (specs.precision > DBL_DIG || fabs(value) >= prevPowerOfTen[DBL_DIG - specs.precision + 1]) {
specs.precision = DBL_DIG;
fspecs.format = float_format::general;
fspecs.showpoint = specs.alt;
} else {
#ifdef __cpp_if_constexpr
if constexpr (std::is_same<T, double>()) {
#else
if (std::is_same<T, double>()) {
#endif
if (fabs(value) < prevPowerOfTen[DBL_DIG - specs.precision]) {
value = static_cast<T>( std::nextafter(value, value >= 0.0 ? 1e15 : -1e15) );
}
}
}
}

if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit.
fspecs.sign = sign::minus;
value = -value;
Expand Down
8 changes: 6 additions & 2 deletions include/fmt/printf.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ template <typename T, typename Context> class arg_converter {

template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>
void operator()(U value) {
if (type_ != 'd' && type_ != 'i' && type_ != 'o' && type_ != 'u' &&
type_ != 'x' && type_ != 'X')
return;
bool is_signed = type_ == 'd' || type_ == 'i';
using target_type = conditional_t<std::is_same<T, void>::value, U, T>;
if (const_check(sizeof(target_type) <= sizeof(int))) {
Expand Down Expand Up @@ -250,8 +253,9 @@ class printf_arg_formatter : public arg_formatter<Char> {
if (std::is_same<T, Char>::value) {
format_specs fmt_specs = this->specs;
if (fmt_specs.type != presentation_type::none &&
fmt_specs.type != presentation_type::chr) {
return (*this)(static_cast<int>(value));
fmt_specs.type != presentation_type::chr &&
fmt_specs.type != presentation_type::any) {
fmt_specs.type = presentation_type::chr;
}
fmt_specs.sign = sign::none;
fmt_specs.alt = false;
Expand Down
3 changes: 3 additions & 0 deletions src/format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
//
// For the license information refer to format.h.

#ifdef __GNUC__
#pragma GCC visibility push(default)
#endif
#include "fmt/format-inl.h"

FMT_BEGIN_NAMESPACE
Expand Down

0 comments on commit 1dcbdf8

Please sign in to comment.