Fix handling of uintptr_t

This commit is contained in:
Victor Zverovich 2019-06-12 08:10:15 -07:00
parent 9d7b64a259
commit e5422db4b2
3 changed files with 11 additions and 28 deletions

View File

@ -236,7 +236,7 @@ FMT_FUNC void system_error::init(int err_code, string_view format_str,
namespace internal { namespace internal {
template <> FMT_FUNC int count_digits<4>(internal::uintptr_t n) { template <> FMT_FUNC int count_digits<4>(internal::uintptr n) {
// Assume little endian; pointer formatting is implementation-defined anyway. // Assume little endian; pointer formatting is implementation-defined anyway.
int i = static_cast<int>(sizeof(void*)) - 1; int i = static_cast<int>(sizeof(void*)) - 1;
while (i > 0 && n.value[i] == 0) --i; while (i > 0 && n.value[i] == 0) --i;

View File

@ -243,13 +243,14 @@ namespace internal {
#endif #endif
// A fallback implementation of uintptr_t for systems that lack it. // A fallback implementation of uintptr_t for systems that lack it.
namespace uintptr { struct uintptr {
struct uintptr_t {
unsigned char value[sizeof(void*)]; unsigned char value[sizeof(void*)];
}; };
} // namespace uintptr #ifdef UINTPTR_MAX
using uintptr::uintptr_t; using uintptr_t = ::uintptr_t;
typedef std::numeric_limits<uintptr_t> numutil; #else
using uintptr_t = uintptr;
#endif
template <typename T> inline bool use_grisu() { template <typename T> inline bool use_grisu() {
return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 && return FMT_USE_GRISU && std::numeric_limits<double>::is_iec559 &&
@ -303,25 +304,7 @@ typename Allocator::value_type* allocate(Allocator& alloc, std::size_t n) {
#endif #endif
} }
} // namespace internal } // namespace internal
FMT_END_NAMESPACE
namespace std {
using namespace fmt::v5::internal::uintptr;
// Standard permits specialization of std::numeric_limits. This specialization
// is used to detect presence of uintptr_t.
template <>
class numeric_limits<fmt::internal::uintptr_t>
: public std::numeric_limits<int> {
public:
typedef uintptr_t uintptr_type;
static uintptr_type to_uint(const void* p) {
return fmt::internal::bit_cast<uintptr_type>(p);
}
};
} // namespace std
FMT_BEGIN_NAMESPACE
template <typename Range> class basic_writer; template <typename Range> class basic_writer;
template <typename OutputIt, typename T = typename OutputIt::value_type> template <typename OutputIt, typename T = typename OutputIt::value_type>
@ -751,7 +734,7 @@ template <unsigned BITS, typename UInt> inline int count_digits(UInt n) {
return num_digits; return num_digits;
} }
template <> int count_digits<4>(internal::uintptr_t n); template <> int count_digits<4>(internal::uintptr n);
template <typename Char> template <typename Char>
inline size_t count_code_points(basic_string_view<Char> s) { inline size_t count_code_points(basic_string_view<Char> s) {
@ -980,7 +963,7 @@ inline Char* format_uint(Char* buffer, UInt value, int num_digits,
} }
template <unsigned BASE_BITS, typename Char> template <unsigned BASE_BITS, typename Char>
Char* format_uint(Char* buffer, internal::uintptr_t n, int num_digits, Char* format_uint(Char* buffer, internal::uintptr n, int num_digits,
bool = false) { bool = false) {
auto char_digits = std::numeric_limits<unsigned char>::digits / 4; auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
int start = (num_digits + char_digits - 1) / char_digits - 1; int start = (num_digits + char_digits - 1) / char_digits - 1;
@ -1411,7 +1394,7 @@ class arg_formatter_base {
} }
void write_pointer(const void* p) { void write_pointer(const void* p) {
writer_.write_pointer(internal::numutil::to_uint(p), specs_); writer_.write_pointer(internal::bit_cast<internal::uintptr_t>(p), specs_);
} }
protected: protected:

View File

@ -257,7 +257,7 @@ TEST(UtilTest, CountDigits) {
TEST(UtilTest, WriteUIntPtr) { TEST(UtilTest, WriteUIntPtr) {
fmt::memory_buffer buf; fmt::memory_buffer buf;
fmt::writer writer(buf); fmt::writer writer(buf);
writer.write_pointer(fmt::internal::bit_cast<fmt::internal::uintptr_t>( writer.write_pointer(fmt::internal::bit_cast<fmt::internal::uintptr>(
reinterpret_cast<void*>(0xface)), reinterpret_cast<void*>(0xface)),
nullptr); nullptr);
EXPECT_EQ("0xface", to_string(buf)); EXPECT_EQ("0xface", to_string(buf));