Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
spdlog
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
spdlog
Commits
3826ac14
Commit
3826ac14
authored
Feb 23, 2018
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bumped bundled fmt version to 4.1.0
parent
d650fa24
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
3219 additions
and
3957 deletions
+3219
-3957
include/spdlog/fmt/bundled/format.cc
include/spdlog/fmt/bundled/format.cc
+12
-52
include/spdlog/fmt/bundled/format.h
include/spdlog/fmt/bundled/format.h
+2412
-2898
include/spdlog/fmt/bundled/ostream.h
include/spdlog/fmt/bundled/ostream.h
+51
-57
include/spdlog/fmt/bundled/posix.h
include/spdlog/fmt/bundled/posix.h
+218
-275
include/spdlog/fmt/bundled/printf.h
include/spdlog/fmt/bundled/printf.h
+423
-532
include/spdlog/fmt/bundled/time.h
include/spdlog/fmt/bundled/time.h
+103
-143
No files found.
include/spdlog/fmt/bundled/format.cc
View file @
3826ac14
...
@@ -72,9 +72,11 @@
...
@@ -72,9 +72,11 @@
// Dummy implementations of strerror_r and strerror_s called if corresponding
// Dummy implementations of strerror_r and strerror_s called if corresponding
// system functions are not available.
// system functions are not available.
FMT_MAYBE_UNUSED
static
inline
fmt
::
internal
::
Null
<>
strerror_r
(
int
,
char
*
,
...)
{
static
inline
fmt
::
internal
::
Null
<>
strerror_r
(
int
,
char
*
,
...)
{
return
fmt
::
internal
::
Null
<>
();
return
fmt
::
internal
::
Null
<>
();
}
}
FMT_MAYBE_UNUSED
static
inline
fmt
::
internal
::
Null
<>
strerror_s
(
char
*
,
std
::
size_t
,
...)
{
static
inline
fmt
::
internal
::
Null
<>
strerror_s
(
char
*
,
std
::
size_t
,
...)
{
return
fmt
::
internal
::
Null
<>
();
return
fmt
::
internal
::
Null
<>
();
}
}
...
@@ -121,7 +123,7 @@ typedef void (*FormatFunc)(Writer &, int, StringRef);
...
@@ -121,7 +123,7 @@ typedef void (*FormatFunc)(Writer &, int, StringRef);
// Buffer should be at least of size 1.
// Buffer should be at least of size 1.
int
safe_strerror
(
int
safe_strerror
(
int
error_code
,
char
*&
buffer
,
std
::
size_t
buffer_size
)
FMT_NOEXCEPT
{
int
error_code
,
char
*&
buffer
,
std
::
size_t
buffer_size
)
FMT_NOEXCEPT
{
FMT_ASSERT
(
buffer
!=
0
&&
buffer_size
!=
0
,
"invalid buffer"
);
FMT_ASSERT
(
buffer
!=
FMT_NULL
&&
buffer_size
!=
0
,
"invalid buffer"
);
class
StrError
{
class
StrError
{
private:
private:
...
@@ -159,6 +161,11 @@ int safe_strerror(
...
@@ -159,6 +161,11 @@ int safe_strerror(
ERANGE
:
result
;
ERANGE
:
result
;
}
}
#ifdef __c2__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
// Fallback to strerror if strerror_r and strerror_s are not available.
// Fallback to strerror if strerror_r and strerror_s are not available.
int
fallback
(
internal
::
Null
<>
)
{
int
fallback
(
internal
::
Null
<>
)
{
errno
=
0
;
errno
=
0
;
...
@@ -166,13 +173,15 @@ int safe_strerror(
...
@@ -166,13 +173,15 @@ int safe_strerror(
return
errno
;
return
errno
;
}
}
#ifdef __c2__
# pragma clang diagnostic pop
#endif
public:
public:
StrError
(
int
err_code
,
char
*&
buf
,
std
::
size_t
buf_size
)
StrError
(
int
err_code
,
char
*&
buf
,
std
::
size_t
buf_size
)
:
error_code_
(
err_code
),
buffer_
(
buf
),
buffer_size_
(
buf_size
)
{}
:
error_code_
(
err_code
),
buffer_
(
buf
),
buffer_size_
(
buf_size
)
{}
int
run
()
{
int
run
()
{
// Suppress a warning about unused strerror_r.
strerror_r
(
0
,
FMT_NULL
,
""
);
return
handle
(
strerror_r
(
error_code_
,
buffer_
,
buffer_size_
));
return
handle
(
strerror_r
(
error_code_
,
buffer_
,
buffer_size_
));
}
}
};
};
...
@@ -396,51 +405,6 @@ FMT_FUNC void format_system_error(
...
@@ -396,51 +405,6 @@ FMT_FUNC void format_system_error(
fmt
::
format_error_code
(
out
,
error_code
,
message
);
// 'fmt::' is for bcc32.
fmt
::
format_error_code
(
out
,
error_code
,
message
);
// 'fmt::' is for bcc32.
}
}
template
<
typename
Char
>
void
internal
::
ArgMap
<
Char
>::
init
(
const
ArgList
&
args
)
{
if
(
!
map_
.
empty
())
return
;
typedef
internal
::
NamedArg
<
Char
>
NamedArg
;
const
NamedArg
*
named_arg
=
FMT_NULL
;
bool
use_values
=
args
.
type
(
ArgList
::
MAX_PACKED_ARGS
-
1
)
==
internal
::
Arg
::
NONE
;
if
(
use_values
)
{
for
(
unsigned
i
=
0
;
/*nothing*/
;
++
i
)
{
internal
::
Arg
::
Type
arg_type
=
args
.
type
(
i
);
switch
(
arg_type
)
{
case
internal
:
:
Arg
::
NONE
:
return
;
case
internal
:
:
Arg
::
NAMED_ARG
:
named_arg
=
static_cast
<
const
NamedArg
*>
(
args
.
values_
[
i
].
pointer
);
map_
.
push_back
(
Pair
(
named_arg
->
name
,
*
named_arg
));
break
;
default:
/*nothing*/
;
}
}
return
;
}
for
(
unsigned
i
=
0
;
i
!=
ArgList
::
MAX_PACKED_ARGS
;
++
i
)
{
internal
::
Arg
::
Type
arg_type
=
args
.
type
(
i
);
if
(
arg_type
==
internal
::
Arg
::
NAMED_ARG
)
{
named_arg
=
static_cast
<
const
NamedArg
*>
(
args
.
args_
[
i
].
pointer
);
map_
.
push_back
(
Pair
(
named_arg
->
name
,
*
named_arg
));
}
}
for
(
unsigned
i
=
ArgList
::
MAX_PACKED_ARGS
;
/*nothing*/
;
++
i
)
{
switch
(
args
.
args_
[
i
].
type
)
{
case
internal
:
:
Arg
::
NONE
:
return
;
case
internal
:
:
Arg
::
NAMED_ARG
:
named_arg
=
static_cast
<
const
NamedArg
*>
(
args
.
args_
[
i
].
pointer
);
map_
.
push_back
(
Pair
(
named_arg
->
name
,
*
named_arg
));
break
;
default:
/*nothing*/
;
}
}
}
template
<
typename
Char
>
template
<
typename
Char
>
void
internal
::
FixedBuffer
<
Char
>::
grow
(
std
::
size_t
)
{
void
internal
::
FixedBuffer
<
Char
>::
grow
(
std
::
size_t
)
{
FMT_THROW
(
std
::
runtime_error
(
"buffer overflow"
));
FMT_THROW
(
std
::
runtime_error
(
"buffer overflow"
));
...
@@ -502,8 +466,6 @@ template struct internal::BasicData<void>;
...
@@ -502,8 +466,6 @@ template struct internal::BasicData<void>;
template
void
internal
::
FixedBuffer
<
char
>
::
grow
(
std
::
size_t
);
template
void
internal
::
FixedBuffer
<
char
>
::
grow
(
std
::
size_t
);
template
void
internal
::
ArgMap
<
char
>
::
init
(
const
ArgList
&
args
);
template
FMT_API
int
internal
::
CharTraits
<
char
>
::
format_float
(
template
FMT_API
int
internal
::
CharTraits
<
char
>
::
format_float
(
char
*
buffer
,
std
::
size_t
size
,
const
char
*
format
,
char
*
buffer
,
std
::
size_t
size
,
const
char
*
format
,
unsigned
width
,
int
precision
,
double
value
);
unsigned
width
,
int
precision
,
double
value
);
...
@@ -516,8 +478,6 @@ template FMT_API int internal::CharTraits<char>::format_float(
...
@@ -516,8 +478,6 @@ template FMT_API int internal::CharTraits<char>::format_float(
template
void
internal
::
FixedBuffer
<
wchar_t
>
::
grow
(
std
::
size_t
);
template
void
internal
::
FixedBuffer
<
wchar_t
>
::
grow
(
std
::
size_t
);
template
void
internal
::
ArgMap
<
wchar_t
>
::
init
(
const
ArgList
&
args
);
template
FMT_API
int
internal
::
CharTraits
<
wchar_t
>
::
format_float
(
template
FMT_API
int
internal
::
CharTraits
<
wchar_t
>
::
format_float
(
wchar_t
*
buffer
,
std
::
size_t
size
,
const
wchar_t
*
format
,
wchar_t
*
buffer
,
std
::
size_t
size
,
const
wchar_t
*
format
,
unsigned
width
,
int
precision
,
double
value
);
unsigned
width
,
int
precision
,
double
value
);
...
...
include/spdlog/fmt/bundled/format.h
View file @
3826ac14
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 @
3826ac14
...
@@ -13,25 +13,22 @@
...
@@ -13,25 +13,22 @@
#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_
;
public:
public:
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
)
{}
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
)
{}
protected:
protected:
// The put-area is actually always empty. This makes the implementation
// The put-area is actually always empty. This makes the implementation
// simpler and has the advantage that the streambuf and the buffer are always
// simpler and has the advantage that the streambuf and the buffer are always
// in sync and sputc never writes into uninitialized memory. The obvious
// in sync and sputc never writes into uninitialized memory. The obvious
...
@@ -39,15 +36,13 @@ protected:
...
@@ -39,15 +36,13 @@ protected:
// to overflow. There is no disadvantage here for sputn since this always
// to overflow. There is no disadvantage here for sputn since this always
// results in a call to xsputn.
// results in a call to xsputn.
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
FMT_OVERRIDE
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
FMT_OVERRIDE
{
{
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
buffer_
.
push_back
(
static_cast
<
Char
>
(
ch
));
buffer_
.
push_back
(
static_cast
<
Char
>
(
ch
));
return
ch
;
return
ch
;
}
}
std
::
streamsize
xsputn
(
const
Char
*
s
,
std
::
streamsize
count
)
FMT_OVERRIDE
std
::
streamsize
xsputn
(
const
Char
*
s
,
std
::
streamsize
count
)
FMT_OVERRIDE
{
{
buffer_
.
append
(
s
,
s
+
count
);
buffer_
.
append
(
s
,
s
+
count
);
return
count
;
return
count
;
}
}
...
@@ -55,21 +50,20 @@ protected:
...
@@ -55,21 +50,20 @@ protected:
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
<>
);
template
<
typename
T
>
typename
EnableIf
<
sizeof
(
T
)
==
0
>::
type
operator
<<
(
const
T
&
);
};
};
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
)
};
};
};
};
...
@@ -81,12 +75,12 @@ FMT_API void write(std::ostream &os, Writer &w);
...
@@ -81,12 +75,12 @@ FMT_API 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
.
exceptions
(
std
::
ios_base
::
failbit
|
std
::
ios_base
::
badbit
);
output
<<
value
;
output
<<
value
;
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
buffer
.
size
());
BasicStringRef
<
Char
>
str
(
&
buffer
[
0
],
buffer
.
size
());
...
...
include/spdlog/fmt/bundled/posix.h
View file @
3826ac14
...
@@ -64,39 +64,31 @@
...
@@ -64,39 +64,31 @@
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
namespace
fmt
namespace
fmt
{
{
// An error code.
// An error code.
class
ErrorCode
class
ErrorCode
{
{
private:
private:
int
value_
;
int
value_
;
public:
public:
explicit
ErrorCode
(
int
value
=
0
)
FMT_NOEXCEPT
:
explicit
ErrorCode
(
int
value
=
0
)
FMT_NOEXCEPT
:
value_
(
value
)
{}
value_
(
value
)
{}
int
get
()
const
FMT_NOEXCEPT
int
get
()
const
FMT_NOEXCEPT
{
return
value_
;
}
{
return
value_
;
}
};
};
// A buffered file.
// A buffered file.
class
BufferedFile
class
BufferedFile
{
{
private:
private:
FILE
*
file_
;
FILE
*
file_
;
friend
class
File
;
friend
class
File
;
explicit
BufferedFile
(
FILE
*
f
)
:
file_
(
f
)
{}
explicit
BufferedFile
(
FILE
*
f
)
:
file_
(
f
)
{}
public:
public:
// Constructs a BufferedFile object which doesn't represent any file.
// Constructs a BufferedFile object which doesn't represent any file.
BufferedFile
()
FMT_NOEXCEPT
:
BufferedFile
()
FMT_NOEXCEPT
:
file_
(
FMT_NULL
)
{}
file_
(
FMT_NULL
)
{}
// Destroys the object closing the file it represents if any.
// Destroys the object closing the file it represents if any.
FMT_API
~
BufferedFile
()
FMT_NOEXCEPT
;
FMT_API
~
BufferedFile
()
FMT_NOEXCEPT
;
...
@@ -105,37 +97,31 @@ BufferedFile() FMT_NOEXCEPT :
...
@@ -105,37 +97,31 @@ BufferedFile() FMT_NOEXCEPT :
// Emulate a move constructor and a move assignment operator if rvalue
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
// references are not supported.
private:
private:
// A proxy object to emulate a move constructor.
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
// It is private to make it impossible call operator Proxy directly.
struct
Proxy
struct
Proxy
{
{
FILE
*
file
;
FILE
*
file
;
};
};
public:
public:
// A "move constructor" for moving from a temporary.
// A "move constructor" for moving from a temporary.
BufferedFile
(
Proxy
p
)
FMT_NOEXCEPT
:
BufferedFile
(
Proxy
p
)
FMT_NOEXCEPT
:
file_
(
p
.
file
)
{}
file_
(
p
.
file
)
{}
// A "move constructor" for moving from an lvalue.
// A "move constructor" for moving from an lvalue.
BufferedFile
(
BufferedFile
&
f
)
FMT_NOEXCEPT
:
BufferedFile
(
BufferedFile
&
f
)
FMT_NOEXCEPT
:
file_
(
f
.
file_
)
{
file_
(
f
.
file_
)
{
f
.
file_
=
FMT_NULL
;
f
.
file_
=
FMT_NULL
;
}
}
// A "move assignment operator" for moving from a temporary.
// A "move assignment operator" for moving from a temporary.
BufferedFile
&
operator
=
(
Proxy
p
)
BufferedFile
&
operator
=
(
Proxy
p
)
{
{
close
();
close
();
file_
=
p
.
file
;
file_
=
p
.
file
;
return
*
this
;
return
*
this
;
}
}
// A "move assignment operator" for moving from an lvalue.
// A "move assignment operator" for moving from an lvalue.
BufferedFile
&
operator
=
(
BufferedFile
&
other
)
BufferedFile
&
operator
=
(
BufferedFile
&
other
)
{
{
close
();
close
();
file_
=
other
.
file_
;
file_
=
other
.
file_
;
other
.
file_
=
FMT_NULL
;
other
.
file_
=
FMT_NULL
;
...
@@ -144,26 +130,22 @@ BufferedFile(BufferedFile &f) FMT_NOEXCEPT :
...
@@ -144,26 +130,22 @@ BufferedFile(BufferedFile &f) FMT_NOEXCEPT :
// Returns a proxy object for moving from a temporary:
// Returns a proxy object for moving from a temporary:
// BufferedFile file = BufferedFile(...);
// BufferedFile file = BufferedFile(...);
operator
Proxy
()
FMT_NOEXCEPT
operator
Proxy
()
FMT_NOEXCEPT
{
{
Proxy
p
=
{
file_
};
Proxy
p
=
{
file_
};
file_
=
FMT_NULL
;
file_
=
FMT_NULL
;
return
p
;
return
p
;
}
}
#else
#else
private:
private:
FMT_DISALLOW_COPY_AND_ASSIGN
(
BufferedFile
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
BufferedFile
);
public:
public:
BufferedFile
(
BufferedFile
&&
other
)
FMT_NOEXCEPT
:
BufferedFile
(
BufferedFile
&&
other
)
FMT_NOEXCEPT
:
file_
(
other
.
file_
)
{
file_
(
other
.
file_
)
{
other
.
file_
=
FMT_NULL
;
other
.
file_
=
FMT_NULL
;
}
}
BufferedFile
&
operator
=
(
BufferedFile
&&
other
)
BufferedFile
&
operator
=
(
BufferedFile
&&
other
)
{
{
close
();
close
();
file_
=
other
.
file_
;
file_
=
other
.
file_
;
other
.
file_
=
FMT_NULL
;
other
.
file_
=
FMT_NULL
;
...
@@ -178,17 +160,13 @@ BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
...
@@ -178,17 +160,13 @@ BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
FMT_API
void
close
();
FMT_API
void
close
();
// Returns the pointer to a FILE object representing this file.
// Returns the pointer to a FILE object representing this file.
FILE
*
get
()
const
FMT_NOEXCEPT
FILE
*
get
()
const
FMT_NOEXCEPT
{
return
file_
;
}
{
return
file_
;
}
// We place parentheses around fileno to workaround a bug in some versions
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
// of MinGW that define fileno as a macro.
FMT_API
int
(
fileno
)()
const
;
FMT_API
int
(
fileno
)()
const
;
void
print
(
CStringRef
format_str
,
const
ArgList
&
args
)
void
print
(
CStringRef
format_str
,
const
ArgList
&
args
)
{
{
fmt
::
print
(
file_
,
format_str
,
args
);
fmt
::
print
(
file_
,
format_str
,
args
);
}
}
FMT_VARIADIC
(
void
,
print
,
CStringRef
)
FMT_VARIADIC
(
void
,
print
,
CStringRef
)
...
@@ -200,26 +178,23 @@ BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
...
@@ -200,26 +178,23 @@ BufferedFile(BufferedFile &&other) FMT_NOEXCEPT :
// closing the file multiple times will cause a crash on Windows rather
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
// invalid parameter handler with _set_invalid_parameter_handler.
class
File
class
File
{
{
private:
private:
int
fd_
;
// File descriptor.
int
fd_
;
// File descriptor.
// Constructs a File object with a given descriptor.
// Constructs a File object with a given descriptor.
explicit
File
(
int
fd
)
:
fd_
(
fd
)
{}
explicit
File
(
int
fd
)
:
fd_
(
fd
)
{}
public:
public:
// Possible values for the oflag argument to the constructor.
// Possible values for the oflag argument to the constructor.
enum
enum
{
{
RDONLY
=
FMT_POSIX
(
O_RDONLY
),
// Open for reading only.
RDONLY
=
FMT_POSIX
(
O_RDONLY
),
// Open for reading only.
WRONLY
=
FMT_POSIX
(
O_WRONLY
),
// Open for writing only.
WRONLY
=
FMT_POSIX
(
O_WRONLY
),
// Open for writing only.
RDWR
=
FMT_POSIX
(
O_RDWR
)
// Open for reading and writing.
RDWR
=
FMT_POSIX
(
O_RDWR
)
// Open for reading and writing.
};
};
// Constructs a File object which doesn't represent any file.
// Constructs a File object which doesn't represent any file.
File
()
FMT_NOEXCEPT
:
File
()
FMT_NOEXCEPT
:
fd_
(
-
1
)
{}
fd_
(
-
1
)
{}
// Opens a file and constructs a File object representing this file.
// Opens a file and constructs a File object representing this file.
FMT_API
File
(
CStringRef
path
,
int
oflag
);
FMT_API
File
(
CStringRef
path
,
int
oflag
);
...
@@ -228,37 +203,31 @@ File() FMT_NOEXCEPT :
...
@@ -228,37 +203,31 @@ File() FMT_NOEXCEPT :
// Emulate a move constructor and a move assignment operator if rvalue
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
// references are not supported.
private:
private:
// A proxy object to emulate a move constructor.
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
// It is private to make it impossible call operator Proxy directly.
struct
Proxy
struct
Proxy
{
{
int
fd
;
int
fd
;
};
};
public:
public:
// A "move constructor" for moving from a temporary.
// A "move constructor" for moving from a temporary.
File
(
Proxy
p
)
FMT_NOEXCEPT
:
File
(
Proxy
p
)
FMT_NOEXCEPT
:
fd_
(
p
.
fd
)
{}
fd_
(
p
.
fd
)
{}
// A "move constructor" for moving from an lvalue.
// A "move constructor" for moving from an lvalue.
File
(
File
&
other
)
FMT_NOEXCEPT
:
File
(
File
&
other
)
FMT_NOEXCEPT
:
fd_
(
other
.
fd_
)
{
fd_
(
other
.
fd_
)
{
other
.
fd_
=
-
1
;
other
.
fd_
=
-
1
;
}
}
// A "move assignment operator" for moving from a temporary.
// A "move assignment operator" for moving from a temporary.
File
&
operator
=
(
Proxy
p
)
File
&
operator
=
(
Proxy
p
)
{
{
close
();
close
();
fd_
=
p
.
fd
;
fd_
=
p
.
fd
;
return
*
this
;
return
*
this
;
}
}
// A "move assignment operator" for moving from an lvalue.
// A "move assignment operator" for moving from an lvalue.
File
&
operator
=
(
File
&
other
)
File
&
operator
=
(
File
&
other
)
{
{
close
();
close
();
fd_
=
other
.
fd_
;
fd_
=
other
.
fd_
;
other
.
fd_
=
-
1
;
other
.
fd_
=
-
1
;
...
@@ -267,26 +236,22 @@ File(File &other) FMT_NOEXCEPT :
...
@@ -267,26 +236,22 @@ File(File &other) FMT_NOEXCEPT :
// Returns a proxy object for moving from a temporary:
// Returns a proxy object for moving from a temporary:
// File file = File(...);
// File file = File(...);
operator
Proxy
()
FMT_NOEXCEPT
operator
Proxy
()
FMT_NOEXCEPT
{
{
Proxy
p
=
{
fd_
};
Proxy
p
=
{
fd_
};
fd_
=
-
1
;
fd_
=
-
1
;
return
p
;
return
p
;
}
}
#else
#else
private:
private:
FMT_DISALLOW_COPY_AND_ASSIGN
(
File
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
File
);
public:
public:
File
(
File
&&
other
)
FMT_NOEXCEPT
:
File
(
File
&&
other
)
FMT_NOEXCEPT
:
fd_
(
other
.
fd_
)
{
fd_
(
other
.
fd_
)
{
other
.
fd_
=
-
1
;
other
.
fd_
=
-
1
;
}
}
File
&
operator
=
(
File
&&
other
)
File
&
operator
=
(
File
&&
other
)
{
{
close
();
close
();
fd_
=
other
.
fd_
;
fd_
=
other
.
fd_
;
other
.
fd_
=
-
1
;
other
.
fd_
=
-
1
;
...
@@ -298,10 +263,7 @@ File(File &&other) FMT_NOEXCEPT :
...
@@ -298,10 +263,7 @@ File(File &&other) FMT_NOEXCEPT :
FMT_API
~
File
()
FMT_NOEXCEPT
;
FMT_API
~
File
()
FMT_NOEXCEPT
;
// Returns the file descriptor.
// Returns the file descriptor.
int
descriptor
()
const
FMT_NOEXCEPT
int
descriptor
()
const
FMT_NOEXCEPT
{
return
fd_
;
}
{
return
fd_
;
}
// Closes the file.
// Closes the file.
FMT_API
void
close
();
FMT_API
void
close
();
...
@@ -347,26 +309,22 @@ long getpagesize();
...
@@ -347,26 +309,22 @@ long getpagesize();
#ifdef FMT_LOCALE
#ifdef FMT_LOCALE
// A "C" numeric locale.
// A "C" numeric locale.
class
Locale
class
Locale
{
{
private:
private:
# ifdef _MSC_VER
# ifdef _MSC_VER
typedef
_locale_t
locale_t
;
typedef
_locale_t
locale_t
;
enum
{
LC_NUMERIC_MASK
=
LC_NUMERIC
};
enum
{
LC_NUMERIC_MASK
=
LC_NUMERIC
};
static
locale_t
newlocale
(
int
category_mask
,
const
char
*
locale
,
locale_t
)
static
locale_t
newlocale
(
int
category_mask
,
const
char
*
locale
,
locale_t
)
{
{
return
_create_locale
(
category_mask
,
locale
);
return
_create_locale
(
category_mask
,
locale
);
}
}
static
void
freelocale
(
locale_t
locale
)
static
void
freelocale
(
locale_t
locale
)
{
{
_free_locale
(
locale
);
_free_locale
(
locale
);
}
}
static
double
strtod_l
(
const
char
*
nptr
,
char
**
endptr
,
_locale_t
locale
)
static
double
strtod_l
(
const
char
*
nptr
,
char
**
endptr
,
_locale_t
locale
)
{
{
return
_strtod_l
(
nptr
,
endptr
,
locale
);
return
_strtod_l
(
nptr
,
endptr
,
locale
);
}
}
# endif
# endif
...
@@ -375,28 +333,20 @@ private:
...
@@ -375,28 +333,20 @@ private:
FMT_DISALLOW_COPY_AND_ASSIGN
(
Locale
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
Locale
);
public:
public:
typedef
locale_t
Type
;
typedef
locale_t
Type
;
Locale
()
:
locale_
(
newlocale
(
LC_NUMERIC_MASK
,
"C"
,
FMT_NULL
))
Locale
()
:
locale_
(
newlocale
(
LC_NUMERIC_MASK
,
"C"
,
FMT_NULL
))
{
{
if
(
!
locale_
)
if
(
!
locale_
)
FMT_THROW
(
fmt
::
SystemError
(
errno
,
"cannot create locale"
));
FMT_THROW
(
fmt
::
SystemError
(
errno
,
"cannot create locale"
));
}
}
~
Locale
()
~
Locale
()
{
freelocale
(
locale_
);
}
{
freelocale
(
locale_
);
}
Type
get
()
const
Type
get
()
const
{
return
locale_
;
}
{
return
locale_
;
}
// Converts string to floating-point number and advances str past the end
// Converts string to floating-point number and advances str past the end
// of the parsed input.
// of the parsed input.
double
strtod
(
const
char
*&
str
)
const
double
strtod
(
const
char
*&
str
)
const
{
{
char
*
end
=
FMT_NULL
;
char
*
end
=
FMT_NULL
;
double
result
=
strtod_l
(
str
,
&
end
,
locale_
);
double
result
=
strtod_l
(
str
,
&
end
,
locale_
);
str
=
end
;
str
=
end
;
...
@@ -407,17 +357,10 @@ public:
...
@@ -407,17 +357,10 @@ public:
}
// namespace fmt
}
// namespace fmt
#if !FMT_USE_RVALUE_REFERENCES
#if !FMT_USE_RVALUE_REFERENCES
namespace
std
namespace
std
{
{
// For compatibility with C++98.
// For compatibility with C++98.
inline
fmt
::
BufferedFile
&
move
(
fmt
::
BufferedFile
&
f
)
inline
fmt
::
BufferedFile
&
move
(
fmt
::
BufferedFile
&
f
)
{
return
f
;
}
{
inline
fmt
::
File
&
move
(
fmt
::
File
&
f
)
{
return
f
;
}
return
f
;
}
inline
fmt
::
File
&
move
(
fmt
::
File
&
f
)
{
return
f
;
}
}
}
#endif
#endif
...
...
include/spdlog/fmt/bundled/printf.h
View file @
3826ac14
...
@@ -15,54 +15,39 @@
...
@@ -15,54 +15,39 @@
#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
// 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
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
static
bool
fits_in_int
(
T
value
)
{
{
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
return
value
<=
max
;
return
value
<=
max
;
}
}
static
bool
fits_in_int
(
bool
)
static
bool
fits_in_int
(
bool
)
{
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
)
{
{
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
value
<=
std
::
numeric_limits
<
int
>::
max
();
value
<=
std
::
numeric_limits
<
int
>::
max
();
}
}
static
bool
fits_in_int
(
int
)
static
bool
fits_in_int
(
int
)
{
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"
));
}
}
template
<
typename
T
>
template
<
typename
T
>
int
visit_any_int
(
T
value
)
int
visit_any_int
(
T
value
)
{
{
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
FMT_THROW
(
FormatError
(
"number is too big"
));
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
int
>
(
value
);
return
static_cast
<
int
>
(
value
);
...
@@ -70,62 +55,37 @@ public:
...
@@ -70,62 +55,37 @@ public:
};
};
// 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
;
}
};
};
// returns the default type for format specific "%s"
// returns the default type for format specific "%s"
class
DefaultType
:
public
ArgVisitor
<
DefaultType
,
char
>
class
DefaultType
:
public
ArgVisitor
<
DefaultType
,
char
>
{
{
public:
public:
char
visit_char
(
int
)
{
return
'c'
;
}
char
visit_char
(
int
)
{
return
'c'
;
}
char
visit_bool
(
bool
)
char
visit_bool
(
bool
)
{
return
's'
;
}
{
return
's'
;
}
char
visit_pointer
(
const
void
*
)
char
visit_pointer
(
const
void
*
)
{
return
'p'
;
}
{
return
'p'
;
}
template
<
typename
T
>
template
<
typename
T
>
char
visit_any_int
(
T
)
char
visit_any_int
(
T
)
{
return
'd'
;
}
{
return
'd'
;
}
template
<
typename
T
>
template
<
typename
T
>
char
visit_any_double
(
T
)
char
visit_any_double
(
T
)
{
return
'g'
;
}
{
return
'g'
;
}
char
visit_unhandled_arg
()
char
visit_unhandled_arg
()
{
return
's'
;
}
{
return
's'
;
}
};
};
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
};
};
};
...
@@ -134,69 +94,55 @@ struct is_same<T, T>
...
@@ -134,69 +94,55 @@ 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:
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
)
{}
void
visit_bool
(
bool
value
)
void
visit_bool
(
bool
value
)
{
{
if
(
type_
!=
's'
)
if
(
type_
!=
's'
)
visit_any_int
(
value
);
visit_any_int
(
value
);
}
}
void
visit_char
(
char
value
)
void
visit_char
(
int
value
)
{
{
if
(
type_
!=
's'
)
if
(
type_
!=
's'
)
visit_any_int
(
value
);
visit_any_int
(
value
);
}
}
template
<
typename
U
>
template
<
typename
U
>
void
visit_any_int
(
U
value
)
void
visit_any_int
(
U
value
)
{
{
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
if
(
type_
==
's'
)
if
(
type_
==
's'
)
{
{
is_signed
=
std
::
numeric_limits
<
U
>::
is_signed
;
is_signed
=
std
::
numeric_limits
<
U
>::
is_signed
;
}
}
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
(
const_check
(
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
);
...
@@ -206,19 +152,17 @@ public:
...
@@ -206,19 +152,17 @@ public:
};
};
// 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
)
{}
template
<
typename
T
>
template
<
typename
T
>
void
visit_any_int
(
T
value
)
void
visit_any_int
(
T
value
)
{
{
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
}
}
...
@@ -226,28 +170,24 @@ public:
...
@@ -226,28 +170,24 @@ public:
// 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
)
{}
void
report_unhandled_arg
()
void
report_unhandled_arg
()
{
{
FMT_THROW
(
FormatError
(
"width is not integer"
));
FMT_THROW
(
FormatError
(
"width is not integer"
));
}
}
template
<
typename
T
>
template
<
typename
T
>
unsigned
visit_any_int
(
T
value
)
unsigned
visit_any_int
(
T
value
)
{
{
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
;
}
}
...
@@ -278,18 +218,16 @@ public:
...
@@ -278,18 +218,16 @@ public:
*/
*/
template
<
typename
Impl
,
typename
Char
,
typename
Spec
>
template
<
typename
Impl
,
typename
Char
,
typename
Spec
>
class
BasicPrintfArgFormatter
:
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
,
Spec
>
public
internal
::
ArgFormatterBase
<
Impl
,
Char
,
Spec
>
{
{
private:
private:
void
write_null_pointer
()
{
void
write_null_pointer
()
{
this
->
spec
().
type_
=
0
;
this
->
spec
().
type_
=
0
;
this
->
write
(
"(nil)"
);
this
->
write
(
"(nil)"
);
}
}
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
,
Spec
>
Base
;
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
,
Spec
>
Base
;
public:
public:
/**
/**
\rst
\rst
Constructs an argument formatter object.
Constructs an argument formatter object.
...
@@ -301,8 +239,7 @@ public:
...
@@ -301,8 +239,7 @@ public:
:
internal
::
ArgFormatterBase
<
Impl
,
Char
,
Spec
>
(
w
,
s
)
{}
:
internal
::
ArgFormatterBase
<
Impl
,
Char
,
Spec
>
(
w
,
s
)
{}
/** Formats an argument of type ``bool``. */
/** Formats an argument of type ``bool``. */
void
visit_bool
(
bool
value
)
void
visit_bool
(
bool
value
)
{
{
Spec
&
fmt_spec
=
this
->
spec
();
Spec
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
if
(
fmt_spec
.
type_
!=
's'
)
return
this
->
visit_any_int
(
value
);
return
this
->
visit_any_int
(
value
);
...
@@ -311,38 +248,30 @@ public:
...
@@ -311,38 +248,30 @@ public:
}
}
/** Formats a character. */
/** Formats a character. */
void
visit_char
(
int
value
)
void
visit_char
(
int
value
)
{
{
const
Spec
&
fmt_spec
=
this
->
spec
();
const
Spec
&
fmt_spec
=
this
->
spec
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
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
);
}
}
/** Formats a null-terminated C string. */
/** Formats a null-terminated C string. */
void
visit_cstring
(
const
char
*
value
)
void
visit_cstring
(
const
char
*
value
)
{
{
if
(
value
)
if
(
value
)
Base
::
visit_cstring
(
value
);
Base
::
visit_cstring
(
value
);
else
if
(
this
->
spec
().
type_
==
'p'
)
else
if
(
this
->
spec
().
type_
==
'p'
)
...
@@ -352,8 +281,7 @@ public:
...
@@ -352,8 +281,7 @@ public:
}
}
/** Formats a pointer. */
/** Formats a pointer. */
void
visit_pointer
(
const
void
*
value
)
void
visit_pointer
(
const
void
*
value
)
{
{
if
(
value
)
if
(
value
)
return
Base
::
visit_pointer
(
value
);
return
Base
::
visit_pointer
(
value
);
this
->
spec
().
type_
=
0
;
this
->
spec
().
type_
=
0
;
...
@@ -361,8 +289,7 @@ public:
...
@@ -361,8 +289,7 @@ public:
}
}
/** Formats an argument of a custom (user-defined) type. */
/** Formats an argument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
{
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
*
format
=
format_str
;
const
Char
*
format
=
format_str
;
...
@@ -373,9 +300,8 @@ public:
...
@@ -373,9 +300,8 @@ public:
/** 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
,
FormatSpec
>
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
,
FormatSpec
>
{
{
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
,
FormatSpec
>
(
w
,
s
)
{}
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
,
FormatSpec
>
(
w
,
s
)
{}
...
@@ -383,9 +309,8 @@ public:
...
@@ -383,9 +309,8 @@ public:
/** 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
);
...
@@ -399,7 +324,7 @@ private:
...
@@ -399,7 +324,7 @@ private:
// 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
...
@@ -415,12 +340,9 @@ public:
...
@@ -415,12 +340,9 @@ public:
};
};
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
(;;)
{
for
(;;)
switch
(
*
s
++
)
{
{
switch
(
*
s
++
)
{
case
'-'
:
case
'-'
:
spec
.
align_
=
ALIGN_LEFT
;
spec
.
align_
=
ALIGN_LEFT
;
break
;
break
;
...
@@ -445,8 +367,7 @@ void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
...
@@ -445,8 +367,7 @@ void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
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
()
?
...
@@ -458,26 +379,20 @@ internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
...
@@ -458,26 +379,20 @@ internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
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
;
...
@@ -487,12 +402,9 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
...
@@ -487,12 +402,9 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
}
}
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
));
}
}
...
@@ -500,16 +412,13 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
...
@@ -500,16 +412,13 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
}
}
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
;
...
@@ -523,20 +432,14 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -523,20 +432,14 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
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
));
}
}
else
{
else
{
spec
.
precision_
=
0
;
spec
.
precision_
=
0
;
}
}
}
}
...
@@ -545,8 +448,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -545,8 +448,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
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
...
@@ -555,8 +457,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -555,8 +457,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
// 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
);
...
@@ -592,19 +493,15 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -592,19 +493,15 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
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
(
spec
.
type_
==
's'
)
if
(
spec
.
type_
==
's'
)
{
{
// set the format type to the default if 's' is specified
// set the format type to the default if 's' is specified
spec
.
type_
=
internal
::
DefaultType
().
visit
(
arg
);
spec
.
type_
=
internal
::
DefaultType
().
visit
(
arg
);
}
}
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'
:
...
@@ -622,14 +519,12 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -622,14 +519,12 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
write
(
writer_
,
start
,
s
);
write
(
writer_
,
start
,
s
);
}
}
inline
void
printf
(
Writer
&
w
,
CStringRef
format
,
ArgList
args
)
inline
void
printf
(
Writer
&
w
,
CStringRef
format
,
ArgList
args
)
{
{
PrintfFormatter
<
char
>
(
args
,
w
).
format
(
format
);
PrintfFormatter
<
char
>
(
args
,
w
).
format
(
format
);
}
}
FMT_VARIADIC
(
void
,
printf
,
Writer
&
,
CStringRef
)
FMT_VARIADIC
(
void
,
printf
,
Writer
&
,
CStringRef
)
inline
void
printf
(
WWriter
&
w
,
WCStringRef
format
,
ArgList
args
)
inline
void
printf
(
WWriter
&
w
,
WCStringRef
format
,
ArgList
args
)
{
{
PrintfFormatter
<
wchar_t
>
(
args
,
w
).
format
(
format
);
PrintfFormatter
<
wchar_t
>
(
args
,
w
).
format
(
format
);
}
}
FMT_VARIADIC
(
void
,
printf
,
WWriter
&
,
WCStringRef
)
FMT_VARIADIC
(
void
,
printf
,
WWriter
&
,
WCStringRef
)
...
@@ -643,16 +538,14 @@ FMT_VARIADIC(void, printf, WWriter &, WCStringRef)
...
@@ -643,16 +538,14 @@ FMT_VARIADIC(void, printf, WWriter &, WCStringRef)
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
();
...
@@ -680,8 +573,7 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
...
@@ -680,8 +573,7 @@ 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
)
...
@@ -695,8 +587,7 @@ FMT_VARIADIC(int, printf, CStringRef)
...
@@ -695,8 +587,7 @@ 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
;
MemoryWriter
w
;
printf
(
w
,
format_str
,
args
);
printf
(
w
,
format_str
,
args
);
internal
::
write
(
os
,
w
);
internal
::
write
(
os
,
w
);
...
...
include/spdlog/fmt/bundled/time.h
View file @
3826ac14
...
@@ -19,12 +19,10 @@
...
@@ -19,12 +19,10 @@
# pragma warning(disable: 4996) // "deprecated" functions
# pragma warning(disable: 4996) // "deprecated" functions
#endif
#endif
namespace
fmt
namespace
fmt
{
{
template
<
typename
ArgFormatter
>
template
<
typename
ArgFormatter
>
void
format_arg
(
BasicFormatter
<
char
,
ArgFormatter
>
&
f
,
void
format_arg
(
BasicFormatter
<
char
,
ArgFormatter
>
&
f
,
const
char
*&
format_str
,
const
std
::
tm
&
tm
)
const
char
*&
format_str
,
const
std
::
tm
&
tm
)
{
{
if
(
*
format_str
==
':'
)
if
(
*
format_str
==
':'
)
++
format_str
;
++
format_str
;
const
char
*
end
=
format_str
;
const
char
*
end
=
format_str
;
...
@@ -37,17 +35,14 @@ void format_arg(BasicFormatter<char, ArgFormatter> &f,
...
@@ -37,17 +35,14 @@ void format_arg(BasicFormatter<char, ArgFormatter> &f,
format
[
format
.
size
()
-
1
]
=
'\0'
;
format
[
format
.
size
()
-
1
]
=
'\0'
;
Buffer
<
char
>
&
buffer
=
f
.
writer
().
buffer
();
Buffer
<
char
>
&
buffer
=
f
.
writer
().
buffer
();
std
::
size_t
start
=
buffer
.
size
();
std
::
size_t
start
=
buffer
.
size
();
for
(;;)
for
(;;)
{
{
std
::
size_t
size
=
buffer
.
capacity
()
-
start
;
std
::
size_t
size
=
buffer
.
capacity
()
-
start
;
std
::
size_t
count
=
std
::
strftime
(
&
buffer
[
start
],
size
,
&
format
[
0
],
&
tm
);
std
::
size_t
count
=
std
::
strftime
(
&
buffer
[
start
],
size
,
&
format
[
0
],
&
tm
);
if
(
count
!=
0
)
if
(
count
!=
0
)
{
{
buffer
.
resize
(
start
+
count
);
buffer
.
resize
(
start
+
count
);
break
;
break
;
}
}
if
(
size
>=
format
.
size
()
*
256
)
if
(
size
>=
format
.
size
()
*
256
)
{
{
// If the buffer is 256 times larger than the format string, assume
// If the buffer is 256 times larger than the format string, assume
// that `strftime` gives an empty result. There doesn't seem to be a
// that `strftime` gives an empty result. There doesn't seem to be a
// better way to distinguish the two cases:
// better way to distinguish the two cases:
...
@@ -60,60 +55,36 @@ void format_arg(BasicFormatter<char, ArgFormatter> &f,
...
@@ -60,60 +55,36 @@ void format_arg(BasicFormatter<char, ArgFormatter> &f,
format_str
=
end
+
1
;
format_str
=
end
+
1
;
}
}
namespace
internal
namespace
internal
{
{
inline
Null
<>
localtime_r
(...)
{
return
Null
<>
();
}
inline
Null
<>
localtime_r
(...)
inline
Null
<>
localtime_s
(...)
{
return
Null
<>
();
}
{
inline
Null
<>
gmtime_r
(...)
{
return
Null
<>
();
}
return
Null
<>
();
inline
Null
<>
gmtime_s
(...)
{
return
Null
<>
();
}
}
inline
Null
<>
localtime_s
(...)
{
return
Null
<>
();
}
inline
Null
<>
gmtime_r
(...)
{
return
Null
<>
();
}
inline
Null
<>
gmtime_s
(...)
{
return
Null
<>
();
}
}
}
// Thread-safe replacement for std::localtime
// Thread-safe replacement for std::localtime
inline
std
::
tm
localtime
(
std
::
time_t
time
)
inline
std
::
tm
localtime
(
std
::
time_t
time
)
{
{
struct
LocalTime
{
struct
LocalTime
{
std
::
time_t
time_
;
std
::
time_t
time_
;
std
::
tm
tm_
;
std
::
tm
tm_
;
LocalTime
(
std
::
time_t
t
)
:
time_
(
t
)
{}
LocalTime
(
std
::
time_t
t
)
:
time_
(
t
)
{}
bool
run
()
bool
run
()
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
return
handle
(
localtime_r
(
&
time_
,
&
tm_
));
return
handle
(
localtime_r
(
&
time_
,
&
tm_
));
}
}
bool
handle
(
std
::
tm
*
tm
)
bool
handle
(
std
::
tm
*
tm
)
{
return
tm
!=
FMT_NULL
;
}
{
return
tm
!=
FMT_NULL
;
}
bool
handle
(
internal
::
Null
<>
)
bool
handle
(
internal
::
Null
<>
)
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
return
fallback
(
localtime_s
(
&
tm_
,
&
time_
));
return
fallback
(
localtime_s
(
&
tm_
,
&
time_
));
}
}
bool
fallback
(
int
res
)
bool
fallback
(
int
res
)
{
return
res
==
0
;
}
{
return
res
==
0
;
}
bool
fallback
(
internal
::
Null
<>
)
bool
fallback
(
internal
::
Null
<>
)
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
std
::
tm
*
tm
=
std
::
localtime
(
&
time_
);
std
::
tm
*
tm
=
std
::
localtime
(
&
time_
);
if
(
tm
)
tm_
=
*
tm
;
if
(
tm
)
tm_
=
*
tm
;
...
@@ -129,39 +100,28 @@ inline std::tm localtime(std::time_t time)
...
@@ -129,39 +100,28 @@ inline std::tm localtime(std::time_t time)
}
}
// Thread-safe replacement for std::gmtime
// Thread-safe replacement for std::gmtime
inline
std
::
tm
gmtime
(
std
::
time_t
time
)
inline
std
::
tm
gmtime
(
std
::
time_t
time
)
{
{
struct
GMTime
{
struct
GMTime
{
std
::
time_t
time_
;
std
::
time_t
time_
;
std
::
tm
tm_
;
std
::
tm
tm_
;
GMTime
(
std
::
time_t
t
)
:
time_
(
t
)
{}
GMTime
(
std
::
time_t
t
)
:
time_
(
t
)
{}
bool
run
()
bool
run
()
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
return
handle
(
gmtime_r
(
&
time_
,
&
tm_
));
return
handle
(
gmtime_r
(
&
time_
,
&
tm_
));
}
}
bool
handle
(
std
::
tm
*
tm
)
bool
handle
(
std
::
tm
*
tm
)
{
return
tm
!=
FMT_NULL
;
}
{
return
tm
!=
FMT_NULL
;
}
bool
handle
(
internal
::
Null
<>
)
bool
handle
(
internal
::
Null
<>
)
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
return
fallback
(
gmtime_s
(
&
tm_
,
&
time_
));
return
fallback
(
gmtime_s
(
&
tm_
,
&
time_
));
}
}
bool
fallback
(
int
res
)
bool
fallback
(
int
res
)
{
return
res
==
0
;
}
{
return
res
==
0
;
}
bool
fallback
(
internal
::
Null
<>
)
bool
fallback
(
internal
::
Null
<>
)
{
{
std
::
tm
*
tm
=
std
::
gmtime
(
&
time_
);
std
::
tm
*
tm
=
std
::
gmtime
(
&
time_
);
if
(
tm
!=
FMT_NULL
)
tm_
=
*
tm
;
if
(
tm
!=
FMT_NULL
)
tm_
=
*
tm
;
return
tm
!=
FMT_NULL
;
return
tm
!=
FMT_NULL
;
...
...
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