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
cb4c5949
Commit
cb4c5949
authored
Jun 07, 2019
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Deprecate convert_to_int
parent
40779749
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
61 additions
and
55 deletions
+61
-55
include/fmt/core.h
include/fmt/core.h
+23
-20
include/fmt/format.h
include/fmt/format.h
+1
-3
include/fmt/ostream.h
include/fmt/ostream.h
+0
-8
test/core-test.cc
test/core-test.cc
+23
-8
test/format-test.cc
test/format-test.cc
+2
-2
test/ostream-test.cc
test/ostream-test.cc
+12
-14
No files found.
include/fmt/core.h
View file @
cb4c5949
...
...
@@ -483,17 +483,19 @@ template <typename Context> class basic_format_args;
// A formatter for objects of type T.
template
<
typename
T
,
typename
Char
=
char
,
typename
Enable
=
void
>
struct
formatter
{
// A deleted default constructor indicates a disabled formatter.
formatter
()
=
delete
;
};
template
<
typename
T
,
typename
Char
,
typename
Enable
=
void
>
struct
convert_to_int
:
bool_constant
<!
std
::
is_arithmetic
<
T
>::
value
&&
std
::
is_convertible
<
T
,
int
>::
value
>
{};
struct
FMT_DEPRECATED
convert_to_int
:
bool_constant
<!
std
::
is_arithmetic
<
T
>::
value
&&
std
::
is_convertible
<
T
,
int
>::
value
>
{};
namespace
internal
{
// Specifies if T has an enabled formatter specialization.
The
type can be
// formattable even if it doesn't have a formatter e.g. via conversion.
// Specifies if T has an enabled formatter specialization.
A
type can be
// formattable even if it doesn't have a formatter e.g. via
a
conversion.
template
<
typename
T
,
typename
Context
>
using
has_formatter
=
std
::
is_constructible
<
typename
Context
::
template
formatter_type
<
T
>
>
;
...
...
@@ -603,16 +605,16 @@ inline Container& get_container(std::back_insert_iterator<Container> it) {
return
*
accessor
(
it
).
container
;
}
template
<
typename
T
>
struct
no_formatter_error
:
std
::
false_type
{};
template
<
typename
T
,
typename
Char
=
char
,
typename
Enable
=
void
>
struct
fallback_formatter
{
static_assert
(
no_formatter_error
<
T
>::
value
,
"don't know how to format the type, include fmt/ostream.h if it provides "
"an operator<< that should be used"
);
fallback_formatter
()
=
delete
;
};
// Specifies if T has an enabled fallback_formatter specialization.
template
<
typename
T
,
typename
Context
>
using
has_fallback_formatter
=
std
::
is_constructible
<
fallback_formatter
<
T
,
typename
Context
::
char_type
>>
;
template
<
typename
Char
>
struct
named_arg_base
;
template
<
typename
T
,
typename
Char
>
struct
named_arg
;
...
...
@@ -658,8 +660,6 @@ FMT_TYPE_CONSTANT(const Char*, cstring_type);
FMT_TYPE_CONSTANT
(
basic_string_view
<
Char
>
,
string_type
);
FMT_TYPE_CONSTANT
(
const
void
*
,
pointer_type
);
#undef FMT_TYPE_CONSTANT
FMT_CONSTEXPR
bool
is_integral
(
type
t
)
{
FMT_ASSERT
(
t
!=
internal
::
named_arg_type
,
"invalid argument type"
);
return
t
>
internal
::
none_type
&&
t
<=
internal
::
last_integer_type
;
...
...
@@ -795,6 +795,7 @@ FMT_MAKE_VALUE_SAME(long_long_type, long long)
FMT_MAKE_VALUE_SAME
(
ulong_long_type
,
unsigned
long
long
)
FMT_MAKE_VALUE
(
int_type
,
signed
char
,
int
)
FMT_MAKE_VALUE
(
uint_type
,
unsigned
char
,
unsigned
)
FMT_MAKE_VALUE
(
char_type
,
char
,
int
)
// This doesn't use FMT_MAKE_VALUE because of ambiguity in gcc 4.4.
template
<
typename
C
,
typename
Char
,
...
...
@@ -803,10 +804,11 @@ FMT_CONSTEXPR init<C, int, char_type> make_value(Char val) {
return
{
val
};
}
template
<
typename
C
,
FMT_ENABLE_IF
(
!
std
::
is_same
<
typename
C
::
char_type
,
char
>
::
value
)
>
FMT_CONSTEXPR
init
<
C
,
int
,
char_type
>
make_value
(
char
val
)
{
return
val
;
template
<
typename
C
,
typename
T
,
FMT_ENABLE_IF
(
is_char
<
T
>
::
value
&&
!
std
::
is_same
<
T
,
char
>::
value
&&
!
std
::
is_same
<
T
,
typename
C
::
char_type
>::
value
)
>
FMT_CONSTEXPR
init
<
C
,
int
,
char_type
>
make_value
(
const
T
&
)
{
static_assert
(
!
sizeof
(
T
),
"mixing character types is disallowed"
);
}
FMT_MAKE_VALUE
(
double_type
,
float
,
double
)
...
...
@@ -855,8 +857,8 @@ void make_value(const T*) {
}
template
<
typename
C
,
typename
T
,
FMT_ENABLE_IF
(
std
::
is_enum
<
T
>
::
value
&&
convert_to_int
<
T
,
typename
C
::
char_type
>::
value
)
>
FMT_ENABLE_IF
(
std
::
is_enum
<
T
>
::
value
&&
!
has_formatter
<
T
,
C
>::
value
&&
!
has_fallback_formatter
<
T
,
C
>::
value
)
>
inline
init
<
C
,
int
,
int_type
>
make_value
(
const
T
&
val
)
{
return
static_cast
<
int
>
(
val
);
}
...
...
@@ -866,8 +868,9 @@ inline init<C, int, int_type> make_value(const T& val) {
template
<
typename
C
,
typename
T
,
typename
Char
=
typename
C
::
char_type
,
typename
U
=
typename
std
::
remove_volatile
<
T
>
::
type
,
FMT_ENABLE_IF
(
!
convert_to_int
<
U
,
Char
>::
value
&&
!
std
::
is_same
<
U
,
Char
>::
value
&&
FMT_ENABLE_IF
(
!
std
::
is_same
<
U
,
Char
>::
value
&&
(
!
std
::
is_convertible
<
U
,
int
>::
value
||
has_fallback_formatter
<
U
,
C
>::
value
)
&&
!
std
::
is_convertible
<
U
,
basic_string_view
<
Char
>>::
value
&&
!
std
::
is_constructible
<
basic_string_view
<
Char
>
,
U
>::
value
&&
!
internal
::
is_string
<
U
>::
value
)
>
...
...
include/fmt/format.h
View file @
cb4c5949
...
...
@@ -3035,7 +3035,7 @@ class format_int {
std
::
string
str
()
const
{
return
std
::
string
(
str_
,
size
());
}
};
//
formatter specializations
for the core types corresponding to internal::type
//
A formatter specialization
for the core types corresponding to internal::type
// constants.
template
<
typename
T
,
typename
Char
>
struct
formatter
<
T
,
Char
,
...
...
@@ -3131,8 +3131,6 @@ FMT_FORMAT_AS(Char*, const Char*);
FMT_FORMAT_AS
(
std
::
basic_string
<
Char
>
,
basic_string_view
<
Char
>
);
FMT_FORMAT_AS
(
std
::
nullptr_t
,
const
void
*
);
#undef FMT_FORMAT_AS
template
<
typename
Char
>
struct
formatter
<
void
*
,
Char
>
:
formatter
<
const
void
*
,
Char
>
{
template
<
typename
FormatContext
>
...
...
include/fmt/ostream.h
View file @
cb4c5949
...
...
@@ -109,14 +109,6 @@ struct fallback_formatter<T, Char,
};
}
// namespace internal
// Disable conversion to int if T has an overloaded operator<< which is a free
// function (not a member of std::ostream).
template
<
typename
T
,
typename
Char
>
struct
convert_to_int
<
T
,
Char
,
enable_if_t
<
internal
::
is_streamable
<
T
,
Char
>::
value
>>
{
static
const
bool
value
=
false
;
};
template
<
typename
Char
>
void
vprint
(
std
::
basic_ostream
<
Char
>&
os
,
basic_string_view
<
Char
>
format_str
,
basic_format_args
<
buffer_context
<
Char
>>
args
)
{
...
...
test/core-test.cc
View file @
cb4c5949
...
...
@@ -432,14 +432,29 @@ TEST(StringViewTest, Compare) {
check_op
<
std
::
greater_equal
>
();
}
enum
basic_enum
{};
enum
enum_with_underlying_type
:
char
{};
TEST
(
CoreTest
,
ConvertToInt
)
{
EXPECT_FALSE
((
fmt
::
convert_to_int
<
char
,
char
>::
value
));
EXPECT_FALSE
((
fmt
::
convert_to_int
<
const
char
*
,
char
>::
value
));
EXPECT_TRUE
((
fmt
::
convert_to_int
<
basic_enum
,
char
>::
value
));
EXPECT_TRUE
((
fmt
::
convert_to_int
<
enum_with_underlying_type
,
char
>::
value
));
struct
enabled_formatter
{};
struct
disabled_formatter
{};
struct
disabled_formatter_convertible
{
operator
int
()
const
{
return
42
;
}
};
FMT_BEGIN_NAMESPACE
template
<
>
struct
formatter
<
enabled_formatter
>
{
auto
parse
(
format_parse_context
&
ctx
)
->
decltype
(
ctx
.
begin
())
{
return
ctx
.
begin
();
}
auto
format
(
enabled_formatter
,
format_context
&
ctx
)
->
decltype
(
ctx
.
out
())
{
return
ctx
.
out
();
}
};
FMT_END_NAMESPACE
TEST
(
CoreTest
,
HasFormatter
)
{
using
fmt
::
internal
::
has_formatter
;
using
context
=
fmt
::
format_context
;
EXPECT_TRUE
((
has_formatter
<
enabled_formatter
,
context
>::
value
));
EXPECT_FALSE
((
has_formatter
<
disabled_formatter
,
context
>::
value
));
EXPECT_FALSE
((
has_formatter
<
disabled_formatter_convertible
,
context
>::
value
));
}
struct
convertible_to_int
{
...
...
test/format-test.cc
View file @
cb4c5949
...
...
@@ -1877,8 +1877,8 @@ enum TestEnum { A };
TEST
(
FormatTest
,
Enum
)
{
EXPECT_EQ
(
"0"
,
fmt
::
format
(
"{}"
,
A
));
}
TEST
(
FormatTest
,
FormatterNotSpecialized
)
{
EXPECT_FALSE
((
fmt
::
internal
::
has_formatter
<
fmt
::
formatter
<
TestEnum
>
,
fmt
::
format_context
>::
value
));
EXPECT_FALSE
((
fmt
::
internal
::
has_formatter
<
fmt
::
formatter
<
TestEnum
>
,
fmt
::
format_context
>::
value
));
}
#if FMT_HAS_FEATURE(cxx_strong_enums)
...
...
test/ostream-test.cc
View file @
cb4c5949
...
...
@@ -46,24 +46,22 @@ struct type_with_comma_op {};
template
<
typename
T
>
void
operator
,(
type_with_comma_op
,
const
T
&
);
template
<
typename
T
>
type_with_comma_op
operator
<<
(
T
&
,
const
Date
&
);
enum
TestE
num
{};
static
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
TestE
num
)
{
return
os
<<
"
TestE
num"
;
enum
streamable_e
num
{};
static
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
streamable_e
num
)
{
return
os
<<
"
streamable_e
num"
;
}
static
std
::
wostream
&
operator
<<
(
std
::
wostream
&
os
,
TestE
num
)
{
return
os
<<
L"
TestE
num"
;
static
std
::
wostream
&
operator
<<
(
std
::
wostream
&
os
,
streamable_e
num
)
{
return
os
<<
L"
streamable_e
num"
;
}
enum
TestEnum2
{
A
};
enum
unstreamable_enum
{
};
TEST
(
OStreamTest
,
Enum
)
{
EXPECT_FALSE
((
fmt
::
convert_to_int
<
TestEnum
,
char
>::
value
));
EXPECT_EQ
(
"TestEnum"
,
fmt
::
format
(
"{}"
,
TestEnum
()));
EXPECT_EQ
(
"0"
,
fmt
::
format
(
"{}"
,
A
));
EXPECT_FALSE
((
fmt
::
convert_to_int
<
TestEnum
,
wchar_t
>::
value
));
EXPECT_EQ
(
L"TestEnum"
,
fmt
::
format
(
L"{}"
,
TestEnum
()));
EXPECT_EQ
(
L"0"
,
fmt
::
format
(
L"{}"
,
A
));
EXPECT_EQ
(
"streamable_enum"
,
fmt
::
format
(
"{}"
,
streamable_enum
()));
EXPECT_EQ
(
"0"
,
fmt
::
format
(
"{}"
,
unstreamable_enum
()));
EXPECT_EQ
(
L"streamable_enum"
,
fmt
::
format
(
L"{}"
,
streamable_enum
()));
EXPECT_EQ
(
L"0"
,
fmt
::
format
(
L"{}"
,
unstreamable_enum
()));
}
typedef
fmt
::
back_insert_range
<
fmt
::
internal
::
buffer
<
char
>>
range
;
...
...
@@ -81,8 +79,8 @@ TEST(OStreamTest, CustomArg) {
fmt
::
format_specs
spec
;
test_arg_formatter
af
(
ctx
,
spec
);
fmt
::
visit_format_arg
(
af
,
fmt
::
internal
::
make_arg
<
fmt
::
format_context
>
(
TestE
num
()));
EXPECT_EQ
(
"
TestE
num"
,
std
::
string
(
buffer
.
data
(),
buffer
.
size
()));
af
,
fmt
::
internal
::
make_arg
<
fmt
::
format_context
>
(
streamable_e
num
()));
EXPECT_EQ
(
"
streamable_e
num"
,
std
::
string
(
buffer
.
data
(),
buffer
.
size
()));
}
TEST
(
OStreamTest
,
Format
)
{
...
...
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