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
38325248
Commit
38325248
authored
Oct 03, 2018
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Count width in code points (#628)
parent
deb901b9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
40 additions
and
16 deletions
+40
-16
include/fmt/core.h
include/fmt/core.h
+5
-4
include/fmt/format-inl.h
include/fmt/format-inl.h
+3
-2
include/fmt/format.h
include/fmt/format.h
+31
-10
test/format-test.cc
test/format-test.cc
+1
-0
No files found.
include/fmt/core.h
View file @
38325248
...
@@ -1342,10 +1342,11 @@ struct is_contiguous<internal::basic_buffer<Char> >: std::true_type {};
...
@@ -1342,10 +1342,11 @@ struct is_contiguous<internal::basic_buffer<Char> >: std::true_type {};
/** Formats a string and writes the output to ``out``. */
/** Formats a string and writes the output to ``out``. */
template
<
typename
Container
,
typename
S
>
template
<
typename
Container
,
typename
S
>
typename
std
::
enable_if
<
typename
std
::
enable_if
<
is_contiguous
<
Container
>::
value
,
std
::
back_insert_iterator
<
Container
>>::
type
is_contiguous
<
Container
>::
value
,
std
::
back_insert_iterator
<
Container
>>::
type
vformat_to
(
std
::
back_insert_iterator
<
Container
>
out
,
vformat_to
(
const
S
&
format_str
,
std
::
back_insert_iterator
<
Container
>
out
,
basic_format_args
<
typename
buffer_context
<
FMT_CHAR
(
S
)
>::
type
>
args
)
{
const
S
&
format_str
,
basic_format_args
<
typename
buffer_context
<
FMT_CHAR
(
S
)
>::
type
>
args
)
{
internal
::
container_buffer
<
Container
>
buf
(
internal
::
get_container
(
out
));
internal
::
container_buffer
<
Container
>
buf
(
internal
::
get_container
(
out
));
vformat_to
(
buf
,
internal
::
to_string_view
(
format_str
),
args
);
vformat_to
(
buf
,
internal
::
to_string_view
(
format_str
),
args
);
return
out
;
return
out
;
...
...
include/fmt/format-inl.h
View file @
38325248
...
@@ -192,7 +192,7 @@ void report_error(FormatFunc func, int error_code,
...
@@ -192,7 +192,7 @@ void report_error(FormatFunc func, int error_code,
}
}
}
// namespace
}
// namespace
FMT_FUNC
size_t
internal
::
count_code_points
(
u8string_view
s
)
{
FMT_FUNC
size_t
internal
::
count_code_points
(
basic_string_view
<
char8_t
>
s
)
{
const
char8_t
*
data
=
s
.
data
();
const
char8_t
*
data
=
s
.
data
();
size_t
num_code_points
=
0
;
size_t
num_code_points
=
0
;
for
(
size_t
i
=
0
,
size
=
s
.
size
();
i
!=
size
;
++
i
)
{
for
(
size_t
i
=
0
,
size
=
s
.
size
();
i
!=
size
;
++
i
)
{
...
@@ -845,7 +845,8 @@ FMT_FUNC void report_windows_error(
...
@@ -845,7 +845,8 @@ FMT_FUNC void report_windows_error(
FMT_FUNC
void
vprint
(
std
::
FILE
*
f
,
string_view
format_str
,
format_args
args
)
{
FMT_FUNC
void
vprint
(
std
::
FILE
*
f
,
string_view
format_str
,
format_args
args
)
{
memory_buffer
buffer
;
memory_buffer
buffer
;
vformat_to
(
buffer
,
format_str
,
basic_format_args
<
buffer_context
<
char
>::
type
>
(
args
));
vformat_to
(
buffer
,
format_str
,
basic_format_args
<
buffer_context
<
char
>::
type
>
(
args
));
std
::
fwrite
(
buffer
.
data
(),
1
,
buffer
.
size
(),
f
);
std
::
fwrite
(
buffer
.
data
(),
1
,
buffer
.
size
(),
f
);
}
}
...
...
include/fmt/format.h
View file @
38325248
...
@@ -922,8 +922,11 @@ inline unsigned count_digits(uint64_t n) {
...
@@ -922,8 +922,11 @@ inline unsigned count_digits(uint64_t n) {
}
}
#endif
#endif
template
<
typename
Char
>
inline
size_t
count_code_points
(
basic_string_view
<
Char
>
s
)
{
return
s
.
size
();
}
// Counts the number of code points in a UTF-8 string.
// Counts the number of code points in a UTF-8 string.
FMT_API
size_t
count_code_points
(
u8string_view
s
);
FMT_API
size_t
count_code_points
(
basic_string_view
<
char8_t
>
s
);
inline
char8_t
to_char8_t
(
char
c
)
{
return
static_cast
<
char8_t
>
(
c
);
}
inline
char8_t
to_char8_t
(
char
c
)
{
return
static_cast
<
char8_t
>
(
c
);
}
...
@@ -1456,6 +1459,9 @@ class arg_formatter_base {
...
@@ -1456,6 +1459,9 @@ class arg_formatter_base {
struct
char_writer
{
struct
char_writer
{
char_type
value
;
char_type
value
;
size_t
size
()
const
{
return
1
;
}
template
<
typename
It
>
template
<
typename
It
>
void
operator
()(
It
&&
it
)
const
{
*
it
++
=
value
;
}
void
operator
()(
It
&&
it
)
const
{
*
it
++
=
value
;
}
};
};
...
@@ -2457,11 +2463,14 @@ class basic_writer {
...
@@ -2457,11 +2463,14 @@ class basic_writer {
template
<
typename
F
>
template
<
typename
F
>
struct
padded_int_writer
{
struct
padded_int_writer
{
size_t
size_
;
string_view
prefix
;
string_view
prefix
;
char_type
fill
;
char_type
fill
;
std
::
size_t
padding
;
std
::
size_t
padding
;
F
f
;
F
f
;
size_t
size
()
const
{
return
size_
;
}
template
<
typename
It
>
template
<
typename
It
>
void
operator
()(
It
&&
it
)
const
{
void
operator
()(
It
&&
it
)
const
{
if
(
prefix
.
size
()
!=
0
)
if
(
prefix
.
size
()
!=
0
)
...
@@ -2493,7 +2502,7 @@ class basic_writer {
...
@@ -2493,7 +2502,7 @@ class basic_writer {
align_spec
as
=
spec
;
align_spec
as
=
spec
;
if
(
spec
.
align
()
==
ALIGN_DEFAULT
)
if
(
spec
.
align
()
==
ALIGN_DEFAULT
)
as
.
align_
=
ALIGN_RIGHT
;
as
.
align_
=
ALIGN_RIGHT
;
write_padded
(
size
,
as
,
padded_int_writer
<
F
>
{
prefix
,
fill
,
padding
,
f
});
write_padded
(
size
,
as
,
padded_int_writer
<
F
>
{
size
,
prefix
,
fill
,
padding
,
f
});
}
}
// Writes a decimal integer.
// Writes a decimal integer.
...
@@ -2659,6 +2668,8 @@ class basic_writer {
...
@@ -2659,6 +2668,8 @@ class basic_writer {
char
sign
;
char
sign
;
const
char
*
str
;
const
char
*
str
;
size_t
size
()
const
{
return
static_cast
<
std
::
size_t
>
(
INF_SIZE
);
}
template
<
typename
It
>
template
<
typename
It
>
void
operator
()(
It
&&
it
)
const
{
void
operator
()(
It
&&
it
)
const
{
if
(
sign
)
if
(
sign
)
...
@@ -2673,6 +2684,8 @@ class basic_writer {
...
@@ -2673,6 +2684,8 @@ class basic_writer {
char
sign
;
char
sign
;
internal
::
buffer
&
buffer
;
internal
::
buffer
&
buffer
;
size_t
size
()
const
{
return
buffer
.
size
()
+
(
sign
?
1
:
0
);
}
template
<
typename
It
>
template
<
typename
It
>
void
operator
()(
It
&&
it
)
{
void
operator
()(
It
&&
it
)
{
if
(
sign
)
{
if
(
sign
)
{
...
@@ -2693,11 +2706,15 @@ class basic_writer {
...
@@ -2693,11 +2706,15 @@ class basic_writer {
template
<
typename
Char
>
template
<
typename
Char
>
struct
str_writer
{
struct
str_writer
{
const
Char
*
s
;
const
Char
*
s
;
std
::
size_t
size
;
size_t
size_
;
size_t
size
()
const
{
return
internal
::
count_code_points
(
basic_string_view
<
Char
>
(
s
,
size_
));
}
template
<
typename
It
>
template
<
typename
It
>
void
operator
()(
It
&&
it
)
const
{
void
operator
()(
It
&&
it
)
const
{
it
=
internal
::
copy_str
<
char_type
>
(
s
,
s
+
size
,
it
);
it
=
internal
::
copy_str
<
char_type
>
(
s
,
s
+
size
_
,
it
);
}
}
};
};
...
@@ -2796,11 +2813,12 @@ template <typename F>
...
@@ -2796,11 +2813,12 @@ template <typename F>
void
basic_writer
<
Range
>::
write_padded
(
void
basic_writer
<
Range
>::
write_padded
(
std
::
size_t
size
,
const
align_spec
&
spec
,
F
&&
f
)
{
std
::
size_t
size
,
const
align_spec
&
spec
,
F
&&
f
)
{
unsigned
width
=
spec
.
width
();
unsigned
width
=
spec
.
width
();
if
(
width
<=
size
)
size_t
num_code_points
=
width
!=
0
?
f
.
size
()
:
size
;
if
(
width
<=
num_code_points
)
return
f
(
reserve
(
size
));
return
f
(
reserve
(
size
));
auto
&&
it
=
reserve
(
width
);
auto
&&
it
=
reserve
(
width
+
(
size
-
num_code_points
)
);
char_type
fill
=
static_cast
<
char_type
>
(
spec
.
fill
());
char_type
fill
=
static_cast
<
char_type
>
(
spec
.
fill
());
std
::
size_t
padding
=
width
-
size
;
std
::
size_t
padding
=
width
-
num_code_points
;
if
(
spec
.
align
()
==
ALIGN_RIGHT
)
{
if
(
spec
.
align
()
==
ALIGN_RIGHT
)
{
it
=
std
::
fill_n
(
it
,
padding
,
fill
);
it
=
std
::
fill_n
(
it
,
padding
,
fill
);
f
(
it
);
f
(
it
);
...
@@ -3533,12 +3551,14 @@ using format_to_n_context = typename fmt::format_context_t<
...
@@ -3533,12 +3551,14 @@ using format_to_n_context = typename fmt::format_context_t<
fmt
::
internal
::
truncating_iterator
<
OutputIt
>
,
Char
>::
type
;
fmt
::
internal
::
truncating_iterator
<
OutputIt
>
,
Char
>::
type
;
template
<
typename
OutputIt
,
typename
Char
=
typename
OutputIt
::
value_type
>
template
<
typename
OutputIt
,
typename
Char
=
typename
OutputIt
::
value_type
>
using
format_to_n_args
=
fmt
::
basic_format_args
<
format_to_n_context
<
OutputIt
,
Char
>>
;
using
format_to_n_args
=
fmt
::
basic_format_args
<
format_to_n_context
<
OutputIt
,
Char
>>
;
template
<
typename
OutputIt
,
typename
Char
,
typename
...
Args
>
template
<
typename
OutputIt
,
typename
Char
,
typename
...
Args
>
inline
format_arg_store
<
format_to_n_context
<
OutputIt
,
Char
>
,
Args
...
>
inline
format_arg_store
<
format_to_n_context
<
OutputIt
,
Char
>
,
Args
...
>
make_format_to_n_args
(
const
Args
&
...
args
)
{
make_format_to_n_args
(
const
Args
&
...
args
)
{
return
format_arg_store
<
format_to_n_context
<
OutputIt
,
Char
>
,
Args
...
>
(
args
...);
return
format_arg_store
<
format_to_n_context
<
OutputIt
,
Char
>
,
Args
...
>
(
args
...);
}
}
template
<
typename
OutputIt
,
typename
Char
,
typename
...
Args
>
template
<
typename
OutputIt
,
typename
Char
,
typename
...
Args
>
...
@@ -3561,7 +3581,8 @@ template <typename OutputIt, typename String, typename... Args>
...
@@ -3561,7 +3581,8 @@ template <typename OutputIt, typename String, typename... Args>
inline
typename
std
::
enable_if
<
inline
typename
std
::
enable_if
<
internal
::
is_format_string
<
String
>::
value
,
internal
::
is_format_string
<
String
>::
value
,
format_to_n_result
<
OutputIt
>>::
type
format_to_n
(
format_to_n_result
<
OutputIt
>>::
type
format_to_n
(
OutputIt
out
,
std
::
size_t
n
,
const
String
&
format_str
,
const
Args
&
...
args
)
{
OutputIt
out
,
std
::
size_t
n
,
const
String
&
format_str
,
const
Args
&
...
args
)
{
internal
::
check_format_string
<
Args
...
>
(
format_str
);
internal
::
check_format_string
<
Args
...
>
(
format_str
);
typedef
FMT_CHAR
(
String
)
Char
;
typedef
FMT_CHAR
(
String
)
Char
;
format_arg_store
<
format_to_n_context
<
OutputIt
,
Char
>
,
Args
...
>
as
{
args
...
};
format_arg_store
<
format_to_n_context
<
OutputIt
,
Char
>
,
Args
...
>
as
{
args
...
};
...
...
test/format-test.cc
View file @
38325248
...
@@ -2448,6 +2448,7 @@ TEST(FormatTest, U8StringViewLiteral) {
...
@@ -2448,6 +2448,7 @@ TEST(FormatTest, U8StringViewLiteral) {
const
fmt
::
char8_t
*
data
=
s
.
data
();
const
fmt
::
char8_t
*
data
=
s
.
data
();
EXPECT_EQ
(
data
[
0
],
'a'
);
EXPECT_EQ
(
data
[
0
],
'a'
);
EXPECT_EQ
(
data
[
1
],
'b'
);
EXPECT_EQ
(
data
[
1
],
'b'
);
EXPECT_EQ
(
format
(
"{:*^5}"
_u
,
"🤡"
_u
),
"**🤡**"
_u
);
}
}
#endif
#endif
...
...
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