mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-31 03:07:36 +02:00
Implement a fallback uint128_t
This commit is contained in:
@ -390,7 +390,35 @@ template <typename T> inline auto convert_for_visit(T value) -> T {
|
|||||||
#endif
|
#endif
|
||||||
#if !FMT_USE_INT128
|
#if !FMT_USE_INT128
|
||||||
enum class int128_t {};
|
enum class int128_t {};
|
||||||
enum class uint128_t {};
|
class uint128_t {
|
||||||
|
private:
|
||||||
|
uint64_t lo_, hi_;
|
||||||
|
constexpr uint128_t(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr uint128_t(uint64_t value = 0) : hi_(0), lo_(value) {}
|
||||||
|
explicit operator int() const { return lo_; }
|
||||||
|
explicit operator uint64_t() const { return lo_; }
|
||||||
|
friend auto operator==(const uint128_t& lhs, const uint128_t& rhs) -> bool {
|
||||||
|
return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
|
||||||
|
}
|
||||||
|
friend auto operator&(const uint128_t& lhs, const uint128_t& rhs)
|
||||||
|
-> uint128_t {
|
||||||
|
return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};
|
||||||
|
}
|
||||||
|
friend auto operator-(const uint128_t& lhs, uint64_t rhs) -> uint128_t {
|
||||||
|
FMT_ASSERT(lhs.lo_ >= rhs, "");
|
||||||
|
return {lhs.hi_, lhs.lo_ - rhs};
|
||||||
|
}
|
||||||
|
auto operator>>(int shift) const -> uint128_t {
|
||||||
|
if (shift == 64) return {0, hi_};
|
||||||
|
return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
|
||||||
|
}
|
||||||
|
auto operator<<(int shift) const -> uint128_t {
|
||||||
|
if (shift == 64) return {lo_, 0};
|
||||||
|
return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
|
||||||
|
}
|
||||||
|
};
|
||||||
// Reduce template instantiations.
|
// Reduce template instantiations.
|
||||||
template <typename T> inline auto convert_for_visit(T) -> monostate {
|
template <typename T> inline auto convert_for_visit(T) -> monostate {
|
||||||
return {};
|
return {};
|
||||||
@ -1431,7 +1459,8 @@ template <typename Context> struct arg_mapper {
|
|||||||
!std::is_const<remove_reference_t<T>>::value ||
|
!std::is_const<remove_reference_t<T>>::value ||
|
||||||
has_fallback_formatter<U, char_type>::value> {};
|
has_fallback_formatter<U, char_type>::value> {};
|
||||||
|
|
||||||
#if (FMT_MSC_VER != 0 && FMT_MSC_VER < 1910) || FMT_ICC_VERSION != 0 || FMT_NVCC != 0
|
#if (FMT_MSC_VER != 0 && FMT_MSC_VER < 1910) || FMT_ICC_VERSION != 0 || \
|
||||||
|
FMT_NVCC != 0
|
||||||
// Workaround a bug in MSVC and Intel (Issue 2746).
|
// Workaround a bug in MSVC and Intel (Issue 2746).
|
||||||
template <typename T> FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
|
template <typename T> FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
|
||||||
return val;
|
return val;
|
||||||
|
@ -259,7 +259,7 @@ struct fp {
|
|||||||
using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
|
using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;
|
||||||
const carrier_uint significand_mask = implicit_bit - 1;
|
const carrier_uint significand_mask = implicit_bit - 1;
|
||||||
auto u = bit_cast<carrier_uint>(n);
|
auto u = bit_cast<carrier_uint>(n);
|
||||||
f = u & significand_mask;
|
f = static_cast<uint64_t>(u & significand_mask);
|
||||||
int biased_e =
|
int biased_e =
|
||||||
static_cast<int>((u & exponent_mask<Float>()) >>
|
static_cast<int>((u & exponent_mask<Float>()) >>
|
||||||
dragonbox::float_info<Float>::significand_bits);
|
dragonbox::float_info<Float>::significand_bits);
|
||||||
|
@ -33,6 +33,33 @@ using testing::Return;
|
|||||||
# error core-test includes format.h
|
# error core-test includes format.h
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TEST(uint128_test, ctor) {
|
||||||
|
using fmt::detail::uint128_t;
|
||||||
|
auto n = uint128_t();
|
||||||
|
EXPECT_EQ(n, 0);
|
||||||
|
n = uint128_t(42);
|
||||||
|
EXPECT_EQ(n, 42);
|
||||||
|
EXPECT_EQ(static_cast<uint64_t>(n), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(uint128_test, shift) {
|
||||||
|
auto n = fmt::detail::uint128_t(42);
|
||||||
|
n = n << 64;
|
||||||
|
EXPECT_EQ(static_cast<uint64_t>(n), 0);
|
||||||
|
n = n >> 64;
|
||||||
|
EXPECT_EQ(static_cast<uint64_t>(n), 42);
|
||||||
|
n = n << 62;
|
||||||
|
EXPECT_EQ(static_cast<uint64_t>(n >> 64), 0xa);
|
||||||
|
EXPECT_EQ(static_cast<uint64_t>(n), 0x8000000000000000);
|
||||||
|
n = n >> 62;
|
||||||
|
EXPECT_EQ(static_cast<uint64_t>(n), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(uint128_test, minus) {
|
||||||
|
auto n = fmt::detail::uint128_t(42);
|
||||||
|
EXPECT_EQ(n - 2, 40);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(string_view_test, value_type) {
|
TEST(string_view_test, value_type) {
|
||||||
static_assert(std::is_same<string_view::value_type, char>::value, "");
|
static_assert(std::is_same<string_view::value_type, char>::value, "");
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user