Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
S
spdlog
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
spdlog
Commits
bd6fe569
Commit
bd6fe569
authored
Nov 18, 2016
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
astyle previous commits
parent
d142f135
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
255 additions
and
221 deletions
+255
-221
format.h
include/spdlog/fmt/bundled/format.h
+0
-0
ostream.h
include/spdlog/fmt/bundled/ostream.h
+38
-35
printf.h
include/spdlog/fmt/bundled/printf.h
+217
-186
No files found.
include/spdlog/fmt/bundled/format.h
View file @
bd6fe569
This source diff could not be displayed because it is too large. You can
view the blob
instead.
include/spdlog/fmt/bundled/ostream.h
View file @
bd6fe569
...
@@ -14,21 +14,23 @@ For the license information refer to format.h.
...
@@ -14,21 +14,23 @@ For the license information refer to format.h.
// #include "format.h"
// #include "format.h"
#include <ostream>
#include <ostream>
namespace
fmt
{
namespace
fmt
{
namespace
internal
{
namespace
internal
{
template
<
class
Char
>
template
<
class
Char
>
class
FormatBuf
:
public
std
::
basic_streambuf
<
Char
>
class
FormatBuf
:
public
std
::
basic_streambuf
<
Char
>
{
{
private
:
private
:
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
Buffer
<
Char
>
&
buffer_
;
Buffer
<
Char
>
&
buffer_
;
Char
*
start_
;
Char
*
start_
;
public
:
public
:
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
),
start_
(
&
buffer
[
0
])
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
),
start_
(
&
buffer
[
0
])
{
{
this
->
setp
(
start_
,
start_
+
buffer_
.
capacity
());
this
->
setp
(
start_
,
start_
+
buffer_
.
capacity
());
...
@@ -36,7 +38,8 @@ namespace fmt {
...
@@ -36,7 +38,8 @@ namespace fmt {
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
{
{
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
{
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
{
size_t
buf_size
=
size
();
size_t
buf_size
=
size
();
buffer_
.
resize
(
buf_size
);
buffer_
.
resize
(
buf_size
);
buffer_
.
reserve
(
buf_size
*
2
);
buffer_
.
reserve
(
buf_size
*
2
);
...
@@ -52,38 +55,38 @@ namespace fmt {
...
@@ -52,38 +55,38 @@ namespace fmt {
{
{
return
to_unsigned
(
this
->
pptr
()
-
start_
);
return
to_unsigned
(
this
->
pptr
()
-
start_
);
}
}
};
};
Yes
&
convert
(
std
::
ostream
&
);
Yes
&
convert
(
std
::
ostream
&
);
struct
DummyStream
:
std
::
ostream
struct
DummyStream
:
std
::
ostream
{
{
DummyStream
();
// Suppress a bogus warning in MSVC.
DummyStream
();
// Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
// Hide all operator<< overloads from std::ostream.
void
operator
<<
(
Null
<>
);
void
operator
<<
(
Null
<>
);
};
};
No
&
operator
<<
(
std
::
ostream
&
,
int
);
No
&
operator
<<
(
std
::
ostream
&
,
int
);
template
<
typename
T
>
template
<
typename
T
>
struct
ConvertToIntImpl
<
T
,
true
>
struct
ConvertToIntImpl
<
T
,
true
>
{
{
// Convert to int only if T doesn't have an overloaded operator<<.
// Convert to int only if T doesn't have an overloaded operator<<.
enum
enum
{
{
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
};
};
};
};
// Write the content of w to os.
// Write the content of w to os.
void
write
(
std
::
ostream
&
os
,
Writer
&
w
);
void
write
(
std
::
ostream
&
os
,
Writer
&
w
);
}
// namespace internal
}
// namespace internal
// Formats a value.
// Formats a value.
template
<
typename
Char
,
typename
ArgFormatter
,
typename
T
>
template
<
typename
Char
,
typename
ArgFormatter
,
typename
T
>
void
format_arg
(
BasicFormatter
<
Char
,
ArgFormatter
>
&
f
,
void
format_arg
(
BasicFormatter
<
Char
,
ArgFormatter
>
&
f
,
const
Char
*&
format_str
,
const
T
&
value
)
const
Char
*&
format_str
,
const
T
&
value
)
{
{
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
>
buffer
;
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
>
buffer
;
internal
::
FormatBuf
<
Char
>
format_buf
(
buffer
);
internal
::
FormatBuf
<
Char
>
format_buf
(
buffer
);
...
@@ -93,19 +96,19 @@ namespace fmt {
...
@@ -93,19 +96,19 @@ namespace fmt {
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
format_buf
.
size
());
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
format_buf
.
size
());
typedef
internal
::
MakeArg
<
BasicFormatter
<
Char
>
>
MakeArg
;
typedef
internal
::
MakeArg
<
BasicFormatter
<
Char
>
>
MakeArg
;
format_str
=
f
.
format
(
format_str
,
MakeArg
(
str
));
format_str
=
f
.
format
(
format_str
,
MakeArg
(
str
));
}
}
/**
/**
\rst
\rst
Prints formatted data to the stream *os*.
Prints formatted data to the stream *os*.
**Example**::
**Example**::
print(cerr, "Don't {}!", "panic");
print(cerr, "Don't {}!", "panic");
\endrst
\endrst
*/
*/
FMT_API
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
FMT_API
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
FMT_VARIADIC
(
void
,
print
,
std
::
ostream
&
,
CStringRef
)
FMT_VARIADIC
(
void
,
print
,
std
::
ostream
&
,
CStringRef
)
}
// namespace fmt
}
// namespace fmt
#ifdef FMT_HEADER_ONLY
#ifdef FMT_HEADER_ONLY
...
...
include/spdlog/fmt/bundled/printf.h
View file @
bd6fe569
...
@@ -15,14 +15,16 @@ For the license information refer to format.h.
...
@@ -15,14 +15,16 @@ For the license information refer to format.h.
#include "ostream.h"
#include "ostream.h"
namespace
fmt
{
namespace
fmt
namespace
internal
{
{
namespace
internal
// Checks if a value fits in int - used to avoid warnings about comparing
{
// signed and unsigned integers.
template
<
bool
IsSigned
>
// Checks if a value fits in int - used to avoid warnings about comparing
struct
IntChecker
// signed and unsigned integers.
{
template
<
bool
IsSigned
>
struct
IntChecker
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
static
bool
fits_in_int
(
T
value
)
{
{
...
@@ -33,11 +35,11 @@ namespace fmt {
...
@@ -33,11 +35,11 @@ namespace fmt {
{
{
return
true
;
return
true
;
}
}
};
};
template
<>
template
<>
struct
IntChecker
<
true
>
struct
IntChecker
<
true
>
{
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
static
bool
fits_in_int
(
T
value
)
{
{
...
@@ -48,11 +50,11 @@ namespace fmt {
...
@@ -48,11 +50,11 @@ namespace fmt {
{
{
return
true
;
return
true
;
}
}
};
};
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
{
{
public
:
public
:
void
report_unhandled_arg
()
void
report_unhandled_arg
()
{
{
FMT_THROW
(
FormatError
(
"precision is not integer"
));
FMT_THROW
(
FormatError
(
"precision is not integer"
));
...
@@ -65,51 +67,51 @@ namespace fmt {
...
@@ -65,51 +67,51 @@ namespace fmt {
FMT_THROW
(
FormatError
(
"number is too big"
));
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
int
>
(
value
);
return
static_cast
<
int
>
(
value
);
}
}
};
};
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
{
{
public
:
public
:
template
<
typename
T
>
template
<
typename
T
>
bool
visit_any_int
(
T
value
)
bool
visit_any_int
(
T
value
)
{
{
return
value
==
0
;
return
value
==
0
;
}
}
};
};
template
<
typename
T
,
typename
U
>
template
<
typename
T
,
typename
U
>
struct
is_same
struct
is_same
{
{
enum
enum
{
{
value
=
0
value
=
0
};
};
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
is_same
<
T
,
T
>
struct
is_same
<
T
,
T
>
{
{
enum
enum
{
{
value
=
1
value
=
1
};
};
};
};
// An argument visitor that converts an integer argument to T for printf,
// An argument visitor that converts an integer argument to T for printf,
// if T is an integral type. If T is void, the argument is converted to
// if T is an integral type. If T is void, the argument is converted to
// corresponding signed or unsigned type depending on the type specifier:
// corresponding signed or unsigned type depending on the type specifier:
// 'd' and 'i' - signed, other - unsigned)
// 'd' and 'i' - signed, other - unsigned)
template
<
typename
T
=
void
>
template
<
typename
T
=
void
>
class
ArgConverter
:
public
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
class
ArgConverter
:
public
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
{
{
private
:
private
:
internal
::
Arg
&
arg_
;
internal
::
Arg
&
arg_
;
wchar_t
type_
;
wchar_t
type_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
public
:
public
:
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
:
arg_
(
arg
),
type_
(
type
)
:
arg_
(
arg
),
type_
(
type
)
{}
{}
...
@@ -127,44 +129,50 @@ namespace fmt {
...
@@ -127,44 +129,50 @@ namespace fmt {
using
internal
::
Arg
;
using
internal
::
Arg
;
typedef
typename
internal
::
Conditional
<
typedef
typename
internal
::
Conditional
<
is_same
<
T
,
void
>::
value
,
U
,
T
>::
type
TargetType
;
is_same
<
T
,
void
>::
value
,
U
,
T
>::
type
TargetType
;
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
{
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
{
// Extra casts are used to silence warnings.
// Extra casts are used to silence warnings.
if
(
is_signed
)
{
if
(
is_signed
)
{
arg_
.
type
=
Arg
::
INT
;
arg_
.
type
=
Arg
::
INT
;
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
}
}
else
{
else
{
arg_
.
type
=
Arg
::
UINT
;
arg_
.
type
=
Arg
::
UINT
;
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
));
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
));
}
}
}
}
else
{
else
if
(
is_signed
)
{
{
if
(
is_signed
)
{
arg_
.
type
=
Arg
::
LONG_LONG
;
arg_
.
type
=
Arg
::
LONG_LONG
;
// glibc's printf doesn't sign extend arguments of smaller types:
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
// but we don't have to do the same because it's a UB.
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
}
}
else
{
else
{
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
ulong_long_value
=
arg_
.
ulong_long_value
=
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
}
}
}
}
}
}
};
};
// Converts an integer argument to char for printf.
// Converts an integer argument to char for printf.
class
CharConverter
:
public
ArgVisitor
<
CharConverter
,
void
>
class
CharConverter
:
public
ArgVisitor
<
CharConverter
,
void
>
{
{
private
:
private
:
internal
::
Arg
&
arg_
;
internal
::
Arg
&
arg_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
public
:
public
:
explicit
CharConverter
(
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
explicit
CharConverter
(
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
{}
{}
...
@@ -174,18 +182,18 @@ namespace fmt {
...
@@ -174,18 +182,18 @@ namespace fmt {
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
}
}
};
};
// 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.
class
WidthHandler
:
public
ArgVisitor
<
WidthHandler
,
unsigned
>
class
WidthHandler
:
public
ArgVisitor
<
WidthHandler
,
unsigned
>
{
{
private
:
private
:
FormatSpec
&
spec_
;
FormatSpec
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
public
:
public
:
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
{}
...
@@ -199,7 +207,8 @@ namespace fmt {
...
@@ -199,7 +207,8 @@ namespace fmt {
{
{
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
if
(
internal
::
is_negative
(
value
))
{
if
(
internal
::
is_negative
(
value
))
{
spec_
.
align_
=
ALIGN_LEFT
;
spec_
.
align_
=
ALIGN_LEFT
;
width
=
0
-
width
;
width
=
0
-
width
;
}
}
...
@@ -208,30 +217,30 @@ namespace fmt {
...
@@ -208,30 +217,30 @@ namespace fmt {
FMT_THROW
(
FormatError
(
"number is too big"
));
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
unsigned
>
(
width
);
return
static_cast
<
unsigned
>
(
width
);
}
}
};
};
}
// namespace internal
}
// namespace internal
/**
/**
\rst
\rst
A ``printf`` argument formatter based on the `curiously recurring template
A ``printf`` argument formatter based on the `curiously recurring template
pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
or all of the visit methods with the same signatures as the methods in
or all of the visit methods with the same signatures as the methods in
`~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
`~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
Pass the subclass as the *Impl* template parameter. When a formatting
Pass the subclass as the *Impl* template parameter. When a formatting
function processes an argument, it will dispatch to a visit method
function processes an argument, it will dispatch to a visit method
specific to the argument type. For example, if the argument type is
specific to the argument type. For example, if the argument type is
``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
will be called. If the subclass doesn't contain a method with this signature,
will be called. If the subclass doesn't contain a method with this signature,
then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
superclass will be called.
superclass will be called.
\endrst
\endrst
*/
*/
template
<
typename
Impl
,
typename
Char
>
template
<
typename
Impl
,
typename
Char
>
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
{
{
private
:
private
:
void
write_null_pointer
()
void
write_null_pointer
()
{
{
this
->
spec
().
type_
=
0
;
this
->
spec
().
type_
=
0
;
...
@@ -240,7 +249,7 @@ namespace fmt {
...
@@ -240,7 +249,7 @@ namespace fmt {
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
public
:
public
:
/**
/**
\rst
\rst
Constructs an argument formatter object.
Constructs an argument formatter object.
...
@@ -271,18 +280,22 @@ namespace fmt {
...
@@ -271,18 +280,22 @@ namespace fmt {
w
.
write_int
(
value
,
fmt_spec
);
w
.
write_int
(
value
,
fmt_spec
);
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
CharPtr
out
=
CharPtr
();
CharPtr
out
=
CharPtr
();
if
(
fmt_spec
.
width_
>
1
)
{
if
(
fmt_spec
.
width_
>
1
)
{
Char
fill
=
' '
;
Char
fill
=
' '
;
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
{
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
{
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
out
+=
fmt_spec
.
width_
-
1
;
out
+=
fmt_spec
.
width_
-
1
;
}
}
else
{
else
{
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
}
}
}
}
else
{
else
{
out
=
w
.
grow_buffer
(
1
);
out
=
w
.
grow_buffer
(
1
);
}
}
*
out
=
static_cast
<
Char
>
(
value
);
*
out
=
static_cast
<
Char
>
(
value
);
...
@@ -316,25 +329,25 @@ namespace fmt {
...
@@ -316,25 +329,25 @@ namespace fmt {
const
Char
*
format
=
format_str
;
const
Char
*
format
=
format_str
;
c
.
format
(
&
formatter
,
c
.
value
,
&
format
);
c
.
format
(
&
formatter
,
c
.
value
,
&
format
);
}
}
};
};
/** The default printf argument formatter. */
/** The default printf argument formatter. */
template
<
typename
Char
>
template
<
typename
Char
>
class
PrintfArgFormatter
class
PrintfArgFormatter
:
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
:
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
{
{
public
:
public
:
/** Constructs an argument formatter object. */
/** Constructs an argument formatter object. */
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
{}
};
};
/** This template formats data and writes the output to a writer. */
/** This template formats data and writes the output to a writer. */
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
class
PrintfFormatter
:
private
internal
::
FormatterBase
class
PrintfFormatter
:
private
internal
::
FormatterBase
{
{
private
:
private
:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
...
@@ -348,7 +361,7 @@ namespace fmt {
...
@@ -348,7 +361,7 @@ namespace fmt {
// Parses argument index, flags and width and returns the argument index.
// Parses argument index, flags and width and returns the argument index.
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
public
:
public
:
/**
/**
\rst
\rst
Constructs a ``PrintfFormatter`` object. References to the arguments and
Constructs a ``PrintfFormatter`` object. References to the arguments and
...
@@ -362,13 +375,15 @@ namespace fmt {
...
@@ -362,13 +375,15 @@ namespace fmt {
/** Formats stored arguments and writes the output to the writer. */
/** Formats stored arguments and writes the output to the writer. */
FMT_API
void
format
(
BasicCStringRef
<
Char
>
format_str
);
FMT_API
void
format
(
BasicCStringRef
<
Char
>
format_str
);
};
};
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
void
PrintfFormatter
<
Char
,
AF
>::
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
)
void
PrintfFormatter
<
Char
,
AF
>::
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
)
{
for
(;;)
{
switch
(
*
s
++
)
{
{
for
(;;)
{
switch
(
*
s
++
)
{
case
'-'
:
case
'-'
:
spec
.
align_
=
ALIGN_LEFT
;
spec
.
align_
=
ALIGN_LEFT
;
break
;
break
;
...
@@ -389,12 +404,12 @@ namespace fmt {
...
@@ -389,12 +404,12 @@ namespace fmt {
return
;
return
;
}
}
}
}
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
internal
::
Arg
PrintfFormatter
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
internal
::
Arg
PrintfFormatter
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
unsigned
arg_index
)
unsigned
arg_index
)
{
{
(
void
)
s
;
(
void
)
s
;
const
char
*
error
=
FMT_NULL
;
const
char
*
error
=
FMT_NULL
;
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
...
@@ -402,26 +417,30 @@ namespace fmt {
...
@@ -402,26 +417,30 @@ namespace fmt {
if
(
error
)
if
(
error
)
FMT_THROW
(
FormatError
(
!*
s
?
"invalid format string"
:
error
));
FMT_THROW
(
FormatError
(
!*
s
?
"invalid format string"
:
error
));
return
arg
;
return
arg
;
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
unsigned
PrintfFormatter
<
Char
,
AF
>::
parse_header
(
unsigned
PrintfFormatter
<
Char
,
AF
>::
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
)
const
Char
*&
s
,
FormatSpec
&
spec
)
{
{
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
Char
c
=
*
s
;
Char
c
=
*
s
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
// Parse an argument index (if followed by '$') or a width possibly
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
// preceded with '0' flag(s).
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
if
(
*
s
==
'$'
)
{
// value is an argument index
if
(
*
s
==
'$'
)
// value is an argument index
{
++
s
;
++
s
;
arg_index
=
value
;
arg_index
=
value
;
}
}
else
{
else
{
if
(
c
==
'0'
)
if
(
c
==
'0'
)
spec
.
fill_
=
'0'
;
spec
.
fill_
=
'0'
;
if
(
value
!=
0
)
{
if
(
value
!=
0
)
{
// Nonzero value means that we parsed width and don't need to
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
// parse it or flags again, so return now.
spec
.
width_
=
value
;
spec
.
width_
=
value
;
...
@@ -431,25 +450,29 @@ namespace fmt {
...
@@ -431,25 +450,29 @@ namespace fmt {
}
}
parse_flags
(
spec
,
s
);
parse_flags
(
spec
,
s
);
// Parse width.
// Parse width.
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
{
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
{
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'*'
)
{
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
}
}
return
arg_index
;
return
arg_index
;
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
{
{
const
Char
*
start
=
format_str
.
c_str
();
const
Char
*
start
=
format_str
.
c_str
();
const
Char
*
s
=
start
;
const
Char
*
s
=
start
;
while
(
*
s
)
{
while
(
*
s
)
{
Char
c
=
*
s
++
;
Char
c
=
*
s
++
;
if
(
c
!=
'%'
)
continue
;
if
(
c
!=
'%'
)
continue
;
if
(
*
s
==
c
)
{
if
(
*
s
==
c
)
{
write
(
writer_
,
start
,
s
);
write
(
writer_
,
start
,
s
);
start
=
++
s
;
start
=
++
s
;
continue
;
continue
;
...
@@ -463,12 +486,15 @@ namespace fmt {
...
@@ -463,12 +486,15 @@ namespace fmt {
unsigned
arg_index
=
parse_header
(
s
,
spec
);
unsigned
arg_index
=
parse_header
(
s
,
spec
);
// Parse precision.
// Parse precision.
if
(
*
s
==
'.'
)
{
if
(
*
s
==
'.'
)
{
++
s
;
++
s
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
}
}
else
if
(
*
s
==
'*'
)
{
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
}
}
...
@@ -478,7 +504,8 @@ namespace fmt {
...
@@ -478,7 +504,8 @@ namespace fmt {
Arg
arg
=
get_arg
(
s
,
arg_index
);
Arg
arg
=
get_arg
(
s
,
arg_index
);
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
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
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
spec
.
align_
=
ALIGN_NUMERIC
;
spec
.
align_
=
ALIGN_NUMERIC
;
else
else
...
@@ -487,7 +514,8 @@ namespace fmt {
...
@@ -487,7 +514,8 @@ namespace fmt {
// Parse length and convert the argument to the required type.
// Parse length and convert the argument to the required type.
using
internal
::
ArgConverter
;
using
internal
::
ArgConverter
;
switch
(
*
s
++
)
{
switch
(
*
s
++
)
{
case
'h'
:
case
'h'
:
if
(
*
s
==
'h'
)
if
(
*
s
==
'h'
)
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
...
@@ -522,10 +550,13 @@ namespace fmt {
...
@@ -522,10 +550,13 @@ namespace fmt {
if
(
!*
s
)
if
(
!*
s
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
FMT_THROW
(
FormatError
(
"invalid format string"
));
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
{
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
{
// Normalize type.
// Normalize type.
switch
(
spec
.
type_
)
{
switch
(
spec
.
type_
)
case
'i'
:
case
'u'
:
{
case
'i'
:
case
'u'
:
spec
.
type_
=
'd'
;
spec
.
type_
=
'd'
;
break
;
break
;
case
'c'
:
case
'c'
:
...
@@ -541,83 +572,83 @@ namespace fmt {
...
@@ -541,83 +572,83 @@ namespace fmt {
AF
(
writer_
,
spec
).
visit
(
arg
);
AF
(
writer_
,
spec
).
visit
(
arg
);
}
}
write
(
writer_
,
start
,
s
);
write
(
writer_
,
start
,
s
);
}
}
template
<
typename
Char
>
template
<
typename
Char
>
void
printf
(
BasicWriter
<
Char
>
&
w
,
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
void
printf
(
BasicWriter
<
Char
>
&
w
,
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
{
{
PrintfFormatter
<
Char
>
(
args
,
w
).
format
(
format
);
PrintfFormatter
<
Char
>
(
args
,
w
).
format
(
format
);
}
}
/**
/**
\rst
\rst
Formats arguments and returns the result as a string.
Formats arguments and returns the result as a string.
**Example**::
**Example**::
std::string message = fmt::sprintf("The answer is %d", 42);
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
\endrst
*/
*/
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
{
{
MemoryWriter
w
;
MemoryWriter
w
;
printf
(
w
,
format
,
args
);
printf
(
w
,
format
,
args
);
return
w
.
str
();
return
w
.
str
();
}
}
FMT_VARIADIC
(
std
::
string
,
sprintf
,
CStringRef
)
FMT_VARIADIC
(
std
::
string
,
sprintf
,
CStringRef
)
inline
std
::
wstring
sprintf
(
WCStringRef
format
,
ArgList
args
)
inline
std
::
wstring
sprintf
(
WCStringRef
format
,
ArgList
args
)
{
{
WMemoryWriter
w
;
WMemoryWriter
w
;
printf
(
w
,
format
,
args
);
printf
(
w
,
format
,
args
);
return
w
.
str
();
return
w
.
str
();
}
}
FMT_VARIADIC_W
(
std
::
wstring
,
sprintf
,
WCStringRef
)
FMT_VARIADIC_W
(
std
::
wstring
,
sprintf
,
WCStringRef
)
/**
/**
\rst
\rst
Prints formatted data to the file *f*.
Prints formatted data to the file *f*.
**Example**::
**Example**::
fmt::fprintf(stderr, "Don't %s!", "panic");
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
\endrst
*/
*/
FMT_API
int
fprintf
(
std
::
FILE
*
f
,
CStringRef
format
,
ArgList
args
);
FMT_API
int
fprintf
(
std
::
FILE
*
f
,
CStringRef
format
,
ArgList
args
);
FMT_VARIADIC
(
int
,
fprintf
,
std
::
FILE
*
,
CStringRef
)
FMT_VARIADIC
(
int
,
fprintf
,
std
::
FILE
*
,
CStringRef
)
/**
/**
\rst
\rst
Prints formatted data to ``stdout``.
Prints formatted data to ``stdout``.
**Example**::
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
\endrst
*/
*/
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
{
{
return
fprintf
(
stdout
,
format
,
args
);
return
fprintf
(
stdout
,
format
,
args
);
}
}
FMT_VARIADIC
(
int
,
printf
,
CStringRef
)
FMT_VARIADIC
(
int
,
printf
,
CStringRef
)
/**
/**
\rst
\rst
Prints formatted data to the stream *os*.
Prints formatted data to the stream *os*.
**Example**::
**Example**::
fprintf(cerr, "Don't %s!", "panic");
fprintf(cerr, "Don't %s!", "panic");
\endrst
\endrst
*/
*/
inline
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
inline
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
{
{
MemoryWriter
w
;
MemoryWriter
w
;
printf
(
w
,
format_str
,
args
);
printf
(
w
,
format_str
,
args
);
internal
::
write
(
os
,
w
);
internal
::
write
(
os
,
w
);
return
static_cast
<
int
>
(
w
.
size
());
return
static_cast
<
int
>
(
w
.
size
());
}
}
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
}
// namespace fmt
}
// namespace fmt
#ifdef FMT_HEADER_ONLY
#ifdef FMT_HEADER_ONLY
...
...
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