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
5653e5c9
Commit
5653e5c9
authored
Sep 14, 2016
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
astyle
parent
6312748c
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
564 additions
and
459 deletions
+564
-459
async_log_helper.h
include/spdlog/details/async_log_helper.h
+5
-3
logger_impl.h
include/spdlog/details/logger_impl.h
+4
-2
spdlog_impl.h
include/spdlog/details/spdlog_impl.h
+1
-1
format.h
include/spdlog/fmt/bundled/format.h
+0
-0
ostream.h
include/spdlog/fmt/bundled/ostream.h
+57
-46
printf.h
include/spdlog/fmt/bundled/printf.h
+480
-396
android_sink.h
include/spdlog/sinks/android_sink.h
+5
-4
dist_sink.h
include/spdlog/sinks/dist_sink.h
+4
-2
sink.h
include/spdlog/sinks/sink.h
+6
-3
spdlog.h
include/spdlog/spdlog.h
+2
-2
No files found.
include/spdlog/details/async_log_helper.h
View file @
5653e5c9
...
@@ -253,7 +253,7 @@ inline void spdlog::details::async_log_helper::push_msg(details::async_log_helpe
...
@@ -253,7 +253,7 @@ inline void spdlog::details::async_log_helper::push_msg(details::async_log_helpe
inline
void
spdlog
::
details
::
async_log_helper
::
flush
(
bool
wait_for_q
)
inline
void
spdlog
::
details
::
async_log_helper
::
flush
(
bool
wait_for_q
)
{
{
push_msg
(
async_msg
(
async_msg_type
::
flush
));
push_msg
(
async_msg
(
async_msg_type
::
flush
));
if
(
wait_for_q
)
if
(
wait_for_q
)
wait_empty_q
();
//return only make after the above flush message was processed
wait_empty_q
();
//return only make after the above flush message was processed
}
}
...
@@ -303,8 +303,10 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
...
@@ -303,8 +303,10 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
log_msg
incoming_log_msg
;
log_msg
incoming_log_msg
;
incoming_async_msg
.
fill_log_msg
(
incoming_log_msg
);
incoming_async_msg
.
fill_log_msg
(
incoming_log_msg
);
_formatter
->
format
(
incoming_log_msg
);
_formatter
->
format
(
incoming_log_msg
);
for
(
auto
&
s
:
_sinks
){
for
(
auto
&
s
:
_sinks
)
if
(
s
->
should_log
(
incoming_log_msg
.
level
)){
{
if
(
s
->
should_log
(
incoming_log_msg
.
level
))
{
s
->
log
(
incoming_log_msg
);
s
->
log
(
incoming_log_msg
);
}
}
}
}
...
...
include/spdlog/details/logger_impl.h
View file @
5653e5c9
...
@@ -245,8 +245,10 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons
...
@@ -245,8 +245,10 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons
inline
void
spdlog
::
logger
::
_sink_it
(
details
::
log_msg
&
msg
)
inline
void
spdlog
::
logger
::
_sink_it
(
details
::
log_msg
&
msg
)
{
{
_formatter
->
format
(
msg
);
_formatter
->
format
(
msg
);
for
(
auto
&
sink
:
_sinks
){
for
(
auto
&
sink
:
_sinks
)
if
(
sink
->
should_log
(
msg
.
level
)){
{
if
(
sink
->
should_log
(
msg
.
level
))
{
sink
->
log
(
msg
);
sink
->
log
(
msg
);
}
}
}
}
...
...
include/spdlog/details/spdlog_impl.h
View file @
5653e5c9
...
@@ -108,7 +108,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string&
...
@@ -108,7 +108,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string&
#if defined(__ANDROID__)
#if defined(__ANDROID__)
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
android_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
tag
)
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
android_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
tag
)
{
{
return
create
<
spdlog
::
sinks
::
android_sink
>
(
logger_name
,
tag
);
return
create
<
spdlog
::
sinks
::
android_sink
>
(
logger_name
,
tag
);
}
}
#endif
#endif
...
...
include/spdlog/fmt/bundled/format.h
View file @
5653e5c9
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 @
5653e5c9
...
@@ -14,58 +14,68 @@
...
@@ -14,58 +14,68 @@
// #include "fmt/format.h"
// #include "fmt/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
:
{
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
private
:
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
Buffer
<
Char
>
&
buffer_
;
Char
*
start_
;
Buffer
<
Char
>
&
buffer_
;
Char
*
start_
;
public
:
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
()))
{
size_t
buf_size
=
size
();
buffer_
.
resize
(
buf_size
);
buffer_
.
reserve
(
buf_size
*
2
);
start_
=
&
buffer_
[
0
];
start_
[
buf_size
]
=
traits_type
::
to_char_type
(
ch
);
this
->
setp
(
start_
+
buf_size
+
1
,
start_
+
buf_size
*
2
);
}
}
return
ch
;
}
size_t
size
()
const
{
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
return
to_unsigned
(
this
->
pptr
()
-
start_
);
{
}
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
{
size_t
buf_size
=
size
();
buffer_
.
resize
(
buf_size
);
buffer_
.
reserve
(
buf_size
*
2
);
start_
=
&
buffer_
[
0
];
start_
[
buf_size
]
=
traits_type
::
to_char_type
(
ch
);
this
->
setp
(
start_
+
buf_size
+
1
,
start_
+
buf_size
*
2
);
}
return
ch
;
}
size_t
size
()
const
{
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.
{
// Hide all operator<< overloads from std::ostream.
DummyStream
();
// Suppress a bogus warning in MSVC.
void
operator
<<
(
Null
<>
);
// Hide all operator<< overloads from std::ostream.
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<<.
{
enum
{
// Convert to int only if T doesn't have an overloaded operator<<.
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
enum
};
{
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
};
};
};
// Write the content of w to os.
// Write the content of w to os.
...
@@ -75,16 +85,17 @@ void write(std::ostream &os, Writer &w);
...
@@ -75,16 +85,17 @@ void write(std::ostream &os, Writer &w);
// 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
);
std
::
basic_ostream
<
Char
>
output
(
&
format_buf
);
std
::
basic_ostream
<
Char
>
output
(
&
format_buf
);
output
<<
value
;
output
<<
value
;
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
));
}
}
/**
/**
...
...
include/spdlog/fmt/bundled/printf.h
View file @
5653e5c9
...
@@ -15,60 +15,81 @@
...
@@ -15,60 +15,81 @@
#include "fmt/ostream.h"
#include "fmt/ostream.h"
namespace
fmt
{
namespace
fmt
namespace
internal
{
{
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
IntChecker
{
struct
IntChecker
template
<
typename
T
>
{
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
true
;
}
return
value
<=
max
;
}
static
bool
fits_in_int
(
bool
)
{
return
true
;
}
};
};
template
<>
template
<>
struct
IntChecker
<
true
>
{
struct
IntChecker
<
true
>
template
<
typename
T
>
{
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
)
{
return
true
;
}
value
<=
std
::
numeric_limits
<
int
>::
max
();
}
static
bool
fits_in_int
(
int
)
{
return
true
;
}
};
};
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
{
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
public
:
{
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
)
{
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
template
<
typename
T
>
FMT_THROW
(
FormatError
(
"number is too big"
));
int
visit_any_int
(
T
value
)
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.
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
{
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
public
:
{
template
<
typename
T
>
public
:
bool
visit_any_int
(
T
value
)
{
return
value
==
0
;
}
template
<
typename
T
>
bool
visit_any_int
(
T
value
)
{
return
value
==
0
;
}
};
};
template
<
typename
T
,
typename
U
>
template
<
typename
T
,
typename
U
>
struct
is_same
{
struct
is_same
enum
{
value
=
0
};
{
enum
{
value
=
0
};
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
is_same
<
T
,
T
>
{
struct
is_same
<
T
,
T
>
enum
{
value
=
1
};
{
enum
{
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,
...
@@ -76,99 +97,117 @@ struct is_same<T, T> {
...
@@ -76,99 +97,117 @@ struct is_same<T, T> {
// 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
:
{
internal
::
Arg
&
arg_
;
private
:
wchar_t
type_
;
internal
::
Arg
&
arg_
;
wchar_t
type_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
public
:
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
public
:
:
arg_
(
arg
),
type_
(
type
)
{}
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
)
{
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
template
<
typename
U
>
using
internal
::
Arg
;
void
visit_any_int
(
U
value
)
typedef
typename
internal
::
Conditional
<
{
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
using
internal
::
Arg
;
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.
{
if
(
is_signed
)
{
// Extra casts are used to silence warnings.
arg_
.
type
=
Arg
::
INT
;
if
(
is_signed
)
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
{
}
else
{
arg_
.
type
=
Arg
::
INT
;
arg_
.
type
=
Arg
::
UINT
;
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
}
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
);
{
}
else
{
if
(
is_signed
)
arg_
.
type
=
Arg
::
ULONG_LONG
;
{
arg_
.
ulong_long_value
=
arg_
.
type
=
Arg
::
LONG_LONG
;
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
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.
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
}
else
{
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
ulong_long_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
:
{
internal
::
Arg
&
arg_
;
private
:
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
)
{}
template
<
typename
T
>
template
<
typename
T
>
void
visit_any_int
(
T
value
)
{
void
visit_any_int
(
T
value
)
arg_
.
type
=
internal
::
Arg
::
CHAR
;
{
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
arg_
.
type
=
internal
::
Arg
::
CHAR
;
}
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
:
{
FormatSpec
&
spec_
;
private
:
FormatSpec
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
public
:
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
public
:
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
void
report_unhandled_arg
()
{
FMT_THROW
(
FormatError
(
"width is not integer"
));
void
report_unhandled_arg
()
}
{
FMT_THROW
(
FormatError
(
"width is not integer"
));
template
<
typename
T
>
}
unsigned
visit_any_int
(
T
value
)
{
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
template
<
typename
T
>
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
unsigned
visit_any_int
(
T
value
)
if
(
internal
::
is_negative
(
value
))
{
{
spec_
.
align_
=
ALIGN_LEFT
;
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
width
=
0
-
width
;
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
if
(
internal
::
is_negative
(
value
))
{
spec_
.
align_
=
ALIGN_LEFT
;
width
=
0
-
width
;
}
unsigned
int_max
=
std
::
numeric_limits
<
int
>::
max
();
if
(
width
>
int_max
)
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
unsigned
>
(
width
);
}
}
unsigned
int_max
=
std
::
numeric_limits
<
int
>::
max
();
if
(
width
>
int_max
)
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
unsigned
>
(
width
);
}
};
};
}
// namespace internal
}
// namespace internal
...
@@ -190,302 +229,343 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
...
@@ -190,302 +229,343 @@ class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
\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
:
{
void
write_null_pointer
()
{
private
:
this
->
spec
().
type_
=
0
;
void
write_null_pointer
()
this
->
write
(
"(nil)"
);
{
}
this
->
spec
().
type_
=
0
;
this
->
write
(
"(nil)"
);
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
}
public
:
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
/**
\rst
public
:
Constructs an argument formatter object.
/**
*writer* is a reference to the output writer and *spec* contains format
\rst
specifier information for standard argument types.
Constructs an argument formatter object.
\endrst
*writer* is a reference to the output writer and *spec* contains format
*/
specifier information for standard argument types.
BasicPrintfArgFormatter
(
BasicWriter
<
Char
>
&
writer
,
FormatSpec
&
spec
)
\endrst
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
writer
,
spec
)
{}
*/
BasicPrintfArgFormatter
(
BasicWriter
<
Char
>
&
writer
,
FormatSpec
&
spec
)
/** Formats an argument of type ``bool``. */
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
writer
,
spec
)
{}
void
visit_bool
(
bool
value
)
{
FormatSpec
&
fmt_spec
=
this
->
spec
();
/** Formats an argument of type ``bool``. */
if
(
fmt_spec
.
type_
!=
's'
)
void
visit_bool
(
bool
value
)
return
this
->
visit_any_int
(
value
);
{
fmt_spec
.
type_
=
0
;
FormatSpec
&
fmt_spec
=
this
->
spec
();
this
->
write
(
value
);
if
(
fmt_spec
.
type_
!=
's'
)
}
return
this
->
visit_any_int
(
value
);
fmt_spec
.
type_
=
0
;
/** Formats a character. */
this
->
write
(
value
);
void
visit_char
(
int
value
)
{
}
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
/** Formats a character. */
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
void
visit_char
(
int
value
)
w
.
write_int
(
value
,
fmt_spec
);
{
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
CharPtr
out
=
CharPtr
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
if
(
fmt_spec
.
width_
>
1
)
{
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
Char
fill
=
' '
;
w
.
write_int
(
value
,
fmt_spec
);
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
{
CharPtr
out
=
CharPtr
();
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
if
(
fmt_spec
.
width_
>
1
)
out
+=
fmt_spec
.
width_
-
1
;
{
}
else
{
Char
fill
=
' '
;
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
}
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
}
else
{
{
out
=
w
.
grow_buffer
(
1
);
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
out
+=
fmt_spec
.
width_
-
1
;
}
else
{
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
}
}
else
{
out
=
w
.
grow_buffer
(
1
);
}
*
out
=
static_cast
<
Char
>
(
value
);
}
/** Formats a null-terminated C string. */
void
visit_cstring
(
const
char
*
value
)
{
if
(
value
)
Base
::
visit_cstring
(
value
);
else
if
(
this
->
spec
().
type_
==
'p'
)
write_null_pointer
();
else
this
->
write
(
"(null)"
);
}
/** Formats a pointer. */
void
visit_pointer
(
const
void
*
value
)
{
if
(
value
)
return
Base
::
visit_pointer
(
value
);
this
->
spec
().
type_
=
0
;
write_null_pointer
();
}
/** Formats an argument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
*
format
=
format_str
;
c
.
format
(
&
formatter
,
c
.
value
,
&
format
);
}
}
*
out
=
static_cast
<
Char
>
(
value
);
}
/** Formats a null-terminated C string. */
void
visit_cstring
(
const
char
*
value
)
{
if
(
value
)
Base
::
visit_cstring
(
value
);
else
if
(
this
->
spec
().
type_
==
'p'
)
write_null_pointer
();
else
this
->
write
(
"(null)"
);
}
/** Formats a pointer. */
void
visit_pointer
(
const
void
*
value
)
{
if
(
value
)
return
Base
::
visit_pointer
(
value
);
this
->
spec
().
type_
=
0
;
write_null_pointer
();
}
/** Formats an argument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
*
format
=
format_str
;
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
:
{
/** Constructs an argument formatter object. */
public
:
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
/** Constructs an argument formatter object. */
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
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
:
{
BasicWriter
<
Char
>
&
writer_
;
private
:
BasicWriter
<
Char
>
&
writer_
;
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
// Returns the argument with specified index or, if arg_index is equal
// to the maximum unsigned value, the next argument.
// Returns the argument with specified index or, if arg_index is equal
internal
::
Arg
get_arg
(
// to the maximum unsigned value, the next argument.
const
Char
*
s
,
internal
::
Arg
get_arg
(
unsigned
arg_index
=
(
std
::
numeric_limits
<
unsigned
>::
max
)());
const
Char
*
s
,
unsigned
arg_index
=
(
std
::
numeric_limits
<
unsigned
>::
max
)());
// Parses argument index, flags and width and returns the argument index.
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
// Parses argument index, flags and width and returns the argument index.
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
public
:
/**
public
:
\rst
/**
Constructs a ``PrintfFormatter`` object. References to the arguments and
\rst
the writer are stored in the formatter object so make sure they have
Constructs a ``PrintfFormatter`` object. References to the arguments and
appropriate lifetimes.
the writer are stored in the formatter object so make sure they have
\endrst
appropriate lifetimes.
*/
\endrst
explicit
PrintfFormatter
(
const
ArgList
&
args
,
BasicWriter
<
Char
>
&
w
)
*/
:
FormatterBase
(
args
),
writer_
(
w
)
{}
explicit
PrintfFormatter
(
const
ArgList
&
args
,
BasicWriter
<
Char
>
&
w
)
:
FormatterBase
(
args
),
writer_
(
w
)
{}
/** Formats stored arguments and writes the output to the writer. */
FMT_API
void
format
(
BasicCStringRef
<
Char
>
format_str
);
/** Formats stored arguments and writes the output to the writer. */
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
(;;)
case
'-'
:
{
spec
.
align_
=
ALIGN_LEFT
;
switch
(
*
s
++
)
break
;
{
case
'+'
:
case
'-'
:
spec
.
flags_
|=
SIGN_FLAG
|
PLUS_FLAG
;
spec
.
align_
=
ALIGN_LEFT
;
break
;
break
;
case
'0'
:
case
'+'
:
spec
.
fill_
=
'0'
;
spec
.
flags_
|=
SIGN_FLAG
|
PLUS_FLAG
;
break
;
break
;
case
' '
:
case
'0'
:
spec
.
flags_
|=
SIGN_FLAG
;
spec
.
fill_
=
'0'
;
break
;
break
;
case
'#'
:
case
' '
:
spec
.
flags_
|=
HASH_FLAG
;
spec
.
flags_
|=
SIGN_FLAG
;
break
;
break
;
default
:
case
'#'
:
--
s
;
spec
.
flags_
|=
HASH_FLAG
;
return
;
break
;
default
:
--
s
;
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
;
{
const
char
*
error
=
0
;
(
void
)
s
;
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
const
char
*
error
=
0
;
next_arg
(
error
)
:
FormatterBase
::
get_arg
(
arg_index
-
1
,
error
);
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
if
(
error
)
next_arg
(
error
)
:
FormatterBase
::
get_arg
(
arg_index
-
1
,
error
);
FMT_THROW
(
FormatError
(
!*
s
?
"invalid format string"
:
error
));
if
(
error
)
return
arg
;
FMT_THROW
(
FormatError
(
!*
s
?
"invalid format string"
:
error
));
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
();
{
Char
c
=
*
s
;
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
Char
c
=
*
s
;
// Parse an argument index (if followed by '$') or a width possibly
if
(
c
>=
'0'
&&
c
<=
'9'
)
// preceded with '0' flag(s).
{
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
// Parse an argument index (if followed by '$') or a width possibly
if
(
*
s
==
'$'
)
{
// value is an argument index
// preceded with '0' flag(s).
++
s
;
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
arg_index
=
value
;
if
(
*
s
==
'$'
)
// value is an argument index
}
else
{
{
if
(
c
==
'0'
)
++
s
;
spec
.
fill_
=
'0'
;
arg_index
=
value
;
if
(
value
!=
0
)
{
}
// Nonzero value means that we parsed width and don't need to
else
// parse it or flags again, so return now.
{
spec
.
width_
=
value
;
if
(
c
==
'0'
)
return
arg_index
;
spec
.
fill_
=
'0'
;
}
if
(
value
!=
0
)
{
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
spec
.
width_
=
value
;
return
arg_index
;
}
}
}
}
}
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
==
'*'
)
{
++
s
;
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
}
return
arg_index
;
}
template
<
typename
Char
,
typename
AF
>
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
{
const
Char
*
start
=
format_str
.
c_str
();
const
Char
*
s
=
start
;
while
(
*
s
)
{
Char
c
=
*
s
++
;
if
(
c
!=
'%'
)
continue
;
if
(
*
s
==
c
)
{
write
(
writer_
,
start
,
s
);
start
=
++
s
;
continue
;
}
}
write
(
writer_
,
start
,
s
-
1
);
else
if
(
*
s
==
'*'
)
{
FormatSpec
spec
;
spec
.
align_
=
ALIGN_RIGHT
;
// Parse argument index, flags and width.
unsigned
arg_index
=
parse_header
(
s
,
spec
);
// Parse precision.
if
(
*
s
==
'.'
)
{
++
s
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
}
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
}
}
using
internal
::
Arg
;
Arg
arg
=
get_arg
(
s
,
arg_index
);
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
if
(
spec
.
fill_
==
'0'
)
{
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
spec
.
align_
=
ALIGN_NUMERIC
;
else
spec
.
fill_
=
' '
;
// Ignore '0' flag for non-numeric types.
}
// Parse length and convert the argument to the required type.
using
internal
::
ArgConverter
;
switch
(
*
s
++
)
{
case
'h'
:
if
(
*
s
==
'h'
)
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
else
ArgConverter
<
short
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'l'
:
if
(
*
s
==
'l'
)
ArgConverter
<
fmt
::
LongLong
>
(
arg
,
*++
s
).
visit
(
arg
);
else
ArgConverter
<
long
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'j'
:
ArgConverter
<
intmax_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'z'
:
ArgConverter
<
std
::
size_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
't'
:
ArgConverter
<
std
::
ptrdiff_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'L'
:
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break
;
default
:
--
s
;
ArgConverter
<
void
>
(
arg
,
*
s
).
visit
(
arg
);
}
}
return
arg_index
;
}
// Parse type.
template
<
typename
Char
,
typename
AF
>
if
(
!*
s
)
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
{
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
const
Char
*
start
=
format_str
.
c_str
();
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
{
const
Char
*
s
=
start
;
// Normalize type.
while
(
*
s
)
switch
(
spec
.
type_
)
{
{
case
'i'
:
case
'u'
:
Char
c
=
*
s
++
;
spec
.
type_
=
'd'
;
if
(
c
!=
'%'
)
continue
;
break
;
if
(
*
s
==
c
)
case
'c'
:
{
// TODO: handle wchar_t
write
(
writer_
,
start
,
s
);
internal
::
CharConverter
(
arg
).
visit
(
arg
);
start
=
++
s
;
break
;
continue
;
}
}
write
(
writer_
,
start
,
s
-
1
);
FormatSpec
spec
;
spec
.
align_
=
ALIGN_RIGHT
;
// Parse argument index, flags and width.
unsigned
arg_index
=
parse_header
(
s
,
spec
);
// Parse precision.
if
(
*
s
==
'.'
)
{
++
s
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
}
else
if
(
*
s
==
'*'
)
{
++
s
;
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
}
}
using
internal
::
Arg
;
Arg
arg
=
get_arg
(
s
,
arg_index
);
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
if
(
spec
.
fill_
==
'0'
)
{
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
spec
.
align_
=
ALIGN_NUMERIC
;
else
spec
.
fill_
=
' '
;
// Ignore '0' flag for non-numeric types.
}
// Parse length and convert the argument to the required type.
using
internal
::
ArgConverter
;
switch
(
*
s
++
)
{
case
'h'
:
if
(
*
s
==
'h'
)
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
else
ArgConverter
<
short
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'l'
:
if
(
*
s
==
'l'
)
ArgConverter
<
fmt
::
LongLong
>
(
arg
,
*++
s
).
visit
(
arg
);
else
ArgConverter
<
long
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'j'
:
ArgConverter
<
intmax_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'z'
:
ArgConverter
<
std
::
size_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
't'
:
ArgConverter
<
std
::
ptrdiff_t
>
(
arg
,
*
s
).
visit
(
arg
);
break
;
case
'L'
:
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break
;
default
:
--
s
;
ArgConverter
<
void
>
(
arg
,
*
s
).
visit
(
arg
);
}
// Parse type.
if
(
!*
s
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
{
// Normalize type.
switch
(
spec
.
type_
)
{
case
'i'
:
case
'u'
:
spec
.
type_
=
'd'
;
break
;
case
'c'
:
// TODO: handle wchar_t
internal
::
CharConverter
(
arg
).
visit
(
arg
);
break
;
}
}
start
=
s
;
// Format argument.
AF
(
writer_
,
spec
).
visit
(
arg
);
}
}
write
(
writer_
,
start
,
s
);
start
=
s
;
// Format argument.
AF
(
writer_
,
spec
).
visit
(
arg
);
}
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
);
}
}
/**
/**
...
@@ -497,17 +577,19 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
...
@@ -497,17 +577,19 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
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
;
{
printf
(
w
,
format
,
args
);
MemoryWriter
w
;
return
w
.
str
();
printf
(
w
,
format
,
args
);
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
;
{
printf
(
w
,
format
,
args
);
WMemoryWriter
w
;
return
w
.
str
();
printf
(
w
,
format
,
args
);
return
w
.
str
();
}
}
FMT_VARIADIC_W
(
std
::
wstring
,
sprintf
,
WCStringRef
)
FMT_VARIADIC_W
(
std
::
wstring
,
sprintf
,
WCStringRef
)
...
@@ -532,8 +614,9 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
...
@@ -532,8 +614,9 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
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
)
...
@@ -546,11 +629,12 @@ FMT_VARIADIC(int, printf, CStringRef)
...
@@ -546,11 +629,12 @@ FMT_VARIADIC(int, printf, CStringRef)
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
;
{
printf
(
w
,
format_str
,
args
);
MemoryWriter
w
;
internal
::
write
(
os
,
w
);
printf
(
w
,
format_str
,
args
);
return
static_cast
<
int
>
(
w
.
size
());
internal
::
write
(
os
,
w
);
return
static_cast
<
int
>
(
w
.
size
());
}
}
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
}
// namespace fmt
}
// namespace fmt
...
...
include/spdlog/sinks/android_sink.h
View file @
5653e5c9
...
@@ -32,10 +32,11 @@ public:
...
@@ -32,10 +32,11 @@ public:
const
android_LogPriority
priority
=
convert_to_android
(
msg
.
level
);
const
android_LogPriority
priority
=
convert_to_android
(
msg
.
level
);
// See system/core/liblog/logger_write.c for explanation of return value
// See system/core/liblog/logger_write.c for explanation of return value
const
int
ret
=
__android_log_write
(
const
int
ret
=
__android_log_write
(
priority
,
_tag
.
c_str
(),
msg
.
formatted
.
c_str
()
priority
,
_tag
.
c_str
(),
msg
.
formatted
.
c_str
()
);
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
throw
spdlog_ex
(
"__android_log_write() failed"
,
ret
);
{
throw
spdlog_ex
(
"__android_log_write() failed"
,
ret
);
}
}
}
}
...
...
include/spdlog/sinks/dist_sink.h
View file @
5653e5c9
...
@@ -35,8 +35,10 @@ protected:
...
@@ -35,8 +35,10 @@ protected:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
{
for
(
auto
&
sink
:
_sinks
){
for
(
auto
&
sink
:
_sinks
)
if
(
sink
->
should_log
(
msg
.
level
)){
{
if
(
sink
->
should_log
(
msg
.
level
))
{
sink
->
log
(
msg
);
sink
->
log
(
msg
);
}
}
}
}
...
...
include/spdlog/sinks/sink.h
View file @
5653e5c9
...
@@ -30,15 +30,18 @@ private:
...
@@ -30,15 +30,18 @@ private:
};
};
inline
bool
sink
::
should_log
(
level
::
level_enum
msg_level
)
const
{
inline
bool
sink
::
should_log
(
level
::
level_enum
msg_level
)
const
{
return
msg_level
>=
_level
.
load
(
std
::
memory_order_relaxed
);
return
msg_level
>=
_level
.
load
(
std
::
memory_order_relaxed
);
}
}
inline
void
sink
::
set_level
(
level
::
level_enum
log_level
)
{
inline
void
sink
::
set_level
(
level
::
level_enum
log_level
)
{
_level
.
store
(
log_level
);
_level
.
store
(
log_level
);
}
}
inline
level
::
level_enum
sink
::
level
()
const
{
inline
level
::
level_enum
sink
::
level
()
const
{
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
_level
.
load
(
std
::
memory_order_relaxed
));
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
_level
.
load
(
std
::
memory_order_relaxed
));
}
}
...
...
include/spdlog/spdlog.h
View file @
5653e5c9
...
@@ -20,7 +20,7 @@
...
@@ -20,7 +20,7 @@
namespace
spdlog
namespace
spdlog
{
{
//
//
// Return an existing logger or nullptr if a logger with such name doesn't exist.
// Return an existing logger or nullptr if a logger with such name doesn't exist.
// example: spdlog::get("my_logger")->info("hello {}", "world");
// example: spdlog::get("my_logger")->info("hello {}", "world");
//
//
...
@@ -67,7 +67,7 @@ void set_sync_mode();
...
@@ -67,7 +67,7 @@ void set_sync_mode();
//
//
// Create and register multi/single threaded basic file logger.
// Create and register multi/single threaded basic file logger.
// Basic logger simply writes to given file without any limitatons or rotations.
// Basic logger simply writes to given file without any limitatons or rotations.
//
//
std
::
shared_ptr
<
logger
>
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
);
std
::
shared_ptr
<
logger
>
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
);
...
...
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