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
418659ad
Commit
418659ad
authored
Mar 03, 2018
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix compilation errors on gcc 4.4
parent
1d2adef2
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
232 additions
and
183 deletions
+232
-183
include/fmt/core.h
include/fmt/core.h
+17
-3
include/fmt/format.h
include/fmt/format.h
+156
-128
include/fmt/ostream.h
include/fmt/ostream.h
+2
-2
include/fmt/printf.h
include/fmt/printf.h
+23
-23
test/custom-formatter-test.cc
test/custom-formatter-test.cc
+1
-1
test/format-impl-test.cc
test/format-impl-test.cc
+2
-2
test/format-test.cc
test/format-test.cc
+8
-5
test/util-test.cc
test/util-test.cc
+23
-19
No files found.
include/fmt/core.h
View file @
418659ad
...
@@ -167,6 +167,11 @@
...
@@ -167,6 +167,11 @@
# define FMT_USE_EXPERIMENTAL_STRING_VIEW
# define FMT_USE_EXPERIMENTAL_STRING_VIEW
#endif
#endif
// std::result_of is defined in <functional> in gcc 4.4.
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 404
# include <functional>
#endif
namespace
fmt
{
namespace
fmt
{
// An implementation of declval for pre-C++11 compilers such as gcc 4.
// An implementation of declval for pre-C++11 compilers such as gcc 4.
...
@@ -302,8 +307,6 @@ class basic_buffer {
...
@@ -302,8 +307,6 @@ class basic_buffer {
std
::
size_t
capacity_
;
std
::
size_t
capacity_
;
protected:
protected:
typedef
const
T
&
const_reference
;
basic_buffer
(
T
*
p
=
FMT_NULL
,
std
::
size_t
size
=
0
,
std
::
size_t
capacity
=
0
)
basic_buffer
(
T
*
p
=
FMT_NULL
,
std
::
size_t
size
=
0
,
std
::
size_t
capacity
=
0
)
FMT_NOEXCEPT:
ptr_
(
p
),
size_
(
size
),
capacity_
(
capacity
)
{}
FMT_NOEXCEPT:
ptr_
(
p
),
size_
(
size
),
capacity_
(
capacity
)
{}
...
@@ -322,6 +325,7 @@ class basic_buffer {
...
@@ -322,6 +325,7 @@ class basic_buffer {
public:
public:
typedef
T
value_type
;
typedef
T
value_type
;
typedef
const
T
&
const_reference
;
virtual
~
basic_buffer
()
{}
virtual
~
basic_buffer
()
{}
...
@@ -655,6 +659,16 @@ enum { MAX_PACKED_ARGS = 15 };
...
@@ -655,6 +659,16 @@ enum { MAX_PACKED_ARGS = 15 };
template
<
typename
Context
>
template
<
typename
Context
>
class
arg_map
;
class
arg_map
;
template
<
typename
>
struct
result_of
;
template
<
typename
F
,
typename
...
Args
>
struct
result_of
<
F
(
Args
...)
>
{
// A workaround for gcc 4.4 that doesn't allow F to be a reference.
typedef
typename
std
::
result_of
<
typename
std
::
remove_reference
<
F
>::
type
(
Args
...)
>::
type
type
;
};
}
}
// A formatting argument. It is a trivially copyable/constructible type to
// A formatting argument. It is a trivially copyable/constructible type to
...
@@ -669,7 +683,7 @@ class basic_arg {
...
@@ -669,7 +683,7 @@ class basic_arg {
friend
FMT_CONSTEXPR
basic_arg
<
ContextType
>
internal
::
make_arg
(
const
T
&
value
);
friend
FMT_CONSTEXPR
basic_arg
<
ContextType
>
internal
::
make_arg
(
const
T
&
value
);
template
<
typename
Visitor
,
typename
Ctx
>
template
<
typename
Visitor
,
typename
Ctx
>
friend
FMT_CONSTEXPR
typename
std
::
result_of
<
Visitor
(
int
)
>::
type
friend
FMT_CONSTEXPR
typename
internal
::
result_of
<
Visitor
(
int
)
>::
type
visit
(
Visitor
&&
vis
,
basic_arg
<
Ctx
>
arg
);
visit
(
Visitor
&&
vis
,
basic_arg
<
Ctx
>
arg
);
friend
class
basic_format_args
<
Context
>
;
friend
class
basic_format_args
<
Context
>
;
...
...
include/fmt/format.h
View file @
418659ad
This diff is collapsed.
Click to expand it.
include/fmt/ostream.h
View file @
418659ad
...
@@ -61,8 +61,8 @@ class convert_to_int<T, Char, true> {
...
@@ -61,8 +61,8 @@ class convert_to_int<T, Char, true> {
private:
private:
template
<
typename
U
>
template
<
typename
U
>
static
decltype
(
static
decltype
(
std
::
declval
<
test_stream
<
Char
>&>
()
<<
std
::
declval
<
U
>
(),
std
::
true_type
()
)
internal
::
declval
<
test_stream
<
Char
>&>
(
)
test
(
int
);
<<
internal
::
declval
<
U
>
(),
std
::
true_type
())
test
(
int
);
template
<
typename
>
template
<
typename
>
static
std
::
false_type
test
(...);
static
std
::
false_type
test
(...);
...
...
include/fmt/printf.h
View file @
418659ad
...
@@ -19,7 +19,7 @@ namespace internal {
...
@@ -19,7 +19,7 @@ namespace internal {
// Checks if a value fits in int - used to avoid warnings about comparing
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
// signed and unsigned integers.
template
<
bool
IsSigned
>
template
<
bool
IsSigned
>
struct
IntC
hecker
{
struct
int_c
hecker
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
{
static
bool
fits_in_int
(
T
value
)
{
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
...
@@ -29,7 +29,7 @@ struct IntChecker {
...
@@ -29,7 +29,7 @@ struct IntChecker {
};
};
template
<
>
template
<
>
struct
IntC
hecker
<
true
>
{
struct
int_c
hecker
<
true
>
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
{
static
bool
fits_in_int
(
T
value
)
{
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
...
@@ -38,12 +38,12 @@ struct IntChecker<true> {
...
@@ -38,12 +38,12 @@ struct IntChecker<true> {
static
bool
fits_in_int
(
int
)
{
return
true
;
}
static
bool
fits_in_int
(
int
)
{
return
true
;
}
};
};
class
PrintfPrecisionHandler
{
class
printf_precision_handler
:
public
function
<
int
>
{
public:
public:
template
<
typename
T
>
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
int
>::
type
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
int
>::
type
operator
()(
T
value
)
{
operator
()(
T
value
)
{
if
(
!
IntC
hecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
if
(
!
int_c
hecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
FMT_THROW
(
format_error
(
"number is too big"
));
FMT_THROW
(
format_error
(
"number is too big"
));
return
static_cast
<
int
>
(
value
);
return
static_cast
<
int
>
(
value
);
}
}
...
@@ -57,7 +57,7 @@ class PrintfPrecisionHandler {
...
@@ -57,7 +57,7 @@ class PrintfPrecisionHandler {
};
};
// An argument visitor that returns true iff arg is a zero integer.
// An argument visitor that returns true iff arg is a zero integer.
class
IsZeroInt
{
class
is_zero_int
:
public
function
<
bool
>
{
public:
public:
template
<
typename
T
>
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
bool
>::
type
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
bool
>::
type
...
@@ -77,7 +77,7 @@ struct make_unsigned_or_bool<bool> {
...
@@ -77,7 +77,7 @@ struct make_unsigned_or_bool<bool> {
};
};
template
<
typename
T
,
typename
Context
>
template
<
typename
T
,
typename
Context
>
class
ArgConverter
{
class
arg_converter
:
public
function
<
void
>
{
private:
private:
typedef
typename
Context
::
char_type
Char
;
typedef
typename
Context
::
char_type
Char
;
...
@@ -85,7 +85,7 @@ class ArgConverter {
...
@@ -85,7 +85,7 @@ class ArgConverter {
typename
Context
::
char_type
type_
;
typename
Context
::
char_type
type_
;
public:
public:
ArgC
onverter
(
basic_arg
<
Context
>
&
arg
,
Char
type
)
arg_c
onverter
(
basic_arg
<
Context
>
&
arg
,
Char
type
)
:
arg_
(
arg
),
type_
(
type
)
{}
:
arg_
(
arg
),
type_
(
type
)
{}
void
operator
()(
bool
value
)
{
void
operator
()(
bool
value
)
{
...
@@ -134,19 +134,19 @@ class ArgConverter {
...
@@ -134,19 +134,19 @@ class ArgConverter {
// unsigned).
// unsigned).
template
<
typename
T
,
typename
Context
,
typename
Char
>
template
<
typename
T
,
typename
Context
,
typename
Char
>
void
convert_arg
(
basic_arg
<
Context
>
&
arg
,
Char
type
)
{
void
convert_arg
(
basic_arg
<
Context
>
&
arg
,
Char
type
)
{
visit
(
ArgC
onverter
<
T
,
Context
>
(
arg
,
type
),
arg
);
visit
(
arg_c
onverter
<
T
,
Context
>
(
arg
,
type
),
arg
);
}
}
// Converts an integer argument to char for printf.
// Converts an integer argument to char for printf.
template
<
typename
Context
>
template
<
typename
Context
>
class
CharConverter
{
class
char_converter
:
public
function
<
void
>
{
private:
private:
basic_arg
<
Context
>
&
arg_
;
basic_arg
<
Context
>
&
arg_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharC
onverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
char_c
onverter
);
public:
public:
explicit
CharC
onverter
(
basic_arg
<
Context
>
&
arg
)
:
arg_
(
arg
)
{}
explicit
char_c
onverter
(
basic_arg
<
Context
>
&
arg
)
:
arg_
(
arg
)
{}
template
<
typename
T
>
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
>::
type
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
>::
type
...
@@ -163,16 +163,16 @@ class CharConverter {
...
@@ -163,16 +163,16 @@ class CharConverter {
// Checks if an argument is a valid printf width specifier and sets
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
// left alignment if it is negative.
template
<
typename
Char
>
template
<
typename
Char
>
class
PrintfWidthHandler
{
class
printf_width_handler
:
public
function
<
unsigned
>
{
private:
private:
typedef
basic_format_specs
<
Char
>
format_specs
;
typedef
basic_format_specs
<
Char
>
format_specs
;
format_specs
&
spec_
;
format_specs
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
PrintfWidthH
andler
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
printf_width_h
andler
);
public:
public:
explicit
PrintfWidthH
andler
(
format_specs
&
spec
)
:
spec_
(
spec
)
{}
explicit
printf_width_h
andler
(
format_specs
&
spec
)
:
spec_
(
spec
)
{}
template
<
typename
T
>
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
unsigned
>::
type
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
unsigned
>::
type
...
@@ -213,10 +213,11 @@ class basic_printf_context;
...
@@ -213,10 +213,11 @@ class basic_printf_context;
\endrst
\endrst
*/
*/
template
<
typename
Range
>
template
<
typename
Range
>
class
printf_arg_formatter
:
public
internal
::
arg_formatter_base
<
Range
>
{
class
printf_arg_formatter
:
public
internal
::
function
<
void
>
,
public
internal
::
arg_formatter_base
<
Range
>
{
private:
private:
typedef
typename
Range
::
value_type
char_type
;
typedef
typename
Range
::
value_type
char_type
;
typedef
decltype
(
std
::
declval
<
Range
>
().
begin
())
iterator
;
typedef
decltype
(
internal
::
declval
<
Range
>
().
begin
())
iterator
;
typedef
internal
::
arg_formatter_base
<
Range
>
base
;
typedef
internal
::
arg_formatter_base
<
Range
>
base
;
typedef
basic_printf_context
<
iterator
,
char_type
>
context_type
;
typedef
basic_printf_context
<
iterator
,
char_type
>
context_type
;
...
@@ -417,7 +418,7 @@ unsigned basic_printf_context<OutputIt, Char, AF>::parse_header(
...
@@ -417,7 +418,7 @@ unsigned basic_printf_context<OutputIt, Char, AF>::parse_header(
}
else
if
(
*
it
==
'*'
)
{
}
else
if
(
*
it
==
'*'
)
{
++
it
;
++
it
;
spec
.
width_
=
spec
.
width_
=
visit
(
internal
::
PrintfWidthH
andler
<
char_type
>
(
spec
),
get_arg
(
it
));
visit
(
internal
::
printf_width_h
andler
<
char_type
>
(
spec
),
get_arg
(
it
));
}
}
return
arg_index
;
return
arg_index
;
}
}
...
@@ -453,14 +454,14 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
...
@@ -453,14 +454,14 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
}
else
if
(
*
it
==
'*'
)
{
}
else
if
(
*
it
==
'*'
)
{
++
it
;
++
it
;
spec
.
precision_
=
spec
.
precision_
=
visit
(
internal
::
PrintfPrecisionH
andler
(),
get_arg
(
it
));
visit
(
internal
::
printf_precision_h
andler
(),
get_arg
(
it
));
}
else
{
}
else
{
spec
.
precision_
=
0
;
spec
.
precision_
=
0
;
}
}
}
}
format_arg
arg
=
get_arg
(
it
,
arg_index
);
format_arg
arg
=
get_arg
(
it
,
arg_index
);
if
(
spec
.
flag
(
HASH_FLAG
)
&&
visit
(
internal
::
IsZeroI
nt
(),
arg
))
if
(
spec
.
flag
(
HASH_FLAG
)
&&
visit
(
internal
::
is_zero_i
nt
(),
arg
))
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
if
(
spec
.
fill_
==
'0'
)
{
if
(
spec
.
fill_
==
'0'
)
{
if
(
arg
.
is_arithmetic
())
if
(
arg
.
is_arithmetic
())
...
@@ -514,7 +515,7 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
...
@@ -514,7 +515,7 @@ void basic_printf_context<OutputIt, Char, AF>::format() {
break
;
break
;
case
'c'
:
case
'c'
:
// TODO: handle wchar_t
// TODO: handle wchar_t
visit
(
internal
::
CharC
onverter
<
basic_printf_context
>
(
arg
),
arg
);
visit
(
internal
::
char_c
onverter
<
basic_printf_context
>
(
arg
),
arg
);
break
;
break
;
}
}
}
}
...
@@ -539,8 +540,7 @@ struct printf_context {
...
@@ -539,8 +540,7 @@ struct printf_context {
std
::
back_insert_iterator
<
Buffer
>
,
typename
Buffer
::
value_type
>
type
;
std
::
back_insert_iterator
<
Buffer
>
,
typename
Buffer
::
value_type
>
type
;
};
};
typedef
basic_format_args
<
typedef
basic_format_args
<
printf_context
<
internal
::
buffer
>::
type
>
printf_args
;
typename
printf_context
<
internal
::
buffer
>::
type
>
printf_args
;
inline
std
::
string
vsprintf
(
string_view
format
,
printf_args
args
)
{
inline
std
::
string
vsprintf
(
string_view
format
,
printf_args
args
)
{
memory_buffer
buffer
;
memory_buffer
buffer
;
...
@@ -565,7 +565,7 @@ inline std::string sprintf(string_view format_str, const Args & ... args) {
...
@@ -565,7 +565,7 @@ inline std::string sprintf(string_view format_str, const Args & ... args) {
inline
std
::
wstring
vsprintf
(
inline
std
::
wstring
vsprintf
(
wstring_view
format
,
wstring_view
format
,
basic_format_args
<
typename
printf_context
<
internal
::
wbuffer
>::
type
>
args
)
{
basic_format_args
<
printf_context
<
internal
::
wbuffer
>::
type
>
args
)
{
wmemory_buffer
buffer
;
wmemory_buffer
buffer
;
printf
(
buffer
,
format
,
args
);
printf
(
buffer
,
format
,
args
);
return
to_string
(
buffer
);
return
to_string
(
buffer
);
...
...
test/custom-formatter-test.cc
View file @
418659ad
...
@@ -18,7 +18,7 @@ class CustomArgFormatter :
...
@@ -18,7 +18,7 @@ class CustomArgFormatter :
public
fmt
::
arg_formatter
<
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>>
{
public
fmt
::
arg_formatter
<
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>>
{
public:
public:
typedef
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>
range
;
typedef
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>
range
;
typedef
decltype
(
std
::
declval
<
range
>
().
begin
())
iterator
;
typedef
decltype
(
fmt
::
internal
::
declval
<
range
>
().
begin
())
iterator
;
typedef
fmt
::
arg_formatter
<
range
>
base
;
typedef
fmt
::
arg_formatter
<
range
>
base
;
CustomArgFormatter
(
fmt
::
basic_context
<
iterator
,
char
>
&
ctx
,
CustomArgFormatter
(
fmt
::
basic_context
<
iterator
,
char
>
&
ctx
,
...
...
test/format-impl-test.cc
View file @
418659ad
...
@@ -44,7 +44,7 @@
...
@@ -44,7 +44,7 @@
#undef max
#undef max
template
<
typename
T
>
template
<
typename
T
>
struct
ValueExtractor
{
struct
ValueExtractor
:
fmt
::
internal
::
function
<
T
>
{
T
operator
()(
T
value
)
{
T
operator
()(
T
value
)
{
return
value
;
return
value
;
}
}
...
@@ -59,7 +59,7 @@ struct ValueExtractor {
...
@@ -59,7 +59,7 @@ struct ValueExtractor {
TEST
(
FormatTest
,
ArgConverter
)
{
TEST
(
FormatTest
,
ArgConverter
)
{
long
long
value
=
std
::
numeric_limits
<
long
long
>::
max
();
long
long
value
=
std
::
numeric_limits
<
long
long
>::
max
();
auto
arg
=
fmt
::
internal
::
make_arg
<
fmt
::
context
>
(
value
);
auto
arg
=
fmt
::
internal
::
make_arg
<
fmt
::
context
>
(
value
);
visit
(
fmt
::
internal
::
ArgC
onverter
<
long
long
,
fmt
::
context
>
(
arg
,
'd'
),
arg
);
visit
(
fmt
::
internal
::
arg_c
onverter
<
long
long
,
fmt
::
context
>
(
arg
,
'd'
),
arg
);
EXPECT_EQ
(
value
,
visit
(
ValueExtractor
<
long
long
>
(),
arg
));
EXPECT_EQ
(
value
,
visit
(
ValueExtractor
<
long
long
>
(),
arg
));
}
}
...
...
test/format-test.cc
View file @
418659ad
...
@@ -1205,7 +1205,9 @@ TEST(FormatterTest, FormatPointer) {
...
@@ -1205,7 +1205,9 @@ TEST(FormatterTest, FormatPointer) {
EXPECT_EQ
(
"0x"
+
std
::
string
(
sizeof
(
void
*
)
*
CHAR_BIT
/
4
,
'f'
),
EXPECT_EQ
(
"0x"
+
std
::
string
(
sizeof
(
void
*
)
*
CHAR_BIT
/
4
,
'f'
),
format
(
"{0}"
,
reinterpret_cast
<
void
*>
(
~
uintptr_t
())));
format
(
"{0}"
,
reinterpret_cast
<
void
*>
(
~
uintptr_t
())));
EXPECT_EQ
(
"0x1234"
,
format
(
"{}"
,
fmt
::
ptr
(
reinterpret_cast
<
int
*>
(
0x1234
))));
EXPECT_EQ
(
"0x1234"
,
format
(
"{}"
,
fmt
::
ptr
(
reinterpret_cast
<
int
*>
(
0x1234
))));
EXPECT_EQ
(
"0x0"
,
format
(
"{}"
,
nullptr
));
#if FMT_USE_NULLPTR
EXPECT_EQ
(
"0x0"
,
format
(
"{}"
,
FMT_NULL
));
#endif
}
}
TEST
(
FormatterTest
,
FormatString
)
{
TEST
(
FormatterTest
,
FormatString
)
{
...
@@ -1450,7 +1452,7 @@ TEST(FormatTest, JoinArg) {
...
@@ -1450,7 +1452,7 @@ TEST(FormatTest, JoinArg) {
EXPECT_EQ
(
L"(1, 2, 3)"
,
format
(
L"({})"
,
join
(
v1
,
v1
+
3
,
L", "
)));
EXPECT_EQ
(
L"(1, 2, 3)"
,
format
(
L"({})"
,
join
(
v1
,
v1
+
3
,
L", "
)));
EXPECT_EQ
(
"1, 2, 3"
,
format
(
"{0:{1}}"
,
join
(
v1
,
v1
+
3
,
", "
),
1
));
EXPECT_EQ
(
"1, 2, 3"
,
format
(
"{0:{1}}"
,
join
(
v1
,
v1
+
3
,
", "
),
1
));
#if FMT_
HAS_GXX_CXX11
#if FMT_
USE_TRAILING_RETURN && (!FMT_GCC_VERSION || FMT_GCC_VERSION >= 405)
EXPECT_EQ
(
"(1, 2, 3)"
,
format
(
"({})"
,
join
(
v1
,
", "
)));
EXPECT_EQ
(
"(1, 2, 3)"
,
format
(
"({})"
,
join
(
v1
,
", "
)));
EXPECT_EQ
(
"(+01.20, +03.40)"
,
format
(
"({:+06.2f})"
,
join
(
v2
,
", "
)));
EXPECT_EQ
(
"(+01.20, +03.40)"
,
format
(
"({:+06.2f})"
,
join
(
v2
,
", "
)));
#endif
#endif
...
@@ -1551,7 +1553,8 @@ TEST(FormatTest, FixedEnum) {
...
@@ -1551,7 +1553,8 @@ TEST(FormatTest, FixedEnum) {
typedef
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>
buffer_range
;
typedef
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
>
buffer_range
;
class
mock_arg_formatter
:
class
mock_arg_formatter
:
public
fmt
::
internal
::
function
<
void
>
,
public
fmt
::
internal
::
arg_formatter_base
<
buffer_range
>
{
public
fmt
::
internal
::
arg_formatter_base
<
buffer_range
>
{
private:
private:
MOCK_METHOD1
(
call
,
void
(
int
value
));
MOCK_METHOD1
(
call
,
void
(
int
value
));
...
@@ -1602,8 +1605,8 @@ template <>
...
@@ -1602,8 +1605,8 @@ template <>
struct
formatter
<
variant
>
:
dynamic_formatter
<>
{
struct
formatter
<
variant
>
:
dynamic_formatter
<>
{
auto
format
(
variant
value
,
context
&
ctx
)
->
decltype
(
ctx
.
begin
())
{
auto
format
(
variant
value
,
context
&
ctx
)
->
decltype
(
ctx
.
begin
())
{
if
(
value
.
type
==
variant
::
INT
)
if
(
value
.
type
==
variant
::
INT
)
return
dynamic_formatter
::
format
(
42
,
ctx
);
return
dynamic_formatter
<>
::
format
(
42
,
ctx
);
return
dynamic_formatter
::
format
(
"foo"
,
ctx
);
return
dynamic_formatter
<>
::
format
(
"foo"
,
ctx
);
}
}
};
};
}
}
...
...
test/util-test.cc
View file @
418659ad
...
@@ -478,12 +478,12 @@ bool operator==(custom_value<Char> lhs, custom_value<Char> rhs) {
...
@@ -478,12 +478,12 @@ bool operator==(custom_value<Char> lhs, custom_value<Char> rhs) {
}
}
}
}
template
<
typename
T
>
// Use a unique result type to make sure that there are no undesirable
struct
MockVisitor
{
// conversions.
// Use a unique result type to make sure that there are no undesirable
struct
Result
{};
// conversions.
struct
Result
{};
template
<
typename
T
>
struct
MockVisitor
:
fmt
::
internal
::
function
<
Result
>
{
MockVisitor
()
{
MockVisitor
()
{
ON_CALL
(
*
this
,
visit
(
_
)).
WillByDefault
(
Return
(
Result
()));
ON_CALL
(
*
this
,
visit
(
_
)).
WillByDefault
(
Return
(
Result
()));
}
}
...
@@ -529,8 +529,9 @@ VISIT_TYPE(float, double);
...
@@ -529,8 +529,9 @@ VISIT_TYPE(float, double);
fmt::visit(visitor, make_arg<fmt::basic_context<iterator, Char>>(value)); \
fmt::visit(visitor, make_arg<fmt::basic_context<iterator, Char>>(value)); \
}
}
#define CHECK_ARG(value) { \
#define CHECK_ARG(value, typename_) { \
typename VisitType<decltype(value)>::Type expected = value; \
typedef decltype(value) value_type; \
typename_ VisitType<value_type>::Type expected = value; \
CHECK_ARG_(char, expected, value) \
CHECK_ARG_(char, expected, value) \
CHECK_ARG_(wchar_t, expected, value) \
CHECK_ARG_(wchar_t, expected, value) \
}
}
...
@@ -556,9 +557,9 @@ typename std::enable_if<std::is_floating_point<T>::value, T>::type
...
@@ -556,9 +557,9 @@ typename std::enable_if<std::is_floating_point<T>::value, T>::type
}
}
TYPED_TEST
(
NumericArgTest
,
MakeAndVisit
)
{
TYPED_TEST
(
NumericArgTest
,
MakeAndVisit
)
{
CHECK_ARG
(
test_value
<
TypeParam
>
());
CHECK_ARG
(
test_value
<
TypeParam
>
()
,
typename
);
CHECK_ARG
(
std
::
numeric_limits
<
TypeParam
>::
min
());
CHECK_ARG
(
std
::
numeric_limits
<
TypeParam
>::
min
()
,
typename
);
CHECK_ARG
(
std
::
numeric_limits
<
TypeParam
>::
max
());
CHECK_ARG
(
std
::
numeric_limits
<
TypeParam
>::
max
()
,
typename
);
}
}
TEST
(
UtilTest
,
CharArg
)
{
TEST
(
UtilTest
,
CharArg
)
{
...
@@ -594,22 +595,25 @@ TEST(UtilTest, PointerArg) {
...
@@ -594,22 +595,25 @@ TEST(UtilTest, PointerArg) {
const
void
*
cp
=
0
;
const
void
*
cp
=
0
;
CHECK_ARG_
(
char
,
cp
,
p
);
CHECK_ARG_
(
char
,
cp
,
p
);
CHECK_ARG_
(
wchar_t
,
cp
,
p
);
CHECK_ARG_
(
wchar_t
,
cp
,
p
);
CHECK_ARG
(
cp
);
CHECK_ARG
(
cp
,
);
}
}
TEST
(
UtilTest
,
CustomArg
)
{
struct
check_custom
{
::
Test
test
;
Result
operator
()(
fmt
::
basic_arg
<
fmt
::
context
>::
handle
h
)
const
{
typedef
typename
fmt
::
basic_arg
<
fmt
::
context
>::
handle
handle
;
typedef
MockVisitor
<
handle
>
visitor
;
testing
::
StrictMock
<
visitor
>
v
;
EXPECT_CALL
(
v
,
visit
(
_
)).
WillOnce
(
testing
::
Invoke
([
&
](
handle
h
)
{
fmt
::
memory_buffer
buffer
;
fmt
::
memory_buffer
buffer
;
fmt
::
internal
::
basic_buffer
<
char
>
&
base
=
buffer
;
fmt
::
internal
::
basic_buffer
<
char
>
&
base
=
buffer
;
fmt
::
context
ctx
(
std
::
back_inserter
(
base
),
""
,
fmt
::
format_args
());
fmt
::
context
ctx
(
std
::
back_inserter
(
base
),
""
,
fmt
::
format_args
());
h
.
format
(
ctx
);
h
.
format
(
ctx
);
EXPECT_EQ
(
"test"
,
std
::
string
(
buffer
.
data
(),
buffer
.
size
()));
EXPECT_EQ
(
"test"
,
std
::
string
(
buffer
.
data
(),
buffer
.
size
()));
return
visitor
::
Result
();
return
Result
();
}));
}
};
TEST
(
UtilTest
,
CustomArg
)
{
::
Test
test
;
typedef
MockVisitor
<
fmt
::
basic_arg
<
fmt
::
context
>::
handle
>
visitor
;
testing
::
StrictMock
<
visitor
>
v
;
EXPECT_CALL
(
v
,
visit
(
_
)).
WillOnce
(
testing
::
Invoke
(
check_custom
()));
fmt
::
visit
(
v
,
make_arg
<
fmt
::
context
>
(
test
));
fmt
::
visit
(
v
,
make_arg
<
fmt
::
context
>
(
test
));
}
}
...
...
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