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
bc14c6ee
Commit
bc14c6ee
authored
Jul 03, 2019
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use the decimal point from locale
parent
476f25cd
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
45 additions
and
18 deletions
+45
-18
include/fmt/format-inl.h
include/fmt/format-inl.h
+8
-0
include/fmt/format.h
include/fmt/format.h
+29
-14
src/format.cc
src/format.cc
+2
-0
test/format-test.cc
test/format-test.cc
+0
-4
test/locale-test.cc
test/locale-test.cc
+6
-0
No files found.
include/fmt/format-inl.h
View file @
bc14c6ee
...
@@ -210,12 +210,20 @@ template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
...
@@ -210,12 +210,20 @@ template <typename Char> FMT_FUNC Char thousands_sep_impl(locale_ref loc) {
return
std
::
use_facet
<
std
::
numpunct
<
Char
>>
(
loc
.
get
<
std
::
locale
>
())
return
std
::
use_facet
<
std
::
numpunct
<
Char
>>
(
loc
.
get
<
std
::
locale
>
())
.
thousands_sep
();
.
thousands_sep
();
}
}
template
<
typename
Char
>
FMT_FUNC
Char
decimal_point_impl
(
locale_ref
loc
)
{
return
std
::
use_facet
<
std
::
numpunct
<
Char
>>
(
loc
.
get
<
std
::
locale
>
())
.
decimal_point
();
}
}
// namespace internal
}
// namespace internal
#else
#else
template
<
typename
Char
>
template
<
typename
Char
>
FMT_FUNC
Char
internal
::
thousands_sep_impl
(
locale_ref
)
{
FMT_FUNC
Char
internal
::
thousands_sep_impl
(
locale_ref
)
{
return
FMT_STATIC_THOUSANDS_SEPARATOR
;
return
FMT_STATIC_THOUSANDS_SEPARATOR
;
}
}
template
<
typename
Char
>
FMT_FUNC
Char
internal
::
decimal_point_impl
(
locale_ref
)
{
return
'.'
;
}
#endif
#endif
FMT_API
FMT_FUNC
format_error
::~
format_error
()
FMT_NOEXCEPT
{}
FMT_API
FMT_FUNC
format_error
::~
format_error
()
FMT_NOEXCEPT
{}
...
...
include/fmt/format.h
View file @
bc14c6ee
...
@@ -742,15 +742,21 @@ inline int count_digits(uint32_t n) {
...
@@ -742,15 +742,21 @@ inline int count_digits(uint32_t n) {
#endif
#endif
template
<
typename
Char
>
FMT_API
Char
thousands_sep_impl
(
locale_ref
loc
);
template
<
typename
Char
>
FMT_API
Char
thousands_sep_impl
(
locale_ref
loc
);
template
<
typename
Char
>
inline
Char
thousands_sep
(
locale_ref
loc
)
{
template
<
typename
Char
>
inline
Char
thousands_sep
(
locale_ref
loc
)
{
return
Char
(
thousands_sep_impl
<
char
>
(
loc
));
return
Char
(
thousands_sep_impl
<
char
>
(
loc
));
}
}
template
<
>
inline
wchar_t
thousands_sep
(
locale_ref
loc
)
{
template
<
>
inline
wchar_t
thousands_sep
(
locale_ref
loc
)
{
return
thousands_sep_impl
<
wchar_t
>
(
loc
);
return
thousands_sep_impl
<
wchar_t
>
(
loc
);
}
}
template
<
typename
Char
>
FMT_API
Char
decimal_point_impl
(
locale_ref
loc
);
template
<
typename
Char
>
inline
Char
decimal_point
(
locale_ref
loc
)
{
return
Char
(
decimal_point_impl
<
char
>
(
loc
));
}
template
<
>
inline
wchar_t
decimal_point
(
locale_ref
loc
)
{
return
decimal_point_impl
<
wchar_t
>
(
loc
);
}
// Formats a decimal unsigned integer value writing into buffer.
// Formats a decimal unsigned integer value writing into buffer.
// add_thousands_sep is called after writing each char to add a thousands
// add_thousands_sep is called after writing each char to add a thousands
// separator if necessary.
// separator if necessary.
...
@@ -985,13 +991,13 @@ template <typename Char, typename It> It write_exponent(int exp, It it) {
...
@@ -985,13 +991,13 @@ template <typename Char, typename It> It write_exponent(int exp, It it) {
// The number is given as v = digits * pow(10, exp).
// The number is given as v = digits * pow(10, exp).
template
<
typename
Char
,
typename
It
>
template
<
typename
Char
,
typename
It
>
It
grisu_prettify
(
const
char
*
digits
,
int
size
,
int
exp
,
It
it
,
It
grisu_prettify
(
const
char
*
digits
,
int
size
,
int
exp
,
It
it
,
gen_digits_params
params
)
{
gen_digits_params
params
,
Char
decimal_point
)
{
// pow(10, full_exp - 1) <= v <= pow(10, full_exp).
// pow(10, full_exp - 1) <= v <= pow(10, full_exp).
int
full_exp
=
size
+
exp
;
int
full_exp
=
size
+
exp
;
if
(
!
params
.
fixed
)
{
if
(
!
params
.
fixed
)
{
// Insert a decimal point after the first digit and add an exponent.
// Insert a decimal point after the first digit and add an exponent.
*
it
++
=
static_cast
<
Char
>
(
*
digits
);
*
it
++
=
static_cast
<
Char
>
(
*
digits
);
if
(
size
>
1
)
*
it
++
=
static_cast
<
Char
>
(
'.'
)
;
if
(
size
>
1
)
*
it
++
=
decimal_point
;
exp
+=
size
-
1
;
exp
+=
size
-
1
;
it
=
copy_str
<
Char
>
(
digits
+
1
,
digits
+
size
,
it
);
it
=
copy_str
<
Char
>
(
digits
+
1
,
digits
+
size
,
it
);
if
(
size
<
params
.
num_digits
)
if
(
size
<
params
.
num_digits
)
...
@@ -1005,7 +1011,7 @@ It grisu_prettify(const char* digits, int size, int exp, It it,
...
@@ -1005,7 +1011,7 @@ It grisu_prettify(const char* digits, int size, int exp, It it,
it
=
std
::
fill_n
(
it
,
full_exp
-
size
,
static_cast
<
Char
>
(
'0'
));
it
=
std
::
fill_n
(
it
,
full_exp
-
size
,
static_cast
<
Char
>
(
'0'
));
int
num_zeros
=
(
std
::
max
)(
params
.
num_digits
-
full_exp
,
1
);
int
num_zeros
=
(
std
::
max
)(
params
.
num_digits
-
full_exp
,
1
);
if
(
params
.
trailing_zeros
)
{
if
(
params
.
trailing_zeros
)
{
*
it
++
=
static_cast
<
Char
>
(
'.'
)
;
*
it
++
=
decimal_point
;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if
(
num_zeros
>
1000
)
if
(
num_zeros
>
1000
)
throw
std
::
runtime_error
(
"fuzz mode - avoiding excessive cpu use"
);
throw
std
::
runtime_error
(
"fuzz mode - avoiding excessive cpu use"
);
...
@@ -1018,10 +1024,10 @@ It grisu_prettify(const char* digits, int size, int exp, It it,
...
@@ -1018,10 +1024,10 @@ It grisu_prettify(const char* digits, int size, int exp, It it,
if
(
!
params
.
trailing_zeros
)
{
if
(
!
params
.
trailing_zeros
)
{
// Remove trailing zeros.
// Remove trailing zeros.
while
(
size
>
full_exp
&&
digits
[
size
-
1
]
==
'0'
)
--
size
;
while
(
size
>
full_exp
&&
digits
[
size
-
1
]
==
'0'
)
--
size
;
if
(
size
!=
full_exp
)
*
it
++
=
static_cast
<
Char
>
(
'.'
)
;
if
(
size
!=
full_exp
)
*
it
++
=
decimal_point
;
return
copy_str
<
Char
>
(
digits
+
full_exp
,
digits
+
size
,
it
);
return
copy_str
<
Char
>
(
digits
+
full_exp
,
digits
+
size
,
it
);
}
}
*
it
++
=
static_cast
<
Char
>
(
'.'
)
;
*
it
++
=
decimal_point
;
it
=
copy_str
<
Char
>
(
digits
+
full_exp
,
digits
+
size
,
it
);
it
=
copy_str
<
Char
>
(
digits
+
full_exp
,
digits
+
size
,
it
);
if
(
params
.
num_digits
>
size
)
{
if
(
params
.
num_digits
>
size
)
{
// Add trailing zeros.
// Add trailing zeros.
...
@@ -1037,7 +1043,7 @@ It grisu_prettify(const char* digits, int size, int exp, It it,
...
@@ -1037,7 +1043,7 @@ It grisu_prettify(const char* digits, int size, int exp, It it,
if
(
!
params
.
trailing_zeros
)
if
(
!
params
.
trailing_zeros
)
while
(
size
>
0
&&
digits
[
size
-
1
]
==
'0'
)
--
size
;
while
(
size
>
0
&&
digits
[
size
-
1
]
==
'0'
)
--
size
;
if
(
num_zeros
!=
0
||
size
!=
0
)
{
if
(
num_zeros
!=
0
||
size
!=
0
)
{
*
it
++
=
static_cast
<
Char
>
(
'.'
)
;
*
it
++
=
decimal_point
;
it
=
std
::
fill_n
(
it
,
num_zeros
,
static_cast
<
Char
>
(
'0'
));
it
=
std
::
fill_n
(
it
,
num_zeros
,
static_cast
<
Char
>
(
'0'
));
it
=
copy_str
<
Char
>
(
digits
,
digits
+
size
,
it
);
it
=
copy_str
<
Char
>
(
digits
,
digits
+
size
,
it
);
}
}
...
@@ -1453,18 +1459,24 @@ template <typename Range> class basic_writer {
...
@@ -1453,18 +1459,24 @@ template <typename Range> class basic_writer {
char
sign_
;
char
sign_
;
int
exp_
;
int
exp_
;
internal
::
gen_digits_params
params_
;
internal
::
gen_digits_params
params_
;
char_type
decimal_point_
;
public:
public:
grisu_writer
(
char
sign
,
internal
::
buffer
<
char
>&
digits
,
int
exp
,
grisu_writer
(
char
sign
,
internal
::
buffer
<
char
>&
digits
,
int
exp
,
const
internal
::
gen_digits_params
&
params
)
const
internal
::
gen_digits_params
&
params
,
:
digits_
(
digits
),
sign_
(
sign
),
exp_
(
exp
),
params_
(
params
)
{
char_type
decimal_point
)
:
digits_
(
digits
),
sign_
(
sign
),
exp_
(
exp
),
params_
(
params
),
decimal_point_
(
decimal_point
)
{
int
num_digits
=
static_cast
<
int
>
(
digits
.
size
());
int
num_digits
=
static_cast
<
int
>
(
digits
.
size
());
int
full_exp
=
num_digits
+
exp
-
1
;
int
full_exp
=
num_digits
+
exp
-
1
;
int
precision
=
params
.
num_digits
>
0
?
params
.
num_digits
:
11
;
int
precision
=
params
.
num_digits
>
0
?
params
.
num_digits
:
11
;
params_
.
fixed
|=
full_exp
>=
-
4
&&
full_exp
<
precision
;
params_
.
fixed
|=
full_exp
>=
-
4
&&
full_exp
<
precision
;
auto
it
=
internal
::
grisu_prettify
<
char
>
(
auto
it
=
internal
::
grisu_prettify
<
char
>
(
digits
.
data
(),
num_digits
,
exp
,
internal
::
counting_iterator
<
char
>
(),
digits
.
data
(),
num_digits
,
exp
,
internal
::
counting_iterator
<
char
>
(),
params_
);
params_
,
'.'
);
size_
=
it
.
count
();
size_
=
it
.
count
();
}
}
...
@@ -1475,7 +1487,7 @@ template <typename Range> class basic_writer {
...
@@ -1475,7 +1487,7 @@ template <typename Range> class basic_writer {
if
(
sign_
)
*
it
++
=
static_cast
<
char_type
>
(
sign_
);
if
(
sign_
)
*
it
++
=
static_cast
<
char_type
>
(
sign_
);
int
num_digits
=
static_cast
<
int
>
(
digits_
.
size
());
int
num_digits
=
static_cast
<
int
>
(
digits_
.
size
());
it
=
internal
::
grisu_prettify
<
char_type
>
(
digits_
.
data
(),
num_digits
,
exp_
,
it
=
internal
::
grisu_prettify
<
char_type
>
(
digits_
.
data
(),
num_digits
,
exp_
,
it
,
params_
);
it
,
params_
,
decimal_point_
);
}
}
};
};
...
@@ -2739,15 +2751,18 @@ void internal::basic_writer<Range>::write_double(T value,
...
@@ -2739,15 +2751,18 @@ void internal::basic_writer<Range>::write_double(T value,
}
else
if
(
spec
.
align
()
==
ALIGN_DEFAULT
)
{
}
else
if
(
spec
.
align
()
==
ALIGN_DEFAULT
)
{
as
.
align_
=
ALIGN_RIGHT
;
as
.
align_
=
ALIGN_RIGHT
;
}
}
// TODO: add thousands separators if handler.use_locale is set
char_type
decimal_point
=
handler
.
use_locale
?
internal
::
decimal_point
<
char_type
>
(
locale_
)
:
static_cast
<
char_type
>
(
'.'
);
if
(
use_grisu
)
{
if
(
use_grisu
)
{
auto
params
=
internal
::
gen_digits_params
();
auto
params
=
internal
::
gen_digits_params
();
params
.
fixed
=
handler
.
fixed
;
params
.
fixed
=
handler
.
fixed
;
params
.
num_digits
=
precision
;
params
.
num_digits
=
precision
;
params
.
trailing_zeros
=
(
precision
!=
0
&&
(
handler
.
fixed
||
!
spec
.
type
))
||
params
.
trailing_zeros
=
(
precision
!=
0
&&
(
handler
.
fixed
||
!
spec
.
type
))
||
spec
.
has
(
HASH_FLAG
);
spec
.
has
(
HASH_FLAG
);
write_padded
(
as
,
grisu_writer
{
sign
,
buffer
,
exp
,
params
}
);
write_padded
(
as
,
grisu_writer
(
sign
,
buffer
,
exp
,
params
,
decimal_point
)
);
}
else
{
}
else
{
// TODO: set decimal point
write_padded
(
as
,
double_writer
{
sign
,
buffer
});
write_padded
(
as
,
double_writer
{
sign
,
buffer
});
}
}
}
}
...
...
src/format.cc
View file @
bc14c6ee
...
@@ -22,6 +22,7 @@ template FMT_API std::locale internal::locale_ref::get<std::locale>() const;
...
@@ -22,6 +22,7 @@ template FMT_API std::locale internal::locale_ref::get<std::locale>() const;
// Explicit instantiations for char.
// Explicit instantiations for char.
template
FMT_API
char
internal
::
thousands_sep_impl
(
locale_ref
);
template
FMT_API
char
internal
::
thousands_sep_impl
(
locale_ref
);
template
FMT_API
char
internal
::
decimal_point_impl
(
locale_ref
);
template
FMT_API
void
internal
::
buffer
<
char
>
::
append
(
const
char
*
,
const
char
*
);
template
FMT_API
void
internal
::
buffer
<
char
>
::
append
(
const
char
*
,
const
char
*
);
...
@@ -43,6 +44,7 @@ template FMT_API void internal::sprintf_format(long double,
...
@@ -43,6 +44,7 @@ template FMT_API void internal::sprintf_format(long double,
// Explicit instantiations for wchar_t.
// Explicit instantiations for wchar_t.
template
FMT_API
wchar_t
internal
::
thousands_sep_impl
(
locale_ref
);
template
FMT_API
wchar_t
internal
::
thousands_sep_impl
(
locale_ref
);
template
FMT_API
wchar_t
internal
::
decimal_point_impl
(
locale_ref
);
template
FMT_API
void
internal
::
buffer
<
wchar_t
>
::
append
(
const
wchar_t
*
,
template
FMT_API
void
internal
::
buffer
<
wchar_t
>
::
append
(
const
wchar_t
*
,
const
wchar_t
*
);
const
wchar_t
*
);
...
...
test/format-test.cc
View file @
bc14c6ee
...
@@ -1447,10 +1447,6 @@ TEST(FormatterTest, FormatDouble) {
...
@@ -1447,10 +1447,6 @@ TEST(FormatterTest, FormatDouble) {
EXPECT_EQ
(
buffer
,
format
(
"{:A}"
,
-
42.0
));
EXPECT_EQ
(
buffer
,
format
(
"{:A}"
,
-
42.0
));
}
}
TEST
(
FormatterTest
,
FormatDoubleLocale
)
{
EXPECT_EQ
(
"1.23"
,
format
(
"{:n}"
,
1.23
));
}
TEST
(
FormatterTest
,
PrecisionRounding
)
{
TEST
(
FormatterTest
,
PrecisionRounding
)
{
EXPECT_EQ
(
"0"
,
format
(
"{:.0f}"
,
0.0
));
EXPECT_EQ
(
"0"
,
format
(
"{:.0f}"
,
0.0
));
EXPECT_EQ
(
"0"
,
format
(
"{:.0f}"
,
0.01
));
EXPECT_EQ
(
"0"
,
format
(
"{:.0f}"
,
0.01
));
...
...
test/locale-test.cc
View file @
bc14c6ee
...
@@ -11,9 +11,15 @@
...
@@ -11,9 +11,15 @@
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
template
<
typename
Char
>
struct
numpunct
:
std
::
numpunct
<
Char
>
{
template
<
typename
Char
>
struct
numpunct
:
std
::
numpunct
<
Char
>
{
protected:
protected:
Char
do_decimal_point
()
const
FMT_OVERRIDE
{
return
'?'
;
}
Char
do_thousands_sep
()
const
FMT_OVERRIDE
{
return
'~'
;
}
Char
do_thousands_sep
()
const
FMT_OVERRIDE
{
return
'~'
;
}
};
};
TEST
(
LocaleTest
,
DoubleDecimalPoint
)
{
std
::
locale
loc
(
std
::
locale
(),
new
numpunct
<
char
>
());
EXPECT_EQ
(
"1?23"
,
fmt
::
format
(
loc
,
"{:n}"
,
1.23
));
}
TEST
(
LocaleTest
,
Format
)
{
TEST
(
LocaleTest
,
Format
)
{
std
::
locale
loc
(
std
::
locale
(),
new
numpunct
<
char
>
());
std
::
locale
loc
(
std
::
locale
(),
new
numpunct
<
char
>
());
EXPECT_EQ
(
"1,234,567"
,
fmt
::
format
(
std
::
locale
(),
"{:n}"
,
1234567
));
EXPECT_EQ
(
"1,234,567"
,
fmt
::
format
(
std
::
locale
(),
"{:n}"
,
1234567
));
...
...
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