Simplify data handling

This commit is contained in:
Victor Zverovich 2021-04-23 06:52:10 -07:00
parent 54d3b1710e
commit c47f211296
4 changed files with 52 additions and 87 deletions

View File

@ -234,11 +234,8 @@
# define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275) # define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275)
# ifdef FMT_EXPORT # ifdef FMT_EXPORT
# define FMT_API __declspec(dllexport) # define FMT_API __declspec(dllexport)
# define FMT_EXTERN_TEMPLATE_API FMT_API
# define FMT_EXPORTED
# elif defined(FMT_SHARED) # elif defined(FMT_SHARED)
# define FMT_API __declspec(dllimport) # define FMT_API __declspec(dllimport)
# define FMT_EXTERN_TEMPLATE_API FMT_API
# endif # endif
#else #else
# define FMT_CLASS_API # define FMT_CLASS_API
@ -246,29 +243,6 @@
#ifndef FMT_API #ifndef FMT_API
# define FMT_API # define FMT_API
#endif #endif
#ifndef FMT_EXTERN_TEMPLATE_API
# define FMT_EXTERN_TEMPLATE_API
#endif
#ifndef FMT_INSTANTIATION_DECL_API // clang marks dllexport at extern template.
# ifndef _MSC_VER
# define FMT_INSTANTIATION_DECL_API FMT_API
# else
# define FMT_INSTANTIATION_DECL_API
# endif
#endif
#ifndef FMT_INSTANTIATION_DEF_API // msvc marks dllexport at the definition itself.
# ifndef _MSC_VER
# define FMT_INSTANTIATION_DEF_API
# else
# define FMT_INSTANTIATION_DEF_API FMT_API
# endif
#endif
#ifndef FMT_HEADER_ONLY
# define FMT_EXTERN extern
#else
# define FMT_EXTERN
#endif
// libc++ supports string_view in pre-c++17. // libc++ supports string_view in pre-c++17.
#if (FMT_HAS_INCLUDE(<string_view>) && \ #if (FMT_HAS_INCLUDE(<string_view>) && \
@ -432,9 +406,8 @@ template <typename Char> class basic_string_view {
\endrst \endrst
*/ */
FMT_CONSTEXPR_CHAR_TRAITS FMT_CONSTEXPR_CHAR_TRAITS
FMT_INLINE FMT_INLINE
basic_string_view(const Char* s) basic_string_view(const Char* s) : data_(s) {
: data_(s) {
if (detail::const_check(std::is_same<Char, char>::value && if (detail::const_check(std::is_same<Char, char>::value &&
!detail::is_constant_evaluated())) !detail::is_constant_evaluated()))
size_ = std::strlen(reinterpret_cast<const char*>(s)); size_ = std::strlen(reinterpret_cast<const char*>(s));
@ -2009,7 +1982,7 @@ FMT_GCC_PRAGMA("GCC pop_options")
FMT_END_NAMESPACE FMT_END_NAMESPACE
#ifdef FMT_HEADER_ONLY #ifdef FMT_HEADER_ONLY
#include "format.h" # include "format.h"
#endif #endif
#endif // FMT_CORE_H_ #endif // FMT_CORE_H_

View File

@ -858,6 +858,54 @@ struct fixed_handler {
} }
}; };
// A 128-bit integer type used internally,
struct uint128_wrapper {
uint128_wrapper() = default;
#if FMT_USE_INT128
uint128_t internal_;
constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
: internal_{static_cast<uint128_t>(low) |
(static_cast<uint128_t>(high) << 64)} {}
constexpr uint128_wrapper(uint128_t u) : internal_{u} {}
constexpr uint64_t high() const FMT_NOEXCEPT {
return uint64_t(internal_ >> 64);
}
constexpr uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); }
uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT {
internal_ += n;
return *this;
}
#else
uint64_t high_;
uint64_t low_;
constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
: high_{high},
low_{low} {}
constexpr uint64_t high() const FMT_NOEXCEPT { return high_; }
constexpr uint64_t low() const FMT_NOEXCEPT { return low_; }
uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT {
# if defined(_MSC_VER) && defined(_M_X64)
unsigned char carry = _addcarry_u64(0, low_, n, &low_);
_addcarry_u64(carry, high_, 0, &high_);
return *this;
# else
uint64_t sum = low_ + n;
high_ += (sum < low_ ? 1 : 0);
low_ = sum;
return *this;
# endif
}
#endif
};
// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. // Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox.
namespace dragonbox { namespace dragonbox {
// Computes 128-bit result of multiplication of two 64-bit unsigned integers. // Computes 128-bit result of multiplication of two 64-bit unsigned integers.

View File

@ -897,61 +897,13 @@ using uint32_or_64_or_128_t =
template <typename T> template <typename T>
using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>; using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
// 128-bit integer type used internally
struct FMT_EXTERN_TEMPLATE_API uint128_wrapper {
uint128_wrapper() = default;
#if FMT_USE_INT128
uint128_t internal_;
constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
: internal_{static_cast<uint128_t>(low) |
(static_cast<uint128_t>(high) << 64)} {}
constexpr uint128_wrapper(uint128_t u) : internal_{u} {}
constexpr uint64_t high() const FMT_NOEXCEPT {
return uint64_t(internal_ >> 64);
}
constexpr uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); }
uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT {
internal_ += n;
return *this;
}
#else
uint64_t high_;
uint64_t low_;
constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
: high_{high},
low_{low} {}
constexpr uint64_t high() const FMT_NOEXCEPT { return high_; }
constexpr uint64_t low() const FMT_NOEXCEPT { return low_; }
uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT {
# if defined(_MSC_VER) && defined(_M_X64)
unsigned char carry = _addcarry_u64(0, low_, n, &low_);
_addcarry_u64(carry, high_, 0, &high_);
return *this;
# else
uint64_t sum = low_ + n;
high_ += (sum < low_ ? 1 : 0);
low_ = sum;
return *this;
# endif
}
#endif
};
#define FMT_POWERS_OF_10(factor) \ #define FMT_POWERS_OF_10(factor) \
factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \ factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
(factor)*1000000, (factor)*10000000, (factor)*100000000, \ (factor)*1000000, (factor)*10000000, (factor)*100000000, \
(factor)*1000000000 (factor)*1000000000
// Static data is placed in this class template for the header-only config. // Static data is placed in this class template for the header-only config.
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data { template <typename T = void> struct basic_data {
static constexpr const uint32_t zero_or_powers_of_10_32[] = { static constexpr const uint32_t zero_or_powers_of_10_32[] = {
0, 0, FMT_POWERS_OF_10(1U)}; 0, 0, FMT_POWERS_OF_10(1U)};
@ -1005,10 +957,6 @@ FMT_INLINE uint16_t bsr2log10(int bsr) {
return data[bsr]; return data[bsr];
} }
#ifndef FMT_EXPORTED
FMT_EXTERN template struct FMT_INSTANTIATION_DECL_API basic_data<void>;
#endif
template <typename T> FMT_CONSTEXPR int count_digits_fallback(T n) { template <typename T> FMT_CONSTEXPR int count_digits_fallback(T n) {
int count = 1; int count = 1;
for (;;) { for (;;) {

View File

@ -55,10 +55,6 @@ vformat_to(buffer<char>&, string_view,
type_identity_t<char>>>); type_identity_t<char>>>);
} // namespace detail } // namespace detail
// Clang doesn't allow dllexport on template instantiation definitions:
// https://reviews.llvm.org/D61118.
template struct FMT_INSTANTIATION_DEF_API detail::basic_data<void>;
// Workaround a bug in MSVC2013 that prevents instantiation of format_float. // Workaround a bug in MSVC2013 that prevents instantiation of format_float.
int (*instantiate_format_float)(double, int, detail::float_specs, int (*instantiate_format_float)(double, int, detail::float_specs,
detail::buffer<char>&) = detail::format_float; detail::buffer<char>&) = detail::format_float;