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
6ced4230
Commit
6ced4230
authored
Dec 02, 2015
by
vitaut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial support for custom formatters
parent
5f8af5ef
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
60 additions
and
26 deletions
+60
-26
format.h
format.h
+40
-23
test/util-test.cc
test/util-test.cc
+20
-3
No files found.
format.h
View file @
6ced4230
...
...
@@ -1021,8 +1021,11 @@ template<>
struct
Not
<
false
>
{
enum
{
value
=
1
};
};
// Makes an Arg object from any type.
template
<
typename
Cha
r
>
template
<
typename
Formatte
r
>
class
MakeValue
:
public
Arg
{
public:
typedef
typename
Formatter
::
Char
Char
;
private:
// The following two methods are private to disallow formatting of
// arbitrary pointers. If you want to output a pointer cast it to
...
...
@@ -1060,7 +1063,7 @@ class MakeValue : public Arg {
template
<
typename
T
>
static
void
format_custom_arg
(
void
*
formatter
,
const
void
*
arg
,
void
*
format_str_ptr
)
{
format
(
*
static_cast
<
BasicFormatter
<
Char
>
*>
(
formatter
),
format
(
*
static_cast
<
Formatter
*>
(
formatter
),
*
static_cast
<
const
Char
**>
(
format_str_ptr
),
*
static_cast
<
const
T
*>
(
arg
));
}
...
...
@@ -1166,7 +1169,7 @@ class MakeValue : public Arg {
}
// Additional template param `Char_` is needed here because make_type always
// uses
MakeValue<char>
.
// uses
char
.
template
<
typename
Char_
>
MakeValue
(
const
NamedArg
<
Char_
>
&
value
)
{
pointer
=
&
value
;
}
...
...
@@ -1178,10 +1181,12 @@ template <typename Char>
struct
NamedArg
:
Arg
{
BasicStringRef
<
Char
>
name
;
typedef
internal
::
MakeValue
<
BasicFormatter
<
Char
>
>
MakeValue
;
template
<
typename
T
>
NamedArg
(
BasicStringRef
<
Char
>
argname
,
const
T
&
value
)
:
Arg
(
MakeValue
<
Char
>
(
value
)),
name
(
argname
)
{
type
=
static_cast
<
internal
::
Arg
::
Type
>
(
MakeValue
<
Char
>
::
type
(
value
));
:
Arg
(
MakeValue
(
value
)),
name
(
argname
)
{
type
=
static_cast
<
Arg
::
Type
>
(
MakeValue
::
type
(
value
));
}
};
...
...
@@ -1455,8 +1460,11 @@ class PrintfFormatter : private FormatterBase {
}
// namespace internal
// A formatter.
template
<
typename
Char
>
template
<
typename
Char
Type
>
class
BasicFormatter
:
private
internal
::
FormatterBase
{
public:
typedef
CharType
Char
;
private:
BasicWriter
<
Char
>
&
writer_
;
internal
::
ArgMap
<
Char
>
map_
;
...
...
@@ -1730,7 +1738,9 @@ namespace internal {
inline
uint64_t
make_type
()
{
return
0
;
}
template
<
typename
T
>
inline
uint64_t
make_type
(
const
T
&
arg
)
{
return
MakeValue
<
char
>::
type
(
arg
);
}
inline
uint64_t
make_type
(
const
T
&
arg
)
{
return
MakeValue
<
BasicFormatter
<
char
>
>::
type
(
arg
);
}
template
<
unsigned
N
>
struct
ArgArray
{
...
...
@@ -1754,7 +1764,8 @@ inline void do_set_types(Arg *) {}
template
<
typename
T
,
typename
...
Args
>
inline
void
do_set_types
(
Arg
*
args
,
const
T
&
arg
,
const
Args
&
...
tail
)
{
args
->
type
=
static_cast
<
Arg
::
Type
>
(
MakeValue
<
T
>::
type
(
arg
));
args
->
type
=
static_cast
<
Arg
::
Type
>
(
MakeValue
<
BasicFormatter
<
char
>
>::
type
(
arg
));
do_set_types
(
args
+
1
,
tail
...);
}
...
...
@@ -1770,24 +1781,24 @@ inline void set_types(Value *, const Args & ...) {
// Do nothing as types are passed separately from values.
}
template
<
typename
Cha
r
,
typename
Value
>
template
<
typename
Formatte
r
,
typename
Value
>
inline
void
store_args
(
Value
*
)
{}
template
<
typename
Cha
r
,
typename
Arg
,
typename
T
,
typename
...
Args
>
template
<
typename
Formatte
r
,
typename
Arg
,
typename
T
,
typename
...
Args
>
inline
void
store_args
(
Arg
*
args
,
const
T
&
arg
,
const
Args
&
...
tail
)
{
// Assign only the Value subobject of Arg and don't overwrite type (if any)
// that is assigned by set_types.
Value
&
value
=
*
args
;
value
=
MakeValue
<
Cha
r
>
(
arg
);
store_args
<
Cha
r
>
(
args
+
1
,
tail
...);
value
=
MakeValue
<
Formatte
r
>
(
arg
);
store_args
<
Formatte
r
>
(
args
+
1
,
tail
...);
}
template
<
typename
Cha
r
,
typename
...
Args
>
template
<
typename
Formatte
r
,
typename
...
Args
>
ArgList
make_arg_list
(
typename
ArgArray
<
sizeof
...(
Args
)
>::
Type
array
,
const
Args
&
...
args
)
{
if
(
check
(
sizeof
...(
Args
)
>=
ArgList
::
MAX_PACKED_ARGS
))
set_types
(
array
,
args
...);
store_args
<
Cha
r
>
(
array
,
args
...);
store_args
<
Formatte
r
>
(
array
,
args
...);
return
ArgList
(
make_type
(
args
...),
array
);
}
#else
...
...
@@ -1847,8 +1858,10 @@ class FormatBuf : public std::basic_streambuf<Char> {
# define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
# define FMT_MAKE_ARG_TYPE(n) T##n
# define FMT_MAKE_ARG(n) const T##n &v##n
# define FMT_ASSIGN_char(n) arr[n] = fmt::internal::MakeValue<char>(v##n)
# define FMT_ASSIGN_wchar_t(n) arr[n] = fmt::internal::MakeValue<wchar_t>(v##n)
# define FMT_ASSIGN_char(n) \
arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<char> >(v##n)
# define FMT_ASSIGN_wchar_t(n) \
arr[n] = fmt::internal::MakeValue< fmt::BasicFormatter<wchar_t> >(v##n)
#if FMT_USE_VARIADIC_TEMPLATES
// Defines a variadic function returning void.
...
...
@@ -1856,7 +1869,8 @@ class FormatBuf : public std::basic_streambuf<Char> {
template <typename... Args> \
void func(arg_type arg0, const Args & ... args) { \
typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \
func(arg0, fmt::internal::make_arg_list<Char>(array, args...)); \
func(arg0, fmt::internal::make_arg_list< \
fmt::BasicFormatter<Char> >(array, args...)); \
}
// Defines a variadic constructor.
...
...
@@ -1864,12 +1878,14 @@ class FormatBuf : public std::basic_streambuf<Char> {
template <typename... Args> \
ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \
func(arg0, arg1, fmt::internal::make_arg_list<Char>(array, args...)); \
func(arg0, arg1, fmt::internal::make_arg_list< \
fmt::BasicFormatter<Char> >(array, args...)); \
}
#else
# define FMT_MAKE_REF(n) fmt::internal::MakeValue<Char>(v##n)
# define FMT_MAKE_REF(n) \
fmt::internal::MakeValue< fmt::BasicFormatter<Char> >(v##n)
# define FMT_MAKE_REF2(n) v##n
// Defines a wrapper for a function taking one argument of type arg_type
...
...
@@ -2735,9 +2751,9 @@ void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {
output
<<
value
;
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
format_buf
.
size
());
internal
::
Arg
arg
=
internal
::
MakeValue
<
Char
>
(
str
)
;
arg
.
type
=
static_cast
<
internal
::
Arg
::
Type
>
(
internal
::
MakeValue
<
Char
>
::
type
(
str
));
typedef
internal
::
MakeValue
<
BasicFormatter
<
Char
>
>
MakeValue
;
internal
::
Arg
arg
=
MakeValue
(
str
);
arg
.
type
=
static_cast
<
internal
::
Arg
::
Type
>
(
MakeValue
::
type
(
str
));
format_str
=
f
.
format
(
format_str
,
arg
);
}
...
...
@@ -3062,7 +3078,8 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
const Args & ... args) { \
typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \
call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
fmt::internal::make_arg_list<Char>(array, args...)); \
fmt::internal::make_arg_list< \
fmt::BasicFormatter<Char> >(array, args...)); \
}
#else
// Defines a wrapper for a function taking __VA_ARGS__ arguments
...
...
test/util-test.cc
View file @
6ced4230
...
...
@@ -69,9 +69,9 @@ std::basic_ostream<Char> &operator<<(std::basic_ostream<Char> &os, Test) {
template
<
typename
Char
,
typename
T
>
Arg
make_arg
(
const
T
&
value
)
{
Arg
arg
=
fmt
::
internal
::
MakeValue
<
Char
>
(
value
)
;
arg
.
type
=
static_cast
<
Arg
::
Type
>
(
fmt
::
internal
::
MakeValue
<
Char
>
::
type
(
value
));
typedef
fmt
::
internal
::
MakeValue
<
fmt
::
BasicFormatter
<
Char
>
>
MakeValue
;
Arg
arg
=
MakeValue
(
value
);
arg
.
type
=
static_cast
<
Arg
::
Type
>
(
MakeValue
::
type
(
value
));
return
arg
;
}
}
// namespace
...
...
@@ -575,6 +575,23 @@ TEST(UtilTest, ArgList) {
EXPECT_EQ
(
Arg
::
NONE
,
args
[
1
].
type
);
}
struct
CustomFormatter
{
typedef
char
Char
;
};
void
format
(
CustomFormatter
&
,
const
char
*&
s
,
const
Test
&
)
{
s
=
"custom_format"
;
}
TEST
(
UtilTest
,
MakeValueWithCustomFormatter
)
{
::
Test
t
;
Arg
arg
=
fmt
::
internal
::
MakeValue
<
CustomFormatter
>
(
t
);
CustomFormatter
formatter
;
const
char
*
s
=
""
;
arg
.
custom
.
format
(
&
formatter
,
&
t
,
&
s
);
EXPECT_STREQ
(
"custom_format"
,
s
);
}
struct
Result
{
Arg
arg
;
...
...
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