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
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
730 additions
and
696 deletions
+730
-696
format.h
include/spdlog/fmt/bundled/format.h
+0
-0
ostream.h
include/spdlog/fmt/bundled/ostream.h
+95
-92
printf.h
include/spdlog/fmt/bundled/printf.h
+634
-603
sink.h
include/spdlog/sinks/sink.h
+1
-1
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,98 +14,101 @@ For the license information refer to format.h.
...
@@ -14,98 +14,101 @@ 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
>
{
class
FormatBuf
:
public
std
::
basic_streambuf
<
Char
>
{
template
<
class
Char
>
private
:
class
FormatBuf
:
public
std
::
basic_streambuf
<
Char
>
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
{
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
private
:
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
Buffer
<
Char
>
&
buffer_
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
Char
*
start_
;
Buffer
<
Char
>
&
buffer_
;
public
:
Char
*
start_
;
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
),
start_
(
&
buffer
[
0
])
{
public
:
this
->
setp
(
start_
,
start_
+
buffer_
.
capacity
());
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
),
start_
(
&
buffer
[
0
])
}
{
this
->
setp
(
start_
,
start_
+
buffer_
.
capacity
());
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
}
{
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
{
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
size_t
buf_size
=
size
();
{
buffer_
.
resize
(
buf_size
);
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
buffer_
.
reserve
(
buf_size
*
2
);
{
size_t
buf_size
=
size
();
start_
=
&
buffer_
[
0
];
buffer_
.
resize
(
buf_size
);
start_
[
buf_size
]
=
traits_type
::
to_char_type
(
ch
);
buffer_
.
reserve
(
buf_size
*
2
);
this
->
setp
(
start_
+
buf_size
+
1
,
start_
+
buf_size
*
2
);
}
start_
=
&
buffer_
[
0
];
return
ch
;
start_
[
buf_size
]
=
traits_type
::
to_char_type
(
ch
);
}
this
->
setp
(
start_
+
buf_size
+
1
,
start_
+
buf_size
*
2
);
}
size_t
size
()
const
return
ch
;
{
}
return
to_unsigned
(
this
->
pptr
()
-
start_
);
}
size_t
size
()
const
};
{
return
to_unsigned
(
this
->
pptr
()
-
start_
);
Yes
&
convert
(
std
::
ostream
&
);
}
};
struct
DummyStream
:
std
::
ostream
{
Yes
&
convert
(
std
::
ostream
&
);
DummyStream
();
// Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
struct
DummyStream
:
std
::
ostream
void
operator
<<
(
Null
<>
);
{
};
DummyStream
();
// Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
No
&
operator
<<
(
std
::
ostream
&
,
int
);
void
operator
<<
(
Null
<>
);
};
template
<
typename
T
>
struct
ConvertToIntImpl
<
T
,
true
>
No
&
operator
<<
(
std
::
ostream
&
,
int
);
{
// Convert to int only if T doesn't have an overloaded operator<<.
template
<
typename
T
>
enum
struct
ConvertToIntImpl
<
T
,
true
>
{
{
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
// Convert to int only if T doesn't have an overloaded operator<<.
};
enum
};
{
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
// Write the content of w to os.
};
void
write
(
std
::
ostream
&
os
,
Writer
&
w
);
};
}
// namespace internal
// Write the content of w to os.
// Formats a value.
void
write
(
std
::
ostream
&
os
,
Writer
&
w
);
template
<
typename
Char
,
typename
ArgFormatter
,
typename
T
>
}
// namespace internal
void
format_arg
(
BasicFormatter
<
Char
,
ArgFormatter
>
&
f
,
const
Char
*&
format_str
,
const
T
&
value
)
// Formats a value.
{
template
<
typename
Char
,
typename
ArgFormatter
,
typename
T
>
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
>
buffer
;
void
format_arg
(
BasicFormatter
<
Char
,
ArgFormatter
>
&
f
,
const
Char
*&
format_str
,
const
T
&
value
)
internal
::
FormatBuf
<
Char
>
format_buf
(
buffer
);
{
std
::
basic_ostream
<
Char
>
output
(
&
format_buf
);
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
>
buffer
;
output
<<
value
;
internal
::
FormatBuf
<
Char
>
format_buf
(
buffer
);
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
format_buf
.
size
());
std
::
basic_ostream
<
Char
>
output
(
&
format_buf
);
typedef
internal
::
MakeArg
<
BasicFormatter
<
Char
>
>
MakeArg
;
output
<<
value
;
format_str
=
f
.
format
(
format_str
,
MakeArg
(
str
));
}
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
format_buf
.
size
());
typedef
internal
::
MakeArg
<
BasicFormatter
<
Char
>
>
MakeArg
;
/**
format_str
=
f
.
format
(
format_str
,
MakeArg
(
str
));
\rst
}
Prints formatted data to the stream *os*.
/**
**Example**::
\rst
Prints formatted data to the stream *os*.
print(cerr, "Don't {}!", "panic");
\endrst
**Example**::
*/
FMT_API
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
print(cerr, "Don't {}!", "panic");
FMT_VARIADIC
(
void
,
print
,
std
::
ostream
&
,
CStringRef
)
\endrst
*/
FMT_API
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
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,609 +15,640 @@ For the license information refer to format.h.
...
@@ -15,609 +15,640 @@ 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
>
template
<
typename
T
>
struct
IntChecker
static
bool
fits_in_int
(
T
value
)
{
{
template
<
typename
T
>
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
static
bool
fits_in_int
(
T
value
)
return
value
<=
max
;
{
}
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
static
bool
fits_in_int
(
bool
)
return
value
<=
max
;
{
}
return
true
;
static
bool
fits_in_int
(
bool
)
}
{
};
return
true
;
}
template
<>
};
struct
IntChecker
<
true
>
{
template
<>
template
<
typename
T
>
struct
IntChecker
<
true
>
static
bool
fits_in_int
(
T
value
)
{
{
template
<
typename
T
>
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
static
bool
fits_in_int
(
T
value
)
value
<=
std
::
numeric_limits
<
int
>::
max
();
{
}
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
static
bool
fits_in_int
(
int
)
value
<=
std
::
numeric_limits
<
int
>::
max
();
{
}
return
true
;
static
bool
fits_in_int
(
int
)
}
{
};
return
true
;
}
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
};
{
public
:
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
void
report_unhandled_arg
()
{
{
public
:
FMT_THROW
(
FormatError
(
"precision is not integer"
));
void
report_unhandled_arg
()
}
{
FMT_THROW
(
FormatError
(
"precision is not integer"
));
template
<
typename
T
>
}
int
visit_any_int
(
T
value
)
{
template
<
typename
T
>
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
int
visit_any_int
(
T
value
)
FMT_THROW
(
FormatError
(
"number is too big"
));
{
return
static_cast
<
int
>
(
value
);
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
}
FMT_THROW
(
FormatError
(
"number is too big"
));
};
return
static_cast
<
int
>
(
value
);
}
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
};
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
{
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
public
:
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
template
<
typename
T
>
{
bool
visit_any_int
(
T
value
)
public
:
{
template
<
typename
T
>
return
value
==
0
;
bool
visit_any_int
(
T
value
)
}
{
};
return
value
==
0
;
}
template
<
typename
T
,
typename
U
>
};
struct
is_same
{
template
<
typename
T
,
typename
U
>
enum
struct
is_same
{
{
value
=
0
enum
};
{
};
value
=
0
};
template
<
typename
T
>
};
struct
is_same
<
T
,
T
>
{
template
<
typename
T
>
enum
struct
is_same
<
T
,
T
>
{
{
value
=
1
enum
};
{
};
value
=
1
};
// 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
// corresponding signed or unsigned type depending on the type specifier:
// An argument visitor that converts an integer argument to T for printf,
// 'd' and 'i' - signed, other - unsigned)
// if T is an integral type. If T is void, the argument is converted to
template
<
typename
T
=
void
>
// corresponding signed or unsigned type depending on the type specifier:
class
ArgConverter
:
public
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
// 'd' and 'i' - signed, other - unsigned)
{
template
<
typename
T
=
void
>
private
:
class
ArgConverter
:
public
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
internal
::
Arg
&
arg_
;
{
wchar_t
type_
;
private
:
internal
::
Arg
&
arg_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
wchar_t
type_
;
public
:
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
:
arg_
(
arg
),
type_
(
type
)
public
:
{}
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
:
arg_
(
arg
),
type_
(
type
)
void
visit_bool
(
bool
value
)
{}
{
if
(
type_
!=
's'
)
void
visit_bool
(
bool
value
)
visit_any_int
(
value
);
{
}
if
(
type_
!=
's'
)
visit_any_int
(
value
);
template
<
typename
U
>
}
void
visit_any_int
(
U
value
)
{
template
<
typename
U
>
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
void
visit_any_int
(
U
value
)
using
internal
::
Arg
;
{
typedef
typename
internal
::
Conditional
<
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
is_same
<
T
,
void
>::
value
,
U
,
T
>::
type
TargetType
;
using
internal
::
Arg
;
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
{
typedef
typename
internal
::
Conditional
<
// Extra casts are used to silence warnings.
is_same
<
T
,
void
>::
value
,
U
,
T
>::
type
TargetType
;
if
(
is_signed
)
{
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
arg_
.
type
=
Arg
::
INT
;
{
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
// Extra casts are used to silence warnings.
}
if
(
is_signed
)
else
{
{
arg_
.
type
=
Arg
::
UINT
;
arg_
.
type
=
Arg
::
INT
;
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
));
}
}
else
}
{
else
{
arg_
.
type
=
Arg
::
UINT
;
if
(
is_signed
)
{
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
arg_
.
type
=
Arg
::
LONG_LONG
;
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
));
// glibc's printf doesn't sign extend arguments of smaller types:
}
// std::printf("%lld", -42); // prints "4294967254"
}
// but we don't have to do the same because it's a UB.
else
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
{
}
if
(
is_signed
)
else
{
{
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
type
=
Arg
::
LONG_LONG
;
arg_
.
ulong_long_value
=
// glibc's printf doesn't sign extend arguments of smaller types:
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
// std::printf("%lld", -42); // prints "4294967254"
}
// but we don't have to do the same because it's a UB.
}
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
}
}
};
else
{
// Converts an integer argument to char for printf.
arg_
.
type
=
Arg
::
ULONG_LONG
;
class
CharConverter
:
public
ArgVisitor
<
CharConverter
,
void
>
arg_
.
ulong_long_value
=
{
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
private
:
}
internal
::
Arg
&
arg_
;
}
}
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
};
public
:
// Converts an integer argument to char for printf.
explicit
CharConverter
(
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
class
CharConverter
:
public
ArgVisitor
<
CharConverter
,
void
>
{}
{
private
:
template
<
typename
T
>
internal
::
Arg
&
arg_
;
void
visit_any_int
(
T
value
)
{
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
public
:
}
explicit
CharConverter
(
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
};
{}
// Checks if an argument is a valid printf width specifier and sets
template
<
typename
T
>
// left alignment if it is negative.
void
visit_any_int
(
T
value
)
class
WidthHandler
:
public
ArgVisitor
<
WidthHandler
,
unsigned
>
{
{
arg_
.
type
=
internal
::
Arg
::
CHAR
;
private
:
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
FormatSpec
&
spec_
;
}
};
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
// Checks if an argument is a valid printf width specifier and sets
public
:
// left alignment if it is negative.
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
class
WidthHandler
:
public
ArgVisitor
<
WidthHandler
,
unsigned
>
{}
{
private
:
void
report_unhandled_arg
()
FormatSpec
&
spec_
;
{
FMT_THROW
(
FormatError
(
"width is not integer"
));
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
}
public
:
template
<
typename
T
>
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
unsigned
visit_any_int
(
T
value
)
{}
{
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
void
report_unhandled_arg
()
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
{
if
(
internal
::
is_negative
(
value
))
{
FMT_THROW
(
FormatError
(
"width is not integer"
));
spec_
.
align_
=
ALIGN_LEFT
;
}
width
=
0
-
width
;
}
template
<
typename
T
>
unsigned
int_max
=
std
::
numeric_limits
<
int
>::
max
();
unsigned
visit_any_int
(
T
value
)
if
(
width
>
int_max
)
{
FMT_THROW
(
FormatError
(
"number is too big"
));
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
return
static_cast
<
unsigned
>
(
width
);
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
}
if
(
internal
::
is_negative
(
value
))
};
{
}
// namespace internal
spec_
.
align_
=
ALIGN_LEFT
;
width
=
0
-
width
;
/**
}
\rst
unsigned
int_max
=
std
::
numeric_limits
<
int
>::
max
();
A ``printf`` argument formatter based on the `curiously recurring template
if
(
width
>
int_max
)
pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
unsigned
>
(
width
);
To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
}
or all of the visit methods with the same signatures as the methods in
};
`~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
}
// namespace internal
Pass the subclass as the *Impl* template parameter. When a formatting
function processes an argument, it will dispatch to a visit method
/**
specific to the argument type. For example, if the argument type is
\rst
``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
A ``printf`` argument formatter based on the `curiously recurring template
will be called. If the subclass doesn't contain a method with this signature,
pattern <http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern>`_.
then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
superclass will be called.
To use `~fmt::BasicPrintfArgFormatter` define a subclass that implements some
\endrst
or all of the visit methods with the same signatures as the methods in
*/
`~fmt::ArgVisitor`, for example, `~fmt::ArgVisitor::visit_int()`.
template
<
typename
Impl
,
typename
Char
>
Pass the subclass as the *Impl* template parameter. When a formatting
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
function processes an argument, it will dispatch to a visit method
{
specific to the argument type. For example, if the argument type is
private
:
``double`` then the `~fmt::ArgVisitor::visit_double()` method of a subclass
void
write_null_pointer
()
will be called. If the subclass doesn't contain a method with this signature,
{
then a corresponding method of `~fmt::BasicPrintfArgFormatter` or its
this
->
spec
().
type_
=
0
;
superclass will be called.
this
->
write
(
"(nil)"
);
\endrst
}
*/
template
<
typename
Impl
,
typename
Char
>
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
{
public
:
private
:
/**
void
write_null_pointer
()
\rst
{
Constructs an argument formatter object.
this
->
spec
().
type_
=
0
;
*writer* is a reference to the output writer and *spec* contains format
this
->
write
(
"(nil)"
);
specifier information for standard argument types.
}
\endrst
*/
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
BasicPrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
w
,
s
)
public
:
{}
/**
\rst
/** Formats an argument of type ``bool``. */
Constructs an argument formatter object.
void
visit_bool
(
bool
value
)
*writer* is a reference to the output writer and *spec* contains format
{
specifier information for standard argument types.
FormatSpec
&
fmt_spec
=
this
->
spec
();
\endrst
if
(
fmt_spec
.
type_
!=
's'
)
*/
return
this
->
visit_any_int
(
value
);
BasicPrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
fmt_spec
.
type_
=
0
;
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
w
,
s
)
this
->
write
(
value
);
{}
}
/** Formats an argument of type ``bool``. */
/** Formats a character. */
void
visit_bool
(
bool
value
)
void
visit_char
(
int
value
)
{
{
FormatSpec
&
fmt_spec
=
this
->
spec
();
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
return
this
->
visit_any_int
(
value
);
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
fmt_spec
.
type_
=
0
;
w
.
write_int
(
value
,
fmt_spec
);
this
->
write
(
value
);
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
}
CharPtr
out
=
CharPtr
();
if
(
fmt_spec
.
width_
>
1
)
{
/** Formats a character. */
Char
fill
=
' '
;
void
visit_char
(
int
value
)
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
{
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
{
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
out
+=
fmt_spec
.
width_
-
1
;
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
}
w
.
write_int
(
value
,
fmt_spec
);
else
{
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
CharPtr
out
=
CharPtr
();
}
if
(
fmt_spec
.
width_
>
1
)
}
{
else
{
Char
fill
=
' '
;
out
=
w
.
grow_buffer
(
1
);
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
}
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
*
out
=
static_cast
<
Char
>
(
value
);
{
}
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
out
+=
fmt_spec
.
width_
-
1
;
/** Formats a null-terminated C string. */
}
void
visit_cstring
(
const
char
*
value
)
else
{
{
if
(
value
)
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
Base
::
visit_cstring
(
value
);
}
else
if
(
this
->
spec
().
type_
==
'p'
)
}
write_null_pointer
();
else
else
{
this
->
write
(
"(null)"
);
out
=
w
.
grow_buffer
(
1
);
}
}
*
out
=
static_cast
<
Char
>
(
value
);
/** Formats a pointer. */
}
void
visit_pointer
(
const
void
*
value
)
{
/** Formats a null-terminated C string. */
if
(
value
)
void
visit_cstring
(
const
char
*
value
)
return
Base
::
visit_pointer
(
value
);
{
this
->
spec
().
type_
=
0
;
if
(
value
)
write_null_pointer
();
Base
::
visit_cstring
(
value
);
}
else
if
(
this
->
spec
().
type_
==
'p'
)
write_null_pointer
();
/** Formats an argument of a custom (user-defined) type. */
else
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
this
->
write
(
"(null)"
);
{
}
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
const
Char
format_str
[]
=
{
'}'
,
0
};
/** Formats a pointer. */
const
Char
*
format
=
format_str
;
void
visit_pointer
(
const
void
*
value
)
c
.
format
(
&
formatter
,
c
.
value
,
&
format
);
{
}
if
(
value
)
};
return
Base
::
visit_pointer
(
value
);
this
->
spec
().
type_
=
0
;
/** The default printf argument formatter. */
write_null_pointer
();
template
<
typename
Char
>
}
class
PrintfArgFormatter
:
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
/** Formats an argument of a custom (user-defined) type. */
{
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
public
:
{
/** Constructs an argument formatter object. */
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
const
Char
format_str
[]
=
{
'}'
,
0
};
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
const
Char
*
format
=
format_str
;
{}
c
.
format
(
&
formatter
,
c
.
value
,
&
format
);
};
}
};
/** This template formats data and writes the output to a writer. */
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
/** The default printf argument formatter. */
class
PrintfFormatter
:
private
internal
::
FormatterBase
template
<
typename
Char
>
{
class
PrintfArgFormatter
private
:
:
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
BasicWriter
<
Char
>
&
writer_
;
{
public
:
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
/** Constructs an argument formatter object. */
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
// Returns the argument with specified index or, if arg_index is equal
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
// to the maximum unsigned value, the next argument.
{}
internal
::
Arg
get_arg
(
};
const
Char
*
s
,
unsigned
arg_index
=
(
std
::
numeric_limits
<
unsigned
>::
max
)());
/** This template formats data and writes the output to a writer. */
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
// Parses argument index, flags and width and returns the argument index.
class
PrintfFormatter
:
private
internal
::
FormatterBase
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
{
private
:
public
:
BasicWriter
<
Char
>
&
writer_
;
/**
\rst
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
Constructs a ``PrintfFormatter`` object. References to the arguments and
the writer are stored in the formatter object so make sure they have
// Returns the argument with specified index or, if arg_index is equal
appropriate lifetimes.
// to the maximum unsigned value, the next argument.
\endrst
internal
::
Arg
get_arg
(
*/
const
Char
*
s
,
explicit
PrintfFormatter
(
const
ArgList
&
al
,
BasicWriter
<
Char
>
&
w
)
unsigned
arg_index
=
(
std
::
numeric_limits
<
unsigned
>::
max
)());
:
FormatterBase
(
al
),
writer_
(
w
)
{}
// Parses argument index, flags and width and returns the argument index.
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
/** Formats stored arguments and writes the output to the writer. */
FMT_API
void
format
(
BasicCStringRef
<
Char
>
format_str
);
public
:
};
/**
\rst
template
<
typename
Char
,
typename
AF
>
Constructs a ``PrintfFormatter`` object. References to the arguments and
void
PrintfFormatter
<
Char
,
AF
>::
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
)
the writer are stored in the formatter object so make sure they have
{
appropriate lifetimes.
for
(;;)
{
\endrst
switch
(
*
s
++
)
{
*/
case
'-'
:
explicit
PrintfFormatter
(
const
ArgList
&
al
,
BasicWriter
<
Char
>
&
w
)
spec
.
align_
=
ALIGN_LEFT
;
:
FormatterBase
(
al
),
writer_
(
w
)
break
;
{}
case
'+'
:
spec
.
flags_
|=
SIGN_FLAG
|
PLUS_FLAG
;
/** Formats stored arguments and writes the output to the writer. */
break
;
FMT_API
void
format
(
BasicCStringRef
<
Char
>
format_str
);
case
'0'
:
};
spec
.
fill_
=
'0'
;
break
;
template
<
typename
Char
,
typename
AF
>
case
' '
:
void
PrintfFormatter
<
Char
,
AF
>::
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
)
spec
.
flags_
|=
SIGN_FLAG
;
{
break
;
for
(;;)
case
'#'
:
{
spec
.
flags_
|=
HASH_FLAG
;
switch
(
*
s
++
)
break
;
{
default
:
case
'-'
:
--
s
;
spec
.
align_
=
ALIGN_LEFT
;
return
;
break
;
}
case
'+'
:
}
spec
.
flags_
|=
SIGN_FLAG
|
PLUS_FLAG
;
}
break
;
case
'0'
:
template
<
typename
Char
,
typename
AF
>
spec
.
fill_
=
'0'
;
internal
::
Arg
PrintfFormatter
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
break
;
unsigned
arg_index
)
case
' '
:
{
spec
.
flags_
|=
SIGN_FLAG
;
(
void
)
s
;
break
;
const
char
*
error
=
FMT_NULL
;
case
'#'
:
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
spec
.
flags_
|=
HASH_FLAG
;
next_arg
(
error
)
:
FormatterBase
::
get_arg
(
arg_index
-
1
,
error
);
break
;
if
(
error
)
default
:
FMT_THROW
(
FormatError
(
!*
s
?
"invalid format string"
:
error
));
--
s
;
return
arg
;
return
;
}
}
}
template
<
typename
Char
,
typename
AF
>
}
unsigned
PrintfFormatter
<
Char
,
AF
>::
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
)
template
<
typename
Char
,
typename
AF
>
{
internal
::
Arg
PrintfFormatter
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
unsigned
arg_index
)
Char
c
=
*
s
;
{
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
(
void
)
s
;
// Parse an argument index (if followed by '$') or a width possibly
const
char
*
error
=
FMT_NULL
;
// preceded with '0' flag(s).
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
next_arg
(
error
)
:
FormatterBase
::
get_arg
(
arg_index
-
1
,
error
);
if
(
*
s
==
'$'
)
{
// value is an argument index
if
(
error
)
++
s
;
FMT_THROW
(
FormatError
(
!*
s
?
"invalid format string"
:
error
));
arg_index
=
value
;
return
arg
;
}
}
else
{
if
(
c
==
'0'
)
template
<
typename
Char
,
typename
AF
>
spec
.
fill_
=
'0'
;
unsigned
PrintfFormatter
<
Char
,
AF
>::
parse_header
(
if
(
value
!=
0
)
{
const
Char
*&
s
,
FormatSpec
&
spec
)
// Nonzero value means that we parsed width and don't need to
{
// parse it or flags again, so return now.
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
spec
.
width_
=
value
;
Char
c
=
*
s
;
return
arg_index
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
}
{
}
// Parse an argument index (if followed by '$') or a width possibly
}
// preceded with '0' flag(s).
parse_flags
(
spec
,
s
);
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
// Parse width.
if
(
*
s
==
'$'
)
// value is an argument index
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
{
{
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
++
s
;
}
arg_index
=
value
;
else
if
(
*
s
==
'*'
)
{
}
++
s
;
else
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
{
}
if
(
c
==
'0'
)
return
arg_index
;
spec
.
fill_
=
'0'
;
}
if
(
value
!=
0
)
{
template
<
typename
Char
,
typename
AF
>
// Nonzero value means that we parsed width and don't need to
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
// parse it or flags again, so return now.
{
spec
.
width_
=
value
;
const
Char
*
start
=
format_str
.
c_str
();
return
arg_index
;
const
Char
*
s
=
start
;
}
while
(
*
s
)
{
}
Char
c
=
*
s
++
;
}
if
(
c
!=
'%'
)
continue
;
parse_flags
(
spec
,
s
);
if
(
*
s
==
c
)
{
// Parse width.
write
(
writer_
,
start
,
s
);
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
start
=
++
s
;
{
continue
;
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
}
}
write
(
writer_
,
start
,
s
-
1
);
else
if
(
*
s
==
'*'
)
{
FormatSpec
spec
;
++
s
;
spec
.
align_
=
ALIGN_RIGHT
;
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
}
// Parse argument index, flags and width.
return
arg_index
;
unsigned
arg_index
=
parse_header
(
s
,
spec
);
}
// Parse precision.
template
<
typename
Char
,
typename
AF
>
if
(
*
s
==
'.'
)
{
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
++
s
;
{
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
const
Char
*
start
=
format_str
.
c_str
();
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
const
Char
*
s
=
start
;
}
while
(
*
s
)
else
if
(
*
s
==
'*'
)
{
{
++
s
;
Char
c
=
*
s
++
;
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
if
(
c
!=
'%'
)
continue
;
}
if
(
*
s
==
c
)
}
{
write
(
writer_
,
start
,
s
);
using
internal
::
Arg
;
start
=
++
s
;
Arg
arg
=
get_arg
(
s
,
arg_index
);
continue
;
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
}
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
write
(
writer_
,
start
,
s
-
1
);
if
(
spec
.
fill_
==
'0'
)
{
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
FormatSpec
spec
;
spec
.
align_
=
ALIGN_NUMERIC
;
spec
.
align_
=
ALIGN_RIGHT
;
else
spec
.
fill_
=
' '
;
// Ignore '0' flag for non-numeric types.
// Parse argument index, flags and width.
}
unsigned
arg_index
=
parse_header
(
s
,
spec
);
// Parse length and convert the argument to the required type.
// Parse precision.
using
internal
::
ArgConverter
;
if
(
*
s
==
'.'
)
switch
(
*
s
++
)
{
{
case
'h'
:
++
s
;
if
(
*
s
==
'h'
)
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
{
else
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
ArgConverter
<
short
>
(
arg
,
*
s
).
visit
(
arg
);
}
break
;
else
if
(
*
s
==
'*'
)
case
'l'
:
{
if
(
*
s
==
'l'
)
++
s
;
ArgConverter
<
fmt
::
LongLong
>
(
arg
,
*++
s
).
visit
(
arg
);
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
else
}
ArgConverter
<
long
>
(
arg
,
*
s
).
visit
(
arg
);
}
break
;
case
'j'
:
using
internal
::
Arg
;
ArgConverter
<
intmax_t
>
(
arg
,
*
s
).
visit
(
arg
);
Arg
arg
=
get_arg
(
s
,
arg_index
);
break
;
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
case
'z'
:
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
ArgConverter
<
std
::
size_t
>
(
arg
,
*
s
).
visit
(
arg
);
if
(
spec
.
fill_
==
'0'
)
break
;
{
case
't'
:
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
ArgConverter
<
std
::
ptrdiff_t
>
(
arg
,
*
s
).
visit
(
arg
);
spec
.
align_
=
ALIGN_NUMERIC
;
break
;
else
case
'L'
:
spec
.
fill_
=
' '
;
// Ignore '0' flag for non-numeric types.
// printf produces garbage when 'L' is omitted for long double, no
}
// need to do the same.
break
;
// Parse length and convert the argument to the required type.
default
:
using
internal
::
ArgConverter
;
--
s
;
switch
(
*
s
++
)
ArgConverter
<
void
>
(
arg
,
*
s
).
visit
(
arg
);
{
}
case
'h'
:
if
(
*
s
==
'h'
)
// Parse type.
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
if
(
!*
s
)
else
FMT_THROW
(
FormatError
(
"invalid format string"
));
ArgConverter
<
short
>
(
arg
,
*
s
).
visit
(
arg
);
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
break
;
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
{
case
'l'
:
// Normalize type.
if
(
*
s
==
'l'
)
switch
(
spec
.
type_
)
{
ArgConverter
<
fmt
::
LongLong
>
(
arg
,
*++
s
).
visit
(
arg
);
case
'i'
:
case
'u'
:
else
spec
.
type_
=
'd'
;
ArgConverter
<
long
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
break
;
case
'c'
:
case
'j'
:
// TODO: handle wchar_t
ArgConverter
<
intmax_t
>
(
arg
,
*
s
).
visit
(
arg
);
internal
::
CharConverter
(
arg
).
visit
(
arg
);
break
;
break
;
case
'z'
:
}
ArgConverter
<
std
::
size_t
>
(
arg
,
*
s
).
visit
(
arg
);
}
break
;
case
't'
:
start
=
s
;
ArgConverter
<
std
::
ptrdiff_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
// Format argument.
case
'L'
:
AF
(
writer_
,
spec
).
visit
(
arg
);
// printf produces garbage when 'L' is omitted for long double, no
}
// need to do the same.
write
(
writer_
,
start
,
s
);
break
;
}
default
:
--
s
;
template
<
typename
Char
>
ArgConverter
<
void
>
(
arg
,
*
s
).
visit
(
arg
);
void
printf
(
BasicWriter
<
Char
>
&
w
,
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
}
{
PrintfFormatter
<
Char
>
(
args
,
w
).
format
(
format
);
// Parse type.
}
if
(
!*
s
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
/**
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
\rst
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
Formats arguments and returns the result as a string.
{
// Normalize type.
**Example**::
switch
(
spec
.
type_
)
{
std::string message = fmt::sprintf("The answer is %d", 42);
case
'i'
:
\endrst
case
'u'
:
*/
spec
.
type_
=
'd'
;
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
break
;
{
case
'c'
:
MemoryWriter
w
;
// TODO: handle wchar_t
printf
(
w
,
format
,
args
);
internal
::
CharConverter
(
arg
).
visit
(
arg
);
return
w
.
str
();
break
;
}
}
FMT_VARIADIC
(
std
::
string
,
sprintf
,
CStringRef
)
}
inline
std
::
wstring
sprintf
(
WCStringRef
format
,
ArgList
args
)
start
=
s
;
{
WMemoryWriter
w
;
// Format argument.
printf
(
w
,
format
,
args
);
AF
(
writer_
,
spec
).
visit
(
arg
);
return
w
.
str
();
}
}
write
(
writer_
,
start
,
s
);
FMT_VARIADIC_W
(
std
::
wstring
,
sprintf
,
WCStringRef
)
}
/**
template
<
typename
Char
>
\rst
void
printf
(
BasicWriter
<
Char
>
&
w
,
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
Prints formatted data to the file *f*.
{
PrintfFormatter
<
Char
>
(
args
,
w
).
format
(
format
);
**Example**::
}
fmt::fprintf(stderr, "Don't %s!", "panic");
/**
\endrst
\rst
*/
Formats arguments and returns the result as a string.
FMT_API
int
fprintf
(
std
::
FILE
*
f
,
CStringRef
format
,
ArgList
args
);
FMT_VARIADIC
(
int
,
fprintf
,
std
::
FILE
*
,
CStringRef
)
**Example**::
/**
std::string message = fmt::sprintf("The answer is %d", 42);
\rst
\endrst
Prints formatted data to ``stdout``.
*/
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
**Example**::
{
MemoryWriter
w
;
fmt::printf("Elapsed time: %.2f seconds", 1.23);
printf
(
w
,
format
,
args
);
\endrst
return
w
.
str
();
*/
}
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
FMT_VARIADIC
(
std
::
string
,
sprintf
,
CStringRef
)
{
return
fprintf
(
stdout
,
format
,
args
);
inline
std
::
wstring
sprintf
(
WCStringRef
format
,
ArgList
args
)
}
{
FMT_VARIADIC
(
int
,
printf
,
CStringRef
)
WMemoryWriter
w
;
printf
(
w
,
format
,
args
);
/**
return
w
.
str
();
\rst
}
Prints formatted data to the stream *os*.
FMT_VARIADIC_W
(
std
::
wstring
,
sprintf
,
WCStringRef
)
**Example**::
/**
\rst
fprintf(cerr, "Don't %s!", "panic");
Prints formatted data to the file *f*.
\endrst
*/
**Example**::
inline
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
{
fmt::fprintf(stderr, "Don't %s!", "panic");
MemoryWriter
w
;
\endrst
printf
(
w
,
format_str
,
args
);
*/
internal
::
write
(
os
,
w
);
FMT_API
int
fprintf
(
std
::
FILE
*
f
,
CStringRef
format
,
ArgList
args
);
return
static_cast
<
int
>
(
w
.
size
());
FMT_VARIADIC
(
int
,
fprintf
,
std
::
FILE
*
,
CStringRef
)
}
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
/**
\rst
Prints formatted data to ``stdout``.
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
*/
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
{
return
fprintf
(
stdout
,
format
,
args
);
}
FMT_VARIADIC
(
int
,
printf
,
CStringRef
)
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
inline
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
{
MemoryWriter
w
;
printf
(
w
,
format_str
,
args
);
internal
::
write
(
os
,
w
);
return
static_cast
<
int
>
(
w
.
size
());
}
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
}
// namespace fmt
}
// namespace fmt
#ifdef FMT_HEADER_ONLY
#ifdef FMT_HEADER_ONLY
...
...
include/spdlog/sinks/sink.h
View file @
bd6fe569
...
@@ -17,7 +17,7 @@ class sink
...
@@ -17,7 +17,7 @@ class sink
public
:
public
:
sink
()
sink
()
{
{
_level
=
level
::
trace
;
_level
=
level
::
trace
;
}
}
virtual
~
sink
()
{}
virtual
~
sink
()
{}
...
...
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