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
ec4233f2
Commit
ec4233f2
authored
Aug 14, 2015
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed warnings conversion 'size_t' to 'int' on windows issue #119
parent
77acf29c
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
2562 additions
and
2753 deletions
+2562
-2753
include/spdlog/details/format.cc
include/spdlog/details/format.cc
+866
-895
include/spdlog/details/format.h
include/spdlog/details/format.h
+1696
-1858
No files found.
include/spdlog/details/format.cc
View file @
ec4233f2
/*
/*
Formatting library for C++
Formatting library for C++
Copyright (c) 2012 - 2015, Victor Zverovich
Copyright (c) 2012 - 2015, Victor Zverovich
All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#include "format.h"
#include "format.h"
...
@@ -133,9 +133,7 @@ struct IntChecker {
...
@@ -133,9 +133,7 @@ struct IntChecker {
unsigned
max
=
INT_MAX
;
unsigned
max
=
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
<
>
...
@@ -148,7 +146,7 @@ struct IntChecker<true> {
...
@@ -148,7 +146,7 @@ struct IntChecker<true> {
const
char
RESET_COLOR
[]
=
"
\x1b
[0m"
;
const
char
RESET_COLOR
[]
=
"
\x1b
[0m"
;
typedef
void
(
*
FormatFunc
)(
fmt
::
Writer
&
,
int
,
fmt
::
StringRef
);
typedef
void
(
*
FormatFunc
)(
fmt
::
Writer
&
,
int
,
fmt
::
StringRef
);
// Portable thread-safe version of strerror.
// Portable thread-safe version of strerror.
// Sets buffer to point to a string describing the error code.
// Sets buffer to point to a string describing the error code.
...
@@ -160,7 +158,7 @@ typedef void(*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
...
@@ -160,7 +158,7 @@ typedef void(*FormatFunc)(fmt::Writer &, int, fmt::StringRef);
// other - failure
// other - failure
// 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
!=
0
&&
buffer_size
!=
0
,
"invalid buffer"
);
class
StrError
{
class
StrError
{
...
@@ -219,7 +217,7 @@ int safe_strerror(
...
@@ -219,7 +217,7 @@ int safe_strerror(
}
}
void
format_error_code
(
fmt
::
Writer
&
out
,
int
error_code
,
void
format_error_code
(
fmt
::
Writer
&
out
,
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
// Report error code making sure that the output fits into
// Report error code making sure that the output fits into
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
// bad_alloc.
// bad_alloc.
...
@@ -237,7 +235,7 @@ void format_error_code(fmt::Writer &out, int error_code,
...
@@ -237,7 +235,7 @@ void format_error_code(fmt::Writer &out, int error_code,
}
}
void
report_error
(
FormatFunc
func
,
void
report_error
(
FormatFunc
func
,
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
fmt
::
MemoryWriter
full_message
;
fmt
::
MemoryWriter
full_message
;
func
(
full_message
,
error_code
,
message
);
func
(
full_message
,
error_code
,
message
);
// Use Writer::data instead of Writer::c_str to avoid potential memory
// Use Writer::data instead of Writer::c_str to avoid potential memory
...
@@ -248,11 +246,9 @@ void report_error(FormatFunc func,
...
@@ -248,11 +246,9 @@ void report_error(FormatFunc func,
// 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
fmt
::
internal
::
ArgVisitor
<
IsZeroInt
,
bool
>
{
class
IsZeroInt
:
public
fmt
::
internal
::
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
;
}
};
};
// Parses an unsigned integer advancing s to the end of the parsed input.
// Parses an unsigned integer advancing s to the end of the parsed input.
...
@@ -302,12 +298,12 @@ void check_sign(const Char *&s, const Arg &arg) {
...
@@ -302,12 +298,12 @@ void check_sign(const Char *&s, const Arg &arg) {
// 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
fmt
::
internal
::
ArgVisitor
<
WidthHandler
,
unsigned
>
{
class
WidthHandler
:
public
fmt
::
internal
::
ArgVisitor
<
WidthHandler
,
unsigned
>
{
private:
private:
fmt
::
FormatSpec
&
spec_
;
fmt
::
FormatSpec
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
public:
public:
explicit
WidthHandler
(
fmt
::
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
explicit
WidthHandler
(
fmt
::
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
void
report_unhandled_arg
()
{
void
report_unhandled_arg
()
{
...
@@ -330,7 +326,7 @@ public:
...
@@ -330,7 +326,7 @@ public:
class
PrecisionHandler
:
class
PrecisionHandler
:
public
fmt
::
internal
::
ArgVisitor
<
PrecisionHandler
,
int
>
{
public
fmt
::
internal
::
ArgVisitor
<
PrecisionHandler
,
int
>
{
public:
public:
void
report_unhandled_arg
()
{
void
report_unhandled_arg
()
{
FMT_THROW
(
fmt
::
FormatError
(
"precision is not integer"
));
FMT_THROW
(
fmt
::
FormatError
(
"precision is not integer"
));
}
}
...
@@ -346,13 +342,13 @@ public:
...
@@ -346,13 +342,13 @@ public:
// Converts an integer argument to an integral type T for printf.
// Converts an integer argument to an integral type T for printf.
template
<
typename
T
>
template
<
typename
T
>
class
ArgConverter
:
public
fmt
::
internal
::
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
{
class
ArgConverter
:
public
fmt
::
internal
::
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
{
private:
private:
fmt
::
internal
::
Arg
&
arg_
;
fmt
::
internal
::
Arg
&
arg_
;
wchar_t
type_
;
wchar_t
type_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
public:
public:
ArgConverter
(
fmt
::
internal
::
Arg
&
arg
,
wchar_t
type
)
ArgConverter
(
fmt
::
internal
::
Arg
&
arg
,
wchar_t
type
)
:
arg_
(
arg
),
type_
(
type
)
{}
:
arg_
(
arg
),
type_
(
type
)
{}
...
@@ -365,20 +361,17 @@ public:
...
@@ -365,20 +361,17 @@ public:
if
(
is_signed
)
{
if
(
is_signed
)
{
arg_
.
type
=
Arg
::
INT
;
arg_
.
type
=
Arg
::
INT
;
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
T
>
(
value
));
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
T
>
(
value
));
}
}
else
{
else
{
arg_
.
type
=
Arg
::
UINT
;
arg_
.
type
=
Arg
::
UINT
;
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
typename
fmt
::
internal
::
MakeUnsigned
<
T
>::
Type
>
(
value
));
static_cast
<
typename
fmt
::
internal
::
MakeUnsigned
<
T
>::
Type
>
(
value
));
}
}
}
}
else
{
else
{
if
(
is_signed
)
{
if
(
is_signed
)
{
arg_
.
type
=
Arg
::
LONG_LONG
;
arg_
.
type
=
Arg
::
LONG_LONG
;
arg_
.
long_long_value
=
arg_
.
long_long_value
=
static_cast
<
typename
fmt
::
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
static_cast
<
typename
fmt
::
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
}
}
else
{
else
{
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
ulong_long_value
=
arg_
.
ulong_long_value
=
static_cast
<
typename
fmt
::
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
static_cast
<
typename
fmt
::
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
...
@@ -389,12 +382,12 @@ public:
...
@@ -389,12 +382,12 @@ public:
// Converts an integer argument to char for printf.
// Converts an integer argument to char for printf.
class
CharConverter
:
public
fmt
::
internal
::
ArgVisitor
<
CharConverter
,
void
>
{
class
CharConverter
:
public
fmt
::
internal
::
ArgVisitor
<
CharConverter
,
void
>
{
private:
private:
fmt
::
internal
::
Arg
&
arg_
;
fmt
::
internal
::
Arg
&
arg_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
public:
public:
explicit
CharConverter
(
fmt
::
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
{}
explicit
CharConverter
(
fmt
::
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
{}
template
<
typename
T
>
template
<
typename
T
>
...
@@ -409,33 +402,25 @@ namespace internal {
...
@@ -409,33 +402,25 @@ namespace internal {
template
<
typename
Impl
,
typename
Char
>
template
<
typename
Impl
,
typename
Char
>
class
BasicArgFormatter
:
public
ArgVisitor
<
Impl
,
void
>
{
class
BasicArgFormatter
:
public
ArgVisitor
<
Impl
,
void
>
{
private:
private:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
FormatSpec
&
spec_
;
FormatSpec
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
BasicArgFormatter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
BasicArgFormatter
);
protected:
protected:
BasicWriter
<
Char
>
&
writer
()
{
BasicWriter
<
Char
>
&
writer
()
{
return
writer_
;
}
return
writer_
;
const
FormatSpec
&
spec
()
const
{
return
spec_
;
}
}
const
FormatSpec
&
spec
()
const
{
return
spec_
;
}
public:
public:
BasicArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
BasicArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
:
writer_
(
w
),
spec_
(
s
)
{}
:
writer_
(
w
),
spec_
(
s
)
{}
template
<
typename
T
>
template
<
typename
T
>
void
visit_any_int
(
T
value
)
{
void
visit_any_int
(
T
value
)
{
writer_
.
write_int
(
value
,
spec_
);
}
writer_
.
write_int
(
value
,
spec_
);
}
template
<
typename
T
>
template
<
typename
T
>
void
visit_any_double
(
T
value
)
{
void
visit_any_double
(
T
value
)
{
writer_
.
write_double
(
value
,
spec_
);
}
writer_
.
write_double
(
value
,
spec_
);
}
void
visit_bool
(
bool
value
)
{
void
visit_bool
(
bool
value
)
{
if
(
spec_
.
type_
)
{
if
(
spec_
.
type_
)
{
...
@@ -463,15 +448,12 @@ public:
...
@@ -463,15 +448,12 @@ public:
if
(
spec_
.
align_
==
ALIGN_RIGHT
)
{
if
(
spec_
.
align_
==
ALIGN_RIGHT
)
{
std
::
fill_n
(
out
,
spec_
.
width_
-
1
,
fill
);
std
::
fill_n
(
out
,
spec_
.
width_
-
1
,
fill
);
out
+=
spec_
.
width_
-
1
;
out
+=
spec_
.
width_
-
1
;
}
}
else
if
(
spec_
.
align_
==
ALIGN_CENTER
)
{
else
if
(
spec_
.
align_
==
ALIGN_CENTER
)
{
out
=
writer_
.
fill_padding
(
out
,
spec_
.
width_
,
1
,
fill
);
out
=
writer_
.
fill_padding
(
out
,
spec_
.
width_
,
1
,
fill
);
}
}
else
{
else
{
std
::
fill_n
(
out
+
1
,
spec_
.
width_
-
1
,
fill
);
std
::
fill_n
(
out
+
1
,
spec_
.
width_
-
1
,
fill
);
}
}
}
}
else
{
else
{
out
=
writer_
.
grow_buffer
(
1
);
out
=
writer_
.
grow_buffer
(
1
);
}
}
*
out
=
internal
::
CharTraits
<
Char
>::
cast
(
value
);
*
out
=
internal
::
CharTraits
<
Char
>::
cast
(
value
);
...
@@ -499,11 +481,11 @@ public:
...
@@ -499,11 +481,11 @@ public:
// An argument formatter.
// An argument formatter.
template
<
typename
Char
>
template
<
typename
Char
>
class
ArgFormatter
:
public
BasicArgFormatter
<
ArgFormatter
<
Char
>
,
Char
>
{
class
ArgFormatter
:
public
BasicArgFormatter
<
ArgFormatter
<
Char
>
,
Char
>
{
private:
private:
BasicFormatter
<
Char
>
&
formatter_
;
BasicFormatter
<
Char
>
&
formatter_
;
const
Char
*
format_
;
const
Char
*
format_
;
public:
public:
ArgFormatter
(
BasicFormatter
<
Char
>
&
f
,
FormatSpec
&
s
,
const
Char
*
fmt
)
ArgFormatter
(
BasicFormatter
<
Char
>
&
f
,
FormatSpec
&
s
,
const
Char
*
fmt
)
:
BasicArgFormatter
<
ArgFormatter
<
Char
>
,
Char
>
(
f
.
writer
(),
s
),
:
BasicArgFormatter
<
ArgFormatter
<
Char
>
,
Char
>
(
f
.
writer
(),
s
),
formatter_
(
f
),
format_
(
fmt
)
{}
formatter_
(
f
),
format_
(
fmt
)
{}
...
@@ -516,7 +498,7 @@ public:
...
@@ -516,7 +498,7 @@ public:
template
<
typename
Char
>
template
<
typename
Char
>
class
PrintfArgFormatter
:
class
PrintfArgFormatter
:
public
BasicArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
{
public
BasicArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
{
public:
public:
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
:
BasicArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
:
BasicArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
...
@@ -533,12 +515,10 @@ public:
...
@@ -533,12 +515,10 @@ public:
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
);
...
@@ -632,14 +612,17 @@ FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
...
@@ -632,14 +612,17 @@ FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
#if FMT_USE_WINDOWS_H
#if FMT_USE_WINDOWS_H
FMT_FUNC
fmt
::
internal
::
UTF8ToUTF16
::
UTF8ToUTF16
(
fmt
::
StringRef
s
)
{
FMT_FUNC
fmt
::
internal
::
UTF8ToUTF16
::
UTF8ToUTF16
(
fmt
::
StringRef
s
)
{
int
length
=
MultiByteToWideChar
(
CP_UTF8
,
MB_ERR_INVALID_CHARS
,
s
.
data
(),
s
.
size
(),
0
,
0
);
static
const
char
ERROR_MSG
[]
=
"cannot convert string from UTF-8 to UTF-16"
;
static
const
char
ERROR_MSG
[]
=
"cannot convert string from UTF-8 to UTF-16"
;
if
(
s
.
size
()
>
INT_MAX
)
FMT_THROW
(
WindowsError
(
ERROR_INVALID_PARAMETER
,
ERROR_MSG
));
int
s_size
=
static_cast
<
int
>
(
s
.
size
());
int
length
=
MultiByteToWideChar
(
CP_UTF8
,
MB_ERR_INVALID_CHARS
,
s
.
data
(),
s_size
,
0
,
0
);
if
(
length
==
0
)
if
(
length
==
0
)
FMT_THROW
(
WindowsError
(
GetLastError
(),
ERROR_MSG
));
FMT_THROW
(
WindowsError
(
GetLastError
(),
ERROR_MSG
));
buffer_
.
resize
(
length
+
1
);
buffer_
.
resize
(
length
+
1
);
length
=
MultiByteToWideChar
(
length
=
MultiByteToWideChar
(
CP_UTF8
,
MB_ERR_INVALID_CHARS
,
s
.
data
(),
s
.
size
()
,
&
buffer_
[
0
],
length
);
CP_UTF8
,
MB_ERR_INVALID_CHARS
,
s
.
data
(),
s_size
,
&
buffer_
[
0
],
length
);
if
(
length
==
0
)
if
(
length
==
0
)
FMT_THROW
(
WindowsError
(
GetLastError
(),
ERROR_MSG
));
FMT_THROW
(
WindowsError
(
GetLastError
(),
ERROR_MSG
));
buffer_
[
length
]
=
0
;
buffer_
[
length
]
=
0
;
...
@@ -653,12 +636,15 @@ FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
...
@@ -653,12 +636,15 @@ FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
}
}
FMT_FUNC
int
fmt
::
internal
::
UTF16ToUTF8
::
convert
(
fmt
::
WStringRef
s
)
{
FMT_FUNC
int
fmt
::
internal
::
UTF16ToUTF8
::
convert
(
fmt
::
WStringRef
s
)
{
int
length
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
s
.
data
(),
s
.
size
(),
0
,
0
,
0
,
0
);
if
(
s
.
size
()
>
INT_MAX
)
return
ERROR_INVALID_PARAMETER
;
int
s_size
=
static_cast
<
int
>
(
s
.
size
());
int
length
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
s
.
data
(),
s_size
,
0
,
0
,
0
,
0
);
if
(
length
==
0
)
if
(
length
==
0
)
return
GetLastError
();
return
GetLastError
();
buffer_
.
resize
(
length
+
1
);
buffer_
.
resize
(
length
+
1
);
length
=
WideCharToMultiByte
(
length
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
s
.
data
(),
s
.
size
()
,
&
buffer_
[
0
],
length
,
0
,
0
);
CP_UTF8
,
0
,
s
.
data
(),
s_size
,
&
buffer_
[
0
],
length
,
0
,
0
);
if
(
length
==
0
)
if
(
length
==
0
)
return
GetLastError
();
return
GetLastError
();
buffer_
[
length
]
=
0
;
buffer_
[
length
]
=
0
;
...
@@ -676,22 +662,18 @@ FMT_FUNC void fmt::WindowsError::init(
...
@@ -676,22 +662,18 @@ FMT_FUNC void fmt::WindowsError::init(
FMT_FUNC
void
fmt
::
internal
::
format_windows_error
(
FMT_FUNC
void
fmt
::
internal
::
format_windows_error
(
fmt
::
Writer
&
out
,
int
error_code
,
fmt
::
Writer
&
out
,
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
class
String
{
class
String
{
private:
private:
LPWSTR
str_
;
LPWSTR
str_
;
public:
public:
String
()
:
str_
()
{}
String
()
:
str_
()
{}
~
String
()
{
~
String
()
{
LocalFree
(
str_
);
}
LocalFree
(
str_
);
LPWSTR
*
ptr
()
{
return
&
str_
;
}
}
LPWSTR
*
ptr
()
{
return
&
str_
;
}
LPCWSTR
c_str
()
const
{
return
str_
;
}
LPCWSTR
c_str
()
const
{
return
str_
;
}
};
};
FMT_TRY
{
FMT_TRY
{
String
system_message
;
String
system_message
;
if
(
FormatMessageW
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
if
(
FormatMessageW
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
0
,
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
0
,
...
@@ -711,8 +693,8 @@ FMT_FUNC void fmt::internal::format_windows_error(
...
@@ -711,8 +693,8 @@ FMT_FUNC void fmt::internal::format_windows_error(
FMT_FUNC
void
fmt
::
internal
::
format_system_error
(
FMT_FUNC
void
fmt
::
internal
::
format_system_error
(
fmt
::
Writer
&
out
,
int
error_code
,
fmt
::
Writer
&
out
,
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
FMT_TRY
{
FMT_TRY
{
MemoryBuffer
<
char
,
INLINE_BUFFER_SIZE
>
buffer
;
MemoryBuffer
<
char
,
INLINE_BUFFER_SIZE
>
buffer
;
buffer
.
resize
(
INLINE_BUFFER_SIZE
);
buffer
.
resize
(
INLINE_BUFFER_SIZE
);
for
(;;)
{
for
(;;)
{
...
@@ -749,8 +731,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
...
@@ -749,8 +731,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
map_
.
insert
(
Pair
(
named_arg
->
name
,
*
named_arg
));
map_
.
insert
(
Pair
(
named_arg
->
name
,
*
named_arg
));
break
;
break
;
default:
default:
/*nothing*/
/*nothing*/
;
;
}
}
}
}
return
;
return
;
...
@@ -771,8 +752,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
...
@@ -771,8 +752,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
map_
.
insert
(
Pair
(
named_arg
->
name
,
*
named_arg
));
map_
.
insert
(
Pair
(
named_arg
->
name
,
*
named_arg
));
break
;
break
;
default:
default:
/*nothing*/
/*nothing*/
;
;
}
}
}
}
}
}
...
@@ -854,8 +834,7 @@ FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
...
@@ -854,8 +834,7 @@ FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
case
Arg
:
:
NAMED_ARG
:
case
Arg
:
:
NAMED_ARG
:
arg
=
*
static_cast
<
const
internal
::
Arg
*>
(
arg
.
pointer
);
arg
=
*
static_cast
<
const
internal
::
Arg
*>
(
arg
.
pointer
);
default:
default:
/*nothing*/
/*nothing*/
;
;
}
}
return
arg
;
return
arg
;
}
}
...
@@ -933,8 +912,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
...
@@ -933,8 +912,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
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
)
{
...
@@ -949,8 +927,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
...
@@ -949,8 +927,7 @@ unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
// Parse width.
// Parse width.
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
{
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
{
spec
.
width_
=
parse_nonnegative_int
(
s
);
spec
.
width_
=
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'*'
)
{
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
width_
=
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
spec
.
width_
=
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
}
}
...
@@ -983,8 +960,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
...
@@ -983,8 +960,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
++
s
;
++
s
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
spec
.
precision_
=
parse_nonnegative_int
(
s
);
spec
.
precision_
=
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'*'
)
{
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
precision_
=
PrecisionHandler
().
visit
(
get_arg
(
s
));
spec
.
precision_
=
PrecisionHandler
().
visit
(
get_arg
(
s
));
}
}
...
@@ -1039,8 +1015,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
...
@@ -1039,8 +1015,7 @@ void fmt::internal::PrintfFormatter<Char>::format(
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
'i'
:
case
'u'
:
case
'u'
:
spec
.
type_
=
'd'
;
spec
.
type_
=
'd'
;
break
;
break
;
case
'c'
:
case
'c'
:
...
@@ -1095,8 +1070,7 @@ const Char *fmt::BasicFormatter<Char>::format(
...
@@ -1095,8 +1070,7 @@ const Char *fmt::BasicFormatter<Char>::format(
FMT_THROW
(
FormatError
(
"invalid fill character '{'"
));
FMT_THROW
(
FormatError
(
"invalid fill character '{'"
));
s
+=
2
;
s
+=
2
;
spec
.
fill_
=
c
;
spec
.
fill_
=
c
;
}
}
else
++
s
;
else
++
s
;
if
(
spec
.
align_
==
ALIGN_NUMERIC
)
if
(
spec
.
align_
==
ALIGN_NUMERIC
)
require_numeric_argument
(
arg
,
'='
);
require_numeric_argument
(
arg
,
'='
);
break
;
break
;
...
@@ -1137,8 +1111,7 @@ const Char *fmt::BasicFormatter<Char>::format(
...
@@ -1137,8 +1111,7 @@ const Char *fmt::BasicFormatter<Char>::format(
// Parse width.
// Parse width.
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
spec
.
width_
=
parse_nonnegative_int
(
s
);
spec
.
width_
=
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'{'
)
{
else
if
(
*
s
==
'{'
)
{
++
s
;
++
s
;
Arg
width_arg
=
is_name_start
(
*
s
)
?
Arg
width_arg
=
is_name_start
(
*
s
)
?
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
...
@@ -1176,8 +1149,7 @@ const Char *fmt::BasicFormatter<Char>::format(
...
@@ -1176,8 +1149,7 @@ const Char *fmt::BasicFormatter<Char>::format(
spec
.
precision_
=
0
;
spec
.
precision_
=
0
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
spec
.
precision_
=
parse_nonnegative_int
(
s
);
spec
.
precision_
=
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'{'
)
{
else
if
(
*
s
==
'{'
)
{
++
s
;
++
s
;
Arg
precision_arg
=
Arg
precision_arg
=
is_name_start
(
*
s
)
?
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
is_name_start
(
*
s
)
?
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
...
@@ -1207,8 +1179,7 @@ const Char *fmt::BasicFormatter<Char>::format(
...
@@ -1207,8 +1179,7 @@ const Char *fmt::BasicFormatter<Char>::format(
if
(
value
>
INT_MAX
)
if
(
value
>
INT_MAX
)
FMT_THROW
(
FormatError
(
"number is too big"
));
FMT_THROW
(
FormatError
(
"number is too big"
));
spec
.
precision_
=
static_cast
<
int
>
(
value
);
spec
.
precision_
=
static_cast
<
int
>
(
value
);
}
}
else
{
else
{
FMT_THROW
(
FormatError
(
"missing precision specifier"
));
FMT_THROW
(
FormatError
(
"missing precision specifier"
));
}
}
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
||
arg
.
type
==
Arg
::
POINTER
)
{
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
||
arg
.
type
==
Arg
::
POINTER
)
{
...
@@ -1253,13 +1224,13 @@ void fmt::BasicFormatter<Char>::format(BasicCStringRef<Char> format_str) {
...
@@ -1253,13 +1224,13 @@ void fmt::BasicFormatter<Char>::format(BasicCStringRef<Char> format_str) {
}
}
FMT_FUNC
void
fmt
::
report_system_error
(
FMT_FUNC
void
fmt
::
report_system_error
(
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
report_error
(
internal
::
format_system_error
,
error_code
,
message
);
report_error
(
internal
::
format_system_error
,
error_code
,
message
);
}
}
#if FMT_USE_WINDOWS_H
#if FMT_USE_WINDOWS_H
FMT_FUNC
void
fmt
::
report_windows_error
(
FMT_FUNC
void
fmt
::
report_windows_error
(
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
int
error_code
,
fmt
::
StringRef
message
)
FMT_NOEXCEPT
{
report_error
(
internal
::
format_windows_error
,
error_code
,
message
);
report_error
(
internal
::
format_windows_error
,
error_code
,
message
);
}
}
#endif
#endif
...
...
include/spdlog/details/format.h
View file @
ec4233f2
/*
/*
Formatting library for C++
Formatting library for C++
Copyright (c) 2012 - 2015, Victor Zverovich
Copyright (c) 2012 - 2015, Victor Zverovich
All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
#ifndef FMT_FORMAT_H_
#ifndef FMT_FORMAT_H_
#define FMT_FORMAT_H_
#define FMT_FORMAT_H_
...
@@ -206,36 +206,36 @@ template <typename Char, typename T>
...
@@ -206,36 +206,36 @@ template <typename Char, typename T>
void
format
(
BasicFormatter
<
Char
>
&
f
,
const
Char
*&
format_str
,
const
T
&
value
);
void
format
(
BasicFormatter
<
Char
>
&
f
,
const
Char
*&
format_str
,
const
T
&
value
);
/**
/**
\rst
\rst
A string reference. It can be constructed from a C string or ``std::string``.
A string reference. It can be constructed from a C string or ``std::string``.
You can use one of the following typedefs for common character types:
You can use one of the following typedefs for common character types:
+------------+-------------------------+
+------------+-------------------------+
| Type | Definition |
| Type | Definition |
+============+=========================+
+============+=========================+
| StringRef | BasicStringRef<char> |
| StringRef | BasicStringRef<char> |
+------------+-------------------------+
+------------+-------------------------+
| WStringRef | BasicStringRef<wchar_t> |
| WStringRef | BasicStringRef<wchar_t> |
+------------+-------------------------+
+------------+-------------------------+
This class is most useful as a parameter type to allow passing
This class is most useful as a parameter type to allow passing
different types of strings to a function, for example::
different types of strings to a function, for example::
template <typename... Args>
template <typename... Args>
std::string format(StringRef format_str, const Args & ... args);
std::string format(StringRef format_str, const Args & ... args);
format("{}", 42);
format("{}", 42);
format(std::string("{}"), 42);
format(std::string("{}"), 42);
\endrst
\endrst
*/
*/
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicStringRef
{
class
BasicStringRef
{
private:
private:
const
Char
*
data_
;
const
Char
*
data_
;
std
::
size_t
size_
;
std
::
size_t
size_
;
public:
public:
/** Constructs a string reference object from a C string and a size. */
/** Constructs a string reference object from a C string and a size. */
BasicStringRef
(
const
Char
*
s
,
std
::
size_t
size
)
:
data_
(
s
),
size_
(
size
)
{}
BasicStringRef
(
const
Char
*
s
,
std
::
size_t
size
)
:
data_
(
s
),
size_
(
size
)
{}
...
@@ -266,14 +266,10 @@ public:
...
@@ -266,14 +266,10 @@ public:
}
}
/** Returns the pointer to a C string. */
/** Returns the pointer to a C string. */
const
Char
*
data
()
const
{
const
Char
*
data
()
const
{
return
data_
;
}
return
data_
;
}
/** Returns the string size. */
/** Returns the string size. */
std
::
size_t
size
()
const
{
std
::
size_t
size
()
const
{
return
size_
;
}
return
size_
;
}
friend
bool
operator
==
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
friend
bool
operator
==
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
return
lhs
.
data_
==
rhs
.
data_
;
return
lhs
.
data_
==
rhs
.
data_
;
...
@@ -292,36 +288,36 @@ typedef BasicStringRef<wchar_t> WStringRef;
...
@@ -292,36 +288,36 @@ typedef BasicStringRef<wchar_t> WStringRef;
/**
/**
\rst
\rst
A reference to a null terminated string. It can be constructed from a C
A reference to a null terminated string. It can be constructed from a C
string or ``std::string``.
string or ``std::string``.
You can use one of the following typedefs for common character types:
You can use one of the following typedefs for common character types:
+-------------+--------------------------+
+-------------+--------------------------+
| Type | Definition |
| Type | Definition |
+=============+==========================+
+=============+==========================+
| CStringRef | BasicCStringRef<char> |
| CStringRef | BasicCStringRef<char> |
+-------------+--------------------------+
+-------------+--------------------------+
| WCStringRef | BasicCStringRef<wchar_t> |
| WCStringRef | BasicCStringRef<wchar_t> |
+-------------+--------------------------+
+-------------+--------------------------+
This class is most useful as a parameter type to allow passing
This class is most useful as a parameter type to allow passing
different types of strings to a function, for example::
different types of strings to a function, for example::
template <typename... Args>
template <typename... Args>
std::string format(CStringRef format_str, const Args & ... args);
std::string format(CStringRef format_str, const Args & ... args);
format("{}", 42);
format("{}", 42);
format(std::string("{}"), 42);
format(std::string("{}"), 42);
\endrst
\endrst
*/
*/
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicCStringRef
{
class
BasicCStringRef
{
private:
private:
const
Char
*
data_
;
const
Char
*
data_
;
public:
public:
/** Constructs a string reference object from a C string. */
/** Constructs a string reference object from a C string. */
BasicCStringRef
(
const
Char
*
s
)
:
data_
(
s
)
{}
BasicCStringRef
(
const
Char
*
s
)
:
data_
(
s
)
{}
...
@@ -333,19 +329,17 @@ public:
...
@@ -333,19 +329,17 @@ public:
BasicCStringRef
(
const
std
::
basic_string
<
Char
>
&
s
)
:
data_
(
s
.
c_str
())
{}
BasicCStringRef
(
const
std
::
basic_string
<
Char
>
&
s
)
:
data_
(
s
.
c_str
())
{}
/** Returns the pointer to a C string. */
/** Returns the pointer to a C string. */
const
Char
*
c_str
()
const
{
const
Char
*
c_str
()
const
{
return
data_
;
}
return
data_
;
}
};
};
typedef
BasicCStringRef
<
char
>
CStringRef
;
typedef
BasicCStringRef
<
char
>
CStringRef
;
typedef
BasicCStringRef
<
wchar_t
>
WCStringRef
;
typedef
BasicCStringRef
<
wchar_t
>
WCStringRef
;
/**
/**
A formatting error such as invalid format string.
A formatting error such as invalid format string.
*/
*/
class
FormatError
:
public
std
::
runtime_error
{
class
FormatError
:
public
std
::
runtime_error
{
public:
public:
explicit
FormatError
(
CStringRef
message
)
explicit
FormatError
(
CStringRef
message
)
:
std
::
runtime_error
(
message
.
c_str
())
{}
:
std
::
runtime_error
(
message
.
c_str
())
{}
};
};
...
@@ -363,23 +357,21 @@ inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) {
...
@@ -363,23 +357,21 @@ inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) {
}
}
#else
#else
template
<
typename
T
>
template
<
typename
T
>
inline
T
*
make_ptr
(
T
*
ptr
,
std
::
size_t
)
{
inline
T
*
make_ptr
(
T
*
ptr
,
std
::
size_t
)
{
return
ptr
;
}
return
ptr
;
}
#endif
#endif
}
// namespace internal
}
// namespace internal
/**
/**
\rst
\rst
A buffer supporting a subset of ``std::vector``'s operations.
A buffer supporting a subset of ``std::vector``'s operations.
\endrst
\endrst
*/
*/
template
<
typename
T
>
template
<
typename
T
>
class
Buffer
{
class
Buffer
{
private:
private:
FMT_DISALLOW_COPY_AND_ASSIGN
(
Buffer
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
Buffer
);
protected:
protected:
T
*
ptr_
;
T
*
ptr_
;
std
::
size_t
size_
;
std
::
size_t
size_
;
std
::
size_t
capacity_
;
std
::
size_t
capacity_
;
...
@@ -395,18 +387,14 @@ protected:
...
@@ -395,18 +387,14 @@ protected:
*/
*/
virtual
void
grow
(
std
::
size_t
size
)
=
0
;
virtual
void
grow
(
std
::
size_t
size
)
=
0
;
public:
public:
virtual
~
Buffer
()
{}
virtual
~
Buffer
()
{}
/** Returns the size of this buffer. */
/** Returns the size of this buffer. */
std
::
size_t
size
()
const
{
std
::
size_t
size
()
const
{
return
size_
;
}
return
size_
;
}
/** Returns the capacity of this buffer. */
/** Returns the capacity of this buffer. */
std
::
size_t
capacity
()
const
{
std
::
size_t
capacity
()
const
{
return
capacity_
;
}
return
capacity_
;
}
/**
/**
Resizes the buffer. If T is a POD type new elements may not be initialized.
Resizes the buffer. If T is a POD type new elements may not be initialized.
...
@@ -427,7 +415,7 @@ public:
...
@@ -427,7 +415,7 @@ public:
grow
(
capacity
);
grow
(
capacity
);
}
}
void
clear
()
FMT_NOEXCEPT
{
size_
=
0
;
}
void
clear
()
FMT_NOEXCEPT
{
size_
=
0
;
}
void
push_back
(
const
T
&
value
)
{
void
push_back
(
const
T
&
value
)
{
if
(
size_
==
capacity_
)
if
(
size_
==
capacity_
)
...
@@ -439,12 +427,8 @@ public:
...
@@ -439,12 +427,8 @@ public:
template
<
typename
U
>
template
<
typename
U
>
void
append
(
const
U
*
begin
,
const
U
*
end
);
void
append
(
const
U
*
begin
,
const
U
*
end
);
T
&
operator
[](
std
::
size_t
index
)
{
T
&
operator
[](
std
::
size_t
index
)
{
return
ptr_
[
index
];
}
return
ptr_
[
index
];
const
T
&
operator
[](
std
::
size_t
index
)
const
{
return
ptr_
[
index
];
}
}
const
T
&
operator
[](
std
::
size_t
index
)
const
{
return
ptr_
[
index
];
}
};
};
template
<
typename
T
>
template
<
typename
T
>
...
@@ -463,7 +447,7 @@ namespace internal {
...
@@ -463,7 +447,7 @@ namespace internal {
// the object itself.
// the object itself.
template
<
typename
T
,
std
::
size_t
SIZE
,
typename
Allocator
=
std
::
allocator
<
T
>
>
template
<
typename
T
,
std
::
size_t
SIZE
,
typename
Allocator
=
std
::
allocator
<
T
>
>
class
MemoryBuffer
:
private
Allocator
,
public
Buffer
<
T
>
{
class
MemoryBuffer
:
private
Allocator
,
public
Buffer
<
T
>
{
private:
private:
T
data_
[
SIZE
];
T
data_
[
SIZE
];
// Free memory allocated by the buffer.
// Free memory allocated by the buffer.
...
@@ -471,18 +455,16 @@ private:
...
@@ -471,18 +455,16 @@ private:
if
(
this
->
ptr_
!=
data_
)
this
->
deallocate
(
this
->
ptr_
,
this
->
capacity_
);
if
(
this
->
ptr_
!=
data_
)
this
->
deallocate
(
this
->
ptr_
,
this
->
capacity_
);
}
}
protected:
protected:
void
grow
(
std
::
size_t
size
);
void
grow
(
std
::
size_t
size
);
public:
public:
explicit
MemoryBuffer
(
const
Allocator
&
alloc
=
Allocator
())
explicit
MemoryBuffer
(
const
Allocator
&
alloc
=
Allocator
())
:
Allocator
(
alloc
),
Buffer
<
T
>
(
data_
,
SIZE
)
{}
:
Allocator
(
alloc
),
Buffer
<
T
>
(
data_
,
SIZE
)
{}
~
MemoryBuffer
()
{
~
MemoryBuffer
()
{
free
();
}
free
();
}
#if FMT_USE_RVALUE_REFERENCES
#if FMT_USE_RVALUE_REFERENCES
private:
private:
// Move data from other to this buffer.
// Move data from other to this buffer.
void
move
(
MemoryBuffer
&
other
)
{
void
move
(
MemoryBuffer
&
other
)
{
Allocator
&
this_alloc
=
*
this
,
&
other_alloc
=
other
;
Allocator
&
this_alloc
=
*
this
,
&
other_alloc
=
other
;
...
@@ -493,8 +475,7 @@ private:
...
@@ -493,8 +475,7 @@ private:
this
->
ptr_
=
data_
;
this
->
ptr_
=
data_
;
std
::
copy
(
other
.
data_
,
std
::
copy
(
other
.
data_
,
other
.
data_
+
this
->
size_
,
make_ptr
(
data_
,
this
->
capacity_
));
other
.
data_
+
this
->
size_
,
make_ptr
(
data_
,
this
->
capacity_
));
}
}
else
{
else
{
this
->
ptr_
=
other
.
ptr_
;
this
->
ptr_
=
other
.
ptr_
;
// Set pointer to the inline array so that delete is not called
// Set pointer to the inline array so that delete is not called
// when freeing.
// when freeing.
...
@@ -502,7 +483,7 @@ private:
...
@@ -502,7 +483,7 @@ private:
}
}
}
}
public:
public:
MemoryBuffer
(
MemoryBuffer
&&
other
)
{
MemoryBuffer
(
MemoryBuffer
&&
other
)
{
move
(
other
);
move
(
other
);
}
}
...
@@ -516,9 +497,7 @@ public:
...
@@ -516,9 +497,7 @@ public:
#endif
#endif
// Returns a copy of the allocator associated with this buffer.
// Returns a copy of the allocator associated with this buffer.
Allocator
get_allocator
()
const
{
Allocator
get_allocator
()
const
{
return
*
this
;
}
return
*
this
;
}
};
};
template
<
typename
T
,
std
::
size_t
SIZE
,
typename
Allocator
>
template
<
typename
T
,
std
::
size_t
SIZE
,
typename
Allocator
>
...
@@ -543,10 +522,10 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
...
@@ -543,10 +522,10 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
// A fixed-size buffer.
// A fixed-size buffer.
template
<
typename
Char
>
template
<
typename
Char
>
class
FixedBuffer
:
public
fmt
::
Buffer
<
Char
>
{
class
FixedBuffer
:
public
fmt
::
Buffer
<
Char
>
{
public:
public:
FixedBuffer
(
Char
*
array
,
std
::
size_t
size
)
:
fmt
::
Buffer
<
Char
>
(
array
,
size
)
{}
FixedBuffer
(
Char
*
array
,
std
::
size_t
size
)
:
fmt
::
Buffer
<
Char
>
(
array
,
size
)
{}
protected:
protected:
void
grow
(
std
::
size_t
size
);
void
grow
(
std
::
size_t
size
);
};
};
...
@@ -564,19 +543,11 @@ inline int getsign(double x) {
...
@@ -564,19 +543,11 @@ inline int getsign(double x) {
// Portable version of isinf.
// Portable version of isinf.
# ifdef isinf
# ifdef isinf
inline
int
isinfinity
(
double
x
)
{
inline
int
isinfinity
(
double
x
)
{
return
isinf
(
x
);
}
return
isinf
(
x
);
inline
int
isinfinity
(
long
double
x
)
{
return
isinf
(
x
);
}
}
inline
int
isinfinity
(
long
double
x
)
{
return
isinf
(
x
);
}
# else
# else
inline
int
isinfinity
(
double
x
)
{
inline
int
isinfinity
(
double
x
)
{
return
std
::
isinf
(
x
);
}
return
std
::
isinf
(
x
);
inline
int
isinfinity
(
long
double
x
)
{
return
std
::
isinf
(
x
);
}
}
inline
int
isinfinity
(
long
double
x
)
{
return
std
::
isinf
(
x
);
}
# endif
# endif
#else
#else
inline
int
getsign
(
double
value
)
{
inline
int
getsign
(
double
value
)
{
...
@@ -587,9 +558,7 @@ inline int getsign(double value) {
...
@@ -587,9 +558,7 @@ inline int getsign(double value) {
_ecvt_s
(
buffer
,
sizeof
(
buffer
),
value
,
0
,
&
dec
,
&
sign
);
_ecvt_s
(
buffer
,
sizeof
(
buffer
),
value
,
0
,
&
dec
,
&
sign
);
return
sign
;
return
sign
;
}
}
inline
int
isinfinity
(
double
x
)
{
inline
int
isinfinity
(
double
x
)
{
return
!
_finite
(
x
);
}
return
!
_finite
(
x
);
}
inline
int
isinfinity
(
long
double
x
)
{
inline
int
isinfinity
(
long
double
x
)
{
return
!
_finite
(
static_cast
<
double
>
(
x
));
return
!
_finite
(
static_cast
<
double
>
(
x
));
}
}
...
@@ -597,15 +566,13 @@ inline int isinfinity(long double x) {
...
@@ -597,15 +566,13 @@ inline int isinfinity(long double x) {
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicCharTraits
{
class
BasicCharTraits
{
public:
public:
#if _SECURE_SCL
#if _SECURE_SCL
typedef
stdext
::
checked_array_iterator
<
Char
*>
CharPtr
;
typedef
stdext
::
checked_array_iterator
<
Char
*>
CharPtr
;
#else
#else
typedef
Char
*
CharPtr
;
typedef
Char
*
CharPtr
;
#endif
#endif
static
Char
cast
(
wchar_t
value
)
{
static
Char
cast
(
wchar_t
value
)
{
return
static_cast
<
Char
>
(
value
);
}
return
static_cast
<
Char
>
(
value
);
}
};
};
template
<
typename
Char
>
template
<
typename
Char
>
...
@@ -613,14 +580,12 @@ class CharTraits;
...
@@ -613,14 +580,12 @@ class CharTraits;
template
<
>
template
<
>
class
CharTraits
<
char
>
:
public
BasicCharTraits
<
char
>
{
class
CharTraits
<
char
>
:
public
BasicCharTraits
<
char
>
{
private:
private:
// Conversion from wchar_t to char is not allowed.
// Conversion from wchar_t to char is not allowed.
static
char
convert
(
wchar_t
);
static
char
convert
(
wchar_t
);
public:
public:
static
char
convert
(
char
value
)
{
static
char
convert
(
char
value
)
{
return
value
;
}
return
value
;
}
// Formats a floating-point number.
// Formats a floating-point number.
template
<
typename
T
>
template
<
typename
T
>
...
@@ -630,13 +595,9 @@ public:
...
@@ -630,13 +595,9 @@ public:
template
<
>
template
<
>
class
CharTraits
<
wchar_t
>
:
public
BasicCharTraits
<
wchar_t
>
{
class
CharTraits
<
wchar_t
>
:
public
BasicCharTraits
<
wchar_t
>
{
public:
public:
static
wchar_t
convert
(
char
value
)
{
static
wchar_t
convert
(
char
value
)
{
return
value
;
}
return
value
;
static
wchar_t
convert
(
wchar_t
value
)
{
return
value
;
}
}
static
wchar_t
convert
(
wchar_t
value
)
{
return
value
;
}
template
<
typename
T
>
template
<
typename
T
>
static
int
format_float
(
wchar_t
*
buffer
,
std
::
size_t
size
,
static
int
format_float
(
wchar_t
*
buffer
,
std
::
size_t
size
,
...
@@ -647,17 +608,13 @@ public:
...
@@ -647,17 +608,13 @@ public:
template
<
bool
IsSigned
>
template
<
bool
IsSigned
>
struct
SignChecker
{
struct
SignChecker
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
is_negative
(
T
value
)
{
static
bool
is_negative
(
T
value
)
{
return
value
<
0
;
}
return
value
<
0
;
}
};
};
template
<
>
template
<
>
struct
SignChecker
<
false
>
{
struct
SignChecker
<
false
>
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
is_negative
(
T
)
{
static
bool
is_negative
(
T
)
{
return
false
;
}
return
false
;
}
};
};
// Returns true if value is negative, false otherwise.
// Returns true if value is negative, false otherwise.
...
@@ -669,14 +626,10 @@ inline bool is_negative(T value) {
...
@@ -669,14 +626,10 @@ inline bool is_negative(T value) {
// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
template
<
bool
FitsIn32Bits
>
template
<
bool
FitsIn32Bits
>
struct
TypeSelector
{
struct
TypeSelector
{
typedef
uint32_t
Type
;
};
typedef
uint32_t
Type
;
};
template
<
>
template
<
>
struct
TypeSelector
<
false
>
{
struct
TypeSelector
<
false
>
{
typedef
uint64_t
Type
;
};
typedef
uint64_t
Type
;
};
template
<
typename
T
>
template
<
typename
T
>
struct
IntTraits
{
struct
IntTraits
{
...
@@ -688,9 +641,7 @@ struct IntTraits {
...
@@ -688,9 +641,7 @@ struct IntTraits {
// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
// MakeUnsigned<T>::Type gives an unsigned type corresponding to integer type T.
template
<
typename
T
>
template
<
typename
T
>
struct
MakeUnsigned
{
struct
MakeUnsigned
{
typedef
T
Type
;
};
typedef
T
Type
;
};
#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
template <> \
template <> \
...
@@ -793,46 +744,30 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
...
@@ -793,46 +744,30 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
// A converter from UTF-8 to UTF-16.
// A converter from UTF-8 to UTF-16.
// It is only provided for Windows since other systems support UTF-8 natively.
// It is only provided for Windows since other systems support UTF-8 natively.
class
UTF8ToUTF16
{
class
UTF8ToUTF16
{
private:
private:
MemoryBuffer
<
wchar_t
,
INLINE_BUFFER_SIZE
>
buffer_
;
MemoryBuffer
<
wchar_t
,
INLINE_BUFFER_SIZE
>
buffer_
;
public:
public:
explicit
UTF8ToUTF16
(
StringRef
s
);
explicit
UTF8ToUTF16
(
StringRef
s
);
operator
WStringRef
()
const
{
operator
WStringRef
()
const
{
return
WStringRef
(
&
buffer_
[
0
],
size
());
}
return
WStringRef
(
&
buffer_
[
0
],
size
());
size_t
size
()
const
{
return
buffer_
.
size
()
-
1
;
}
}
const
wchar_t
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
size_t
size
()
const
{
std
::
wstring
str
()
const
{
return
std
::
wstring
(
&
buffer_
[
0
],
size
());
}
return
buffer_
.
size
()
-
1
;
}
const
wchar_t
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
std
::
wstring
str
()
const
{
return
std
::
wstring
(
&
buffer_
[
0
],
size
());
}
};
};
// A converter from UTF-16 to UTF-8.
// A converter from UTF-16 to UTF-8.
// It is only provided for Windows since other systems support UTF-8 natively.
// It is only provided for Windows since other systems support UTF-8 natively.
class
UTF16ToUTF8
{
class
UTF16ToUTF8
{
private:
private:
MemoryBuffer
<
char
,
INLINE_BUFFER_SIZE
>
buffer_
;
MemoryBuffer
<
char
,
INLINE_BUFFER_SIZE
>
buffer_
;
public:
public:
UTF16ToUTF8
()
{}
UTF16ToUTF8
()
{}
explicit
UTF16ToUTF8
(
WStringRef
s
);
explicit
UTF16ToUTF8
(
WStringRef
s
);
operator
StringRef
()
const
{
operator
StringRef
()
const
{
return
StringRef
(
&
buffer_
[
0
],
size
());
}
return
StringRef
(
&
buffer_
[
0
],
size
());
size_t
size
()
const
{
return
buffer_
.
size
()
-
1
;
}
}
const
char
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
size_t
size
()
const
{
std
::
string
str
()
const
{
return
std
::
string
(
&
buffer_
[
0
],
size
());
}
return
buffer_
.
size
()
-
1
;
}
const
char
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
std
::
string
str
()
const
{
return
std
::
string
(
&
buffer_
[
0
],
size
());
}
// Performs conversion returning a system error code instead of
// Performs conversion returning a system error code instead of
// throwing exception on conversion error. This method may still throw
// throwing exception on conversion error. This method may still throw
...
@@ -855,7 +790,7 @@ struct Value {
...
@@ -855,7 +790,7 @@ struct Value {
std
::
size_t
size
;
std
::
size_t
size
;
};
};
typedef
void
(
*
FormatFunc
)(
typedef
void
(
*
FormatFunc
)(
void
*
formatter
,
const
void
*
arg
,
void
*
format_str_ptr
);
void
*
formatter
,
const
void
*
arg
,
void
*
format_str_ptr
);
struct
CustomValue
{
struct
CustomValue
{
...
@@ -916,7 +851,7 @@ struct WCharHelper<T, wchar_t> {
...
@@ -916,7 +851,7 @@ struct WCharHelper<T, wchar_t> {
template
<
typename
T
>
template
<
typename
T
>
class
IsConvertibleToInt
{
class
IsConvertibleToInt
{
private:
private:
typedef
char
yes
[
1
];
typedef
char
yes
[
1
];
typedef
char
no
[
2
];
typedef
char
no
[
2
];
...
@@ -925,7 +860,7 @@ private:
...
@@ -925,7 +860,7 @@ private:
static
yes
&
convert
(
fmt
::
ULongLong
);
static
yes
&
convert
(
fmt
::
ULongLong
);
static
no
&
convert
(...);
static
no
&
convert
(...);
public:
public:
enum
{
value
=
(
sizeof
(
convert
(
get
()))
==
sizeof
(
yes
))
};
enum
{
value
=
(
sizeof
(
convert
(
get
()))
==
sizeof
(
yes
))
};
};
};
...
@@ -945,30 +880,22 @@ template<bool B, class T = void>
...
@@ -945,30 +880,22 @@ template<bool B, class T = void>
struct
EnableIf
{};
struct
EnableIf
{};
template
<
class
T
>
template
<
class
T
>
struct
EnableIf
<
true
,
T
>
{
struct
EnableIf
<
true
,
T
>
{
typedef
T
type
;
};
typedef
T
type
;
};
template
<
bool
B
,
class
T
,
class
F
>
template
<
bool
B
,
class
T
,
class
F
>
struct
Conditional
{
struct
Conditional
{
typedef
T
type
;
};
typedef
T
type
;
};
template
<
class
T
,
class
F
>
template
<
class
T
,
class
F
>
struct
Conditional
<
false
,
T
,
F
>
{
struct
Conditional
<
false
,
T
,
F
>
{
typedef
F
type
;
};
typedef
F
type
;
};
// A helper function to suppress bogus "conditional expression is constant"
// A helper function to suppress bogus "conditional expression is constant"
// warnings.
// warnings.
inline
bool
check
(
bool
value
)
{
inline
bool
check
(
bool
value
)
{
return
value
;
}
return
value
;
}
// Makes an Arg object from any type.
// Makes an Arg object from any type.
template
<
typename
Char
>
template
<
typename
Char
>
class
MakeValue
:
public
Arg
{
class
MakeValue
:
public
Arg
{
private:
private:
// The following two methods are private to disallow formatting of
// The following two methods are private to disallow formatting of
// arbitrary pointers. If you want to output a pointer cast it to
// arbitrary pointers. If you want to output a pointer cast it to
// "void *" or "const void *". In particular, this forbids formatting
// "void *" or "const void *". In particular, this forbids formatting
...
@@ -1008,7 +935,7 @@ private:
...
@@ -1008,7 +935,7 @@ private:
*
static_cast
<
const
T
*>
(
arg
));
*
static_cast
<
const
T
*>
(
arg
));
}
}
public:
public:
MakeValue
()
{}
MakeValue
()
{}
#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
...
@@ -1059,9 +986,7 @@ public:
...
@@ -1059,9 +986,7 @@ public:
MakeValue
(
typename
WCharHelper
<
wchar_t
,
Char
>::
Supported
value
)
{
MakeValue
(
typename
WCharHelper
<
wchar_t
,
Char
>::
Supported
value
)
{
int_value
=
value
;
int_value
=
value
;
}
}
static
uint64_t
type
(
wchar_t
)
{
static
uint64_t
type
(
wchar_t
)
{
return
Arg
::
CHAR
;
}
return
Arg
::
CHAR
;
}
#define FMT_MAKE_STR_VALUE(Type, TYPE) \
#define FMT_MAKE_STR_VALUE(Type, TYPE) \
MakeValue(Type value) { set_string(value); } \
MakeValue(Type value) { set_string(value); } \
...
@@ -1110,14 +1035,10 @@ public:
...
@@ -1110,14 +1035,10 @@ public:
// Additional template param `Char_` is needed here because make_type always
// Additional template param `Char_` is needed here because make_type always
// uses MakeValue<char>.
// uses MakeValue<char>.
template
<
typename
Char_
>
template
<
typename
Char_
>
MakeValue
(
const
NamedArg
<
Char_
>
&
value
)
{
MakeValue
(
const
NamedArg
<
Char_
>
&
value
)
{
pointer
=
&
value
;
}
pointer
=
&
value
;
}
template
<
typename
Char_
>
template
<
typename
Char_
>
static
uint64_t
type
(
const
NamedArg
<
Char_
>
&
)
{
static
uint64_t
type
(
const
NamedArg
<
Char_
>
&
)
{
return
Arg
::
NAMED_ARG
;
}
return
Arg
::
NAMED_ARG
;
}
};
};
template
<
typename
Char
>
template
<
typename
Char
>
...
@@ -1155,7 +1076,7 @@ struct NamedArg : Arg {
...
@@ -1155,7 +1076,7 @@ struct NamedArg : Arg {
// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
template
<
typename
Impl
,
typename
Result
>
template
<
typename
Impl
,
typename
Result
>
class
ArgVisitor
{
class
ArgVisitor
{
public:
public:
void
report_unhandled_arg
()
{}
void
report_unhandled_arg
()
{}
Result
visit_unhandled_arg
()
{
Result
visit_unhandled_arg
()
{
...
@@ -1249,7 +1170,7 @@ public:
...
@@ -1249,7 +1170,7 @@ public:
};
};
class
RuntimeError
:
public
std
::
runtime_error
{
class
RuntimeError
:
public
std
::
runtime_error
{
protected:
protected:
RuntimeError
()
:
std
::
runtime_error
(
""
)
{}
RuntimeError
()
:
std
::
runtime_error
(
""
)
{}
};
};
...
@@ -1265,7 +1186,7 @@ class ArgMap;
...
@@ -1265,7 +1186,7 @@ class ArgMap;
/** An argument list. */
/** An argument list. */
class
ArgList
{
class
ArgList
{
private:
private:
// To reduce compiled code size per formatting function call, types of first
// To reduce compiled code size per formatting function call, types of first
// MAX_PACKED_ARGS arguments are passed in the types_ field.
// MAX_PACKED_ARGS arguments are passed in the types_ field.
uint64_t
types_
;
uint64_t
types_
;
...
@@ -1289,7 +1210,7 @@ private:
...
@@ -1289,7 +1210,7 @@ private:
template
<
typename
Char
>
template
<
typename
Char
>
friend
class
internal
::
ArgMap
;
friend
class
internal
::
ArgMap
;
public:
public:
// Maximum number of arguments with packed types.
// Maximum number of arguments with packed types.
enum
{
MAX_PACKED_ARGS
=
16
};
enum
{
MAX_PACKED_ARGS
=
16
};
...
@@ -1333,13 +1254,13 @@ namespace internal {
...
@@ -1333,13 +1254,13 @@ namespace internal {
template
<
typename
Char
>
template
<
typename
Char
>
class
ArgMap
{
class
ArgMap
{
private:
private:
typedef
std
::
map
<
fmt
::
BasicStringRef
<
Char
>
,
internal
::
Arg
>
MapType
;
typedef
std
::
map
<
fmt
::
BasicStringRef
<
Char
>
,
internal
::
Arg
>
MapType
;
typedef
typename
MapType
::
value_type
Pair
;
typedef
typename
MapType
::
value_type
Pair
;
MapType
map_
;
MapType
map_
;
public:
public:
void
init
(
const
ArgList
&
args
);
void
init
(
const
ArgList
&
args
);
const
internal
::
Arg
*
find
(
const
fmt
::
BasicStringRef
<
Char
>
&
name
)
const
{
const
internal
::
Arg
*
find
(
const
fmt
::
BasicStringRef
<
Char
>
&
name
)
const
{
...
@@ -1349,17 +1270,15 @@ public:
...
@@ -1349,17 +1270,15 @@ public:
};
};
class
FormatterBase
{
class
FormatterBase
{
private:
private:
ArgList
args_
;
ArgList
args_
;
int
next_arg_index_
;
int
next_arg_index_
;
// Returns the argument with specified index.
// Returns the argument with specified index.
Arg
do_get_arg
(
unsigned
arg_index
,
const
char
*&
error
);
Arg
do_get_arg
(
unsigned
arg_index
,
const
char
*&
error
);
protected:
protected:
const
ArgList
&
args
()
const
{
const
ArgList
&
args
()
const
{
return
args_
;
}
return
args_
;
}
explicit
FormatterBase
(
const
ArgList
&
args
)
{
explicit
FormatterBase
(
const
ArgList
&
args
)
{
args_
=
args
;
args_
=
args
;
...
@@ -1385,7 +1304,7 @@ protected:
...
@@ -1385,7 +1304,7 @@ protected:
// A printf formatter.
// A printf formatter.
template
<
typename
Char
>
template
<
typename
Char
>
class
PrintfFormatter
:
private
FormatterBase
{
class
PrintfFormatter
:
private
FormatterBase
{
private:
private:
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
// Returns the argument with specified index or, if arg_index is equal
...
@@ -1396,7 +1315,7 @@ private:
...
@@ -1396,7 +1315,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:
explicit
PrintfFormatter
(
const
ArgList
&
args
)
:
FormatterBase
(
args
)
{}
explicit
PrintfFormatter
(
const
ArgList
&
args
)
:
FormatterBase
(
args
)
{}
void
format
(
BasicWriter
<
Char
>
&
writer
,
BasicCStringRef
<
Char
>
format_str
);
void
format
(
BasicWriter
<
Char
>
&
writer
,
BasicCStringRef
<
Char
>
format_str
);
};
};
...
@@ -1405,7 +1324,7 @@ public:
...
@@ -1405,7 +1324,7 @@ public:
// A formatter.
// A formatter.
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicFormatter
:
private
internal
::
FormatterBase
{
class
BasicFormatter
:
private
internal
::
FormatterBase
{
private:
private:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
internal
::
ArgMap
<
Char
>
map_
;
internal
::
ArgMap
<
Char
>
map_
;
...
@@ -1423,13 +1342,11 @@ private:
...
@@ -1423,13 +1342,11 @@ private:
// Parses argument name and returns corresponding argument.
// Parses argument name and returns corresponding argument.
internal
::
Arg
parse_arg_name
(
const
Char
*&
s
);
internal
::
Arg
parse_arg_name
(
const
Char
*&
s
);
public:
public:
BasicFormatter
(
const
ArgList
&
args
,
BasicWriter
<
Char
>
&
w
)
BasicFormatter
(
const
ArgList
&
args
,
BasicWriter
<
Char
>
&
w
)
:
FormatterBase
(
args
),
writer_
(
w
)
{}
:
FormatterBase
(
args
),
writer_
(
w
)
{}
BasicWriter
<
Char
>
&
writer
()
{
BasicWriter
<
Char
>
&
writer
()
{
return
writer_
;
}
return
writer_
;
}
void
format
(
BasicCStringRef
<
Char
>
format_str
);
void
format
(
BasicCStringRef
<
Char
>
format_str
);
...
@@ -1452,24 +1369,12 @@ struct EmptySpec {};
...
@@ -1452,24 +1369,12 @@ struct EmptySpec {};
// A type specifier.
// A type specifier.
template
<
char
TYPE
>
template
<
char
TYPE
>
struct
TypeSpec
:
EmptySpec
{
struct
TypeSpec
:
EmptySpec
{
Alignment
align
()
const
{
Alignment
align
()
const
{
return
ALIGN_DEFAULT
;
}
return
ALIGN_DEFAULT
;
unsigned
width
()
const
{
return
0
;
}
}
int
precision
()
const
{
return
-
1
;
}
unsigned
width
()
const
{
bool
flag
(
unsigned
)
const
{
return
false
;
}
return
0
;
char
type
()
const
{
return
TYPE
;
}
}
char
fill
()
const
{
return
' '
;
}
int
precision
()
const
{
return
-
1
;
}
bool
flag
(
unsigned
)
const
{
return
false
;
}
char
type
()
const
{
return
TYPE
;
}
char
fill
()
const
{
return
' '
;
}
};
};
// A width specifier.
// A width specifier.
...
@@ -1481,12 +1386,8 @@ struct WidthSpec {
...
@@ -1481,12 +1386,8 @@ struct WidthSpec {
WidthSpec
(
unsigned
width
,
wchar_t
fill
)
:
width_
(
width
),
fill_
(
fill
)
{}
WidthSpec
(
unsigned
width
,
wchar_t
fill
)
:
width_
(
width
),
fill_
(
fill
)
{}
unsigned
width
()
const
{
unsigned
width
()
const
{
return
width_
;
}
return
width_
;
wchar_t
fill
()
const
{
return
fill_
;
}
}
wchar_t
fill
()
const
{
return
fill_
;
}
};
};
// An alignment specifier.
// An alignment specifier.
...
@@ -1496,13 +1397,9 @@ struct AlignSpec : WidthSpec {
...
@@ -1496,13 +1397,9 @@ struct AlignSpec : WidthSpec {
AlignSpec
(
unsigned
width
,
wchar_t
fill
,
Alignment
align
=
ALIGN_DEFAULT
)
AlignSpec
(
unsigned
width
,
wchar_t
fill
,
Alignment
align
=
ALIGN_DEFAULT
)
:
WidthSpec
(
width
,
fill
),
align_
(
align
)
{}
:
WidthSpec
(
width
,
fill
),
align_
(
align
)
{}
Alignment
align
()
const
{
Alignment
align
()
const
{
return
align_
;
}
return
align_
;
}
int
precision
()
const
{
int
precision
()
const
{
return
-
1
;
}
return
-
1
;
}
};
};
// An alignment and type specifier.
// An alignment and type specifier.
...
@@ -1510,12 +1407,8 @@ template <char TYPE>
...
@@ -1510,12 +1407,8 @@ template <char TYPE>
struct
AlignTypeSpec
:
AlignSpec
{
struct
AlignTypeSpec
:
AlignSpec
{
AlignTypeSpec
(
unsigned
width
,
wchar_t
fill
)
:
AlignSpec
(
width
,
fill
)
{}
AlignTypeSpec
(
unsigned
width
,
wchar_t
fill
)
:
AlignSpec
(
width
,
fill
)
{}
bool
flag
(
unsigned
)
const
{
bool
flag
(
unsigned
)
const
{
return
false
;
}
return
false
;
char
type
()
const
{
return
TYPE
;
}
}
char
type
()
const
{
return
TYPE
;
}
};
};
// A full format specifier.
// A full format specifier.
...
@@ -1528,86 +1421,76 @@ struct FormatSpec : AlignSpec {
...
@@ -1528,86 +1421,76 @@ struct FormatSpec : AlignSpec {
unsigned
width
=
0
,
char
type
=
0
,
wchar_t
fill
=
' '
)
unsigned
width
=
0
,
char
type
=
0
,
wchar_t
fill
=
' '
)
:
AlignSpec
(
width
,
fill
),
flags_
(
0
),
precision_
(
-
1
),
type_
(
type
)
{}
:
AlignSpec
(
width
,
fill
),
flags_
(
0
),
precision_
(
-
1
),
type_
(
type
)
{}
bool
flag
(
unsigned
f
)
const
{
bool
flag
(
unsigned
f
)
const
{
return
(
flags_
&
f
)
!=
0
;
}
return
(
flags_
&
f
)
!=
0
;
int
precision
()
const
{
return
precision_
;
}
}
char
type
()
const
{
return
type_
;
}
int
precision
()
const
{
return
precision_
;
}
char
type
()
const
{
return
type_
;
}
};
};
// An integer format specifier.
// An integer format specifier.
template
<
typename
T
,
typename
SpecT
=
TypeSpec
<
0
>,
typename
Char
=
char
>
template
<
typename
T
,
typename
SpecT
=
TypeSpec
<
0
>,
typename
Char
=
char
>
class
IntFormatSpec
:
public
SpecT
{
class
IntFormatSpec
:
public
SpecT
{
private:
private:
T
value_
;
T
value_
;
public:
public:
IntFormatSpec
(
T
val
,
const
SpecT
&
spec
=
SpecT
())
IntFormatSpec
(
T
val
,
const
SpecT
&
spec
=
SpecT
())
:
SpecT
(
spec
),
value_
(
val
)
{}
:
SpecT
(
spec
),
value_
(
val
)
{}
T
value
()
const
{
T
value
()
const
{
return
value_
;
}
return
value_
;
}
};
};
// A string format specifier.
// A string format specifier.
template
<
typename
Char
>
template
<
typename
Char
>
class
StrFormatSpec
:
public
AlignSpec
{
class
StrFormatSpec
:
public
AlignSpec
{
private:
private:
const
Char
*
str_
;
const
Char
*
str_
;
public:
public:
template
<
typename
FillChar
>
template
<
typename
FillChar
>
StrFormatSpec
(
const
Char
*
str
,
unsigned
width
,
FillChar
fill
)
StrFormatSpec
(
const
Char
*
str
,
unsigned
width
,
FillChar
fill
)
:
AlignSpec
(
width
,
fill
),
str_
(
str
)
{
:
AlignSpec
(
width
,
fill
),
str_
(
str
)
{
internal
::
CharTraits
<
Char
>::
convert
(
FillChar
());
internal
::
CharTraits
<
Char
>::
convert
(
FillChar
());
}
}
const
Char
*
str
()
const
{
const
Char
*
str
()
const
{
return
str_
;
}
return
str_
;
}
};
};
/**
/**
Returns an integer format specifier to format the value in base 2.
Returns an integer format specifier to format the value in base 2.
*/
*/
IntFormatSpec
<
int
,
TypeSpec
<
'b'
>
>
bin
(
int
value
);
IntFormatSpec
<
int
,
TypeSpec
<
'b'
>
>
bin
(
int
value
);
/**
/**
Returns an integer format specifier to format the value in base 8.
Returns an integer format specifier to format the value in base 8.
*/
*/
IntFormatSpec
<
int
,
TypeSpec
<
'o'
>
>
oct
(
int
value
);
IntFormatSpec
<
int
,
TypeSpec
<
'o'
>
>
oct
(
int
value
);
/**
/**
Returns an integer format specifier to format the value in base 16 using
Returns an integer format specifier to format the value in base 16 using
lower-case letters for the digits above 9.
lower-case letters for the digits above 9.
*/
*/
IntFormatSpec
<
int
,
TypeSpec
<
'x'
>
>
hex
(
int
value
);
IntFormatSpec
<
int
,
TypeSpec
<
'x'
>
>
hex
(
int
value
);
/**
/**
Returns an integer formatter format specifier to format in base 16 using
Returns an integer formatter format specifier to format in base 16 using
upper-case letters for the digits above 9.
upper-case letters for the digits above 9.
*/
*/
IntFormatSpec
<
int
,
TypeSpec
<
'X'
>
>
hexu
(
int
value
);
IntFormatSpec
<
int
,
TypeSpec
<
'X'
>
>
hexu
(
int
value
);
/**
/**
\rst
\rst
Returns an integer format specifier to pad the formatted argument with the
Returns an integer format specifier to pad the formatted argument with the
fill character to the specified width using the default (right) numeric
fill character to the specified width using the default (right) numeric
alignment.
alignment.
**Example**::
**Example**::
MemoryWriter out;
MemoryWriter out;
out << pad(hex(0xcafe), 8, '0');
out << pad(hex(0xcafe), 8, '0');
// out.str() == "0000cafe"
// out.str() == "0000cafe"
\endrst
\endrst
*/
*/
template
<
char
TYPE_CODE
,
typename
Char
>
template
<
char
TYPE_CODE
,
typename
Char
>
IntFormatSpec
<
int
,
AlignTypeSpec
<
TYPE_CODE
>
,
Char
>
pad
(
IntFormatSpec
<
int
,
AlignTypeSpec
<
TYPE_CODE
>
,
Char
>
pad
(
int
value
,
unsigned
width
,
Char
fill
=
' '
);
int
value
,
unsigned
width
,
Char
fill
=
' '
);
...
@@ -1615,26 +1498,26 @@ IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
...
@@ -1615,26 +1498,26 @@ IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad(
#define FMT_DEFINE_INT_FORMATTERS(TYPE) \
#define FMT_DEFINE_INT_FORMATTERS(TYPE) \
inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
} \
} \
\
\
inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
} \
} \
\
\
inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \
inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \
return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \
} \
} \
\
\
inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \
inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \
return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \
} \
} \
\
\
template <char TYPE_CODE> \
template <char TYPE_CODE> \
inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \
inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \
IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \
IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \
return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \
return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \
f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \
} \
} \
\
\
/* For compatibility with older compilers we provide two overloads for pad, */
\
/* For compatibility with older compilers we provide two overloads for pad, */
\
/* one that takes a fill character and one that doesn't. In the future this */
\
/* one that takes a fill character and one that doesn't. In the future this */
\
...
@@ -1646,20 +1529,20 @@ inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \
...
@@ -1646,20 +1529,20 @@ inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \
unsigned width, Char fill) { \
unsigned width, Char fill) { \
return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \
return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \
f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \
} \
} \
\
\
inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \
TYPE value, unsigned width) { \
TYPE value, unsigned width) { \
return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \
value, AlignTypeSpec<0>(width, ' ')); \
value, AlignTypeSpec<0>(width, ' ')); \
} \
} \
\
\
template <typename Char> \
template <typename Char> \
inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \
TYPE value, unsigned width, Char fill) { \
TYPE value, unsigned width, Char fill) { \
return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \
value, AlignTypeSpec<0>(width, fill)); \
value, AlignTypeSpec<0>(width, fill)); \
}
}
FMT_DEFINE_INT_FORMATTERS
(
int
)
FMT_DEFINE_INT_FORMATTERS
(
int
)
FMT_DEFINE_INT_FORMATTERS
(
long
)
FMT_DEFINE_INT_FORMATTERS
(
long
)
...
@@ -1669,17 +1552,17 @@ FMT_DEFINE_INT_FORMATTERS(LongLong)
...
@@ -1669,17 +1552,17 @@ FMT_DEFINE_INT_FORMATTERS(LongLong)
FMT_DEFINE_INT_FORMATTERS
(
ULongLong
)
FMT_DEFINE_INT_FORMATTERS
(
ULongLong
)
/**
/**
\rst
\rst
Returns a string formatter that pads the formatted argument with the fill
Returns a string formatter that pads the formatted argument with the fill
character to the specified width using the default (left) string alignment.
character to the specified width using the default (left) string alignment.
**Example**::
**Example**::
std::string s = str(MemoryWriter() << pad("abc", 8));
std::string s = str(MemoryWriter() << pad("abc", 8));
// s == "abc "
// s == "abc "
\endrst
\endrst
*/
*/
template
<
typename
Char
>
template
<
typename
Char
>
inline
StrFormatSpec
<
Char
>
pad
(
inline
StrFormatSpec
<
Char
>
pad
(
const
Char
*
str
,
unsigned
width
,
Char
fill
=
' '
)
{
const
Char
*
str
,
unsigned
width
,
Char
fill
=
' '
)
{
...
@@ -1711,14 +1594,10 @@ inline StrFormatSpec<wchar_t> pad(
...
@@ -1711,14 +1594,10 @@ inline StrFormatSpec<wchar_t> pad(
# define FMT_GEN15(f) FMT_GEN14(f), f(14)
# define FMT_GEN15(f) FMT_GEN14(f), f(14)
namespace
internal
{
namespace
internal
{
inline
uint64_t
make_type
()
{
inline
uint64_t
make_type
()
{
return
0
;
}
return
0
;
}
template
<
typename
T
>
template
<
typename
T
>
inline
uint64_t
make_type
(
const
T
&
arg
)
{
inline
uint64_t
make_type
(
const
T
&
arg
)
{
return
MakeValue
<
char
>::
type
(
arg
);
}
return
MakeValue
<
char
>::
type
(
arg
);
}
template
<
unsigned
N
>
template
<
unsigned
N
>
struct
ArgArray
{
struct
ArgArray
{
...
@@ -1892,21 +1771,21 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
...
@@ -1892,21 +1771,21 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) {
FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
/**
/**
An error returned by an operating system or a language runtime,
An error returned by an operating system or a language runtime,
for example a file opening error.
for example a file opening error.
*/
*/
class
SystemError
:
public
internal
::
RuntimeError
{
class
SystemError
:
public
internal
::
RuntimeError
{
private:
private:
void
init
(
int
err_code
,
CStringRef
format_str
,
ArgList
args
);
void
init
(
int
err_code
,
CStringRef
format_str
,
ArgList
args
);
protected:
protected:
int
error_code_
;
int
error_code_
;
typedef
char
Char
;
// For FMT_VARIADIC_CTOR.
typedef
char
Char
;
// For FMT_VARIADIC_CTOR.
SystemError
()
{}
SystemError
()
{}
public:
public:
/**
/**
\rst
\rst
Constructs a :class:`fmt::SystemError` object with the description
Constructs a :class:`fmt::SystemError` object with the description
...
@@ -1937,32 +1816,30 @@ public:
...
@@ -1937,32 +1816,30 @@ public:
}
}
FMT_VARIADIC_CTOR
(
SystemError
,
init
,
int
,
CStringRef
)
FMT_VARIADIC_CTOR
(
SystemError
,
init
,
int
,
CStringRef
)
int
error_code
()
const
{
int
error_code
()
const
{
return
error_code_
;
}
return
error_code_
;
}
};
};
/**
/**
\rst
\rst
This template provides operations for formatting and writing data into
This template provides operations for formatting and writing data into
a character stream. The output is stored in a buffer provided by a subclass
a character stream. The output is stored in a buffer provided by a subclass
such as :class:`fmt::BasicMemoryWriter`.
such as :class:`fmt::BasicMemoryWriter`.
You can use one of the following typedefs for common character types:
You can use one of the following typedefs for common character types:
+---------+----------------------+
+---------+----------------------+
| Type | Definition |
| Type | Definition |
+=========+======================+
+=========+======================+
| Writer | BasicWriter<char> |
| Writer | BasicWriter<char> |
+---------+----------------------+
+---------+----------------------+
| WWriter | BasicWriter<wchar_t> |
| WWriter | BasicWriter<wchar_t> |
+---------+----------------------+
+---------+----------------------+
\endrst
\endrst
*/
*/
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicWriter
{
class
BasicWriter
{
private:
private:
// Output buffer.
// Output buffer.
Buffer
<
Char
>
&
buffer_
;
Buffer
<
Char
>
&
buffer_
;
...
@@ -1972,13 +1849,9 @@ private:
...
@@ -1972,13 +1849,9 @@ private:
#if _SECURE_SCL
#if _SECURE_SCL
// Returns pointer value.
// Returns pointer value.
static
Char
*
get
(
CharPtr
p
)
{
static
Char
*
get
(
CharPtr
p
)
{
return
p
.
base
();
}
return
p
.
base
();
}
#else
#else
static
Char
*
get
(
Char
*
p
)
{
static
Char
*
get
(
Char
*
p
)
{
return
p
;
}
return
p
;
}
#endif
#endif
// Fills the padding around the content and returns the pointer to the
// Fills the padding around the content and returns the pointer to the
...
@@ -2010,8 +1883,7 @@ private:
...
@@ -2010,8 +1883,7 @@ private:
if
(
internal
::
is_negative
(
value
))
{
if
(
internal
::
is_negative
(
value
))
{
abs_value
=
0
-
abs_value
;
abs_value
=
0
-
abs_value
;
*
write_unsigned_decimal
(
abs_value
,
1
)
=
'-'
;
*
write_unsigned_decimal
(
abs_value
,
1
)
=
'-'
;
}
}
else
{
else
{
write_unsigned_decimal
(
abs_value
,
0
);
write_unsigned_decimal
(
abs_value
,
0
);
}
}
}
}
...
@@ -2068,13 +1940,13 @@ private:
...
@@ -2068,13 +1940,13 @@ private:
friend
class
internal
::
PrintfArgFormatter
<
Char
>
;
friend
class
internal
::
PrintfArgFormatter
<
Char
>
;
protected:
protected:
/**
/**
Constructs a ``BasicWriter`` object.
Constructs a ``BasicWriter`` object.
*/
*/
explicit
BasicWriter
(
Buffer
<
Char
>
&
b
)
:
buffer_
(
b
)
{}
explicit
BasicWriter
(
Buffer
<
Char
>
&
b
)
:
buffer_
(
b
)
{}
public:
public:
/**
/**
\rst
\rst
Destroys a ``BasicWriter`` object.
Destroys a ``BasicWriter`` object.
...
@@ -2085,17 +1957,13 @@ public:
...
@@ -2085,17 +1957,13 @@ public:
/**
/**
Returns the total number of characters written.
Returns the total number of characters written.
*/
*/
std
::
size_t
size
()
const
{
std
::
size_t
size
()
const
{
return
buffer_
.
size
();
}
return
buffer_
.
size
();
}
/**
/**
Returns a pointer to the output buffer content. No terminating null
Returns a pointer to the output buffer content. No terminating null
character is appended.
character is appended.
*/
*/
const
Char
*
data
()
const
FMT_NOEXCEPT
{
const
Char
*
data
()
const
FMT_NOEXCEPT
{
return
&
buffer_
[
0
];
}
return
&
buffer_
[
0
];
}
/**
/**
Returns a pointer to the output buffer content with terminating null
Returns a pointer to the output buffer content with terminating null
...
@@ -2237,7 +2105,7 @@ public:
...
@@ -2237,7 +2105,7 @@ public:
return
*
this
;
return
*
this
;
}
}
void
clear
()
FMT_NOEXCEPT
{
buffer_
.
clear
();
}
void
clear
()
FMT_NOEXCEPT
{
buffer_
.
clear
();
}
};
};
template
<
typename
Char
>
template
<
typename
Char
>
...
@@ -2251,15 +2119,12 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
...
@@ -2251,15 +2119,12 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
if
(
spec
.
align
()
==
ALIGN_RIGHT
)
{
if
(
spec
.
align
()
==
ALIGN_RIGHT
)
{
std
::
fill_n
(
out
,
spec
.
width
()
-
size
,
fill
);
std
::
fill_n
(
out
,
spec
.
width
()
-
size
,
fill
);
out
+=
spec
.
width
()
-
size
;
out
+=
spec
.
width
()
-
size
;
}
}
else
if
(
spec
.
align
()
==
ALIGN_CENTER
)
{
else
if
(
spec
.
align
()
==
ALIGN_CENTER
)
{
out
=
fill_padding
(
out
,
spec
.
width
(),
size
,
fill
);
out
=
fill_padding
(
out
,
spec
.
width
(),
size
,
fill
);
}
}
else
{
else
{
std
::
fill_n
(
out
+
size
,
spec
.
width
()
-
size
,
fill
);
std
::
fill_n
(
out
+
size
,
spec
.
width
()
-
size
,
fill
);
}
}
}
}
else
{
else
{
out
=
grow_buffer
(
size
);
out
=
grow_buffer
(
size
);
}
}
std
::
copy
(
s
,
s
+
size
,
out
);
std
::
copy
(
s
,
s
+
size
,
out
);
...
@@ -2268,7 +2133,7 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
...
@@ -2268,7 +2133,7 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
template
<
typename
Char
>
template
<
typename
Char
>
typename
BasicWriter
<
Char
>::
CharPtr
typename
BasicWriter
<
Char
>::
CharPtr
BasicWriter
<
Char
>::
fill_padding
(
BasicWriter
<
Char
>::
fill_padding
(
CharPtr
buffer
,
unsigned
total_size
,
CharPtr
buffer
,
unsigned
total_size
,
std
::
size_t
content_size
,
wchar_t
fill
)
{
std
::
size_t
content_size
,
wchar_t
fill
)
{
std
::
size_t
padding
=
total_size
-
content_size
;
std
::
size_t
padding
=
total_size
-
content_size
;
...
@@ -2284,7 +2149,7 @@ BasicWriter<Char>::fill_padding(
...
@@ -2284,7 +2149,7 @@ BasicWriter<Char>::fill_padding(
template
<
typename
Char
>
template
<
typename
Char
>
template
<
typename
Spec
>
template
<
typename
Spec
>
typename
BasicWriter
<
Char
>::
CharPtr
typename
BasicWriter
<
Char
>::
CharPtr
BasicWriter
<
Char
>::
prepare_int_buffer
(
BasicWriter
<
Char
>::
prepare_int_buffer
(
unsigned
num_digits
,
const
Spec
&
spec
,
unsigned
num_digits
,
const
Spec
&
spec
,
const
char
*
prefix
,
unsigned
prefix_size
)
{
const
char
*
prefix
,
unsigned
prefix_size
)
{
unsigned
width
=
spec
.
width
();
unsigned
width
=
spec
.
width
();
...
@@ -2325,20 +2190,17 @@ BasicWriter<Char>::prepare_int_buffer(
...
@@ -2325,20 +2190,17 @@ BasicWriter<Char>::prepare_int_buffer(
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
p
);
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
p
);
p
+=
size
;
p
+=
size
;
std
::
fill
(
p
,
end
,
fill
);
std
::
fill
(
p
,
end
,
fill
);
}
}
else
if
(
align
==
ALIGN_CENTER
)
{
else
if
(
align
==
ALIGN_CENTER
)
{
p
=
fill_padding
(
p
,
width
,
size
,
fill
);
p
=
fill_padding
(
p
,
width
,
size
,
fill
);
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
p
);
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
p
);
p
+=
size
;
p
+=
size
;
}
}
else
{
else
{
if
(
align
==
ALIGN_NUMERIC
)
{
if
(
align
==
ALIGN_NUMERIC
)
{
if
(
prefix_size
!=
0
)
{
if
(
prefix_size
!=
0
)
{
p
=
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
p
);
p
=
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
p
);
size
-=
prefix_size
;
size
-=
prefix_size
;
}
}
}
}
else
{
else
{
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
end
-
size
);
std
::
copy
(
prefix
,
prefix
+
prefix_size
,
end
-
size
);
}
}
std
::
fill
(
p
,
end
-
size
,
fill
);
std
::
fill
(
p
,
end
-
size
,
fill
);
...
@@ -2358,22 +2220,19 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
...
@@ -2358,22 +2220,19 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
prefix
[
0
]
=
'-'
;
prefix
[
0
]
=
'-'
;
++
prefix_size
;
++
prefix_size
;
abs_value
=
0
-
abs_value
;
abs_value
=
0
-
abs_value
;
}
}
else
if
(
spec
.
flag
(
SIGN_FLAG
))
{
else
if
(
spec
.
flag
(
SIGN_FLAG
))
{
prefix
[
0
]
=
spec
.
flag
(
PLUS_FLAG
)
?
'+'
:
' '
;
prefix
[
0
]
=
spec
.
flag
(
PLUS_FLAG
)
?
'+'
:
' '
;
++
prefix_size
;
++
prefix_size
;
}
}
switch
(
spec
.
type
())
{
switch
(
spec
.
type
())
{
case
0
:
case
0
:
case
'd'
:
{
case
'd'
:
{
unsigned
num_digits
=
internal
::
count_digits
(
abs_value
);
unsigned
num_digits
=
internal
::
count_digits
(
abs_value
);
CharPtr
p
=
prepare_int_buffer
(
CharPtr
p
=
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
)
+
1
-
num_digits
;
num_digits
,
spec
,
prefix
,
prefix_size
)
+
1
-
num_digits
;
internal
::
format_decimal
(
get
(
p
),
abs_value
,
num_digits
);
internal
::
format_decimal
(
get
(
p
),
abs_value
,
num_digits
);
break
;
break
;
}
}
case
'x'
:
case
'x'
:
case
'X'
:
{
case
'X'
:
{
UnsignedType
n
=
abs_value
;
UnsignedType
n
=
abs_value
;
if
(
spec
.
flag
(
HASH_FLAG
))
{
if
(
spec
.
flag
(
HASH_FLAG
))
{
prefix
[
prefix_size
++
]
=
'0'
;
prefix
[
prefix_size
++
]
=
'0'
;
...
@@ -2393,8 +2252,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
...
@@ -2393,8 +2252,7 @@ void BasicWriter<Char>::write_int(T value, Spec spec) {
}
while
((
n
>>=
4
)
!=
0
);
}
while
((
n
>>=
4
)
!=
0
);
break
;
break
;
}
}
case
'b'
:
case
'b'
:
case
'B'
:
{
case
'B'
:
{
UnsignedType
n
=
abs_value
;
UnsignedType
n
=
abs_value
;
if
(
spec
.
flag
(
HASH_FLAG
))
{
if
(
spec
.
flag
(
HASH_FLAG
))
{
prefix
[
prefix_size
++
]
=
'0'
;
prefix
[
prefix_size
++
]
=
'0'
;
...
@@ -2444,10 +2302,7 @@ void BasicWriter<Char>::write_double(
...
@@ -2444,10 +2302,7 @@ void BasicWriter<Char>::write_double(
case
0
:
case
0
:
type
=
'g'
;
type
=
'g'
;
break
;
break
;
case
'e'
:
case
'e'
:
case
'f'
:
case
'g'
:
case
'a'
:
case
'f'
:
case
'g'
:
case
'a'
:
break
;
break
;
case
'F'
:
case
'F'
:
#ifdef _MSC_VER
#ifdef _MSC_VER
...
@@ -2455,9 +2310,7 @@ void BasicWriter<Char>::write_double(
...
@@ -2455,9 +2310,7 @@ void BasicWriter<Char>::write_double(
type
=
'f'
;
type
=
'f'
;
#endif
#endif
// Fall through.
// Fall through.
case
'E'
:
case
'E'
:
case
'G'
:
case
'A'
:
case
'G'
:
case
'A'
:
upper
=
true
;
upper
=
true
;
break
;
break
;
default:
default:
...
@@ -2471,8 +2324,7 @@ void BasicWriter<Char>::write_double(
...
@@ -2471,8 +2324,7 @@ void BasicWriter<Char>::write_double(
if
(
internal
::
getsign
(
static_cast
<
double
>
(
value
)))
{
if
(
internal
::
getsign
(
static_cast
<
double
>
(
value
)))
{
sign
=
'-'
;
sign
=
'-'
;
value
=
-
value
;
value
=
-
value
;
}
}
else
if
(
spec
.
flag
(
SIGN_FLAG
))
{
else
if
(
spec
.
flag
(
SIGN_FLAG
))
{
sign
=
spec
.
flag
(
PLUS_FLAG
)
?
'+'
:
' '
;
sign
=
spec
.
flag
(
PLUS_FLAG
)
?
'+'
:
' '
;
}
}
...
@@ -2516,7 +2368,7 @@ void BasicWriter<Char>::write_double(
...
@@ -2516,7 +2368,7 @@ void BasicWriter<Char>::write_double(
}
}
// Build format string.
// Build format string.
enum
{
MAX_FORMAT_SIZE
=
10
};
// longest format: %#-*.*Lg
enum
{
MAX_FORMAT_SIZE
=
10
};
// longest format: %#-*.*Lg
Char
format
[
MAX_FORMAT_SIZE
];
Char
format
[
MAX_FORMAT_SIZE
];
Char
*
format_ptr
=
format
;
Char
*
format_ptr
=
format
;
*
format_ptr
++
=
'%'
;
*
format_ptr
++
=
'%'
;
...
@@ -2525,8 +2377,7 @@ void BasicWriter<Char>::write_double(
...
@@ -2525,8 +2377,7 @@ void BasicWriter<Char>::write_double(
*
format_ptr
++
=
'#'
;
*
format_ptr
++
=
'#'
;
if
(
spec
.
align
()
==
ALIGN_CENTER
)
{
if
(
spec
.
align
()
==
ALIGN_CENTER
)
{
width_for_sprintf
=
0
;
width_for_sprintf
=
0
;
}
}
else
{
else
{
if
(
spec
.
align
()
==
ALIGN_LEFT
)
if
(
spec
.
align
()
==
ALIGN_LEFT
)
*
format_ptr
++
=
'-'
;
*
format_ptr
++
=
'-'
;
if
(
width
!=
0
)
if
(
width
!=
0
)
...
@@ -2563,8 +2414,7 @@ void BasicWriter<Char>::write_double(
...
@@ -2563,8 +2414,7 @@ void BasicWriter<Char>::write_double(
*
start
!=
' '
)
{
*
start
!=
' '
)
{
*
(
start
-
1
)
=
sign
;
*
(
start
-
1
)
=
sign
;
sign
=
0
;
sign
=
0
;
}
}
else
{
else
{
*
(
start
-
1
)
=
fill
;
*
(
start
-
1
)
=
fill
;
}
}
++
n
;
++
n
;
...
@@ -2593,45 +2443,45 @@ void BasicWriter<Char>::write_double(
...
@@ -2593,45 +2443,45 @@ void BasicWriter<Char>::write_double(
}
}
/**
/**
\rst
\rst
This class template provides operations for formatting and writing data
This class template provides operations for formatting and writing data
into a character stream. The output is stored in a memory buffer that grows
into a character stream. The output is stored in a memory buffer that grows
dynamically.
dynamically.
You can use one of the following typedefs for common character types
You can use one of the following typedefs for common character types
and the standard allocator:
and the standard allocator:
+---------------+-----------------------------------------------------+
+---------------+-----------------------------------------------------+
| Type | Definition |
| Type | Definition |
+===============+=====================================================+
+===============+=====================================================+
| MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> |
| MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> |
+---------------+-----------------------------------------------------+
+---------------+-----------------------------------------------------+
| WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
| WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
+---------------+-----------------------------------------------------+
+---------------+-----------------------------------------------------+
**Example**::
**Example**::
MemoryWriter out;
MemoryWriter out;
out << "The answer is " << 42 << "\n";
out << "The answer is " << 42 << "\n";
out.write("({:+f}, {:+f})", -3.14, 3.14);
out.write("({:+f}, {:+f})", -3.14, 3.14);
This will write the following output to the ``out`` object:
This will write the following output to the ``out`` object:
.. code-block:: none
.. code-block:: none
The answer is 42
The answer is 42
(-3.140000, +3.140000)
(-3.140000, +3.140000)
The output can be converted to an ``std::string`` with ``out.str()`` or
The output can be converted to an ``std::string`` with ``out.str()`` or
accessed as a C string with ``out.c_str()``.
accessed as a C string with ``out.c_str()``.
\endrst
\endrst
*/
*/
template
<
typename
Char
,
typename
Allocator
=
std
::
allocator
<
Char
>
>
template
<
typename
Char
,
typename
Allocator
=
std
::
allocator
<
Char
>
>
class
BasicMemoryWriter
:
public
BasicWriter
<
Char
>
{
class
BasicMemoryWriter
:
public
BasicWriter
<
Char
>
{
private:
private:
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
,
Allocator
>
buffer_
;
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
,
Allocator
>
buffer_
;
public:
public:
explicit
BasicMemoryWriter
(
const
Allocator
&
alloc
=
Allocator
())
explicit
BasicMemoryWriter
(
const
Allocator
&
alloc
=
Allocator
())
:
BasicWriter
<
Char
>
(
buffer_
),
buffer_
(
alloc
)
{}
:
BasicWriter
<
Char
>
(
buffer_
),
buffer_
(
alloc
)
{}
...
@@ -2662,31 +2512,31 @@ typedef BasicMemoryWriter<char> MemoryWriter;
...
@@ -2662,31 +2512,31 @@ typedef BasicMemoryWriter<char> MemoryWriter;
typedef
BasicMemoryWriter
<
wchar_t
>
WMemoryWriter
;
typedef
BasicMemoryWriter
<
wchar_t
>
WMemoryWriter
;
/**
/**
\rst
\rst
This class template provides operations for formatting and writing data
This class template provides operations for formatting and writing data
into a fixed-size array. For writing into a dynamically growing buffer
into a fixed-size array. For writing into a dynamically growing buffer
use :class:`fmt::BasicMemoryWriter`.
use :class:`fmt::BasicMemoryWriter`.
Any write method will throw ``std::runtime_error`` if the output doesn't fit
Any write method will throw ``std::runtime_error`` if the output doesn't fit
into the array.
into the array.
You can use one of the following typedefs for common character types:
You can use one of the following typedefs for common character types:
+--------------+---------------------------+
+--------------+---------------------------+
| Type | Definition |
| Type | Definition |
+==============+===========================+
+==============+===========================+
| ArrayWriter | BasicArrayWriter<char> |
| ArrayWriter | BasicArrayWriter<char> |
+--------------+---------------------------+
+--------------+---------------------------+
| WArrayWriter | BasicArrayWriter<wchar_t> |
| WArrayWriter | BasicArrayWriter<wchar_t> |
+--------------+---------------------------+
+--------------+---------------------------+
\endrst
\endrst
*/
*/
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicArrayWriter
:
public
BasicWriter
<
Char
>
{
class
BasicArrayWriter
:
public
BasicWriter
<
Char
>
{
private:
private:
internal
::
FixedBuffer
<
Char
>
buffer_
;
internal
::
FixedBuffer
<
Char
>
buffer_
;
public:
public:
/**
/**
\rst
\rst
Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
...
@@ -2703,7 +2553,7 @@ public:
...
@@ -2703,7 +2553,7 @@ public:
\endrst
\endrst
*/
*/
template
<
std
::
size_t
SIZE
>
template
<
std
::
size_t
SIZE
>
explicit
BasicArrayWriter
(
Char
(
&
array
)[
SIZE
])
explicit
BasicArrayWriter
(
Char
(
&
array
)[
SIZE
])
:
BasicWriter
<
Char
>
(
buffer_
),
buffer_
(
array
,
SIZE
)
{}
:
BasicWriter
<
Char
>
(
buffer_
),
buffer_
(
array
,
SIZE
)
{}
};
};
...
@@ -2730,10 +2580,10 @@ void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
...
@@ -2730,10 +2580,10 @@ void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT;
/** A Windows error. */
/** A Windows error. */
class
WindowsError
:
public
SystemError
{
class
WindowsError
:
public
SystemError
{
private:
private:
void
init
(
int
error_code
,
CStringRef
format_str
,
ArgList
args
);
void
init
(
int
error_code
,
CStringRef
format_str
,
ArgList
args
);
public:
public:
/**
/**
\rst
\rst
Constructs a :class:`fmt::WindowsError` object with the description
Constructs a :class:`fmt::WindowsError` object with the description
...
@@ -2777,21 +2627,21 @@ void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
...
@@ -2777,21 +2627,21 @@ void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT;
enum
Color
{
BLACK
,
RED
,
GREEN
,
YELLOW
,
BLUE
,
MAGENTA
,
CYAN
,
WHITE
};
enum
Color
{
BLACK
,
RED
,
GREEN
,
YELLOW
,
BLUE
,
MAGENTA
,
CYAN
,
WHITE
};
/**
/**
Formats a string and prints it to stdout using ANSI escape sequences
Formats a string and prints it to stdout using ANSI escape sequences
to specify color (experimental).
to specify color (experimental).
Example:
Example:
PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;
PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;
*/
*/
void
print_colored
(
Color
c
,
CStringRef
format
,
ArgList
args
);
void
print_colored
(
Color
c
,
CStringRef
format
,
ArgList
args
);
/**
/**
\rst
\rst
Formats arguments and returns the result as a string.
Formats arguments and returns the result as a string.
**Example**::
**Example**::
std::string message = format("The answer is {}", 42);
std::string message = format("The answer is {}", 42);
\endrst
\endrst
*/
*/
inline
std
::
string
format
(
CStringRef
format_str
,
ArgList
args
)
{
inline
std
::
string
format
(
CStringRef
format_str
,
ArgList
args
)
{
MemoryWriter
w
;
MemoryWriter
w
;
...
@@ -2806,36 +2656,36 @@ inline std::wstring format(WCStringRef format_str, ArgList args) {
...
@@ -2806,36 +2656,36 @@ inline std::wstring format(WCStringRef format_str, ArgList args) {
}
}
/**
/**
\rst
\rst
Prints formatted data to the file *f*.
Prints formatted data to the file *f*.
**Example**::
**Example**::
print(stderr, "Don't {}!", "panic");
print(stderr, "Don't {}!", "panic");
\endrst
\endrst
*/
*/
void
print
(
std
::
FILE
*
f
,
CStringRef
format_str
,
ArgList
args
);
void
print
(
std
::
FILE
*
f
,
CStringRef
format_str
,
ArgList
args
);
/**
/**
\rst
\rst
Prints formatted data to ``stdout``.
Prints formatted data to ``stdout``.
**Example**::
**Example**::
print("Elapsed time: {0:.2f} seconds", 1.23);
print("Elapsed time: {0:.2f} seconds", 1.23);
\endrst
\endrst
*/
*/
void
print
(
CStringRef
format_str
,
ArgList
args
);
void
print
(
CStringRef
format_str
,
ArgList
args
);
/**
/**
\rst
\rst
Prints formatted data to the stream *os*.
Prints formatted data to the stream *os*.
**Example**::
**Example**::
print(cerr, "Don't {}!", "panic");
print(cerr, "Don't {}!", "panic");
\endrst
\endrst
*/
*/
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
template
<
typename
Char
>
template
<
typename
Char
>
...
@@ -2844,13 +2694,13 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
...
@@ -2844,13 +2694,13 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) {
}
}
/**
/**
\rst
\rst
Formats arguments and returns the result as a string.
Formats arguments and returns the result as a string.
**Example**::
**Example**::
std::string message = fmt::sprintf("The answer is %d", 42);
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
\endrst
*/
*/
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
{
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
{
MemoryWriter
w
;
MemoryWriter
w
;
...
@@ -2859,37 +2709,37 @@ inline std::string sprintf(CStringRef format, ArgList args) {
...
@@ -2859,37 +2709,37 @@ inline std::string sprintf(CStringRef format, ArgList args) {
}
}
/**
/**
\rst
\rst
Prints formatted data to the file *f*.
Prints formatted data to the file *f*.
**Example**::
**Example**::
fmt::fprintf(stderr, "Don't %s!", "panic");
fmt::fprintf(stderr, "Don't %s!", "panic");
\endrst
\endrst
*/
*/
int
fprintf
(
std
::
FILE
*
f
,
CStringRef
format
,
ArgList
args
);
int
fprintf
(
std
::
FILE
*
f
,
CStringRef
format
,
ArgList
args
);
/**
/**
\rst
\rst
Prints formatted data to ``stdout``.
Prints formatted data to ``stdout``.
**Example**::
**Example**::
fmt::printf("Elapsed time: %.2f seconds", 1.23);
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
\endrst
*/
*/
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
{
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
{
return
fprintf
(
stdout
,
format
,
args
);
return
fprintf
(
stdout
,
format
,
args
);
}
}
/**
/**
Fast integer formatter.
Fast integer formatter.
*/
*/
class
FormatInt
{
class
FormatInt
{
private:
private:
// Buffer should be large enough to hold all digits (digits10 + 1),
// Buffer should be large enough to hold all digits (digits10 + 1),
// a sign and a null character.
// a sign and a null character.
enum
{
BUFFER_SIZE
=
std
::
numeric_limits
<
ULongLong
>::
digits10
+
3
};
enum
{
BUFFER_SIZE
=
std
::
numeric_limits
<
ULongLong
>::
digits10
+
3
};
mutable
char
buffer_
[
BUFFER_SIZE
];
mutable
char
buffer_
[
BUFFER_SIZE
];
char
*
str_
;
char
*
str_
;
...
@@ -2925,16 +2775,10 @@ private:
...
@@ -2925,16 +2775,10 @@ private:
*--
str_
=
'-'
;
*--
str_
=
'-'
;
}
}
public:
public:
explicit
FormatInt
(
int
value
)
{
explicit
FormatInt
(
int
value
)
{
FormatSigned
(
value
);
}
FormatSigned
(
value
);
explicit
FormatInt
(
long
value
)
{
FormatSigned
(
value
);
}
}
explicit
FormatInt
(
LongLong
value
)
{
FormatSigned
(
value
);
}
explicit
FormatInt
(
long
value
)
{
FormatSigned
(
value
);
}
explicit
FormatInt
(
LongLong
value
)
{
FormatSigned
(
value
);
}
explicit
FormatInt
(
unsigned
value
)
:
str_
(
format_decimal
(
value
))
{}
explicit
FormatInt
(
unsigned
value
)
:
str_
(
format_decimal
(
value
))
{}
explicit
FormatInt
(
unsigned
long
value
)
:
str_
(
format_decimal
(
value
))
{}
explicit
FormatInt
(
unsigned
long
value
)
:
str_
(
format_decimal
(
value
))
{}
explicit
FormatInt
(
ULongLong
value
)
:
str_
(
format_decimal
(
value
))
{}
explicit
FormatInt
(
ULongLong
value
)
:
str_
(
format_decimal
(
value
))
{}
...
@@ -2942,17 +2786,13 @@ public:
...
@@ -2942,17 +2786,13 @@ public:
/**
/**
Returns the number of characters written to the output buffer.
Returns the number of characters written to the output buffer.
*/
*/
std
::
size_t
size
()
const
{
std
::
size_t
size
()
const
{
return
buffer_
-
str_
+
BUFFER_SIZE
-
1
;
}
return
buffer_
-
str_
+
BUFFER_SIZE
-
1
;
}
/**
/**
Returns a pointer to the output buffer content. No terminating null
Returns a pointer to the output buffer content. No terminating null
character is appended.
character is appended.
*/
*/
const
char
*
data
()
const
{
const
char
*
data
()
const
{
return
str_
;
}
return
str_
;
}
/**
/**
Returns a pointer to the output buffer content with terminating null
Returns a pointer to the output buffer content with terminating null
...
@@ -2968,9 +2808,7 @@ public:
...
@@ -2968,9 +2808,7 @@ public:
Returns the content of the output buffer as an ``std::string``.
Returns the content of the output buffer as an ``std::string``.
\endrst
\endrst
*/
*/
std
::
string
str
()
const
{
std
::
string
str
()
const
{
return
std
::
string
(
str_
,
size
());
}
return
std
::
string
(
str_
,
size
());
}
};
};
// Formats a decimal integer value writing into buffer and returns
// Formats a decimal integer value writing into buffer and returns
...
@@ -2999,15 +2837,15 @@ inline void format_decimal(char *&buffer, T value) {
...
@@ -2999,15 +2837,15 @@ inline void format_decimal(char *&buffer, T value) {
}
}
/**
/**
\rst
\rst
Returns a named argument for formatting functions.
Returns a named argument for formatting functions.
**Example**::
**Example**::
print("Elapsed time: {s:.2f} seconds", arg("s", 1.23));
print("Elapsed time: {s:.2f} seconds", arg("s", 1.23));
\endrst
\endrst
*/
*/
template
<
typename
T
>
template
<
typename
T
>
inline
internal
::
NamedArg
<
char
>
arg
(
StringRef
name
,
const
T
&
arg
)
{
inline
internal
::
NamedArg
<
char
>
arg
(
StringRef
name
,
const
T
&
arg
)
{
return
internal
::
NamedArg
<
char
>
(
name
,
arg
);
return
internal
::
NamedArg
<
char
>
(
name
,
arg
);
...
@@ -3096,32 +2934,32 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
...
@@ -3096,32 +2934,32 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
#endif // FMT_USE_VARIADIC_TEMPLATES
#endif // FMT_USE_VARIADIC_TEMPLATES
/**
/**
\rst
\rst
Defines a variadic function with the specified return type, function name
Defines a variadic function with the specified return type, function name
and argument types passed as variable arguments to this macro.
and argument types passed as variable arguments to this macro.
**Example**::
**Example**::
void print_error(const char *file, int line, const char *format,
void print_error(const char *file, int line, const char *format,
fmt::ArgList args) {
fmt::ArgList args) {
fmt::print("{}: {}: ", file, line);
fmt::print("{}: {}: ", file, line);
fmt::print(format, args);
fmt::print(format, args);
}
}
FMT_VARIADIC(void, print_error, const char *, int, const char *)
FMT_VARIADIC(void, print_error, const char *, int, const char *)
``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that
``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that
don't implement variadic templates. You don't have to use this macro if
don't implement variadic templates. You don't have to use this macro if
you don't need legacy compiler support and can use variadic templates
you don't need legacy compiler support and can use variadic templates
directly::
directly::
template <typename... Args>
template <typename... Args>
void print_error(const char *file, int line, const char *format,
void print_error(const char *file, int line, const char *format,
const Args & ... args) {
const Args & ... args) {
fmt::print("{}: {}: ", file, line);
fmt::print("{}: {}: ", file, line);
fmt::print(format, args...);
fmt::print(format, args...);
}
}
\endrst
\endrst
*/
*/
#define FMT_VARIADIC(ReturnType, func, ...) \
#define FMT_VARIADIC(ReturnType, func, ...) \
FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
...
@@ -3133,19 +2971,19 @@ fmt::print(format, args...);
...
@@ -3133,19 +2971,19 @@ fmt::print(format, args...);
#define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
#define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id)
/**
/**
\rst
\rst
Convenient macro to capture the arguments' names and values into several
Convenient macro to capture the arguments' names and values into several
``fmt::arg(name, value)``.
``fmt::arg(name, value)``.
**Example**::
**Example**::
int x = 1, y = 2;
int x = 1, y = 2;
print("point: ({x}, {y})", FMT_CAPTURE(x, y));
print("point: ({x}, {y})", FMT_CAPTURE(x, y));
// same as:
// same as:
// print("point: ({x}, {y})", arg("x", x), arg("y", y));
// print("point: ({x}, {y})", arg("x", x), arg("y", y));
\endrst
\endrst
*/
*/
#define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
#define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__)
#define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
#define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__)
...
...
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