Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
0c8ffe9b
Commit
0c8ffe9b
authored
Sep 18, 2020
by
Junekey Jeon
Committed by
Victor Zverovich
Sep 19, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement Dragonbox (first version)
parent
42699bf4
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1747 additions
and
37 deletions
+1747
-37
include/fmt/format-inl.h
include/fmt/format-inl.h
+1616
-35
include/fmt/format.h
include/fmt/format.h
+131
-2
No files found.
include/fmt/format-inl.h
View file @
0c8ffe9b
This diff is collapsed.
Click to expand it.
include/fmt/format.h
View file @
0c8ffe9b
...
@@ -182,6 +182,12 @@ FMT_END_NAMESPACE
...
@@ -182,6 +182,12 @@ FMT_END_NAMESPACE
#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER
#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER
# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
#endif
#endif
#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz))
# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
#endif
#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll))
# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
#endif
// Some compilers masquerade as both MSVC and GCC-likes or otherwise support
// Some compilers masquerade as both MSVC and GCC-likes or otherwise support
// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
...
@@ -236,6 +242,59 @@ inline int clzll(uint64_t x) {
...
@@ -236,6 +242,59 @@ inline int clzll(uint64_t x) {
FMT_END_NAMESPACE
FMT_END_NAMESPACE
#endif
#endif
// Same for __builtin_ctz and __builtin_ctzll
#if FMT_MSC_VER && !defined(FMT_BUILTIN_CTZLL) && !defined(_MANAGED)
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
FMT_BEGIN_NAMESPACE
namespace
detail
{
// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
# ifndef __clang__
# pragma intrinsic(_BitScanForward)
# endif
inline
int
ctz
(
uint32_t
x
)
{
unsigned
long
r
=
0
;
_BitScanForward
(
&
r
,
x
);
FMT_ASSERT
(
x
!=
0
,
""
);
// Static analysis complains about using uninitialized data
// "r", but the only way that can happen is if "x" is 0,
// which the callers guarantee to not happen.
FMT_SUPPRESS_MSC_WARNING
(
6102
)
return
static_cast
<
int
>
(
r
);
}
# define FMT_BUILTIN_CTZ(n) detail::ctz(n)
# if defined(_WIN64) && !defined(__clang__)
# pragma intrinsic(_BitScanForward64)
# endif
inline
int
ctzll
(
uint64_t
x
)
{
unsigned
long
r
=
0
;
FMT_ASSERT
(
x
!=
0
,
""
);
// Static analysis complains about using uninitialized data
// "r", but the only way that can happen is if "x" is 0,
// which the callers guarantee to not happen.
FMT_SUPPRESS_MSC_WARNING
(
6102
)
# ifdef _WIN64
_BitScanForward64
(
&
r
,
x
);
# else
// Scan the low 32 bits.
if
(
_BitScanForward
(
&
r
,
static_cast
<
uint32_t
>
(
x
)))
return
r
;
// Scan the high 32 bits.
_BitScanReverse
(
&
r
,
static_cast
<
uint32_t
>
(
x
>>
32
));
r
+=
32
;
# endif
return
static_cast
<
int
>
(
r
);
}
# define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
}
// namespace detail
FMT_END_NAMESPACE
#endif
// Enable the deprecated numeric alignment.
// Enable the deprecated numeric alignment.
#ifndef FMT_DEPRECATED_NUMERIC_ALIGN
#ifndef FMT_DEPRECATED_NUMERIC_ALIGN
# define FMT_DEPRECATED_NUMERIC_ALIGN 0
# define FMT_DEPRECATED_NUMERIC_ALIGN 0
...
@@ -555,6 +614,10 @@ template <typename T> constexpr bool use_grisu() {
...
@@ -555,6 +614,10 @@ template <typename T> constexpr bool use_grisu() {
sizeof
(
T
)
<=
sizeof
(
double
);
sizeof
(
T
)
<=
sizeof
(
double
);
}
}
#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
# define FMT_USE_FULL_CACHE_DRAGONBOX 0
#endif
template
<
typename
T
>
template
<
typename
T
>
template
<
typename
U
>
template
<
typename
U
>
void
buffer
<
T
>::
append
(
const
U
*
begin
,
const
U
*
end
)
{
void
buffer
<
T
>::
append
(
const
U
*
begin
,
const
U
*
end
)
{
...
@@ -778,13 +841,72 @@ using uint32_or_64_or_128_t =
...
@@ -778,13 +841,72 @@ using uint32_or_64_or_128_t =
conditional_t
<
num_bits
<
T
>
()
<=
64
,
uint64_t
,
uint128_t
>>
;
conditional_t
<
num_bits
<
T
>
()
<=
64
,
uint64_t
,
uint128_t
>>
;
#endif
#endif
// 128-bit integer type used internally
struct
uint128_wrapper
{
uint128_wrapper
()
=
default
;
#if FMT_USE_INT128
uint128_t
internal_
;
uint128_wrapper
(
uint64_t
high
,
uint64_t
low
)
FMT_NOEXCEPT
:
internal_
{
static_cast
<
uint128_t
>
(
low
)
|
(
static_cast
<
uint128_t
>
(
high
)
<<
64
)}
{}
uint128_wrapper
(
uint128_t
u
)
:
internal_
{
u
}
{}
uint64_t
high
()
const
FMT_NOEXCEPT
{
return
uint64_t
(
internal_
>>
64
);
}
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_
;
uint128_wrapper
(
uint64_t
high
,
uint64_t
low
)
FMT_NOEXCEPT
:
high_
{
high
},
low_
{
low
}
{}
uint64_t
high
()
const
FMT_NOEXCEPT
{
return
high_
;
}
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
};
// Table entry type for divisibility test used internally
template
<
typename
T
>
struct
divtest_table_entry
{
T
mod_inv
;
T
max_quotient
;
};
// 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
FMT_EXTERN_TEMPLATE_API
basic_data
{
static
const
uint64_t
powers_of_10_64
[];
static
const
uint64_t
powers_of_10_64
[];
static
const
uint32_t
zero_or_powers_of_10_32
[];
static
const
uint32_t
zero_or_powers_of_10_32
[];
static
const
uint64_t
zero_or_powers_of_10_64
[];
static
const
uint64_t
zero_or_powers_of_10_64
[];
static
const
uint64_t
pow10_significands
[];
static
const
uint64_t
grisu_pow10_significands
[];
static
const
int16_t
pow10_exponents
[];
static
const
int16_t
grisu_pow10_exponents
[];
static
const
divtest_table_entry
<
uint32_t
>
divtest_table_for_pow5_32
[];
static
const
divtest_table_entry
<
uint64_t
>
divtest_table_for_pow5_64
[];
static
const
uint64_t
dragonbox_pow10_significands_64
[];
static
const
uint128_wrapper
dragonbox_pow10_significands_128
[];
#if !FMT_USE_FULL_CACHE_DRAGONBOX
static
const
uint64_t
powers_of_5_64
[];
static
const
uint32_t
dragonbox_pow10_recovery_errors
[];
#endif
// GCC generates slightly better code for pairs than chars.
// GCC generates slightly better code for pairs than chars.
using
digit_pair
=
char
[
2
];
using
digit_pair
=
char
[
2
];
static
const
digit_pair
digits
[];
static
const
digit_pair
digits
[];
...
@@ -878,6 +1000,13 @@ template <> int count_digits<4>(detail::fallback_uintptr n);
...
@@ -878,6 +1000,13 @@ template <> int count_digits<4>(detail::fallback_uintptr n);
# define FMT_ALWAYS_INLINE inline
# define FMT_ALWAYS_INLINE inline
#endif
#endif
// To suppress unnecessary security cookie checks
#if defined(FMT_MSC_VER) && !defined(__clang__)
# define FMT_SAFEBUFFERS __declspec(safebuffers)
#else
# define FMT_SAFEBUFFERS
#endif
#ifdef FMT_BUILTIN_CLZ
#ifdef FMT_BUILTIN_CLZ
// Optional version of count_digits for better performance on 32-bit platforms.
// Optional version of count_digits for better performance on 32-bit platforms.
inline
int
count_digits
(
uint32_t
n
)
{
inline
int
count_digits
(
uint32_t
n
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment