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
e928b672
Commit
e928b672
authored
Jul 04, 2018
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix MSVC 2013 build
parent
ec218a3a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
59 additions
and
73 deletions
+59
-73
include/fmt/core.h
include/fmt/core.h
+23
-18
include/fmt/format.h
include/fmt/format.h
+12
-41
include/fmt/printf.h
include/fmt/printf.h
+24
-14
No files found.
include/fmt/core.h
View file @
e928b672
...
...
@@ -948,10 +948,10 @@ struct get_type {
};
template
<
typename
Context
>
FMT_CONSTEXPR
u
int64_t
get_types
()
{
return
0
;
}
FMT_CONSTEXPR
u
nsigned
long
long
get_types
()
{
return
0
;
}
template
<
typename
Context
,
typename
Arg
,
typename
...
Args
>
FMT_CONSTEXPR
u
int64_t
get_types
()
{
FMT_CONSTEXPR
u
nsigned
long
long
get_types
()
{
return
get_type
<
Context
,
Arg
>::
value
|
(
get_types
<
Context
,
Args
...
>
()
<<
4
);
}
...
...
@@ -995,27 +995,32 @@ class format_arg_store {
internal
::
value
<
Context
>
,
basic_format_arg
<
Context
>>::
type
value_type
;
// If the arguments are not packed, add one more element to mark the end.
value_type
data_
[
NUM_ARGS
+
(
IS_PACKED
&&
NUM_ARGS
!=
0
?
0
:
1
)];
static
const
size_t
DATA_SIZE
=
NUM_ARGS
+
(
IS_PACKED
&&
NUM_ARGS
!=
0
?
0
:
1
);
value_type
data_
[
DATA_SIZE
];
friend
class
basic_format_args
<
Context
>
;
static
FMT_CONSTEXPR
int64_t
get_types
()
{
static
FMT_CONSTEXPR
long
long
get_types
()
{
return
IS_PACKED
?
static_cast
<
int64_t
>
(
internal
::
get_types
<
Context
,
Args
...
>
())
:
-
static_cast
<
int64_t
>
(
NUM_ARGS
);
static_cast
<
long
long
>
(
internal
::
get_types
<
Context
,
Args
...
>
())
:
-
static_cast
<
long
long
>
(
NUM_ARGS
);
}
public:
#if FMT_USE_CONSTEXPR
static
constexpr
int64_t
TYPES
=
get_types
();
static
constexpr
long
long
TYPES
=
get_types
();
#else
static
const
int64_t
TYPES
;
static
const
long
long
TYPES
;
#endif
#if FMT_GCC_VERSION && FMT_GCC_VERSION <= 405
// Workaround an array initialization bug in gcc 4.5 and earlier.
#if (FMT_GCC_VERSION && FMT_GCC_VERSION <= 405) || \
(FMT_MSC_VER && FMT_MSC_VER <= 1800)
// Workaround array initialization issues in gcc <= 4.5 and MSVC <= 2013.
format_arg_store
(
const
Args
&
...
args
)
{
data_
=
{
internal
::
make_arg
<
IS_PACKED
,
Context
>
(
args
)...};
value_type
init
[
DATA_SIZE
]
=
{
internal
::
make_arg
<
IS_PACKED
,
Context
>
(
args
)...};
std
::
memcpy
(
data_
,
init
,
sizeof
(
init
));
}
#else
format_arg_store
(
const
Args
&
...
args
)
...
...
@@ -1025,7 +1030,7 @@ class format_arg_store {
#if !FMT_USE_CONSTEXPR
template
<
typename
Context
,
typename
...
Args
>
const
int64_t
format_arg_store
<
Context
,
Args
...
>::
TYPES
=
get_types
();
const
long
long
format_arg_store
<
Context
,
Args
...
>::
TYPES
=
get_types
();
#endif
/**
...
...
@@ -1057,7 +1062,7 @@ class basic_format_args {
private:
// To reduce compiled code size per formatting function call, types of first
// max_packed_args arguments are passed in the types_ field.
u
int64_t
types_
;
u
nsigned
long
long
types_
;
union
{
// If the number of arguments is less than max_packed_args, the argument
// values are stored in values_, otherwise they are stored in args_.
...
...
@@ -1070,7 +1075,7 @@ class basic_format_args {
typename
internal
::
type
type
(
unsigned
index
)
const
{
unsigned
shift
=
index
*
4
;
u
int64_t
mask
=
0xf
;
u
nsigned
long
long
mask
=
0xf
;
return
static_cast
<
typename
internal
::
type
>
(
(
types_
&
(
mask
<<
shift
))
>>
shift
);
}
...
...
@@ -1081,9 +1086,9 @@ class basic_format_args {
void
set_data
(
const
format_arg
*
args
)
{
args_
=
args
;
}
format_arg
do_get
(
size_type
index
)
const
{
int64_t
signed_types
=
static_cast
<
int64_t
>
(
types_
);
long
long
signed_types
=
static_cast
<
long
long
>
(
types_
);
if
(
signed_types
<
0
)
{
u
int64_t
num_args
=
static_cast
<
uint64_t
>
(
-
signed_types
);
u
nsigned
long
long
num_args
=
static_cast
<
unsigned
long
long
>
(
-
signed_types
);
return
index
<
num_args
?
args_
[
index
]
:
format_arg
();
}
format_arg
arg
;
...
...
@@ -1119,10 +1124,10 @@ class basic_format_args {
}
unsigned
max_size
()
const
{
int64_t
signed_types
=
static_cast
<
int64_t
>
(
types_
);
long
long
signed_types
=
static_cast
<
long
long
>
(
types_
);
return
static_cast
<
unsigned
>
(
signed_types
<
0
?
-
signed_types
:
static_cast
<
int64_t
>
(
internal
::
max_packed_args
));
-
signed_types
:
static_cast
<
long
long
>
(
internal
::
max_packed_args
));
}
};
...
...
include/fmt/format.h
View file @
e928b672
...
...
@@ -1293,28 +1293,6 @@ struct align_spec : empty_spec {
// Format specifiers.
template
<
typename
Char
>
class
basic_format_specs
:
public
align_spec
{
private:
template
<
typename
FillChar
>
typename
std
::
enable_if
<
std
::
is_same
<
FillChar
,
Char
>::
value
||
std
::
is_same
<
FillChar
,
char
>::
value
,
void
>::
type
set
(
fill_spec
<
FillChar
>
fill
)
{
fill_
=
fill
.
value
();
}
void
set
(
width_spec
width
)
{
width_
=
width
.
value
();
}
void
set
(
type_spec
type
)
{
type_
=
type
.
value
();
}
template
<
typename
Spec
,
typename
...
Specs
>
void
set
(
Spec
spec
,
Specs
...
tail
)
{
set
(
spec
);
set
(
tail
...);
}
public:
unsigned
flags_
;
int
precision_
;
...
...
@@ -1324,12 +1302,6 @@ class basic_format_specs : public align_spec {
unsigned
width
=
0
,
char
type
=
0
,
wchar_t
fill
=
' '
)
:
align_spec
(
width
,
fill
),
flags_
(
0
),
precision_
(
-
1
),
type_
(
type
)
{}
template
<
typename
...
FormatSpecs
>
explicit
basic_format_specs
(
FormatSpecs
...
specs
)
:
align_spec
(
0
,
' '
),
flags_
(
0
),
precision_
(
-
1
),
type_
(
0
)
{
set
(
specs
...);
}
FMT_CONSTEXPR
bool
flag
(
unsigned
f
)
const
{
return
(
flags_
&
f
)
!=
0
;
}
FMT_CONSTEXPR
int
precision
()
const
{
return
precision_
;
}
FMT_CONSTEXPR
Char
type
()
const
{
return
type_
;
}
...
...
@@ -1576,7 +1548,18 @@ class arg_formatter_base {
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
iterator
>::
type
operator
()(
T
value
)
{
writer_
.
write_int
(
value
,
specs_
);
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if
(
std
::
is_same
<
T
,
bool
>::
value
)
{
if
(
specs_
.
type_
)
return
(
*
this
)(
value
?
1
:
0
);
write
(
value
);
}
else
if
(
std
::
is_same
<
T
,
char_type
>::
value
)
{
internal
::
handle_char_specs
(
specs_
,
char_spec_handler
(
*
this
,
static_cast
<
char_type
>
(
value
)));
}
else
{
writer_
.
write_int
(
value
,
specs_
);
}
return
out
();
}
...
...
@@ -1587,13 +1570,6 @@ class arg_formatter_base {
return
out
();
}
iterator
operator
()(
bool
value
)
{
if
(
specs_
.
type_
)
return
(
*
this
)(
value
?
1
:
0
);
write
(
value
);
return
out
();
}
struct
char_spec_handler
:
internal
::
error_handler
{
arg_formatter_base
&
formatter
;
char_type
value
;
...
...
@@ -1605,11 +1581,6 @@ class arg_formatter_base {
void
on_char
()
{
formatter
.
write_char
(
value
);
}
};
iterator
operator
()(
char_type
value
)
{
internal
::
handle_char_specs
(
specs_
,
char_spec_handler
(
*
this
,
value
));
return
out
();
}
struct
cstring_spec_handler
:
internal
::
error_handler
{
arg_formatter_base
&
formatter
;
const
char_type
*
value
;
...
...
include/fmt/printf.h
View file @
e928b672
...
...
@@ -252,23 +252,33 @@ class printf_arg_formatter:
using
base
::
operator
();
/** Formats an argument of type ``bool``. */
iterator
operator
()(
bool
value
)
{
format_specs
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
return
(
*
this
)(
value
?
1
:
0
);
fmt_spec
.
type_
=
0
;
this
->
write
(
value
);
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_integral
<
T
>::
value
,
iterator
>::
type
operator
()(
T
value
)
{
// MSVC2013 fails to compile separate overloads for bool and char_type so
// use std::is_same instead.
if
(
std
::
is_same
<
T
,
bool
>::
value
)
{
format_specs
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
return
base
::
operator
()(
value
?
1
:
0
);
fmt_spec
.
type_
=
0
;
this
->
write
(
value
);
}
else
if
(
std
::
is_same
<
T
,
char_type
>::
value
)
{
format_specs
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
return
(
*
this
)(
static_cast
<
int
>
(
value
));
fmt_spec
.
flags_
=
0
;
fmt_spec
.
align_
=
ALIGN_RIGHT
;
return
base
::
operator
()(
value
);
}
else
{
return
base
::
operator
()(
value
);
}
return
this
->
out
();
}
/** Formats a character. */
iterator
operator
()(
char_type
value
)
{
format_specs
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
return
(
*
this
)(
static_cast
<
int
>
(
value
));
fmt_spec
.
flags_
=
0
;
fmt_spec
.
align_
=
ALIGN_RIGHT
;
template
<
typename
T
>
typename
std
::
enable_if
<
std
::
is_floating_point
<
T
>::
value
,
iterator
>::
type
operator
()(
T
value
)
{
return
base
::
operator
()(
value
);
}
...
...
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