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
d705d516
Commit
d705d516
authored
Dec 29, 2016
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Parameterize basic_format_arg on context (#442)
parent
422236af
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
105 additions
and
100 deletions
+105
-100
fmt/format.cc
fmt/format.cc
+4
-2
fmt/format.h
fmt/format.h
+70
-67
fmt/printf.h
fmt/printf.h
+24
-25
test/format-impl-test.cc
test/format-impl-test.cc
+2
-1
test/util-test.cc
test/util-test.cc
+5
-5
No files found.
fmt/format.cc
View file @
d705d516
...
...
@@ -458,7 +458,7 @@ template struct internal::BasicData<void>;
template
void
internal
::
FixedBuffer
<
char
>
::
grow
(
std
::
size_t
);
template
void
internal
::
ArgMap
<
char
>
::
init
(
const
format_args
&
args
);
template
void
internal
::
ArgMap
<
format_context
>
::
init
(
const
format_args
&
args
);
template
void
printf_context
<
char
>
::
format
(
Writer
&
writer
);
...
...
@@ -472,9 +472,11 @@ template int internal::CharTraits<char>::format_float(
// Explicit instantiations for wchar_t.
template
class
basic_format_context
<
wchar_t
>;
template
void
internal
::
FixedBuffer
<
wchar_t
>
::
grow
(
std
::
size_t
);
template
void
internal
::
ArgMap
<
w
char_
t
>
::
init
(
const
wformat_args
&
args
);
template
void
internal
::
ArgMap
<
w
format_contex
t
>
::
init
(
const
wformat_args
&
args
);
template
void
printf_context
<
wchar_t
>
::
format
(
WWriter
&
writer
);
...
...
fmt/format.h
View file @
d705d516
This diff is collapsed.
Click to expand it.
fmt/printf.h
View file @
d705d516
...
...
@@ -80,14 +80,16 @@ struct is_same<T, T> {
enum
{
value
=
1
};
};
template
<
typename
T
,
typename
C
har
>
template
<
typename
T
,
typename
C
ontext
>
class
ArgConverter
{
private:
basic_format_arg
<
Char
>
&
arg_
;
Char
type_
;
typedef
typename
Context
::
char_type
Char
;
basic_format_arg
<
Context
>
&
arg_
;
typename
Context
::
char_type
type_
;
public:
ArgConverter
(
basic_format_arg
<
C
har
>
&
arg
,
Char
type
)
ArgConverter
(
basic_format_arg
<
C
ontext
>
&
arg
,
Char
type
)
:
arg_
(
arg
),
type_
(
type
)
{}
void
operator
()(
bool
value
)
{
...
...
@@ -105,11 +107,11 @@ class ArgConverter {
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
{
// Extra casts are used to silence warnings.
if
(
is_signed
)
{
arg_
=
internal
::
make_arg
<
format_c
ontext
>
(
arg_
=
internal
::
make_arg
<
C
ontext
>
(
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
)));
}
else
{
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
arg_
=
internal
::
make_arg
<
format_c
ontext
>
(
arg_
=
internal
::
make_arg
<
C
ontext
>
(
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
)));
}
}
else
{
...
...
@@ -117,10 +119,9 @@ class ArgConverter {
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
arg_
=
internal
::
make_arg
<
format_context
>
(
static_cast
<
LongLong
>
(
value
));
arg_
=
internal
::
make_arg
<
Context
>
(
static_cast
<
LongLong
>
(
value
));
}
else
{
arg_
=
internal
::
make_arg
<
format_c
ontext
>
(
arg_
=
internal
::
make_arg
<
C
ontext
>
(
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
));
}
}
...
...
@@ -137,32 +138,30 @@ class ArgConverter {
// If T is void, the argument is converted to corresponding signed or unsigned
// type depending on the type specifier: 'd' and 'i' - signed, other -
// unsigned).
template
<
typename
T
,
typename
Char
>
void
convert_arg
(
basic_format_arg
<
C
har
>
&
arg
,
Char
type
)
{
visit
(
ArgConverter
<
T
,
C
har
>
(
arg
,
type
),
arg
);
template
<
typename
T
,
typename
C
ontext
,
typename
C
har
>
void
convert_arg
(
basic_format_arg
<
C
ontext
>
&
arg
,
Char
type
)
{
visit
(
ArgConverter
<
T
,
C
ontext
>
(
arg
,
type
),
arg
);
}
// Converts an integer argument to char for printf.
template
<
typename
C
har
>
template
<
typename
C
ontext
>
class
CharConverter
{
private:
basic_format_arg
<
C
har
>
&
arg_
;
basic_format_arg
<
C
ontext
>
&
arg_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
public:
explicit
CharConverter
(
basic_format_arg
<
C
har
>
&
arg
)
:
arg_
(
arg
)
{}
explicit
CharConverter
(
basic_format_arg
<
C
ontext
>
&
arg
)
:
arg_
(
arg
)
{}
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
>::
type
operator
()(
T
value
)
{
arg_
=
internal
::
make_arg
<
basic_format_context
<
Char
>>
(
static_cast
<
char
>
(
value
));
arg_
=
internal
::
make_arg
<
Context
>
(
static_cast
<
char
>
(
value
));
}
template
<
typename
T
>
typename
std
::
enable_if
<!
std
::
is_integral
<
T
>::
value
>::
type
operator
()(
T
value
)
{
typename
std
::
enable_if
<!
std
::
is_integral
<
T
>::
value
>::
type
operator
()(
T
)
{
// No coversion needed for non-integral types.
}
};
...
...
@@ -301,12 +300,13 @@ class printf_context :
private:
typedef
internal
::
format_context_base
<
Char
,
printf_context
>
Base
;
typedef
typename
Base
::
format_arg
format_arg
;
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument.
basic_format_arg
<
Char
>
get_arg
(
format_arg
get_arg
(
const
Char
*
s
,
unsigned
arg_index
=
(
std
::
numeric_limits
<
unsigned
>::
max
)());
...
...
@@ -356,12 +356,11 @@ void printf_context<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s) {
}
template
<
typename
Char
,
typename
AF
>
basic_format_arg
<
Char
>
printf_context
<
Char
,
AF
>::
get_arg
(
typename
printf_context
<
Char
,
AF
>::
format_arg
printf_context
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
unsigned
arg_index
)
{
(
void
)
s
;
const
char
*
error
=
0
;
basic_format_arg
<
Char
>
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
format_arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
this
->
next_arg
(
error
)
:
Base
::
get_arg
(
arg_index
-
1
,
error
);
if
(
error
)
FMT_THROW
(
format_error
(
!*
s
?
"invalid format string"
:
error
));
...
...
@@ -433,7 +432,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
}
}
basic_format_arg
<
Char
>
arg
=
get_arg
(
s
,
arg_index
);
format_arg
arg
=
get_arg
(
s
,
arg_index
);
if
(
spec
.
flag
(
HASH_FLAG
)
&&
visit
(
internal
::
IsZeroInt
(),
arg
))
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
if
(
spec
.
fill_
==
'0'
)
{
...
...
@@ -488,7 +487,7 @@ void printf_context<Char, AF>::format(BasicWriter<Char> &writer) {
break
;
case
'c'
:
// TODO: handle wchar_t
visit
(
internal
::
CharConverter
<
Char
>
(
arg
),
arg
);
visit
(
internal
::
CharConverter
<
printf_context
<
Char
,
AF
>
>
(
arg
),
arg
);
break
;
}
}
...
...
test/format-impl-test.cc
View file @
d705d516
...
...
@@ -58,7 +58,8 @@ TEST(FormatTest, ArgConverter) {
using
fmt
::
format_arg
;
fmt
::
LongLong
value
=
std
::
numeric_limits
<
fmt
::
LongLong
>::
max
();
format_arg
arg
=
fmt
::
internal
::
make_arg
<
fmt
::
format_context
>
(
value
);
visit
(
fmt
::
internal
::
ArgConverter
<
fmt
::
LongLong
,
char
>
(
arg
,
'd'
),
arg
);
visit
(
fmt
::
internal
::
ArgConverter
<
fmt
::
LongLong
,
fmt
::
format_context
>
(
arg
,
'd'
),
arg
);
EXPECT_EQ
(
value
,
visit
(
ValueExtractor
<
fmt
::
LongLong
>
(),
arg
));
}
...
...
test/util-test.cc
View file @
d705d516
...
...
@@ -73,9 +73,9 @@ void format_value(fmt::BasicWriter<Char> &w, Test,
w
<<
"test"
;
}
template
<
typename
C
har
,
typename
T
>
basic_format_arg
<
C
har
>
make_arg
(
const
T
&
value
)
{
return
fmt
::
internal
::
make_arg
<
fmt
::
basic_format_context
<
Char
>
>
(
value
);
template
<
typename
C
ontext
,
typename
T
>
basic_format_arg
<
C
ontext
>
make_arg
(
const
T
&
value
)
{
return
fmt
::
internal
::
make_arg
<
Context
>
(
value
);
}
}
// namespace
...
...
@@ -487,7 +487,7 @@ VISIT_TYPE(float, double);
#define CHECK_ARG_(Char, expected, value) { \
testing::StrictMock<MockVisitor<decltype(expected)>> visitor; \
EXPECT_CALL(visitor, visit(expected)); \
fmt::visit(visitor, make_arg<
Char
>(value)); \
fmt::visit(visitor, make_arg<
fmt::basic_format_context<Char>
>(value)); \
}
#define CHECK_ARG(value) { \
...
...
@@ -575,7 +575,7 @@ TEST(UtilTest, CustomArg) {
EXPECT_EQ
(
"test"
,
w
.
str
());
return
Visitor
::
Result
();
}));
fmt
::
visit
(
visitor
,
make_arg
<
char
>
(
test
));
fmt
::
visit
(
visitor
,
make_arg
<
fmt
::
format_context
>
(
test
));
}
TEST
(
ArgVisitorTest
,
VisitInvalidArg
)
{
...
...
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