Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
S
spdlog
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
spdlog
Commits
6312748c
Commit
6312748c
authored
Sep 14, 2016
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated bundled fmt to version 1fb0586b065c4202e976528a6bdc6384dc56dc04
parent
87d79eb9
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
658 additions
and
1330 deletions
+658
-1330
format.cc
include/spdlog/fmt/bundled/format.cc
+3
-3
format.h
include/spdlog/fmt/bundled/format.h
+533
-1110
ostream.cc
include/spdlog/fmt/bundled/ostream.cc
+5
-14
ostream.h
include/spdlog/fmt/bundled/ostream.h
+17
-37
printf.h
include/spdlog/fmt/bundled/printf.h
+100
-166
No files found.
include/spdlog/fmt/bundled/format.cc
View file @
6312748c
...
@@ -25,9 +25,9 @@
...
@@ -25,9 +25,9 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
*/
// Commented out by spdlog to use header only
// Commented out by spdlog to use header only
// #include "fmt/format.h"
// #include "fmt/format.h"
// #include "fmt/printf.h"
// #include "fmt/printf.h"
#include <string.h>
#include <string.h>
...
...
include/spdlog/fmt/bundled/format.h
View file @
6312748c
...
@@ -244,13 +244,10 @@ typedef __int64 intmax_t;
...
@@ -244,13 +244,10 @@ typedef __int64 intmax_t;
#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL)
#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL)
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
namespace
fmt
namespace
fmt
{
{
namespace
internal
{
namespace
internal
{
# pragma intrinsic(_BitScanReverse)
# pragma intrinsic(_BitScanReverse)
inline
uint32_t
clz
(
uint32_t
x
)
inline
uint32_t
clz
(
uint32_t
x
)
{
{
unsigned
long
r
=
0
;
unsigned
long
r
=
0
;
_BitScanReverse
(
&
r
,
x
);
_BitScanReverse
(
&
r
,
x
);
...
@@ -267,8 +264,7 @@ inline uint32_t clz(uint32_t x)
...
@@ -267,8 +264,7 @@ inline uint32_t clz(uint32_t x)
# pragma intrinsic(_BitScanReverse64)
# pragma intrinsic(_BitScanReverse64)
# endif
# endif
inline
uint32_t
clzll
(
uint64_t
x
)
inline
uint32_t
clzll
(
uint64_t
x
)
{
{
unsigned
long
r
=
0
;
unsigned
long
r
=
0
;
# ifdef _WIN64
# ifdef _WIN64
_BitScanReverse64
(
&
r
,
x
);
_BitScanReverse64
(
&
r
,
x
);
...
@@ -293,78 +289,47 @@ inline uint32_t clzll(uint64_t x)
...
@@ -293,78 +289,47 @@ inline uint32_t clzll(uint64_t x)
}
}
#endif
#endif
namespace
fmt
namespace
fmt
{
{
namespace
internal
{
namespace
internal
struct
DummyInt
{
{
struct
DummyInt
{
int
data
[
2
];
int
data
[
2
];
operator
int
()
const
operator
int
()
const
{
return
0
;
}
{
return
0
;
}
};
};
typedef
std
::
numeric_limits
<
fmt
::
internal
::
DummyInt
>
FPUtil
;
typedef
std
::
numeric_limits
<
fmt
::
internal
::
DummyInt
>
FPUtil
;
// Dummy implementations of system functions such as signbit and ecvt called
// Dummy implementations of system functions such as signbit and ecvt called
// if the latter are not available.
// if the latter are not available.
inline
DummyInt
signbit
(...)
inline
DummyInt
signbit
(...)
{
return
DummyInt
();
}
{
inline
DummyInt
_ecvt_s
(...)
{
return
DummyInt
();
}
return
DummyInt
();
inline
DummyInt
isinf
(...)
{
return
DummyInt
();
}
}
inline
DummyInt
_finite
(...)
{
return
DummyInt
();
}
inline
DummyInt
_ecvt_s
(...)
inline
DummyInt
isnan
(...)
{
return
DummyInt
();
}
{
inline
DummyInt
_isnan
(...)
{
return
DummyInt
();
}
return
DummyInt
();
}
inline
DummyInt
isinf
(...)
{
return
DummyInt
();
}
inline
DummyInt
_finite
(...)
{
return
DummyInt
();
}
inline
DummyInt
isnan
(...)
{
return
DummyInt
();
}
inline
DummyInt
_isnan
(...)
{
return
DummyInt
();
}
// A helper function to suppress bogus "conditional expression is constant"
// A helper function to suppress bogus "conditional expression is constant"
// warnings.
// warnings.
template
<
typename
T
>
template
<
typename
T
>
inline
T
const_check
(
T
value
)
inline
T
const_check
(
T
value
)
{
return
value
;
}
{
return
value
;
}
}
}
}
// namespace fmt
}
// namespace fmt
namespace
std
namespace
std
{
{
// Standard permits specialization of std::numeric_limits. This specialization
// Standard permits specialization of std::numeric_limits. This specialization
// is used to resolve ambiguity between isinf and std::isinf in glibc:
// is used to resolve ambiguity between isinf and std::isinf in glibc:
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891
// and the same for isnan and signbit.
// and the same for isnan and signbit.
template
<>
template
<>
class
numeric_limits
<
fmt
::
internal
::
DummyInt
>
:
class
numeric_limits
<
fmt
::
internal
::
DummyInt
>
:
public
std
::
numeric_limits
<
int
>
public
std
::
numeric_limits
<
int
>
{
{
public
:
public
:
// Portable version of isinf.
// Portable version of isinf.
template
<
typename
T
>
template
<
typename
T
>
static
bool
isinfinity
(
T
x
)
static
bool
isinfinity
(
T
x
)
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
// The resolution "priority" is:
// The resolution "priority" is:
// isinf macro > std::isinf > ::isinf > fmt::internal::isinf
// isinf macro > std::isinf > ::isinf > fmt::internal::isinf
if
(
const_check
(
sizeof
(
isinf
(
x
))
==
sizeof
(
bool
)
||
if
(
const_check
(
sizeof
(
isinf
(
x
))
==
sizeof
(
bool
)
||
sizeof
(
isinf
(
x
))
==
sizeof
(
int
)))
sizeof
(
isinf
(
x
))
==
sizeof
(
int
)))
{
{
return
isinf
(
x
)
!=
0
;
return
isinf
(
x
)
!=
0
;
}
}
return
!
_finite
(
static_cast
<
double
>
(
x
));
return
!
_finite
(
static_cast
<
double
>
(
x
));
...
@@ -372,20 +337,17 @@ public:
...
@@ -372,20 +337,17 @@ public:
// Portable version of isnan.
// Portable version of isnan.
template
<
typename
T
>
template
<
typename
T
>
static
bool
isnotanumber
(
T
x
)
static
bool
isnotanumber
(
T
x
)
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
if
(
const_check
(
sizeof
(
isnan
(
x
))
==
sizeof
(
bool
)
||
if
(
const_check
(
sizeof
(
isnan
(
x
))
==
sizeof
(
bool
)
||
sizeof
(
isnan
(
x
))
==
sizeof
(
int
)))
sizeof
(
isnan
(
x
))
==
sizeof
(
int
)))
{
{
return
isnan
(
x
)
!=
0
;
return
isnan
(
x
)
!=
0
;
}
}
return
_isnan
(
static_cast
<
double
>
(
x
))
!=
0
;
return
_isnan
(
static_cast
<
double
>
(
x
))
!=
0
;
}
}
// Portable version of signbit.
// Portable version of signbit.
static
bool
isnegative
(
double
x
)
static
bool
isnegative
(
double
x
)
{
{
using
namespace
fmt
::
internal
;
using
namespace
fmt
::
internal
;
if
(
const_check
(
sizeof
(
signbit
(
x
))
==
sizeof
(
int
)))
if
(
const_check
(
sizeof
(
signbit
(
x
))
==
sizeof
(
int
)))
return
signbit
(
x
)
!=
0
;
return
signbit
(
x
)
!=
0
;
...
@@ -399,8 +361,7 @@ public:
...
@@ -399,8 +361,7 @@ public:
};
};
}
// namespace std
}
// namespace std
namespace
fmt
namespace
fmt
{
{
// Fix the warning about long long on older versions of GCC
// Fix the warning about long long on older versions of GCC
// that don't support the diagnostic pragma.
// that don't support the diagnostic pragma.
...
@@ -452,13 +413,12 @@ class BasicFormatter;
...
@@ -452,13 +413,12 @@ class BasicFormatter;
\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
)
{}
...
@@ -484,26 +444,18 @@ public:
...
@@ -484,26 +444,18 @@ public:
Converts a string reference to an ``std::string`` object.
Converts a string reference to an ``std::string`` object.
\endrst
\endrst
*/
*/
std
::
basic_string
<
Char
>
to_string
()
const
std
::
basic_string
<
Char
>
to_string
()
const
{
{
return
std
::
basic_string
<
Char
>
(
data_
,
size_
);
return
std
::
basic_string
<
Char
>
(
data_
,
size_
);
}
}
/** Returns a pointer to the string data. */
/** Returns a pointer to the string data. */
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_
;
}
// Lexicographically compare this string reference to other.
// Lexicographically compare this string reference to other.
int
compare
(
BasicStringRef
other
)
const
int
compare
(
BasicStringRef
other
)
const
{
{
std
::
size_t
size
=
size_
<
other
.
size_
?
size_
:
other
.
size_
;
std
::
size_t
size
=
size_
<
other
.
size_
?
size_
:
other
.
size_
;
int
result
=
std
::
char_traits
<
Char
>::
compare
(
data_
,
other
.
data_
,
size
);
int
result
=
std
::
char_traits
<
Char
>::
compare
(
data_
,
other
.
data_
,
size
);
if
(
result
==
0
)
if
(
result
==
0
)
...
@@ -511,28 +463,22 @@ public:
...
@@ -511,28 +463,22 @@ public:
return
result
;
return
result
;
}
}
friend
bool
operator
==
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
friend
bool
operator
==
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
{
return
lhs
.
compare
(
rhs
)
==
0
;
return
lhs
.
compare
(
rhs
)
==
0
;
}
}
friend
bool
operator
!=
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
friend
bool
operator
!=
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
{
return
lhs
.
compare
(
rhs
)
!=
0
;
return
lhs
.
compare
(
rhs
)
!=
0
;
}
}
friend
bool
operator
<
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
friend
bool
operator
<
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
{
return
lhs
.
compare
(
rhs
)
<
0
;
return
lhs
.
compare
(
rhs
)
<
0
;
}
}
friend
bool
operator
<=
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
friend
bool
operator
<=
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
{
return
lhs
.
compare
(
rhs
)
<=
0
;
return
lhs
.
compare
(
rhs
)
<=
0
;
}
}
friend
bool
operator
>
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
friend
bool
operator
>
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
{
return
lhs
.
compare
(
rhs
)
>
0
;
return
lhs
.
compare
(
rhs
)
>
0
;
}
}
friend
bool
operator
>=
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
friend
bool
operator
>=
(
BasicStringRef
lhs
,
BasicStringRef
rhs
)
{
{
return
lhs
.
compare
(
rhs
)
>=
0
;
return
lhs
.
compare
(
rhs
)
>=
0
;
}
}
};
};
...
@@ -566,12 +512,11 @@ typedef BasicStringRef<wchar_t> WStringRef;
...
@@ -566,12 +512,11 @@ typedef BasicStringRef<wchar_t> WStringRef;
\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
)
{}
...
@@ -583,33 +528,25 @@ public:
...
@@ -583,33 +528,25 @@ 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
())
{}
~
FormatError
()
throw
();
~
FormatError
()
throw
();
};
};
namespace
internal
namespace
internal
{
{
// 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 <> \
...
@@ -624,8 +561,7 @@ FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
...
@@ -624,8 +561,7 @@ FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
// Casts nonnegative integer to unsigned.
// Casts nonnegative integer to unsigned.
template
<
typename
Int
>
template
<
typename
Int
>
inline
typename
MakeUnsigned
<
Int
>::
Type
to_unsigned
(
Int
value
)
inline
typename
MakeUnsigned
<
Int
>::
Type
to_unsigned
(
Int
value
)
{
{
FMT_ASSERT
(
value
>=
0
,
"negative value"
);
FMT_ASSERT
(
value
>=
0
,
"negative value"
);
return
static_cast
<
typename
MakeUnsigned
<
Int
>::
Type
>
(
value
);
return
static_cast
<
typename
MakeUnsigned
<
Int
>::
Type
>
(
value
);
}
}
...
@@ -637,16 +573,12 @@ enum { INLINE_BUFFER_SIZE = 500 };
...
@@ -637,16 +573,12 @@ enum { INLINE_BUFFER_SIZE = 500 };
#if FMT_SECURE_SCL
#if FMT_SECURE_SCL
// Use checked iterator to avoid warnings on MSVC.
// Use checked iterator to avoid warnings on MSVC.
template
<
typename
T
>
template
<
typename
T
>
inline
stdext
::
checked_array_iterator
<
T
*>
make_ptr
(
T
*
ptr
,
std
::
size_t
size
)
inline
stdext
::
checked_array_iterator
<
T
*>
make_ptr
(
T
*
ptr
,
std
::
size_t
size
)
{
{
return
stdext
::
checked_array_iterator
<
T
*>
(
ptr
,
size
);
return
stdext
::
checked_array_iterator
<
T
*>
(
ptr
,
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
...
@@ -656,12 +588,11 @@ inline T *make_ptr(T *ptr, std::size_t)
...
@@ -656,12 +588,11 @@ inline T *make_ptr(T *ptr, std::size_t)
\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_
;
...
@@ -677,26 +608,19 @@ protected:
...
@@ -677,26 +608,19 @@ 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.
*/
*/
void
resize
(
std
::
size_t
new_size
)
void
resize
(
std
::
size_t
new_size
)
{
{
if
(
new_size
>
capacity_
)
if
(
new_size
>
capacity_
)
grow
(
new_size
);
grow
(
new_size
);
size_
=
new_size
;
size_
=
new_size
;
...
@@ -707,16 +631,14 @@ public:
...
@@ -707,16 +631,14 @@ public:
Reserves space to store at least *capacity* elements.
Reserves space to store at least *capacity* elements.
\endrst
\endrst
*/
*/
void
reserve
(
std
::
size_t
capacity
)
void
reserve
(
std
::
size_t
capacity
)
{
{
if
(
capacity
>
capacity_
)
if
(
capacity
>
capacity_
)
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_
)
grow
(
size_
+
1
);
grow
(
size_
+
1
);
ptr_
[
size_
++
]
=
value
;
ptr_
[
size_
++
]
=
value
;
...
@@ -726,20 +648,13 @@ public:
...
@@ -726,20 +648,13 @@ 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
];
}
{
const
T
&
operator
[](
std
::
size_t
index
)
const
{
return
ptr_
[
index
];
}
return
ptr_
[
index
];
}
const
T
&
operator
[](
std
::
size_t
index
)
const
{
return
ptr_
[
index
];
}
};
};
template
<
typename
T
>
template
<
typename
T
>
template
<
typename
U
>
template
<
typename
U
>
void
Buffer
<
T
>::
append
(
const
U
*
begin
,
const
U
*
end
)
void
Buffer
<
T
>::
append
(
const
U
*
begin
,
const
U
*
end
)
{
{
std
::
size_t
new_size
=
size_
+
internal
::
to_unsigned
(
end
-
begin
);
std
::
size_t
new_size
=
size_
+
internal
::
to_unsigned
(
end
-
begin
);
if
(
new_size
>
capacity_
)
if
(
new_size
>
capacity_
)
grow
(
new_size
);
grow
(
new_size
);
...
@@ -748,51 +663,41 @@ void Buffer<T>::append(const U *begin, const U *end)
...
@@ -748,51 +663,41 @@ void Buffer<T>::append(const U *begin, const U *end)
size_
=
new_size
;
size_
=
new_size
;
}
}
namespace
internal
namespace
internal
{
{
// A memory buffer for trivially copyable/constructible types with the first
// A memory buffer for trivially copyable/constructible types with the first
// SIZE elements stored in the object itself.
// SIZE elements stored in 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
];
// Deallocate memory allocated by the buffer.
// Deallocate memory allocated by the buffer.
void
deallocate
()
void
deallocate
()
{
{
if
(
this
->
ptr_
!=
data_
)
Allocator
::
deallocate
(
this
->
ptr_
,
this
->
capacity_
);
if
(
this
->
ptr_
!=
data_
)
Allocator
::
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
()
{
deallocate
();
}
{
deallocate
();
}
#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
;
this_alloc
=
std
::
move
(
other_alloc
);
this_alloc
=
std
::
move
(
other_alloc
);
this
->
size_
=
other
.
size_
;
this
->
size_
=
other
.
size_
;
this
->
capacity_
=
other
.
capacity_
;
this
->
capacity_
=
other
.
capacity_
;
if
(
other
.
ptr_
==
other
.
data_
)
if
(
other
.
ptr_
==
other
.
data_
)
{
{
this
->
ptr_
=
data_
;
this
->
ptr_
=
data_
;
std
::
uninitialized_copy
(
other
.
data_
,
other
.
data_
+
this
->
size_
,
std
::
uninitialized_copy
(
other
.
data_
,
other
.
data_
+
this
->
size_
,
make_ptr
(
data_
,
this
->
capacity_
));
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 deallocating.
// when deallocating.
...
@@ -800,14 +705,12 @@ private:
...
@@ -800,14 +705,12 @@ private:
}
}
}
}
public
:
public
:
MemoryBuffer
(
MemoryBuffer
&&
other
)
MemoryBuffer
(
MemoryBuffer
&&
other
)
{
{
move
(
other
);
move
(
other
);
}
}
MemoryBuffer
&
operator
=
(
MemoryBuffer
&&
other
)
MemoryBuffer
&
operator
=
(
MemoryBuffer
&&
other
)
{
{
assert
(
this
!=
&
other
);
assert
(
this
!=
&
other
);
deallocate
();
deallocate
();
move
(
other
);
move
(
other
);
...
@@ -816,15 +719,11 @@ public:
...
@@ -816,15 +719,11 @@ 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
>
void
MemoryBuffer
<
T
,
SIZE
,
Allocator
>::
grow
(
std
::
size_t
size
)
void
MemoryBuffer
<
T
,
SIZE
,
Allocator
>::
grow
(
std
::
size_t
size
)
{
{
std
::
size_t
new_capacity
=
this
->
capacity_
+
this
->
capacity_
/
2
;
std
::
size_t
new_capacity
=
this
->
capacity_
+
this
->
capacity_
/
2
;
if
(
size
>
new_capacity
)
if
(
size
>
new_capacity
)
new_capacity
=
size
;
new_capacity
=
size
;
...
@@ -845,45 +744,36 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size)
...
@@ -845,45 +744,36 @@ 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
:
FMT_API
void
grow
(
std
::
size_t
size
);
FMT_API
void
grow
(
std
::
size_t
size
);
};
};
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicCharTraits
class
BasicCharTraits
{
{
public
:
public
:
#if FMT_SECURE_SCL
#if FMT_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
(
int
value
)
static
Char
cast
(
int
value
)
{
return
static_cast
<
Char
>
(
value
);
}
{
return
static_cast
<
Char
>
(
value
);
}
};
};
template
<
typename
Char
>
template
<
typename
Char
>
class
CharTraits
;
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
>
...
@@ -892,17 +782,10 @@ public:
...
@@ -892,17 +782,10 @@ 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
)
{
return
value
;
}
static
wchar_t
convert
(
char
value
)
static
wchar_t
convert
(
wchar_t
value
)
{
return
value
;
}
{
return
value
;
}
static
wchar_t
convert
(
wchar_t
value
)
{
return
value
;
}
template
<
typename
T
>
template
<
typename
T
>
FMT_API
static
int
format_float
(
wchar_t
*
buffer
,
std
::
size_t
size
,
FMT_API
static
int
format_float
(
wchar_t
*
buffer
,
std
::
size_t
size
,
...
@@ -911,49 +794,33 @@ public:
...
@@ -911,49 +794,33 @@ public:
// Checks if a number is negative - used to avoid warnings.
// Checks if a number is negative - used to avoid warnings.
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.
// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
template
<
typename
T
>
template
<
typename
T
>
inline
bool
is_negative
(
T
value
)
inline
bool
is_negative
(
T
value
)
{
{
return
SignChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
is_negative
(
value
);
return
SignChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
is_negative
(
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
{
{
// Smallest of uint32_t and uint64_t that is large enough to represent
// Smallest of uint32_t and uint64_t that is large enough to represent
// all values of T.
// all values of T.
typedef
typename
typedef
typename
...
@@ -965,8 +832,7 @@ FMT_API void report_unknown_type(char code, const char *type);
...
@@ -965,8 +832,7 @@ FMT_API void report_unknown_type(char code, const char *type);
// Static data is placed in this class template to allow header-only
// Static data is placed in this class template to allow header-only
// configuration.
// configuration.
template
<
typename
T
=
void
>
template
<
typename
T
=
void
>
struct
FMT_API
BasicData
struct
FMT_API
BasicData
{
{
static
const
uint32_t
POWERS_OF_10_32
[];
static
const
uint32_t
POWERS_OF_10_32
[];
static
const
uint64_t
POWERS_OF_10_64
[];
static
const
uint64_t
POWERS_OF_10_64
[];
static
const
char
DIGITS
[];
static
const
char
DIGITS
[];
...
@@ -987,8 +853,7 @@ typedef BasicData<> Data;
...
@@ -987,8 +853,7 @@ typedef BasicData<> Data;
#ifdef FMT_BUILTIN_CLZLL
#ifdef FMT_BUILTIN_CLZLL
// Returns the number of decimal digits in n. Leading zeros are not counted
// Returns the number of decimal digits in n. Leading zeros are not counted
// except for n == 0 in which case count_digits returns 1.
// except for n == 0 in which case count_digits returns 1.
inline
unsigned
count_digits
(
uint64_t
n
)
inline
unsigned
count_digits
(
uint64_t
n
)
{
{
// Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
// Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
// and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
// and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
int
t
=
(
64
-
FMT_BUILTIN_CLZLL
(
n
|
1
))
*
1233
>>
12
;
int
t
=
(
64
-
FMT_BUILTIN_CLZLL
(
n
|
1
))
*
1233
>>
12
;
...
@@ -996,11 +861,9 @@ inline unsigned count_digits(uint64_t n)
...
@@ -996,11 +861,9 @@ inline unsigned count_digits(uint64_t n)
}
}
#else
#else
// Fallback version of count_digits used when __builtin_clz is not available.
// Fallback version of count_digits used when __builtin_clz is not available.
inline
unsigned
count_digits
(
uint64_t
n
)
inline
unsigned
count_digits
(
uint64_t
n
)
{
{
unsigned
count
=
1
;
unsigned
count
=
1
;
for
(;;)
for
(;;)
{
{
// Integer division is slow so do it for a group of four digits instead
// Integer division is slow so do it for a group of four digits instead
// of for every digit. The idea comes from the talk by Alexandrescu
// of for every digit. The idea comes from the talk by Alexandrescu
// "Three Optimization Tips for C++". See speed-test for a comparison.
// "Three Optimization Tips for C++". See speed-test for a comparison.
...
@@ -1016,35 +879,31 @@ inline unsigned count_digits(uint64_t n)
...
@@ -1016,35 +879,31 @@ inline unsigned count_digits(uint64_t n)
#ifdef FMT_BUILTIN_CLZ
#ifdef FMT_BUILTIN_CLZ
// Optional version of count_digits for better performance on 32-bit platforms.
// Optional version of count_digits for better performance on 32-bit platforms.
inline
unsigned
count_digits
(
uint32_t
n
)
inline
unsigned
count_digits
(
uint32_t
n
)
{
{
int
t
=
(
32
-
FMT_BUILTIN_CLZ
(
n
|
1
))
*
1233
>>
12
;
int
t
=
(
32
-
FMT_BUILTIN_CLZ
(
n
|
1
))
*
1233
>>
12
;
return
to_unsigned
(
t
)
-
(
n
<
Data
::
POWERS_OF_10_32
[
t
])
+
1
;
return
to_unsigned
(
t
)
-
(
n
<
Data
::
POWERS_OF_10_32
[
t
])
+
1
;
}
}
#endif
#endif
// A functor that doesn't add a thousands separator.
// A functor that doesn't add a thousands separator.
struct
NoThousandsSep
struct
NoThousandsSep
{
{
template
<
typename
Char
>
template
<
typename
Char
>
void
operator
()(
Char
*
)
{}
void
operator
()(
Char
*
)
{}
};
};
// A functor that adds a thousands separator.
// A functor that adds a thousands separator.
class
ThousandsSep
class
ThousandsSep
{
{
private
:
private
:
fmt
::
StringRef
sep_
;
fmt
::
StringRef
sep_
;
// Index of a decimal digit with the least significant digit having index 0.
// Index of a decimal digit with the least significant digit having index 0.
unsigned
digit_index_
;
unsigned
digit_index_
;
public
:
public
:
explicit
ThousandsSep
(
fmt
::
StringRef
sep
)
:
sep_
(
sep
),
digit_index_
(
0
)
{}
explicit
ThousandsSep
(
fmt
::
StringRef
sep
)
:
sep_
(
sep
),
digit_index_
(
0
)
{}
template
<
typename
Char
>
template
<
typename
Char
>
void
operator
()(
Char
*&
buffer
)
void
operator
()(
Char
*&
buffer
)
{
{
if
(
++
digit_index_
%
3
!=
0
)
if
(
++
digit_index_
%
3
!=
0
)
return
;
return
;
buffer
-=
sep_
.
size
();
buffer
-=
sep_
.
size
();
...
@@ -1058,11 +917,9 @@ public:
...
@@ -1058,11 +917,9 @@ public:
// add a thousands separator if necessary.
// add a thousands separator if necessary.
template
<
typename
UInt
,
typename
Char
,
typename
ThousandsSep
>
template
<
typename
UInt
,
typename
Char
,
typename
ThousandsSep
>
inline
void
format_decimal
(
Char
*
buffer
,
UInt
value
,
unsigned
num_digits
,
inline
void
format_decimal
(
Char
*
buffer
,
UInt
value
,
unsigned
num_digits
,
ThousandsSep
thousands_sep
)
ThousandsSep
thousands_sep
)
{
{
buffer
+=
num_digits
;
buffer
+=
num_digits
;
while
(
value
>=
100
)
while
(
value
>=
100
)
{
{
// Integer division is slow so do it for a group of two digits instead
// Integer division is slow so do it for a group of two digits instead
// of for every digit. The idea comes from the talk by Alexandrescu
// of for every digit. The idea comes from the talk by Alexandrescu
// "Three Optimization Tips for C++". See speed-test for a comparison.
// "Three Optimization Tips for C++". See speed-test for a comparison.
...
@@ -1073,8 +930,7 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
...
@@ -1073,8 +930,7 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
*--
buffer
=
Data
::
DIGITS
[
index
];
*--
buffer
=
Data
::
DIGITS
[
index
];
thousands_sep
(
buffer
);
thousands_sep
(
buffer
);
}
}
if
(
value
<
10
)
if
(
value
<
10
)
{
{
*--
buffer
=
static_cast
<
char
>
(
'0'
+
value
);
*--
buffer
=
static_cast
<
char
>
(
'0'
+
value
);
return
;
return
;
}
}
...
@@ -1085,8 +941,7 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
...
@@ -1085,8 +941,7 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits,
}
}
template
<
typename
UInt
,
typename
Char
>
template
<
typename
UInt
,
typename
Char
>
inline
void
format_decimal
(
Char
*
buffer
,
UInt
value
,
unsigned
num_digits
)
inline
void
format_decimal
(
Char
*
buffer
,
UInt
value
,
unsigned
num_digits
)
{
{
return
format_decimal
(
buffer
,
value
,
num_digits
,
NoThousandsSep
());
return
format_decimal
(
buffer
,
value
,
num_digits
,
NoThousandsSep
());
}
}
...
@@ -1101,57 +956,31 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits)
...
@@ -1101,57 +956,31 @@ inline void format_decimal(Char *buffer, UInt value, unsigned num_digits)
#if FMT_USE_WINDOWS_H
#if FMT_USE_WINDOWS_H
// 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
:
FMT_API
explicit
UTF8ToUTF16
(
StringRef
s
);
FMT_API
explicit
UTF8ToUTF16
(
StringRef
s
);
operator
WStringRef
()
const
operator
WStringRef
()
const
{
return
WStringRef
(
&
buffer_
[
0
],
size
());
}
{
size_t
size
()
const
{
return
buffer_
.
size
()
-
1
;
}
return
WStringRef
(
&
buffer_
[
0
],
size
());
const
wchar_t
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
}
std
::
wstring
str
()
const
{
return
std
::
wstring
(
&
buffer_
[
0
],
size
());
}
size_t
size
()
const
{
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
()
{}
FMT_API
explicit
UTF16ToUTF8
(
WStringRef
s
);
FMT_API
explicit
UTF16ToUTF8
(
WStringRef
s
);
operator
StringRef
()
const
operator
StringRef
()
const
{
return
StringRef
(
&
buffer_
[
0
],
size
());
}
{
size_t
size
()
const
{
return
buffer_
.
size
()
-
1
;
}
return
StringRef
(
&
buffer_
[
0
],
size
());
const
char
*
c_str
()
const
{
return
&
buffer_
[
0
];
}
}
std
::
string
str
()
const
{
return
std
::
string
(
&
buffer_
[
0
],
size
());
}
size_t
size
()
const
{
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
...
@@ -1164,11 +993,9 @@ FMT_API void format_windows_error(fmt::Writer &out, int error_code,
...
@@ -1164,11 +993,9 @@ FMT_API void format_windows_error(fmt::Writer &out, int error_code,
#endif
#endif
// A formatting argument value.
// A formatting argument value.
struct
Value
struct
Value
{
{
template
<
typename
Char
>
template
<
typename
Char
>
struct
StringValue
struct
StringValue
{
{
const
Char
*
value
;
const
Char
*
value
;
std
::
size_t
size
;
std
::
size_t
size
;
};
};
...
@@ -1176,14 +1003,12 @@ struct Value
...
@@ -1176,14 +1003,12 @@ struct Value
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
{
{
const
void
*
value
;
const
void
*
value
;
FormatFunc
format
;
FormatFunc
format
;
};
};
union
union
{
{
int
int_value
;
int
int_value
;
unsigned
uint_value
;
unsigned
uint_value
;
LongLong
long_long_value
;
LongLong
long_long_value
;
...
@@ -1198,8 +1023,7 @@ struct Value
...
@@ -1198,8 +1023,7 @@ struct Value
CustomValue
custom
;
CustomValue
custom
;
};
};
enum
Type
enum
Type
{
{
NONE
,
NAMED_ARG
,
NONE
,
NAMED_ARG
,
// Integer types should go first,
// Integer types should go first,
INT
,
UINT
,
LONG_LONG
,
ULONG_LONG
,
BOOL
,
CHAR
,
LAST_INTEGER_TYPE
=
CHAR
,
INT
,
UINT
,
LONG_LONG
,
ULONG_LONG
,
BOOL
,
CHAR
,
LAST_INTEGER_TYPE
=
CHAR
,
...
@@ -1211,8 +1035,7 @@ struct Value
...
@@ -1211,8 +1035,7 @@ struct Value
// A formatting argument. It is a trivially copyable/constructible type to
// A formatting argument. It is a trivially copyable/constructible type to
// allow storage in internal::MemoryBuffer.
// allow storage in internal::MemoryBuffer.
struct
Arg
:
Value
struct
Arg
:
Value
{
{
Type
type
;
Type
type
;
};
};
...
@@ -1225,15 +1048,13 @@ struct Null {};
...
@@ -1225,15 +1048,13 @@ struct Null {};
// A helper class template to enable or disable overloads taking wide
// A helper class template to enable or disable overloads taking wide
// characters and strings in MakeValue.
// characters and strings in MakeValue.
template
<
typename
T
,
typename
Char
>
template
<
typename
T
,
typename
Char
>
struct
WCharHelper
struct
WCharHelper
{
{
typedef
Null
<
T
>
Supported
;
typedef
Null
<
T
>
Supported
;
typedef
T
Unsupported
;
typedef
T
Unsupported
;
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
WCharHelper
<
T
,
wchar_t
>
struct
WCharHelper
<
T
,
wchar_t
>
{
{
typedef
T
Supported
;
typedef
T
Supported
;
typedef
Null
<
T
>
Unsupported
;
typedef
Null
<
T
>
Unsupported
;
};
};
...
@@ -1249,30 +1070,25 @@ Yes &convert(fmt::ULongLong);
...
@@ -1249,30 +1070,25 @@ Yes &convert(fmt::ULongLong);
No
&
convert
(...);
No
&
convert
(...);
template
<
typename
T
,
bool
ENABLE_CONVERSION
>
template
<
typename
T
,
bool
ENABLE_CONVERSION
>
struct
ConvertToIntImpl
struct
ConvertToIntImpl
{
{
enum
{
value
=
ENABLE_CONVERSION
};
enum
{
value
=
ENABLE_CONVERSION
};
};
};
template
<
typename
T
,
bool
ENABLE_CONVERSION
>
template
<
typename
T
,
bool
ENABLE_CONVERSION
>
struct
ConvertToIntImpl2
struct
ConvertToIntImpl2
{
{
enum
{
value
=
false
};
enum
{
value
=
false
};
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
ConvertToIntImpl2
<
T
,
true
>
struct
ConvertToIntImpl2
<
T
,
true
>
{
{
enum
{
enum
{
// Don't convert numeric types.
// Don't convert numeric types.
value
=
ConvertToIntImpl
<
T
,
!
std
::
numeric_limits
<
T
>::
is_specialized
>::
value
value
=
ConvertToIntImpl
<
T
,
!
std
::
numeric_limits
<
T
>::
is_specialized
>::
value
};
};
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
ConvertToInt
struct
ConvertToInt
{
{
enum
{
enable_conversion
=
sizeof
(
convert
(
get
<
T
>
()))
==
sizeof
(
Yes
)
};
enum
{
enable_conversion
=
sizeof
(
convert
(
get
<
T
>
()))
==
sizeof
(
Yes
)
};
enum
{
value
=
ConvertToIntImpl2
<
T
,
enable_conversion
>::
value
};
enum
{
value
=
ConvertToIntImpl2
<
T
,
enable_conversion
>::
value
};
};
};
...
@@ -1290,38 +1106,25 @@ template<bool B, class T = void>
...
@@ -1290,38 +1106,25 @@ 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
;
};
// For bcc32 which doesn't understand ! in template arguments.
// For bcc32 which doesn't understand ! in template arguments.
template
<
bool
>
template
<
bool
>
struct
Not
struct
Not
{
enum
{
value
=
0
};
};
{
enum
{
value
=
0
};
};
template
<>
template
<>
struct
Not
<
false
>
struct
Not
<
false
>
{
enum
{
value
=
1
};
};
{
enum
{
value
=
1
};
template
<
typename
T
>
};
struct
False
{
enum
{
value
=
0
};
};
template
<
typename
T
,
T
>
struct
LConvCheck
template
<
typename
T
,
T
>
struct
LConvCheck
{
{
LConvCheck
(
int
)
{}
LConvCheck
(
int
)
{}
};
};
...
@@ -1330,24 +1133,48 @@ template<typename T, T> struct LConvCheck
...
@@ -1330,24 +1133,48 @@ template<typename T, T> struct LConvCheck
// ``lconv`` is stubbed as an empty struct.
// ``lconv`` is stubbed as an empty struct.
template
<
typename
LConv
>
template
<
typename
LConv
>
inline
StringRef
thousands_sep
(
inline
StringRef
thousands_sep
(
LConv
*
lc
,
LConvCheck
<
char
*
LConv
::*
,
&
LConv
::
thousands_sep
>
=
0
)
LConv
*
lc
,
LConvCheck
<
char
*
LConv
::*
,
&
LConv
::
thousands_sep
>
=
0
)
{
{
return
lc
->
thousands_sep
;
return
lc
->
thousands_sep
;
}
}
inline
fmt
::
StringRef
thousands_sep
(...)
inline
fmt
::
StringRef
thousands_sep
(...)
{
return
""
;
}
{
return
""
;
#define FMT_CONCAT(a, b) a##b
#if FMT_GCC_VERSION >= 407
# define FMT_UNUSED __attribute__((unused))
#else
# define FMT_UNUSED
#endif
#ifndef FMT_USE_STATIC_ASSERT
# define FMT_USE_STATIC_ASSERT 0
#endif
#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
(FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
#else
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
# define FMT_STATIC_ASSERT(cond, message) \
typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
#endif
template
<
typename
Formatter
,
typename
Char
,
typename
T
>
void
format_arg
(
Formatter
&
,
const
Char
*
,
const
T
&
)
{
FMT_STATIC_ASSERT
(
False
<
T
>::
value
,
"Cannot format argument. To enable the use of ostream "
"operator<< include fmt/ostream.h. Otherwise provide "
"an overload of format_arg."
);
}
}
// Makes an Arg object from any type.
// Makes an Arg object from any type.
template
<
typename
Formatter
>
template
<
typename
Formatter
>
class
MakeValue
:
public
Arg
class
MakeValue
:
public
Arg
{
{
public
:
public
:
typedef
typename
Formatter
::
Char
Char
;
typedef
typename
Formatter
::
Char
Char
;
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
...
@@ -1370,14 +1197,12 @@ private:
...
@@ -1370,14 +1197,12 @@ private:
MakeValue
(
typename
WCharHelper
<
const
std
::
wstring
&
,
Char
>::
Unsupported
);
MakeValue
(
typename
WCharHelper
<
const
std
::
wstring
&
,
Char
>::
Unsupported
);
MakeValue
(
typename
WCharHelper
<
WStringRef
,
Char
>::
Unsupported
);
MakeValue
(
typename
WCharHelper
<
WStringRef
,
Char
>::
Unsupported
);
void
set_string
(
StringRef
str
)
void
set_string
(
StringRef
str
)
{
{
string
.
value
=
str
.
data
();
string
.
value
=
str
.
data
();
string
.
size
=
str
.
size
();
string
.
size
=
str
.
size
();
}
}
void
set_string
(
WStringRef
str
)
void
set_string
(
WStringRef
str
)
{
{
wstring
.
value
=
str
.
data
();
wstring
.
value
=
str
.
data
();
wstring
.
size
=
str
.
size
();
wstring
.
size
=
str
.
size
();
}
}
...
@@ -1385,14 +1210,13 @@ private:
...
@@ -1385,14 +1210,13 @@ private:
// Formats an argument of a custom type, such as a user-defined class.
// Formats an argument of a custom type, such as a user-defined class.
template
<
typename
T
>
template
<
typename
T
>
static
void
format_custom_arg
(
static
void
format_custom_arg
(
void
*
formatter
,
const
void
*
arg
,
void
*
format_str_ptr
)
void
*
formatter
,
const
void
*
arg
,
void
*
format_str_ptr
)
{
{
format_arg
(
*
static_cast
<
Formatter
*>
(
formatter
),
format
(
*
static_cast
<
Formatter
*>
(
formatter
),
*
static_cast
<
const
Char
**>
(
format_str_ptr
),
*
static_cast
<
const
Char
**>
(
format_str_ptr
),
*
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) \
...
@@ -1408,8 +1232,7 @@ public:
...
@@ -1408,8 +1232,7 @@ public:
FMT_MAKE_VALUE
(
int
,
int_value
,
INT
)
FMT_MAKE_VALUE
(
int
,
int_value
,
INT
)
FMT_MAKE_VALUE
(
unsigned
,
uint_value
,
UINT
)
FMT_MAKE_VALUE
(
unsigned
,
uint_value
,
UINT
)
MakeValue
(
long
value
)
MakeValue
(
long
value
)
{
{
// To minimize the number of types we need to deal with, long is
// To minimize the number of types we need to deal with, long is
// translated either to int or to long long depending on its size.
// translated either to int or to long long depending on its size.
if
(
const_check
(
sizeof
(
long
)
==
sizeof
(
int
)))
if
(
const_check
(
sizeof
(
long
)
==
sizeof
(
int
)))
...
@@ -1417,20 +1240,17 @@ public:
...
@@ -1417,20 +1240,17 @@ public:
else
else
long_long_value
=
value
;
long_long_value
=
value
;
}
}
static
uint64_t
type
(
long
)
static
uint64_t
type
(
long
)
{
{
return
sizeof
(
long
)
==
sizeof
(
int
)
?
Arg
::
INT
:
Arg
::
LONG_LONG
;
return
sizeof
(
long
)
==
sizeof
(
int
)
?
Arg
::
INT
:
Arg
::
LONG_LONG
;
}
}
MakeValue
(
unsigned
long
value
)
MakeValue
(
unsigned
long
value
)
{
{
if
(
const_check
(
sizeof
(
unsigned
long
)
==
sizeof
(
unsigned
)))
if
(
const_check
(
sizeof
(
unsigned
long
)
==
sizeof
(
unsigned
)))
uint_value
=
static_cast
<
unsigned
>
(
value
);
uint_value
=
static_cast
<
unsigned
>
(
value
);
else
else
ulong_long_value
=
value
;
ulong_long_value
=
value
;
}
}
static
uint64_t
type
(
unsigned
long
)
static
uint64_t
type
(
unsigned
long
)
{
{
return
sizeof
(
unsigned
long
)
==
sizeof
(
unsigned
)
?
return
sizeof
(
unsigned
long
)
==
sizeof
(
unsigned
)
?
Arg
::
UINT
:
Arg
::
ULONG_LONG
;
Arg
::
UINT
:
Arg
::
ULONG_LONG
;
}
}
...
@@ -1445,14 +1265,10 @@ public:
...
@@ -1445,14 +1265,10 @@ public:
FMT_MAKE_VALUE
(
char
,
int_value
,
CHAR
)
FMT_MAKE_VALUE
(
char
,
int_value
,
CHAR
)
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
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
;
}
#endif
#endif
#define FMT_MAKE_STR_VALUE(Type, TYPE) \
#define FMT_MAKE_STR_VALUE(Type, TYPE) \
...
@@ -1461,7 +1277,9 @@ public:
...
@@ -1461,7 +1277,9 @@ public:
FMT_MAKE_VALUE
(
char
*
,
string
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
char
*
,
string
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
const
char
*
,
string
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
const
char
*
,
string
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
signed
char
*
,
sstring
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
const
signed
char
*
,
sstring
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
const
signed
char
*
,
sstring
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
unsigned
char
*
,
ustring
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
const
unsigned
char
*
,
ustring
.
value
,
CSTRING
)
FMT_MAKE_VALUE
(
const
unsigned
char
*
,
ustring
.
value
,
CSTRING
)
FMT_MAKE_STR_VALUE
(
const
std
::
string
&
,
STRING
)
FMT_MAKE_STR_VALUE
(
const
std
::
string
&
,
STRING
)
FMT_MAKE_STR_VALUE
(
StringRef
,
STRING
)
FMT_MAKE_STR_VALUE
(
StringRef
,
STRING
)
...
@@ -1484,60 +1302,47 @@ public:
...
@@ -1484,60 +1302,47 @@ public:
template
<
typename
T
>
template
<
typename
T
>
MakeValue
(
const
T
&
value
,
MakeValue
(
const
T
&
value
,
typename
EnableIf
<
Not
<
typename
EnableIf
<
Not
<
ConvertToInt
<
T
>::
value
>::
value
,
int
>::
type
=
0
)
ConvertToInt
<
T
>::
value
>::
value
,
int
>::
type
=
0
)
{
{
custom
.
value
=
&
value
;
custom
.
value
=
&
value
;
custom
.
format
=
&
format_custom_arg
<
T
>
;
custom
.
format
=
&
format_custom_arg
<
T
>
;
}
}
template
<
typename
T
>
template
<
typename
T
>
MakeValue
(
const
T
&
value
,
MakeValue
(
const
T
&
value
,
typename
EnableIf
<
ConvertToInt
<
T
>::
value
,
int
>::
type
=
0
)
typename
EnableIf
<
ConvertToInt
<
T
>::
value
,
int
>::
type
=
0
)
{
{
int_value
=
value
;
int_value
=
value
;
}
}
template
<
typename
T
>
template
<
typename
T
>
static
uint64_t
type
(
const
T
&
)
static
uint64_t
type
(
const
T
&
)
{
{
return
ConvertToInt
<
T
>::
value
?
Arg
::
INT
:
Arg
::
CUSTOM
;
return
ConvertToInt
<
T
>::
value
?
Arg
::
INT
:
Arg
::
CUSTOM
;
}
}
// Additional template param `Char_` is needed here because make_type always
// Additional template param `Char_` is needed here because make_type always
// uses char.
// uses 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
Formatter
>
template
<
typename
Formatter
>
class
MakeArg
:
public
Arg
class
MakeArg
:
public
Arg
{
{
public
:
public
:
MakeArg
()
MakeArg
()
{
{
type
=
Arg
::
NONE
;
type
=
Arg
::
NONE
;
}
}
template
<
typename
T
>
template
<
typename
T
>
MakeArg
(
const
T
&
value
)
MakeArg
(
const
T
&
value
)
:
Arg
(
MakeValue
<
Formatter
>
(
value
))
:
Arg
(
MakeValue
<
Formatter
>
(
value
))
{
{
type
=
static_cast
<
Arg
::
Type
>
(
MakeValue
<
Formatter
>::
type
(
value
));
type
=
static_cast
<
Arg
::
Type
>
(
MakeValue
<
Formatter
>::
type
(
value
));
}
}
};
};
template
<
typename
Char
>
template
<
typename
Char
>
struct
NamedArg
:
Arg
struct
NamedArg
:
Arg
{
{
BasicStringRef
<
Char
>
name
;
BasicStringRef
<
Char
>
name
;
template
<
typename
T
>
template
<
typename
T
>
...
@@ -1545,9 +1350,8 @@ struct NamedArg : Arg
...
@@ -1545,9 +1350,8 @@ struct NamedArg : Arg
:
Arg
(
MakeArg
<
BasicFormatter
<
Char
>
>
(
value
)),
name
(
argname
)
{}
:
Arg
(
MakeArg
<
BasicFormatter
<
Char
>
>
(
value
)),
name
(
argname
)
{}
};
};
class
RuntimeError
:
public
std
::
runtime_error
class
RuntimeError
:
public
std
::
runtime_error
{
{
protected
:
protected
:
RuntimeError
()
:
std
::
runtime_error
(
""
)
{}
RuntimeError
()
:
std
::
runtime_error
(
""
)
{}
~
RuntimeError
()
throw
();
~
RuntimeError
()
throw
();
};
};
...
@@ -1557,14 +1361,12 @@ class ArgMap;
...
@@ -1557,14 +1361,12 @@ class ArgMap;
}
// namespace internal
}
// namespace internal
/** 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_
;
union
union
{
{
// If the number of arguments is less than MAX_PACKED_ARGS, the argument
// If the number of arguments is less than MAX_PACKED_ARGS, the argument
// values are stored in values_, otherwise they are stored in args_.
// values are stored in values_, otherwise they are stored in args_.
// This is done to reduce compiled code size as storing larger objects
// This is done to reduce compiled code size as storing larger objects
...
@@ -1574,8 +1376,7 @@ private:
...
@@ -1574,8 +1376,7 @@ private:
const
internal
::
Arg
*
args_
;
const
internal
::
Arg
*
args_
;
};
};
internal
::
Arg
::
Type
type
(
unsigned
index
)
const
internal
::
Arg
::
Type
type
(
unsigned
index
)
const
{
{
unsigned
shift
=
index
*
4
;
unsigned
shift
=
index
*
4
;
uint64_t
mask
=
0xf
;
uint64_t
mask
=
0xf
;
return
static_cast
<
internal
::
Arg
::
Type
>
(
return
static_cast
<
internal
::
Arg
::
Type
>
(
...
@@ -1585,7 +1386,7 @@ private:
...
@@ -1585,7 +1386,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
};
...
@@ -1597,13 +1398,11 @@ public:
...
@@ -1597,13 +1398,11 @@ public:
:
types_
(
types
),
args_
(
args
)
{}
:
types_
(
types
),
args_
(
args
)
{}
/** Returns the argument at specified index. */
/** Returns the argument at specified index. */
internal
::
Arg
operator
[](
unsigned
index
)
const
internal
::
Arg
operator
[](
unsigned
index
)
const
{
{
using
internal
::
Arg
;
using
internal
::
Arg
;
Arg
arg
;
Arg
arg
;
bool
use_values
=
type
(
MAX_PACKED_ARGS
-
1
)
==
Arg
::
NONE
;
bool
use_values
=
type
(
MAX_PACKED_ARGS
-
1
)
==
Arg
::
NONE
;
if
(
index
<
MAX_PACKED_ARGS
)
if
(
index
<
MAX_PACKED_ARGS
)
{
{
Arg
::
Type
arg_type
=
type
(
index
);
Arg
::
Type
arg_type
=
type
(
index
);
internal
::
Value
&
val
=
arg
;
internal
::
Value
&
val
=
arg
;
if
(
arg_type
!=
Arg
::
NONE
)
if
(
arg_type
!=
Arg
::
NONE
)
...
@@ -1611,15 +1410,13 @@ public:
...
@@ -1611,15 +1410,13 @@ public:
arg
.
type
=
arg_type
;
arg
.
type
=
arg_type
;
return
arg
;
return
arg
;
}
}
if
(
use_values
)
if
(
use_values
)
{
{
// The index is greater than the number of arguments that can be stored
// The index is greater than the number of arguments that can be stored
// in values, so return a "none" argument.
// in values, so return a "none" argument.
arg
.
type
=
Arg
::
NONE
;
arg
.
type
=
Arg
::
NONE
;
return
arg
;
return
arg
;
}
}
for
(
unsigned
i
=
MAX_PACKED_ARGS
;
i
<=
index
;
++
i
)
for
(
unsigned
i
=
MAX_PACKED_ARGS
;
i
<=
index
;
++
i
)
{
{
if
(
args_
[
i
].
type
==
Arg
::
NONE
)
if
(
args_
[
i
].
type
==
Arg
::
NONE
)
return
args_
[
i
];
return
args_
[
i
];
}
}
...
@@ -1654,109 +1451,92 @@ public:
...
@@ -1654,109 +1451,92 @@ public:
\endrst
\endrst
*/
*/
template
<
typename
Impl
,
typename
Result
>
template
<
typename
Impl
,
typename
Result
>
class
ArgVisitor
class
ArgVisitor
{
{
private
:
private
:
typedef
internal
::
Arg
Arg
;
typedef
internal
::
Arg
Arg
;
public
:
public
:
void
report_unhandled_arg
()
{}
void
report_unhandled_arg
()
{}
Result
visit_unhandled_arg
()
Result
visit_unhandled_arg
()
{
{
FMT_DISPATCH
(
report_unhandled_arg
());
FMT_DISPATCH
(
report_unhandled_arg
());
return
Result
();
return
Result
();
}
}
/** Visits an ``int`` argument. **/
/** Visits an ``int`` argument. **/
Result
visit_int
(
int
value
)
Result
visit_int
(
int
value
)
{
{
return
FMT_DISPATCH
(
visit_any_int
(
value
));
return
FMT_DISPATCH
(
visit_any_int
(
value
));
}
}
/** Visits a ``long long`` argument. **/
/** Visits a ``long long`` argument. **/
Result
visit_long_long
(
LongLong
value
)
Result
visit_long_long
(
LongLong
value
)
{
{
return
FMT_DISPATCH
(
visit_any_int
(
value
));
return
FMT_DISPATCH
(
visit_any_int
(
value
));
}
}
/** Visits an ``unsigned`` argument. **/
/** Visits an ``unsigned`` argument. **/
Result
visit_uint
(
unsigned
value
)
Result
visit_uint
(
unsigned
value
)
{
{
return
FMT_DISPATCH
(
visit_any_int
(
value
));
return
FMT_DISPATCH
(
visit_any_int
(
value
));
}
}
/** Visits an ``unsigned long long`` argument. **/
/** Visits an ``unsigned long long`` argument. **/
Result
visit_ulong_long
(
ULongLong
value
)
Result
visit_ulong_long
(
ULongLong
value
)
{
{
return
FMT_DISPATCH
(
visit_any_int
(
value
));
return
FMT_DISPATCH
(
visit_any_int
(
value
));
}
}
/** Visits a ``bool`` argument. **/
/** Visits a ``bool`` argument. **/
Result
visit_bool
(
bool
value
)
Result
visit_bool
(
bool
value
)
{
{
return
FMT_DISPATCH
(
visit_any_int
(
value
));
return
FMT_DISPATCH
(
visit_any_int
(
value
));
}
}
/** Visits a ``char`` or ``wchar_t`` argument. **/
/** Visits a ``char`` or ``wchar_t`` argument. **/
Result
visit_char
(
int
value
)
Result
visit_char
(
int
value
)
{
{
return
FMT_DISPATCH
(
visit_any_int
(
value
));
return
FMT_DISPATCH
(
visit_any_int
(
value
));
}
}
/** Visits an argument of any integral type. **/
/** Visits an argument of any integral type. **/
template
<
typename
T
>
template
<
typename
T
>
Result
visit_any_int
(
T
)
Result
visit_any_int
(
T
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
/** Visits a ``double`` argument. **/
/** Visits a ``double`` argument. **/
Result
visit_double
(
double
value
)
Result
visit_double
(
double
value
)
{
{
return
FMT_DISPATCH
(
visit_any_double
(
value
));
return
FMT_DISPATCH
(
visit_any_double
(
value
));
}
}
/** Visits a ``long double`` argument. **/
/** Visits a ``long double`` argument. **/
Result
visit_long_double
(
long
double
value
)
Result
visit_long_double
(
long
double
value
)
{
{
return
FMT_DISPATCH
(
visit_any_double
(
value
));
return
FMT_DISPATCH
(
visit_any_double
(
value
));
}
}
/** Visits a ``double`` or ``long double`` argument. **/
/** Visits a ``double`` or ``long double`` argument. **/
template
<
typename
T
>
template
<
typename
T
>
Result
visit_any_double
(
T
)
Result
visit_any_double
(
T
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
/** Visits a null-terminated C string (``const char *``) argument. **/
/** Visits a null-terminated C string (``const char *``) argument. **/
Result
visit_cstring
(
const
char
*
)
Result
visit_cstring
(
const
char
*
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
/** Visits a string argument. **/
/** Visits a string argument. **/
Result
visit_string
(
Arg
::
StringValue
<
char
>
)
Result
visit_string
(
Arg
::
StringValue
<
char
>
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
/** Visits a wide string argument. **/
/** Visits a wide string argument. **/
Result
visit_wstring
(
Arg
::
StringValue
<
wchar_t
>
)
Result
visit_wstring
(
Arg
::
StringValue
<
wchar_t
>
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
/** Visits a pointer argument. **/
/** Visits a pointer argument. **/
Result
visit_pointer
(
const
void
*
)
Result
visit_pointer
(
const
void
*
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
/** Visits an argument of a custom (user-defined) type. **/
/** Visits an argument of a custom (user-defined) type. **/
Result
visit_custom
(
Arg
::
CustomValue
)
Result
visit_custom
(
Arg
::
CustomValue
)
{
{
return
FMT_DISPATCH
(
visit_unhandled_arg
());
return
FMT_DISPATCH
(
visit_unhandled_arg
());
}
}
...
@@ -1768,10 +1548,8 @@ public:
...
@@ -1768,10 +1548,8 @@ public:
called.
called.
\endrst
\endrst
*/
*/
Result
visit
(
const
Arg
&
arg
)
Result
visit
(
const
Arg
&
arg
)
{
{
switch
(
arg
.
type
)
{
switch
(
arg
.
type
)
{
case
Arg
:
:
NONE
:
case
Arg
:
:
NONE
:
case
Arg
:
:
NAMED_ARG
:
case
Arg
:
:
NAMED_ARG
:
FMT_ASSERT
(
false
,
"invalid argument type"
);
FMT_ASSERT
(
false
,
"invalid argument type"
);
...
@@ -1807,14 +1585,12 @@ public:
...
@@ -1807,14 +1585,12 @@ public:
}
}
};
};
enum
Alignment
enum
Alignment
{
{
ALIGN_DEFAULT
,
ALIGN_LEFT
,
ALIGN_RIGHT
,
ALIGN_CENTER
,
ALIGN_NUMERIC
ALIGN_DEFAULT
,
ALIGN_LEFT
,
ALIGN_RIGHT
,
ALIGN_CENTER
,
ALIGN_NUMERIC
};
};
// Flags.
// Flags.
enum
enum
{
{
SIGN_FLAG
=
1
,
PLUS_FLAG
=
2
,
MINUS_FLAG
=
4
,
HASH_FLAG
=
8
,
SIGN_FLAG
=
1
,
PLUS_FLAG
=
2
,
MINUS_FLAG
=
4
,
HASH_FLAG
=
8
,
CHAR_FLAG
=
0x10
// Argument has char type - used in error reporting.
CHAR_FLAG
=
0x10
// Argument has char type - used in error reporting.
};
};
...
@@ -1824,37 +1600,17 @@ struct EmptySpec {};
...
@@ -1824,37 +1600,17 @@ struct EmptySpec {};
// A type specifier.
// A type specifier.
template
<
char
TYPE
>
template
<
char
TYPE
>
struct
TypeSpec
:
EmptySpec
struct
TypeSpec
:
EmptySpec
{
{
Alignment
align
()
const
{
return
ALIGN_DEFAULT
;
}
Alignment
align
()
const
unsigned
width
()
const
{
return
0
;
}
{
int
precision
()
const
{
return
-
1
;
}
return
ALIGN_DEFAULT
;
bool
flag
(
unsigned
)
const
{
return
false
;
}
}
char
type
()
const
{
return
TYPE
;
}
unsigned
width
()
const
char
fill
()
const
{
return
' '
;
}
{
return
0
;
}
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.
struct
WidthSpec
struct
WidthSpec
{
{
unsigned
width_
;
unsigned
width_
;
// Fill is always wchar_t and cast to char if necessary to avoid having
// Fill is always wchar_t and cast to char if necessary to avoid having
// two specialization of WidthSpec and its subclasses.
// two specialization of WidthSpec and its subclasses.
...
@@ -1862,54 +1618,33 @@ struct WidthSpec
...
@@ -1862,54 +1618,33 @@ 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_
;
}
{
wchar_t
fill
()
const
{
return
fill_
;
}
return
width_
;
}
wchar_t
fill
()
const
{
return
fill_
;
}
};
};
// An alignment specifier.
// An alignment specifier.
struct
AlignSpec
:
WidthSpec
struct
AlignSpec
:
WidthSpec
{
{
Alignment
align_
;
Alignment
align_
;
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.
template
<
char
TYPE
>
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
;
}
{
char
type
()
const
{
return
TYPE
;
}
return
false
;
}
char
type
()
const
{
return
TYPE
;
}
};
};
// A full format specifier.
// A full format specifier.
struct
FormatSpec
:
AlignSpec
struct
FormatSpec
:
AlignSpec
{
{
unsigned
flags_
;
unsigned
flags_
;
int
precision_
;
int
precision_
;
char
type_
;
char
type_
;
...
@@ -1918,56 +1653,38 @@ struct FormatSpec : AlignSpec
...
@@ -1918,56 +1653,38 @@ 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
;
}
{
int
precision
()
const
{
return
precision_
;
}
return
(
flags_
&
f
)
!=
0
;
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_
;
}
};
};
/**
/**
...
@@ -2080,39 +1797,33 @@ FMT_DEFINE_INT_FORMATTERS(ULongLong)
...
@@ -2080,39 +1797,33 @@ FMT_DEFINE_INT_FORMATTERS(ULongLong)
*/
*/
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
=
' '
)
{
{
return
StrFormatSpec
<
Char
>
(
str
,
width
,
fill
);
return
StrFormatSpec
<
Char
>
(
str
,
width
,
fill
);
}
}
inline
StrFormatSpec
<
wchar_t
>
pad
(
inline
StrFormatSpec
<
wchar_t
>
pad
(
const
wchar_t
*
str
,
unsigned
width
,
char
fill
=
' '
)
const
wchar_t
*
str
,
unsigned
width
,
char
fill
=
' '
)
{
{
return
StrFormatSpec
<
wchar_t
>
(
str
,
width
,
fill
);
return
StrFormatSpec
<
wchar_t
>
(
str
,
width
,
fill
);
}
}
namespace
internal
namespace
internal
{
{
template
<
typename
Char
>
template
<
typename
Char
>
class
ArgMap
class
ArgMap
{
{
private
:
private
:
typedef
std
::
vector
<
typedef
std
::
vector
<
std
::
pair
<
fmt
::
BasicStringRef
<
Char
>
,
internal
::
Arg
>
>
MapType
;
std
::
pair
<
fmt
::
BasicStringRef
<
Char
>
,
internal
::
Arg
>
>
MapType
;
typedef
typename
MapType
::
value_type
Pair
;
typedef
typename
MapType
::
value_type
Pair
;
MapType
map_
;
MapType
map_
;
public
:
public
:
FMT_API
void
init
(
const
ArgList
&
args
);
FMT_API
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
{
{
// The list is unsorted, so just return the first matching name.
// The list is unsorted, so just return the first matching name.
for
(
typename
MapType
::
const_iterator
it
=
map_
.
begin
(),
end
=
map_
.
end
();
for
(
typename
MapType
::
const_iterator
it
=
map_
.
begin
(),
end
=
map_
.
end
();
it
!=
end
;
++
it
)
it
!=
end
;
++
it
)
{
{
if
(
it
->
first
==
name
)
if
(
it
->
first
==
name
)
return
&
it
->
second
;
return
&
it
->
second
;
}
}
...
@@ -2121,71 +1832,52 @@ public:
...
@@ -2121,71 +1832,52 @@ public:
};
};
template
<
typename
Impl
,
typename
Char
>
template
<
typename
Impl
,
typename
Char
>
class
ArgFormatterBase
:
public
ArgVisitor
<
Impl
,
void
>
class
ArgFormatterBase
:
public
ArgVisitor
<
Impl
,
void
>
{
{
private
:
private
:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
FormatSpec
&
spec_
;
FormatSpec
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgFormatterBase
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgFormatterBase
);
void
write_pointer
(
const
void
*
p
)
void
write_pointer
(
const
void
*
p
)
{
{
spec_
.
flags_
=
HASH_FLAG
;
spec_
.
flags_
=
HASH_FLAG
;
spec_
.
type_
=
'x'
;
spec_
.
type_
=
'x'
;
writer_
.
write_int
(
reinterpret_cast
<
uintptr_t
>
(
p
),
spec_
);
writer_
.
write_int
(
reinterpret_cast
<
uintptr_t
>
(
p
),
spec_
);
}
}
protected
:
protected
:
BasicWriter
<
Char
>
&
writer
()
BasicWriter
<
Char
>
&
writer
()
{
return
writer_
;
}
{
FormatSpec
&
spec
()
{
return
spec_
;
}
return
writer_
;
}
FormatSpec
&
spec
()
{
return
spec_
;
}
void
write
(
bool
value
)
void
write
(
bool
value
)
{
{
const
char
*
str_value
=
value
?
"true"
:
"false"
;
const
char
*
str_value
=
value
?
"true"
:
"false"
;
Arg
::
StringValue
<
char
>
str
=
{
str_value
,
std
::
strlen
(
str_value
)
};
Arg
::
StringValue
<
char
>
str
=
{
str_value
,
std
::
strlen
(
str_value
)
};
writer_
.
write_str
(
str
,
spec_
);
writer_
.
write_str
(
str
,
spec_
);
}
}
void
write
(
const
char
*
value
)
void
write
(
const
char
*
value
)
{
{
Arg
::
StringValue
<
char
>
str
=
{
value
,
value
!=
0
?
std
::
strlen
(
value
)
:
0
};
Arg
::
StringValue
<
char
>
str
=
{
value
,
value
!=
0
?
std
::
strlen
(
value
)
:
0
};
writer_
.
write_str
(
str
,
spec_
);
writer_
.
write_str
(
str
,
spec_
);
}
}
public
:
public
:
ArgFormatterBase
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
ArgFormatterBase
(
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_
)
return
visit_any_int
(
value
);
return
visit_any_int
(
value
);
write
(
value
);
write
(
value
);
}
}
void
visit_char
(
int
value
)
void
visit_char
(
int
value
)
{
{
if
(
spec_
.
type_
&&
spec_
.
type_
!=
'c'
)
{
if
(
spec_
.
type_
&&
spec_
.
type_
!=
'c'
)
{
spec_
.
flags_
|=
CHAR_FLAG
;
spec_
.
flags_
|=
CHAR_FLAG
;
writer_
.
write_int
(
value
,
spec_
);
writer_
.
write_int
(
value
,
spec_
);
return
;
return
;
...
@@ -2196,83 +1888,65 @@ public:
...
@@ -2196,83 +1888,65 @@ public:
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec_
.
fill
());
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec_
.
fill
());
CharPtr
out
=
CharPtr
();
CharPtr
out
=
CharPtr
();
const
unsigned
CHAR_WIDTH
=
1
;
const
unsigned
CHAR_WIDTH
=
1
;
if
(
spec_
.
width_
>
CHAR_WIDTH
)
if
(
spec_
.
width_
>
CHAR_WIDTH
)
{
{
out
=
writer_
.
grow_buffer
(
spec_
.
width_
);
out
=
writer_
.
grow_buffer
(
spec_
.
width_
);
if
(
spec_
.
align_
==
ALIGN_RIGHT
)
if
(
spec_
.
align_
==
ALIGN_RIGHT
)
{
{
std
::
uninitialized_fill_n
(
out
,
spec_
.
width_
-
CHAR_WIDTH
,
fill
);
std
::
uninitialized_fill_n
(
out
,
spec_
.
width_
-
CHAR_WIDTH
,
fill
);
out
+=
spec_
.
width_
-
CHAR_WIDTH
;
out
+=
spec_
.
width_
-
CHAR_WIDTH
;
}
}
else
if
(
spec_
.
align_
==
ALIGN_CENTER
)
{
else
if
(
spec_
.
align_
==
ALIGN_CENTER
)
{
out
=
writer_
.
fill_padding
(
out
,
spec_
.
width_
,
out
=
writer_
.
fill_padding
(
out
,
spec_
.
width_
,
internal
::
const_check
(
CHAR_WIDTH
),
fill
);
internal
::
const_check
(
CHAR_WIDTH
),
fill
);
}
}
else
{
else
{
std
::
uninitialized_fill_n
(
out
+
CHAR_WIDTH
,
std
::
uninitialized_fill_n
(
out
+
CHAR_WIDTH
,
spec_
.
width_
-
CHAR_WIDTH
,
fill
);
spec_
.
width_
-
CHAR_WIDTH
,
fill
);
}
}
}
}
else
{
else
{
out
=
writer_
.
grow_buffer
(
CHAR_WIDTH
);
out
=
writer_
.
grow_buffer
(
CHAR_WIDTH
);
}
}
*
out
=
internal
::
CharTraits
<
Char
>::
cast
(
value
);
*
out
=
internal
::
CharTraits
<
Char
>::
cast
(
value
);
}
}
void
visit_cstring
(
const
char
*
value
)
void
visit_cstring
(
const
char
*
value
)
{
{
if
(
spec_
.
type_
==
'p'
)
if
(
spec_
.
type_
==
'p'
)
return
write_pointer
(
value
);
return
write_pointer
(
value
);
write
(
value
);
write
(
value
);
}
}
void
visit_string
(
Arg
::
StringValue
<
char
>
value
)
void
visit_string
(
Arg
::
StringValue
<
char
>
value
)
{
{
writer_
.
write_str
(
value
,
spec_
);
writer_
.
write_str
(
value
,
spec_
);
}
}
using
ArgVisitor
<
Impl
,
void
>::
visit_wstring
;
using
ArgVisitor
<
Impl
,
void
>::
visit_wstring
;
void
visit_wstring
(
Arg
::
StringValue
<
Char
>
value
)
void
visit_wstring
(
Arg
::
StringValue
<
Char
>
value
)
{
{
writer_
.
write_str
(
value
,
spec_
);
writer_
.
write_str
(
value
,
spec_
);
}
}
void
visit_pointer
(
const
void
*
value
)
void
visit_pointer
(
const
void
*
value
)
{
{
if
(
spec_
.
type_
&&
spec_
.
type_
!=
'p'
)
if
(
spec_
.
type_
&&
spec_
.
type_
!=
'p'
)
report_unknown_type
(
spec_
.
type_
,
"pointer"
);
report_unknown_type
(
spec_
.
type_
,
"pointer"
);
write_pointer
(
value
);
write_pointer
(
value
);
}
}
};
};
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.
FMT_API
Arg
do_get_arg
(
unsigned
arg_index
,
const
char
*&
error
);
FMT_API
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
;
next_arg_index_
=
0
;
next_arg_index_
=
0
;
}
}
// Returns the next argument.
// Returns the next argument.
Arg
next_arg
(
const
char
*&
error
)
Arg
next_arg
(
const
char
*&
error
)
{
{
if
(
next_arg_index_
>=
0
)
if
(
next_arg_index_
>=
0
)
return
do_get_arg
(
internal
::
to_unsigned
(
next_arg_index_
++
),
error
);
return
do_get_arg
(
internal
::
to_unsigned
(
next_arg_index_
++
),
error
);
error
=
"cannot switch from manual to automatic argument indexing"
;
error
=
"cannot switch from manual to automatic argument indexing"
;
...
@@ -2281,15 +1955,12 @@ protected:
...
@@ -2281,15 +1955,12 @@ protected:
// Checks if manual indexing is used and returns the argument with
// Checks if manual indexing is used and returns the argument with
// specified index.
// specified index.
Arg
get_arg
(
unsigned
arg_index
,
const
char
*&
error
)
Arg
get_arg
(
unsigned
arg_index
,
const
char
*&
error
)
{
{
return
check_no_auto_index
(
error
)
?
do_get_arg
(
arg_index
,
error
)
:
Arg
();
return
check_no_auto_index
(
error
)
?
do_get_arg
(
arg_index
,
error
)
:
Arg
();
}
}
bool
check_no_auto_index
(
const
char
*&
error
)
bool
check_no_auto_index
(
const
char
*&
error
)
{
{
if
(
next_arg_index_
>
0
)
{
if
(
next_arg_index_
>
0
)
{
error
=
"cannot switch from automatic to manual argument indexing"
;
error
=
"cannot switch from automatic to manual argument indexing"
;
return
false
;
return
false
;
}
}
...
@@ -2298,8 +1969,7 @@ protected:
...
@@ -2298,8 +1969,7 @@ protected:
}
}
template
<
typename
Char
>
template
<
typename
Char
>
void
write
(
BasicWriter
<
Char
>
&
w
,
const
Char
*
start
,
const
Char
*
end
)
void
write
(
BasicWriter
<
Char
>
&
w
,
const
Char
*
start
,
const
Char
*
end
)
{
{
if
(
start
!=
end
)
if
(
start
!=
end
)
w
<<
BasicStringRef
<
Char
>
(
start
,
internal
::
to_unsigned
(
end
-
start
));
w
<<
BasicStringRef
<
Char
>
(
start
,
internal
::
to_unsigned
(
end
-
start
));
}
}
...
@@ -2324,13 +1994,12 @@ protected:
...
@@ -2324,13 +1994,12 @@ protected:
\endrst
\endrst
*/
*/
template
<
typename
Impl
,
typename
Char
>
template
<
typename
Impl
,
typename
Char
>
class
BasicArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
class
BasicArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
{
{
private
:
private
:
BasicFormatter
<
Char
,
Impl
>
&
formatter_
;
BasicFormatter
<
Char
,
Impl
>
&
formatter_
;
const
Char
*
format_
;
const
Char
*
format_
;
public
:
public
:
/**
/**
\rst
\rst
Constructs an argument formatter object.
Constructs an argument formatter object.
...
@@ -2345,17 +2014,15 @@ public:
...
@@ -2345,17 +2014,15 @@ public:
formatter_
(
formatter
),
format_
(
fmt
)
{}
formatter_
(
formatter
),
format_
(
fmt
)
{}
/** Formats an argument of a custom (user-defined) type. */
/** Formats an argument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
{
c
.
format
(
&
formatter_
,
c
.
value
,
&
format_
);
c
.
format
(
&
formatter_
,
c
.
value
,
&
format_
);
}
}
};
};
/** The default argument formatter. */
/** The default argument formatter. */
template
<
typename
Char
>
template
<
typename
Char
>
class
ArgFormatter
:
public
BasicArgFormatter
<
ArgFormatter
<
Char
>
,
Char
>
class
ArgFormatter
:
public
BasicArgFormatter
<
ArgFormatter
<
Char
>
,
Char
>
{
{
public
:
public
:
/** Constructs an argument formatter object. */
/** Constructs an argument formatter object. */
ArgFormatter
(
BasicFormatter
<
Char
>
&
formatter
,
ArgFormatter
(
BasicFormatter
<
Char
>
&
formatter
,
FormatSpec
&
spec
,
const
Char
*
fmt
)
FormatSpec
&
spec
,
const
Char
*
fmt
)
...
@@ -2364,13 +2031,12 @@ public:
...
@@ -2364,13 +2031,12 @@ public:
/** This template formats data and writes the output to a writer. */
/** This template formats data and writes the output to a writer. */
template
<
typename
CharType
,
typename
ArgFormatter
>
template
<
typename
CharType
,
typename
ArgFormatter
>
class
BasicFormatter
:
private
internal
::
FormatterBase
class
BasicFormatter
:
private
internal
::
FormatterBase
{
{
public
:
public
:
/** The character type for the output. */
/** The character type for the output. */
typedef
CharType
Char
;
typedef
CharType
Char
;
private
:
private
:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
internal
::
ArgMap
<
Char
>
map_
;
internal
::
ArgMap
<
Char
>
map_
;
...
@@ -2388,7 +2054,7 @@ private:
...
@@ -2388,7 +2054,7 @@ 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
:
/**
/**
\rst
\rst
Constructs a ``BasicFormatter`` object. References to the arguments and
Constructs a ``BasicFormatter`` object. References to the arguments and
...
@@ -2400,10 +2066,7 @@ public:
...
@@ -2400,10 +2066,7 @@ public:
:
internal
::
FormatterBase
(
args
),
writer_
(
w
)
{}
:
internal
::
FormatterBase
(
args
),
writer_
(
w
)
{}
/** Returns a reference to the writer associated with this formatter. */
/** Returns a reference to the writer associated with this formatter. */
BasicWriter
<
Char
>
&
writer
()
BasicWriter
<
Char
>
&
writer
()
{
return
writer_
;
}
{
return
writer_
;
}
/** Formats stored arguments and writes the output to the writer. */
/** Formats stored arguments and writes the output to the writer. */
void
format
(
BasicCStringRef
<
Char
>
format_str
);
void
format
(
BasicCStringRef
<
Char
>
format_str
);
...
@@ -2431,30 +2094,23 @@ public:
...
@@ -2431,30 +2094,23 @@ public:
# define FMT_GEN14(f) FMT_GEN13(f), f(13)
# define FMT_GEN14(f) FMT_GEN13(f), f(13)
# 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
()
{
return
0
;
}
inline
uint64_t
make_type
()
{
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
<
BasicFormatter
<
char
>
>::
type
(
arg
);
return
MakeValue
<
BasicFormatter
<
char
>
>::
type
(
arg
);
}
}
template
<
unsigned
N
,
bool
/*IsPacked*/
=
(
N
<
ArgList
::
MAX_PACKED_ARGS
)
>
template
<
unsigned
N
,
bool
/*IsPacked*/
=
(
N
<
ArgList
::
MAX_PACKED_ARGS
)
>
struct
ArgArray
;
struct
ArgArray
;
template
<
unsigned
N
>
template
<
unsigned
N
>
struct
ArgArray
<
N
,
true
/*IsPacked*/
>
struct
ArgArray
<
N
,
true
/*IsPacked*/
>
{
{
typedef
Value
Type
[
N
>
0
?
N
:
1
];
typedef
Value
Type
[
N
>
0
?
N
:
1
];
template
<
typename
Formatter
,
typename
T
>
template
<
typename
Formatter
,
typename
T
>
static
Value
make
(
const
T
&
value
)
static
Value
make
(
const
T
&
value
)
{
{
#ifdef __clang__
#ifdef __clang__
Value
result
=
MakeValue
<
Formatter
>
(
value
);
Value
result
=
MakeValue
<
Formatter
>
(
value
);
// Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
// Workaround a bug in Apple LLVM version 4.2 (clang-425.0.28) of clang:
...
@@ -2464,32 +2120,26 @@ static Value make(const T &value)
...
@@ -2464,32 +2120,26 @@ static Value make(const T &value)
#else
#else
return
MakeValue
<
Formatter
>
(
value
);
return
MakeValue
<
Formatter
>
(
value
);
#endif
#endif
}
}
};
};
template
<
unsigned
N
>
template
<
unsigned
N
>
struct
ArgArray
<
N
,
false
/*IsPacked*/
>
struct
ArgArray
<
N
,
false
/*IsPacked*/
>
{
{
typedef
Arg
Type
[
N
+
1
];
// +1 for the list end Arg::NONE
typedef
Arg
Type
[
N
+
1
];
// +1 for the list end Arg::NONE
template
<
typename
Formatter
,
typename
T
>
template
<
typename
Formatter
,
typename
T
>
static
Arg
make
(
const
T
&
value
)
static
Arg
make
(
const
T
&
value
)
{
return
MakeArg
<
Formatter
>
(
value
);
}
{
return
MakeArg
<
Formatter
>
(
value
);
}
};
};
#if FMT_USE_VARIADIC_TEMPLATES
#if FMT_USE_VARIADIC_TEMPLATES
template
<
typename
Arg
,
typename
...
Args
>
template
<
typename
Arg
,
typename
...
Args
>
inline
uint64_t
make_type
(
const
Arg
&
first
,
const
Args
&
...
tail
)
inline
uint64_t
make_type
(
const
Arg
&
first
,
const
Args
&
...
tail
)
{
{
return
make_type
(
first
)
|
(
make_type
(
tail
...)
<<
4
);
return
make_type
(
first
)
|
(
make_type
(
tail
...)
<<
4
);
}
}
#else
#else
struct
ArgType
struct
ArgType
{
{
uint64_t
type
;
uint64_t
type
;
ArgType
()
:
type
(
0
)
{}
ArgType
()
:
type
(
0
)
{}
...
@@ -2500,8 +2150,7 @@ struct ArgType
...
@@ -2500,8 +2150,7 @@ struct ArgType
# define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
# define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType()
inline
uint64_t
make_type
(
FMT_GEN15
(
FMT_ARG_TYPE_DEFAULT
))
inline
uint64_t
make_type
(
FMT_GEN15
(
FMT_ARG_TYPE_DEFAULT
))
{
{
return
t0
.
type
|
(
t1
.
type
<<
4
)
|
(
t2
.
type
<<
8
)
|
(
t3
.
type
<<
12
)
|
return
t0
.
type
|
(
t1
.
type
<<
4
)
|
(
t2
.
type
<<
8
)
|
(
t3
.
type
<<
12
)
|
(
t4
.
type
<<
16
)
|
(
t5
.
type
<<
20
)
|
(
t6
.
type
<<
24
)
|
(
t7
.
type
<<
28
)
|
(
t4
.
type
<<
16
)
|
(
t5
.
type
<<
20
)
|
(
t6
.
type
<<
24
)
|
(
t7
.
type
<<
28
)
|
(
t8
.
type
<<
32
)
|
(
t9
.
type
<<
36
)
|
(
t10
.
type
<<
40
)
|
(
t11
.
type
<<
44
)
|
(
t8
.
type
<<
32
)
|
(
t9
.
type
<<
36
)
|
(
t10
.
type
<<
40
)
|
(
t11
.
type
<<
44
)
|
...
@@ -2612,19 +2261,18 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT))
...
@@ -2612,19 +2261,18 @@ inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT))
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 a description
Constructs a :class:`fmt::SystemError` object with a description
...
@@ -2643,18 +2291,14 @@ public:
...
@@ -2643,18 +2291,14 @@ public:
throw fmt::SystemError(errno, "cannot open file '{}'", filename);
throw fmt::SystemError(errno, "cannot open file '{}'", filename);
\endrst
\endrst
*/
*/
SystemError
(
int
error_code
,
CStringRef
message
)
SystemError
(
int
error_code
,
CStringRef
message
)
{
{
init
(
error_code
,
message
,
ArgList
());
init
(
error_code
,
message
,
ArgList
());
}
}
FMT_VARIADIC_CTOR
(
SystemError
,
init
,
int
,
CStringRef
)
FMT_VARIADIC_CTOR
(
SystemError
,
init
,
int
,
CStringRef
)
~
SystemError
()
throw
();
~
SystemError
()
throw
();
int
error_code
()
const
int
error_code
()
const
{
return
error_code_
;
}
{
return
error_code_
;
}
};
};
/**
/**
...
@@ -2695,9 +2339,8 @@ FMT_API void format_system_error(fmt::Writer &out, int error_code,
...
@@ -2695,9 +2339,8 @@ FMT_API void format_system_error(fmt::Writer &out, int error_code,
\endrst
\endrst
*/
*/
template
<
typename
Char
>
template
<
typename
Char
>
class
BasicWriter
class
BasicWriter
{
{
private
:
private
:
// Output buffer.
// Output buffer.
Buffer
<
Char
>
&
buffer_
;
Buffer
<
Char
>
&
buffer_
;
...
@@ -2707,15 +2350,9 @@ private:
...
@@ -2707,15 +2350,9 @@ private:
#if FMT_SECURE_SCL
#if FMT_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
...
@@ -2725,8 +2362,7 @@ private:
...
@@ -2725,8 +2362,7 @@ private:
// Grows the buffer by n characters and returns a pointer to the newly
// Grows the buffer by n characters and returns a pointer to the newly
// allocated area.
// allocated area.
CharPtr
grow_buffer
(
std
::
size_t
n
)
CharPtr
grow_buffer
(
std
::
size_t
n
)
{
{
std
::
size_t
size
=
buffer_
.
size
();
std
::
size_t
size
=
buffer_
.
size
();
buffer_
.
resize
(
size
+
n
);
buffer_
.
resize
(
size
+
n
);
return
internal
::
make_ptr
(
&
buffer_
[
size
],
n
);
return
internal
::
make_ptr
(
&
buffer_
[
size
],
n
);
...
@@ -2734,8 +2370,7 @@ private:
...
@@ -2734,8 +2370,7 @@ private:
// Writes an unsigned decimal integer.
// Writes an unsigned decimal integer.
template
<
typename
UInt
>
template
<
typename
UInt
>
Char
*
write_unsigned_decimal
(
UInt
value
,
unsigned
prefix_size
=
0
)
Char
*
write_unsigned_decimal
(
UInt
value
,
unsigned
prefix_size
=
0
)
{
{
unsigned
num_digits
=
internal
::
count_digits
(
value
);
unsigned
num_digits
=
internal
::
count_digits
(
value
);
Char
*
ptr
=
get
(
grow_buffer
(
prefix_size
+
num_digits
));
Char
*
ptr
=
get
(
grow_buffer
(
prefix_size
+
num_digits
));
internal
::
format_decimal
(
ptr
+
prefix_size
,
value
,
num_digits
);
internal
::
format_decimal
(
ptr
+
prefix_size
,
value
,
num_digits
);
...
@@ -2744,25 +2379,20 @@ private:
...
@@ -2744,25 +2379,20 @@ private:
// Writes a decimal integer.
// Writes a decimal integer.
template
<
typename
Int
>
template
<
typename
Int
>
void
write_decimal
(
Int
value
)
void
write_decimal
(
Int
value
)
{
{
typedef
typename
internal
::
IntTraits
<
Int
>::
MainType
MainType
;
typedef
typename
internal
::
IntTraits
<
Int
>::
MainType
MainType
;
MainType
abs_value
=
static_cast
<
MainType
>
(
value
);
MainType
abs_value
=
static_cast
<
MainType
>
(
value
);
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
);
}
}
}
}
// Prepare a buffer for integer formatting.
// Prepare a buffer for integer formatting.
CharPtr
prepare_int_buffer
(
unsigned
num_digits
,
CharPtr
prepare_int_buffer
(
unsigned
num_digits
,
const
EmptySpec
&
,
const
char
*
prefix
,
unsigned
prefix_size
)
const
EmptySpec
&
,
const
char
*
prefix
,
unsigned
prefix_size
)
{
{
unsigned
size
=
prefix_size
+
num_digits
;
unsigned
size
=
prefix_size
+
num_digits
;
CharPtr
p
=
grow_buffer
(
size
);
CharPtr
p
=
grow_buffer
(
size
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
...
@@ -2799,8 +2429,7 @@ private:
...
@@ -2799,8 +2429,7 @@ private:
// Appends floating-point length specifier to the format string.
// Appends floating-point length specifier to the format string.
// The second argument is only used for overload resolution.
// The second argument is only used for overload resolution.
void
append_float_length
(
Char
*&
format_ptr
,
long
double
)
void
append_float_length
(
Char
*&
format_ptr
,
long
double
)
{
{
*
format_ptr
++
=
'L'
;
*
format_ptr
++
=
'L'
;
}
}
...
@@ -2813,13 +2442,13 @@ private:
...
@@ -2813,13 +2442,13 @@ private:
template
<
typename
Impl
,
typename
Char_
>
template
<
typename
Impl
,
typename
Char_
>
friend
class
BasicPrintfArgFormatter
;
friend
class
BasicPrintfArgFormatter
;
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.
...
@@ -2830,26 +2459,19 @@ public:
...
@@ -2830,26 +2459,19 @@ 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
character appended.
character appended.
*/
*/
const
Char
*
c_str
()
const
const
Char
*
c_str
()
const
{
{
std
::
size_t
size
=
buffer_
.
size
();
std
::
size_t
size
=
buffer_
.
size
();
buffer_
.
reserve
(
size
+
1
);
buffer_
.
reserve
(
size
+
1
);
buffer_
[
size
]
=
'\0'
;
buffer_
[
size
]
=
'\0'
;
...
@@ -2861,8 +2483,7 @@ public:
...
@@ -2861,8 +2483,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
::
basic_string
<
Char
>
str
()
const
std
::
basic_string
<
Char
>
str
()
const
{
{
return
std
::
basic_string
<
Char
>
(
&
buffer_
[
0
],
buffer_
.
size
());
return
std
::
basic_string
<
Char
>
(
&
buffer_
[
0
],
buffer_
.
size
());
}
}
...
@@ -2891,32 +2512,26 @@ public:
...
@@ -2891,32 +2512,26 @@ public:
See also :ref:`syntax`.
See also :ref:`syntax`.
\endrst
\endrst
*/
*/
void
write
(
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
void
write
(
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
{
{
BasicFormatter
<
Char
>
(
args
,
*
this
).
format
(
format
);
BasicFormatter
<
Char
>
(
args
,
*
this
).
format
(
format
);
}
}
FMT_VARIADIC_VOID
(
write
,
BasicCStringRef
<
Char
>
)
FMT_VARIADIC_VOID
(
write
,
BasicCStringRef
<
Char
>
)
BasicWriter
&
operator
<<
(
int
value
)
BasicWriter
&
operator
<<
(
int
value
)
{
{
write_decimal
(
value
);
write_decimal
(
value
);
return
*
this
;
return
*
this
;
}
}
BasicWriter
&
operator
<<
(
unsigned
value
)
BasicWriter
&
operator
<<
(
unsigned
value
)
{
{
return
*
this
<<
IntFormatSpec
<
unsigned
>
(
value
);
return
*
this
<<
IntFormatSpec
<
unsigned
>
(
value
);
}
}
BasicWriter
&
operator
<<
(
long
value
)
BasicWriter
&
operator
<<
(
long
value
)
{
{
write_decimal
(
value
);
write_decimal
(
value
);
return
*
this
;
return
*
this
;
}
}
BasicWriter
&
operator
<<
(
unsigned
long
value
)
BasicWriter
&
operator
<<
(
unsigned
long
value
)
{
{
return
*
this
<<
IntFormatSpec
<
unsigned
long
>
(
value
);
return
*
this
<<
IntFormatSpec
<
unsigned
long
>
(
value
);
}
}
BasicWriter
&
operator
<<
(
LongLong
value
)
BasicWriter
&
operator
<<
(
LongLong
value
)
{
{
write_decimal
(
value
);
write_decimal
(
value
);
return
*
this
;
return
*
this
;
}
}
...
@@ -2926,13 +2541,11 @@ public:
...
@@ -2926,13 +2541,11 @@ public:
Formats *value* and writes it to the stream.
Formats *value* and writes it to the stream.
\endrst
\endrst
*/
*/
BasicWriter
&
operator
<<
(
ULongLong
value
)
BasicWriter
&
operator
<<
(
ULongLong
value
)
{
{
return
*
this
<<
IntFormatSpec
<
ULongLong
>
(
value
);
return
*
this
<<
IntFormatSpec
<
ULongLong
>
(
value
);
}
}
BasicWriter
&
operator
<<
(
double
value
)
BasicWriter
&
operator
<<
(
double
value
)
{
{
write_double
(
value
,
FormatSpec
());
write_double
(
value
,
FormatSpec
());
return
*
this
;
return
*
this
;
}
}
...
@@ -2943,8 +2556,7 @@ public:
...
@@ -2943,8 +2556,7 @@ public:
(``'g'``) and writes it to the stream.
(``'g'``) and writes it to the stream.
\endrst
\endrst
*/
*/
BasicWriter
&
operator
<<
(
long
double
value
)
BasicWriter
&
operator
<<
(
long
double
value
)
{
{
write_double
(
value
,
FormatSpec
());
write_double
(
value
,
FormatSpec
());
return
*
this
;
return
*
this
;
}
}
...
@@ -2952,15 +2564,13 @@ public:
...
@@ -2952,15 +2564,13 @@ public:
/**
/**
Writes a character to the stream.
Writes a character to the stream.
*/
*/
BasicWriter
&
operator
<<
(
char
value
)
BasicWriter
&
operator
<<
(
char
value
)
{
{
buffer_
.
push_back
(
value
);
buffer_
.
push_back
(
value
);
return
*
this
;
return
*
this
;
}
}
BasicWriter
&
operator
<<
(
BasicWriter
&
operator
<<
(
typename
internal
::
WCharHelper
<
wchar_t
,
Char
>::
Supported
value
)
typename
internal
::
WCharHelper
<
wchar_t
,
Char
>::
Supported
value
)
{
{
buffer_
.
push_back
(
value
);
buffer_
.
push_back
(
value
);
return
*
this
;
return
*
this
;
}
}
...
@@ -2970,32 +2580,28 @@ public:
...
@@ -2970,32 +2580,28 @@ public:
Writes *value* to the stream.
Writes *value* to the stream.
\endrst
\endrst
*/
*/
BasicWriter
&
operator
<<
(
fmt
::
BasicStringRef
<
Char
>
value
)
BasicWriter
&
operator
<<
(
fmt
::
BasicStringRef
<
Char
>
value
)
{
{
const
Char
*
str
=
value
.
data
();
const
Char
*
str
=
value
.
data
();
buffer_
.
append
(
str
,
str
+
value
.
size
());
buffer_
.
append
(
str
,
str
+
value
.
size
());
return
*
this
;
return
*
this
;
}
}
BasicWriter
&
operator
<<
(
BasicWriter
&
operator
<<
(
typename
internal
::
WCharHelper
<
StringRef
,
Char
>::
Supported
value
)
typename
internal
::
WCharHelper
<
StringRef
,
Char
>::
Supported
value
)
{
{
const
char
*
str
=
value
.
data
();
const
char
*
str
=
value
.
data
();
buffer_
.
append
(
str
,
str
+
value
.
size
());
buffer_
.
append
(
str
,
str
+
value
.
size
());
return
*
this
;
return
*
this
;
}
}
template
<
typename
T
,
typename
Spec
,
typename
FillChar
>
template
<
typename
T
,
typename
Spec
,
typename
FillChar
>
BasicWriter
&
operator
<<
(
IntFormatSpec
<
T
,
Spec
,
FillChar
>
spec
)
BasicWriter
&
operator
<<
(
IntFormatSpec
<
T
,
Spec
,
FillChar
>
spec
)
{
{
internal
::
CharTraits
<
Char
>::
convert
(
FillChar
());
internal
::
CharTraits
<
Char
>::
convert
(
FillChar
());
write_int
(
spec
.
value
(),
spec
);
write_int
(
spec
.
value
(),
spec
);
return
*
this
;
return
*
this
;
}
}
template
<
typename
StrChar
>
template
<
typename
StrChar
>
BasicWriter
&
operator
<<
(
const
StrFormatSpec
<
StrChar
>
&
spec
)
BasicWriter
&
operator
<<
(
const
StrFormatSpec
<
StrChar
>
&
spec
)
{
{
const
StrChar
*
s
=
spec
.
str
();
const
StrChar
*
s
=
spec
.
str
();
write_str
(
s
,
std
::
char_traits
<
Char
>::
length
(
s
),
spec
);
write_str
(
s
,
std
::
char_traits
<
Char
>::
length
(
s
),
spec
);
return
*
this
;
return
*
this
;
...
@@ -3009,29 +2615,20 @@ public:
...
@@ -3009,29 +2615,20 @@ public:
template
<
typename
Char
>
template
<
typename
Char
>
template
<
typename
StrChar
>
template
<
typename
StrChar
>
typename
BasicWriter
<
Char
>::
CharPtr
BasicWriter
<
Char
>::
write_str
(
typename
BasicWriter
<
Char
>::
CharPtr
BasicWriter
<
Char
>::
write_str
(
const
StrChar
*
s
,
std
::
size_t
size
,
const
AlignSpec
&
spec
)
const
StrChar
*
s
,
std
::
size_t
size
,
const
AlignSpec
&
spec
)
{
{
CharPtr
out
=
CharPtr
();
CharPtr
out
=
CharPtr
();
if
(
spec
.
width
()
>
size
)
if
(
spec
.
width
()
>
size
)
{
{
out
=
grow_buffer
(
spec
.
width
());
out
=
grow_buffer
(
spec
.
width
());
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec
.
fill
());
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec
.
fill
());
if
(
spec
.
align
()
==
ALIGN_RIGHT
)
if
(
spec
.
align
()
==
ALIGN_RIGHT
)
{
{
std
::
uninitialized_fill_n
(
out
,
spec
.
width
()
-
size
,
fill
);
std
::
uninitialized_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
::
uninitialized_fill_n
(
out
+
size
,
spec
.
width
()
-
size
,
fill
);
std
::
uninitialized_fill_n
(
out
+
size
,
spec
.
width
()
-
size
,
fill
);
}
}
}
}
else
{
else
{
out
=
grow_buffer
(
size
);
out
=
grow_buffer
(
size
);
}
}
std
::
uninitialized_copy
(
s
,
s
+
size
,
out
);
std
::
uninitialized_copy
(
s
,
s
+
size
,
out
);
...
@@ -3041,18 +2638,15 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
...
@@ -3041,18 +2638,15 @@ typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str(
template
<
typename
Char
>
template
<
typename
Char
>
template
<
typename
StrChar
>
template
<
typename
StrChar
>
void
BasicWriter
<
Char
>::
write_str
(
void
BasicWriter
<
Char
>::
write_str
(
const
internal
::
Arg
::
StringValue
<
StrChar
>
&
s
,
const
FormatSpec
&
spec
)
const
internal
::
Arg
::
StringValue
<
StrChar
>
&
s
,
const
FormatSpec
&
spec
)
{
{
// Check if StrChar is convertible to Char.
// Check if StrChar is convertible to Char.
internal
::
CharTraits
<
Char
>::
convert
(
StrChar
());
internal
::
CharTraits
<
Char
>::
convert
(
StrChar
());
if
(
spec
.
type_
&&
spec
.
type_
!=
's'
)
if
(
spec
.
type_
&&
spec
.
type_
!=
's'
)
internal
::
report_unknown_type
(
spec
.
type_
,
"string"
);
internal
::
report_unknown_type
(
spec
.
type_
,
"string"
);
const
StrChar
*
str_value
=
s
.
value
;
const
StrChar
*
str_value
=
s
.
value
;
std
::
size_t
str_size
=
s
.
size
;
std
::
size_t
str_size
=
s
.
size
;
if
(
str_size
==
0
)
if
(
str_size
==
0
)
{
{
if
(
!
str_value
)
{
if
(
!
str_value
)
{
FMT_THROW
(
FormatError
(
"string pointer is null"
));
FMT_THROW
(
FormatError
(
"string pointer is null"
));
}
}
}
}
...
@@ -3064,10 +2658,9 @@ void BasicWriter<Char>::write_str(
...
@@ -3064,10 +2658,9 @@ void 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
;
std
::
size_t
left_padding
=
padding
/
2
;
std
::
size_t
left_padding
=
padding
/
2
;
Char
fill_char
=
internal
::
CharTraits
<
Char
>::
cast
(
fill
);
Char
fill_char
=
internal
::
CharTraits
<
Char
>::
cast
(
fill
);
...
@@ -3082,15 +2675,13 @@ BasicWriter<Char>::fill_padding(
...
@@ -3082,15 +2675,13 @@ 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
();
Alignment
align
=
spec
.
align
();
Alignment
align
=
spec
.
align
();
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec
.
fill
());
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec
.
fill
());
if
(
spec
.
precision
()
>
static_cast
<
int
>
(
num_digits
))
if
(
spec
.
precision
()
>
static_cast
<
int
>
(
num_digits
))
{
{
// Octal prefix '0' is counted as a digit, so ignore it if precision
// Octal prefix '0' is counted as a digit, so ignore it if precision
// is specified.
// is specified.
if
(
prefix_size
>
0
&&
prefix
[
prefix_size
-
1
]
==
'0'
)
if
(
prefix_size
>
0
&&
prefix
[
prefix_size
-
1
]
==
'0'
)
...
@@ -3102,53 +2693,41 @@ BasicWriter<Char>::prepare_int_buffer(
...
@@ -3102,53 +2693,41 @@ BasicWriter<Char>::prepare_int_buffer(
return
prepare_int_buffer
(
num_digits
,
subspec
,
prefix
,
prefix_size
);
return
prepare_int_buffer
(
num_digits
,
subspec
,
prefix
,
prefix_size
);
buffer_
.
reserve
(
width
);
buffer_
.
reserve
(
width
);
unsigned
fill_size
=
width
-
number_size
;
unsigned
fill_size
=
width
-
number_size
;
if
(
align
!=
ALIGN_LEFT
)
if
(
align
!=
ALIGN_LEFT
)
{
{
CharPtr
p
=
grow_buffer
(
fill_size
);
CharPtr
p
=
grow_buffer
(
fill_size
);
std
::
uninitialized_fill
(
p
,
p
+
fill_size
,
fill
);
std
::
uninitialized_fill
(
p
,
p
+
fill_size
,
fill
);
}
}
CharPtr
result
=
prepare_int_buffer
(
CharPtr
result
=
prepare_int_buffer
(
num_digits
,
subspec
,
prefix
,
prefix_size
);
num_digits
,
subspec
,
prefix
,
prefix_size
);
if
(
align
==
ALIGN_LEFT
)
if
(
align
==
ALIGN_LEFT
)
{
{
CharPtr
p
=
grow_buffer
(
fill_size
);
CharPtr
p
=
grow_buffer
(
fill_size
);
std
::
uninitialized_fill
(
p
,
p
+
fill_size
,
fill
);
std
::
uninitialized_fill
(
p
,
p
+
fill_size
,
fill
);
}
}
return
result
;
return
result
;
}
}
unsigned
size
=
prefix_size
+
num_digits
;
unsigned
size
=
prefix_size
+
num_digits
;
if
(
width
<=
size
)
if
(
width
<=
size
)
{
{
CharPtr
p
=
grow_buffer
(
size
);
CharPtr
p
=
grow_buffer
(
size
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
return
p
+
size
-
1
;
return
p
+
size
-
1
;
}
}
CharPtr
p
=
grow_buffer
(
width
);
CharPtr
p
=
grow_buffer
(
width
);
CharPtr
end
=
p
+
width
;
CharPtr
end
=
p
+
width
;
if
(
align
==
ALIGN_LEFT
)
if
(
align
==
ALIGN_LEFT
)
{
{
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
p
+=
size
;
p
+=
size
;
std
::
uninitialized_fill
(
p
,
end
,
fill
);
std
::
uninitialized_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
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
p
+=
size
;
p
+=
size
;
}
}
else
{
else
if
(
align
==
ALIGN_NUMERIC
)
{
{
if
(
prefix_size
!=
0
)
{
if
(
align
==
ALIGN_NUMERIC
)
{
if
(
prefix_size
!=
0
)
{
p
=
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
p
=
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
p
);
size
-=
prefix_size
;
size
-=
prefix_size
;
}
}
}
}
else
{
else
{
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
end
-
size
);
std
::
uninitialized_copy
(
prefix
,
prefix
+
prefix_size
,
end
-
size
);
}
}
std
::
uninitialized_fill
(
p
,
end
-
size
,
fill
);
std
::
uninitialized_fill
(
p
,
end
-
size
,
fill
);
...
@@ -3159,108 +2738,84 @@ BasicWriter<Char>::prepare_int_buffer(
...
@@ -3159,108 +2738,84 @@ BasicWriter<Char>::prepare_int_buffer(
template
<
typename
Char
>
template
<
typename
Char
>
template
<
typename
T
,
typename
Spec
>
template
<
typename
T
,
typename
Spec
>
void
BasicWriter
<
Char
>::
write_int
(
T
value
,
Spec
spec
)
void
BasicWriter
<
Char
>::
write_int
(
T
value
,
Spec
spec
)
{
{
unsigned
prefix_size
=
0
;
unsigned
prefix_size
=
0
;
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
UnsignedType
abs_value
=
static_cast
<
UnsignedType
>
(
value
);
UnsignedType
abs_value
=
static_cast
<
UnsignedType
>
(
value
);
char
prefix
[
4
]
=
""
;
char
prefix
[
4
]
=
""
;
if
(
internal
::
is_negative
(
value
))
if
(
internal
::
is_negative
(
value
))
{
{
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
'd'
:
{
case
0
:
case
'd'
:
{
unsigned
num_digits
=
internal
::
count_digits
(
abs_value
);
unsigned
num_digits
=
internal
::
count_digits
(
abs_value
);
CharPtr
p
=
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
)
+
1
;
CharPtr
p
=
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
)
+
1
;
internal
::
format_decimal
(
get
(
p
),
abs_value
,
0
);
internal
::
format_decimal
(
get
(
p
),
abs_value
,
0
);
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'
;
prefix
[
prefix_size
++
]
=
spec
.
type
();
prefix
[
prefix_size
++
]
=
spec
.
type
();
}
}
unsigned
num_digits
=
0
;
unsigned
num_digits
=
0
;
do
do
{
{
++
num_digits
;
++
num_digits
;
}
}
while
((
n
>>=
4
)
!=
0
);
while
((
n
>>=
4
)
!=
0
);
Char
*
p
=
get
(
prepare_int_buffer
(
Char
*
p
=
get
(
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
));
num_digits
,
spec
,
prefix
,
prefix_size
));
n
=
abs_value
;
n
=
abs_value
;
const
char
*
digits
=
spec
.
type
()
==
'x'
?
const
char
*
digits
=
spec
.
type
()
==
'x'
?
"0123456789abcdef"
:
"0123456789ABCDEF"
;
"0123456789abcdef"
:
"0123456789ABCDEF"
;
do
do
{
{
*
p
--
=
digits
[
n
&
0xf
];
*
p
--
=
digits
[
n
&
0xf
];
}
}
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'
;
prefix
[
prefix_size
++
]
=
spec
.
type
();
prefix
[
prefix_size
++
]
=
spec
.
type
();
}
}
unsigned
num_digits
=
0
;
unsigned
num_digits
=
0
;
do
do
{
{
++
num_digits
;
++
num_digits
;
}
}
while
((
n
>>=
1
)
!=
0
);
while
((
n
>>=
1
)
!=
0
);
Char
*
p
=
get
(
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
));
Char
*
p
=
get
(
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
));
n
=
abs_value
;
n
=
abs_value
;
do
do
{
{
*
p
--
=
static_cast
<
Char
>
(
'0'
+
(
n
&
1
));
*
p
--
=
static_cast
<
Char
>
(
'0'
+
(
n
&
1
));
}
}
while
((
n
>>=
1
)
!=
0
);
while
((
n
>>=
1
)
!=
0
);
break
;
break
;
}
}
case
'o'
:
case
'o'
:
{
{
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'
;
unsigned
num_digits
=
0
;
unsigned
num_digits
=
0
;
do
do
{
{
++
num_digits
;
++
num_digits
;
}
}
while
((
n
>>=
3
)
!=
0
);
while
((
n
>>=
3
)
!=
0
);
Char
*
p
=
get
(
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
));
Char
*
p
=
get
(
prepare_int_buffer
(
num_digits
,
spec
,
prefix
,
prefix_size
));
n
=
abs_value
;
n
=
abs_value
;
do
do
{
{
*
p
--
=
static_cast
<
Char
>
(
'0'
+
(
n
&
7
));
*
p
--
=
static_cast
<
Char
>
(
'0'
+
(
n
&
7
));
}
}
while
((
n
>>=
3
)
!=
0
);
while
((
n
>>=
3
)
!=
0
);
break
;
break
;
}
}
case
'n'
:
case
'n'
:
{
{
unsigned
num_digits
=
internal
::
count_digits
(
abs_value
);
unsigned
num_digits
=
internal
::
count_digits
(
abs_value
);
fmt
::
StringRef
sep
=
internal
::
thousands_sep
(
std
::
localeconv
());
fmt
::
StringRef
sep
=
""
;
#ifndef ANDROID
sep
=
internal
::
thousands_sep
(
std
::
localeconv
());
#endif
unsigned
size
=
static_cast
<
unsigned
>
(
unsigned
size
=
static_cast
<
unsigned
>
(
num_digits
+
sep
.
size
()
*
((
num_digits
-
1
)
/
3
));
num_digits
+
sep
.
size
()
*
((
num_digits
-
1
)
/
3
));
CharPtr
p
=
prepare_int_buffer
(
size
,
spec
,
prefix
,
prefix_size
)
+
1
;
CharPtr
p
=
prepare_int_buffer
(
size
,
spec
,
prefix
,
prefix_size
)
+
1
;
...
@@ -3276,20 +2831,15 @@ void BasicWriter<Char>::write_int(T value, Spec spec)
...
@@ -3276,20 +2831,15 @@ void BasicWriter<Char>::write_int(T value, Spec spec)
template
<
typename
Char
>
template
<
typename
Char
>
template
<
typename
T
>
template
<
typename
T
>
void
BasicWriter
<
Char
>::
write_double
(
T
value
,
const
FormatSpec
&
spec
)
void
BasicWriter
<
Char
>::
write_double
(
T
value
,
const
FormatSpec
&
spec
)
{
{
// Check type.
// Check type.
char
type
=
spec
.
type
();
char
type
=
spec
.
type
();
bool
upper
=
false
;
bool
upper
=
false
;
switch
(
type
)
switch
(
type
)
{
{
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'
:
#if FMT_MSC_VER
#if FMT_MSC_VER
...
@@ -3297,9 +2847,7 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3297,9 +2847,7 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
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
:
...
@@ -3310,24 +2858,19 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3310,24 +2858,19 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
char
sign
=
0
;
char
sign
=
0
;
// Use isnegative instead of value < 0 because the latter is always
// Use isnegative instead of value < 0 because the latter is always
// false for NaN.
// false for NaN.
if
(
internal
::
FPUtil
::
isnegative
(
static_cast
<
double
>
(
value
)))
if
(
internal
::
FPUtil
::
isnegative
(
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
)
?
'+'
:
' '
;
}
}
if
(
internal
::
FPUtil
::
isnotanumber
(
value
))
if
(
internal
::
FPUtil
::
isnotanumber
(
value
))
{
{
// Format NaN ourselves because sprintf's output is not consistent
// Format NaN ourselves because sprintf's output is not consistent
// across platforms.
// across platforms.
std
::
size_t
nan_size
=
4
;
std
::
size_t
nan_size
=
4
;
const
char
*
nan
=
upper
?
" NAN"
:
" nan"
;
const
char
*
nan
=
upper
?
" NAN"
:
" nan"
;
if
(
!
sign
)
if
(
!
sign
)
{
{
--
nan_size
;
--
nan_size
;
++
nan
;
++
nan
;
}
}
...
@@ -3337,14 +2880,12 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3337,14 +2880,12 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
return
;
return
;
}
}
if
(
internal
::
FPUtil
::
isinfinity
(
value
))
if
(
internal
::
FPUtil
::
isinfinity
(
value
))
{
{
// Format infinity ourselves because sprintf's output is not consistent
// Format infinity ourselves because sprintf's output is not consistent
// across platforms.
// across platforms.
std
::
size_t
inf_size
=
4
;
std
::
size_t
inf_size
=
4
;
const
char
*
inf
=
upper
?
" INF"
:
" inf"
;
const
char
*
inf
=
upper
?
" INF"
:
" inf"
;
if
(
!
sign
)
if
(
!
sign
)
{
{
--
inf_size
;
--
inf_size
;
++
inf
;
++
inf
;
}
}
...
@@ -3356,8 +2897,7 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3356,8 +2897,7 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
std
::
size_t
offset
=
buffer_
.
size
();
std
::
size_t
offset
=
buffer_
.
size
();
unsigned
width
=
spec
.
width
();
unsigned
width
=
spec
.
width
();
if
(
sign
)
if
(
sign
)
{
{
buffer_
.
reserve
(
buffer_
.
size
()
+
(
width
>
1u
?
width
:
1u
));
buffer_
.
reserve
(
buffer_
.
size
()
+
(
width
>
1u
?
width
:
1u
));
if
(
width
>
0
)
if
(
width
>
0
)
--
width
;
--
width
;
...
@@ -3372,19 +2912,15 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3372,19 +2912,15 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
unsigned
width_for_sprintf
=
width
;
unsigned
width_for_sprintf
=
width
;
if
(
spec
.
flag
(
HASH_FLAG
))
if
(
spec
.
flag
(
HASH_FLAG
))
*
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
)
*
format_ptr
++
=
'*'
;
*
format_ptr
++
=
'*'
;
}
}
if
(
spec
.
precision
()
>=
0
)
if
(
spec
.
precision
()
>=
0
)
{
{
*
format_ptr
++
=
'.'
;
*
format_ptr
++
=
'.'
;
*
format_ptr
++
=
'*'
;
*
format_ptr
++
=
'*'
;
}
}
...
@@ -3397,15 +2933,13 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3397,15 +2933,13 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec
.
fill
());
Char
fill
=
internal
::
CharTraits
<
Char
>::
cast
(
spec
.
fill
());
unsigned
n
=
0
;
unsigned
n
=
0
;
Char
*
start
=
0
;
Char
*
start
=
0
;
for
(;;)
for
(;;)
{
{
std
::
size_t
buffer_size
=
buffer_
.
capacity
()
-
offset
;
std
::
size_t
buffer_size
=
buffer_
.
capacity
()
-
offset
;
#if FMT_MSC_VER
#if FMT_MSC_VER
// MSVC's vsnprintf_s doesn't work with zero size, so reserve
// MSVC's vsnprintf_s doesn't work with zero size, so reserve
// space for at least one extra character to make the size non-zero.
// space for at least one extra character to make the size non-zero.
// Note that the buffer's capacity will increase by more than 1.
// Note that the buffer's capacity will increase by more than 1.
if
(
buffer_size
==
0
)
if
(
buffer_size
==
0
)
{
{
buffer_
.
reserve
(
offset
+
1
);
buffer_
.
reserve
(
offset
+
1
);
buffer_size
=
buffer_
.
capacity
()
-
offset
;
buffer_size
=
buffer_
.
capacity
()
-
offset
;
}
}
...
@@ -3413,44 +2947,35 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3413,44 +2947,35 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
start
=
&
buffer_
[
offset
];
start
=
&
buffer_
[
offset
];
int
result
=
internal
::
CharTraits
<
Char
>::
format_float
(
int
result
=
internal
::
CharTraits
<
Char
>::
format_float
(
start
,
buffer_size
,
format
,
width_for_sprintf
,
spec
.
precision
(),
value
);
start
,
buffer_size
,
format
,
width_for_sprintf
,
spec
.
precision
(),
value
);
if
(
result
>=
0
)
if
(
result
>=
0
)
{
{
n
=
internal
::
to_unsigned
(
result
);
n
=
internal
::
to_unsigned
(
result
);
if
(
offset
+
n
<
buffer_
.
capacity
())
if
(
offset
+
n
<
buffer_
.
capacity
())
break
;
// The buffer is large enough - continue with formatting.
break
;
// The buffer is large enough - continue with formatting.
buffer_
.
reserve
(
offset
+
n
+
1
);
buffer_
.
reserve
(
offset
+
n
+
1
);
}
}
else
{
else
{
// If result is negative we ask to increase the capacity by at least 1,
// If result is negative we ask to increase the capacity by at least 1,
// but as std::vector, the buffer grows exponentially.
// but as std::vector, the buffer grows exponentially.
buffer_
.
reserve
(
buffer_
.
capacity
()
+
1
);
buffer_
.
reserve
(
buffer_
.
capacity
()
+
1
);
}
}
}
}
if
(
sign
)
if
(
sign
)
{
{
if
((
spec
.
align
()
!=
ALIGN_RIGHT
&&
spec
.
align
()
!=
ALIGN_DEFAULT
)
||
if
((
spec
.
align
()
!=
ALIGN_RIGHT
&&
spec
.
align
()
!=
ALIGN_DEFAULT
)
||
*
start
!=
' '
)
*
start
!=
' '
)
{
{
*
(
start
-
1
)
=
sign
;
*
(
start
-
1
)
=
sign
;
sign
=
0
;
sign
=
0
;
}
}
else
{
else
{
*
(
start
-
1
)
=
fill
;
*
(
start
-
1
)
=
fill
;
}
}
++
n
;
++
n
;
}
}
if
(
spec
.
align
()
==
ALIGN_CENTER
&&
spec
.
width
()
>
n
)
if
(
spec
.
align
()
==
ALIGN_CENTER
&&
spec
.
width
()
>
n
)
{
{
width
=
spec
.
width
();
width
=
spec
.
width
();
CharPtr
p
=
grow_buffer
(
width
);
CharPtr
p
=
grow_buffer
(
width
);
std
::
memmove
(
get
(
p
)
+
(
width
-
n
)
/
2
,
get
(
p
),
n
*
sizeof
(
Char
));
std
::
memmove
(
get
(
p
)
+
(
width
-
n
)
/
2
,
get
(
p
),
n
*
sizeof
(
Char
));
fill_padding
(
p
,
spec
.
width
(),
n
,
fill
);
fill_padding
(
p
,
spec
.
width
(),
n
,
fill
);
return
;
return
;
}
}
if
(
spec
.
fill
()
!=
' '
||
sign
)
if
(
spec
.
fill
()
!=
' '
||
sign
)
{
{
while
(
*
start
==
' '
)
while
(
*
start
==
' '
)
*
start
++
=
fill
;
*
start
++
=
fill
;
if
(
sign
)
if
(
sign
)
...
@@ -3494,12 +3019,11 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
...
@@ -3494,12 +3019,11 @@ void BasicWriter<Char>::write_double(T value, const FormatSpec &spec)
\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
)
{}
...
@@ -3511,8 +3035,7 @@ public:
...
@@ -3511,8 +3035,7 @@ public:
\endrst
\endrst
*/
*/
BasicMemoryWriter
(
BasicMemoryWriter
&&
other
)
BasicMemoryWriter
(
BasicMemoryWriter
&&
other
)
:
BasicWriter
<
Char
>
(
buffer_
),
buffer_
(
std
::
move
(
other
.
buffer_
))
:
BasicWriter
<
Char
>
(
buffer_
),
buffer_
(
std
::
move
(
other
.
buffer_
))
{
{
}
}
/**
/**
...
@@ -3520,8 +3043,7 @@ public:
...
@@ -3520,8 +3043,7 @@ public:
Moves the content of the other ``BasicMemoryWriter`` object to this one.
Moves the content of the other ``BasicMemoryWriter`` object to this one.
\endrst
\endrst
*/
*/
BasicMemoryWriter
&
operator
=
(
BasicMemoryWriter
&&
other
)
BasicMemoryWriter
&
operator
=
(
BasicMemoryWriter
&&
other
)
{
{
buffer_
=
std
::
move
(
other
.
buffer_
);
buffer_
=
std
::
move
(
other
.
buffer_
);
return
*
this
;
return
*
this
;
}
}
...
@@ -3552,12 +3074,11 @@ typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
...
@@ -3552,12 +3074,11 @@ typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
\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
...
@@ -3589,12 +3110,11 @@ FMT_API void report_system_error(int error_code,
...
@@ -3589,12 +3110,11 @@ FMT_API void report_system_error(int error_code,
#if FMT_USE_WINDOWS_H
#if FMT_USE_WINDOWS_H
/** A Windows error. */
/** A Windows error. */
class
WindowsError
:
public
SystemError
class
WindowsError
:
public
SystemError
{
{
private
:
private
:
FMT_API
void
init
(
int
error_code
,
CStringRef
format_str
,
ArgList
args
);
FMT_API
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
...
@@ -3623,8 +3143,7 @@ public:
...
@@ -3623,8 +3143,7 @@ public:
}
}
\endrst
\endrst
*/
*/
WindowsError
(
int
error_code
,
CStringRef
message
)
WindowsError
(
int
error_code
,
CStringRef
message
)
{
{
init
(
error_code
,
message
,
ArgList
());
init
(
error_code
,
message
,
ArgList
());
}
}
FMT_VARIADIC_CTOR
(
WindowsError
,
init
,
int
,
CStringRef
)
FMT_VARIADIC_CTOR
(
WindowsError
,
init
,
int
,
CStringRef
)
...
@@ -3656,15 +3175,13 @@ FMT_API void print_colored(Color c, CStringRef format, ArgList args);
...
@@ -3656,15 +3175,13 @@ FMT_API void print_colored(Color c, CStringRef format, ArgList args);
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
;
w
.
write
(
format_str
,
args
);
w
.
write
(
format_str
,
args
);
return
w
.
str
();
return
w
.
str
();
}
}
inline
std
::
wstring
format
(
WCStringRef
format_str
,
ArgList
args
)
inline
std
::
wstring
format
(
WCStringRef
format_str
,
ArgList
args
)
{
{
WMemoryWriter
w
;
WMemoryWriter
w
;
w
.
write
(
format_str
,
args
);
w
.
write
(
format_str
,
args
);
return
w
.
str
();
return
w
.
str
();
...
@@ -3695,9 +3212,8 @@ FMT_API void print(CStringRef format_str, ArgList args);
...
@@ -3695,9 +3212,8 @@ FMT_API void print(CStringRef format_str, ArgList 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
};
...
@@ -3705,11 +3221,9 @@ private:
...
@@ -3705,11 +3221,9 @@ private:
char
*
str_
;
char
*
str_
;
// Formats value in reverse and returns the number of digits.
// Formats value in reverse and returns the number of digits.
char
*
format_decimal
(
ULongLong
value
)
char
*
format_decimal
(
ULongLong
value
)
{
{
char
*
buffer_end
=
buffer_
+
BUFFER_SIZE
-
1
;
char
*
buffer_end
=
buffer_
+
BUFFER_SIZE
-
1
;
while
(
value
>=
100
)
while
(
value
>=
100
)
{
{
// Integer division is slow so do it for a group of two digits instead
// Integer division is slow so do it for a group of two digits instead
// of for every digit. The idea comes from the talk by Alexandrescu
// of for every digit. The idea comes from the talk by Alexandrescu
// "Three Optimization Tips for C++". See speed-test for a comparison.
// "Three Optimization Tips for C++". See speed-test for a comparison.
...
@@ -3718,8 +3232,7 @@ private:
...
@@ -3718,8 +3232,7 @@ private:
*--
buffer_end
=
internal
::
Data
::
DIGITS
[
index
+
1
];
*--
buffer_end
=
internal
::
Data
::
DIGITS
[
index
+
1
];
*--
buffer_end
=
internal
::
Data
::
DIGITS
[
index
];
*--
buffer_end
=
internal
::
Data
::
DIGITS
[
index
];
}
}
if
(
value
<
10
)
if
(
value
<
10
)
{
{
*--
buffer_end
=
static_cast
<
char
>
(
'0'
+
value
);
*--
buffer_end
=
static_cast
<
char
>
(
'0'
+
value
);
return
buffer_end
;
return
buffer_end
;
}
}
...
@@ -3729,8 +3242,7 @@ private:
...
@@ -3729,8 +3242,7 @@ private:
return
buffer_end
;
return
buffer_end
;
}
}
void
FormatSigned
(
LongLong
value
)
void
FormatSigned
(
LongLong
value
)
{
{
ULongLong
abs_value
=
static_cast
<
ULongLong
>
(
value
);
ULongLong
abs_value
=
static_cast
<
ULongLong
>
(
value
);
bool
negative
=
value
<
0
;
bool
negative
=
value
<
0
;
if
(
negative
)
if
(
negative
)
...
@@ -3740,26 +3252,16 @@ private:
...
@@ -3740,26 +3252,16 @@ private:
*--
str_
=
'-'
;
*--
str_
=
'-'
;
}
}
public
:
public
:
explicit
FormatInt
(
int
value
)
explicit
FormatInt
(
int
value
)
{
FormatSigned
(
value
);
}
{
explicit
FormatInt
(
long
value
)
{
FormatSigned
(
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
))
{}
/** 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
internal
::
to_unsigned
(
buffer_
-
str_
+
BUFFER_SIZE
-
1
);
return
internal
::
to_unsigned
(
buffer_
-
str_
+
BUFFER_SIZE
-
1
);
}
}
...
@@ -3767,17 +3269,13 @@ public:
...
@@ -3767,17 +3269,13 @@ public:
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
character appended.
character appended.
*/
*/
const
char
*
c_str
()
const
const
char
*
c_str
()
const
{
{
buffer_
[
BUFFER_SIZE
-
1
]
=
'\0'
;
buffer_
[
BUFFER_SIZE
-
1
]
=
'\0'
;
return
str_
;
return
str_
;
}
}
...
@@ -3787,29 +3285,22 @@ public:
...
@@ -3787,29 +3285,22 @@ 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
// a pointer to the end of the formatted string. This function doesn't
// a pointer to the end of the formatted string. This function doesn't
// write a terminating null character.
// write a terminating null character.
template
<
typename
T
>
template
<
typename
T
>
inline
void
format_decimal
(
char
*&
buffer
,
T
value
)
inline
void
format_decimal
(
char
*&
buffer
,
T
value
)
{
{
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
MainType
;
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
MainType
;
MainType
abs_value
=
static_cast
<
MainType
>
(
value
);
MainType
abs_value
=
static_cast
<
MainType
>
(
value
);
if
(
internal
::
is_negative
(
value
))
if
(
internal
::
is_negative
(
value
))
{
{
*
buffer
++
=
'-'
;
*
buffer
++
=
'-'
;
abs_value
=
0
-
abs_value
;
abs_value
=
0
-
abs_value
;
}
}
if
(
abs_value
<
100
)
if
(
abs_value
<
100
)
{
{
if
(
abs_value
<
10
)
{
if
(
abs_value
<
10
)
{
*
buffer
++
=
static_cast
<
char
>
(
'0'
+
abs_value
);
*
buffer
++
=
static_cast
<
char
>
(
'0'
+
abs_value
);
return
;
return
;
}
}
...
@@ -3834,14 +3325,12 @@ inline void format_decimal(char *&buffer, T value)
...
@@ -3834,14 +3325,12 @@ inline void format_decimal(char *&buffer, T value)
\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
);
}
}
template
<
typename
T
>
template
<
typename
T
>
inline
internal
::
NamedArg
<
wchar_t
>
arg
(
WStringRef
name
,
const
T
&
arg
)
inline
internal
::
NamedArg
<
wchar_t
>
arg
(
WStringRef
name
,
const
T
&
arg
)
{
{
return
internal
::
NamedArg
<
wchar_t
>
(
name
,
arg
);
return
internal
::
NamedArg
<
wchar_t
>
(
name
,
arg
);
}
}
...
@@ -3871,7 +3360,6 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
...
@@ -3871,7 +3360,6 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define FMT_CONCAT(a, b) a##b
#define FMT_FOR_EACH_(N, f, ...) \
#define FMT_FOR_EACH_(N, f, ...) \
FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
#define FMT_FOR_EACH(f, ...) \
#define FMT_FOR_EACH(f, ...) \
...
@@ -3980,41 +3468,34 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
...
@@ -3980,41 +3468,34 @@ void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED;
#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__)
namespace
fmt
namespace
fmt
{
{
FMT_VARIADIC
(
std
::
string
,
format
,
CStringRef
)
FMT_VARIADIC
(
std
::
string
,
format
,
CStringRef
)
FMT_VARIADIC_W
(
std
::
wstring
,
format
,
WCStringRef
)
FMT_VARIADIC_W
(
std
::
wstring
,
format
,
WCStringRef
)
FMT_VARIADIC
(
void
,
print
,
CStringRef
)
FMT_VARIADIC
(
void
,
print
,
CStringRef
)
FMT_VARIADIC
(
void
,
print
,
std
::
FILE
*
,
CStringRef
)
FMT_VARIADIC
(
void
,
print
,
std
::
FILE
*
,
CStringRef
)
FMT_VARIADIC
(
void
,
print_colored
,
Color
,
CStringRef
)
FMT_VARIADIC
(
void
,
print_colored
,
Color
,
CStringRef
)
namespace
internal
namespace
internal
{
{
template
<
typename
Char
>
template
<
typename
Char
>
inline
bool
is_name_start
(
Char
c
)
inline
bool
is_name_start
(
Char
c
)
{
{
return
(
'a'
<=
c
&&
c
<=
'z'
)
||
(
'A'
<=
c
&&
c
<=
'Z'
)
||
'_'
==
c
;
return
(
'a'
<=
c
&&
c
<=
'z'
)
||
(
'A'
<=
c
&&
c
<=
'Z'
)
||
'_'
==
c
;
}
}
// 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.
// This function assumes that the first character of s is a digit.
// This function assumes that the first character of s is a digit.
template
<
typename
Char
>
template
<
typename
Char
>
unsigned
parse_nonnegative_int
(
const
Char
*&
s
)
unsigned
parse_nonnegative_int
(
const
Char
*&
s
)
{
{
assert
(
'0'
<=
*
s
&&
*
s
<=
'9'
);
assert
(
'0'
<=
*
s
&&
*
s
<=
'9'
);
unsigned
value
=
0
;
unsigned
value
=
0
;
do
do
{
{
unsigned
new_value
=
value
*
10
+
(
*
s
++
-
'0'
);
unsigned
new_value
=
value
*
10
+
(
*
s
++
-
'0'
);
// Check if value wrapped around.
// Check if value wrapped around.
if
(
new_value
<
value
)
if
(
new_value
<
value
)
{
{
value
=
(
std
::
numeric_limits
<
unsigned
>::
max
)();
value
=
(
std
::
numeric_limits
<
unsigned
>::
max
)();
break
;
break
;
}
}
value
=
new_value
;
value
=
new_value
;
}
}
while
(
'0'
<=
*
s
&&
*
s
<=
'9'
);
while
(
'0'
<=
*
s
&&
*
s
<=
'9'
);
// Convert to unsigned to prevent a warning.
// Convert to unsigned to prevent a warning.
unsigned
max_int
=
(
std
::
numeric_limits
<
int
>::
max
)();
unsigned
max_int
=
(
std
::
numeric_limits
<
int
>::
max
)();
if
(
value
>
max_int
)
if
(
value
>
max_int
)
...
@@ -4022,10 +3503,8 @@ unsigned parse_nonnegative_int(const Char *&s)
...
@@ -4022,10 +3503,8 @@ unsigned parse_nonnegative_int(const Char *&s)
return
value
;
return
value
;
}
}
inline
void
require_numeric_argument
(
const
Arg
&
arg
,
char
spec
)
inline
void
require_numeric_argument
(
const
Arg
&
arg
,
char
spec
)
{
{
if
(
arg
.
type
>
Arg
::
LAST_NUMERIC_TYPE
)
{
if
(
arg
.
type
>
Arg
::
LAST_NUMERIC_TYPE
)
{
std
::
string
message
=
std
::
string
message
=
fmt
::
format
(
"format specifier '{}' requires numeric argument"
,
spec
);
fmt
::
format
(
"format specifier '{}' requires numeric argument"
,
spec
);
FMT_THROW
(
fmt
::
FormatError
(
message
));
FMT_THROW
(
fmt
::
FormatError
(
message
));
...
@@ -4033,12 +3512,10 @@ inline void require_numeric_argument(const Arg &arg, char spec)
...
@@ -4033,12 +3512,10 @@ inline void require_numeric_argument(const Arg &arg, char spec)
}
}
template
<
typename
Char
>
template
<
typename
Char
>
void
check_sign
(
const
Char
*&
s
,
const
Arg
&
arg
)
void
check_sign
(
const
Char
*&
s
,
const
Arg
&
arg
)
{
{
char
sign
=
static_cast
<
char
>
(
*
s
);
char
sign
=
static_cast
<
char
>
(
*
s
);
require_numeric_argument
(
arg
,
sign
);
require_numeric_argument
(
arg
,
sign
);
if
(
arg
.
type
==
Arg
::
UINT
||
arg
.
type
==
Arg
::
ULONG_LONG
)
if
(
arg
.
type
==
Arg
::
UINT
||
arg
.
type
==
Arg
::
ULONG_LONG
)
{
{
FMT_THROW
(
FormatError
(
fmt
::
format
(
FMT_THROW
(
FormatError
(
fmt
::
format
(
"format specifier '{}' requires signed argument"
,
sign
)));
"format specifier '{}' requires signed argument"
,
sign
)));
}
}
...
@@ -4048,10 +3525,8 @@ void check_sign(const Char *&s, const Arg &arg)
...
@@ -4048,10 +3525,8 @@ void check_sign(const Char *&s, const Arg &arg)
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
inline
internal
::
Arg
BasicFormatter
<
Char
,
AF
>::
get_arg
(
inline
internal
::
Arg
BasicFormatter
<
Char
,
AF
>::
get_arg
(
BasicStringRef
<
Char
>
arg_name
,
const
char
*&
error
)
BasicStringRef
<
Char
>
arg_name
,
const
char
*&
error
)
{
{
if
(
check_no_auto_index
(
error
))
{
if
(
check_no_auto_index
(
error
))
{
map_
.
init
(
args
());
map_
.
init
(
args
());
const
internal
::
Arg
*
arg
=
map_
.
find
(
arg_name
);
const
internal
::
Arg
*
arg
=
map_
.
find
(
arg_name
);
if
(
arg
)
if
(
arg
)
...
@@ -4062,13 +3537,11 @@ inline internal::Arg BasicFormatter<Char, AF>::get_arg(
...
@@ -4062,13 +3537,11 @@ inline internal::Arg BasicFormatter<Char, AF>::get_arg(
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
inline
internal
::
Arg
BasicFormatter
<
Char
,
AF
>::
parse_arg_index
(
const
Char
*&
s
)
inline
internal
::
Arg
BasicFormatter
<
Char
,
AF
>::
parse_arg_index
(
const
Char
*&
s
)
{
{
const
char
*
error
=
0
;
const
char
*
error
=
0
;
internal
::
Arg
arg
=
*
s
<
'0'
||
*
s
>
'9'
?
internal
::
Arg
arg
=
*
s
<
'0'
||
*
s
>
'9'
?
next_arg
(
error
)
:
get_arg
(
internal
::
parse_nonnegative_int
(
s
),
error
);
next_arg
(
error
)
:
get_arg
(
internal
::
parse_nonnegative_int
(
s
),
error
);
if
(
error
)
if
(
error
)
{
{
FMT_THROW
(
FormatError
(
FMT_THROW
(
FormatError
(
*
s
!=
'}'
&&
*
s
!=
':'
?
"invalid format string"
:
error
));
*
s
!=
'}'
&&
*
s
!=
':'
?
"invalid format string"
:
error
));
}
}
...
@@ -4076,16 +3549,13 @@ inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s)
...
@@ -4076,16 +3549,13 @@ inline internal::Arg BasicFormatter<Char, AF>::parse_arg_index(const Char *&s)
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
inline
internal
::
Arg
BasicFormatter
<
Char
,
AF
>::
parse_arg_name
(
const
Char
*&
s
)
inline
internal
::
Arg
BasicFormatter
<
Char
,
AF
>::
parse_arg_name
(
const
Char
*&
s
)
{
{
assert
(
internal
::
is_name_start
(
*
s
));
assert
(
internal
::
is_name_start
(
*
s
));
const
Char
*
start
=
s
;
const
Char
*
start
=
s
;
Char
c
;
Char
c
;
do
do
{
{
c
=
*++
s
;
c
=
*++
s
;
}
}
while
(
internal
::
is_name_start
(
c
)
||
(
'0'
<=
c
&&
c
<=
'9'
));
while
(
internal
::
is_name_start
(
c
)
||
(
'0'
<=
c
&&
c
<=
'9'
));
const
char
*
error
=
0
;
const
char
*
error
=
0
;
internal
::
Arg
arg
=
get_arg
(
BasicStringRef
<
Char
>
(
start
,
s
-
start
),
error
);
internal
::
Arg
arg
=
get_arg
(
BasicStringRef
<
Char
>
(
start
,
s
-
start
),
error
);
if
(
error
)
if
(
error
)
...
@@ -4095,28 +3565,22 @@ inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s)
...
@@ -4095,28 +3565,22 @@ inline internal::Arg BasicFormatter<Char, AF>::parse_arg_name(const Char *&s)
template
<
typename
Char
,
typename
ArgFormatter
>
template
<
typename
Char
,
typename
ArgFormatter
>
const
Char
*
BasicFormatter
<
Char
,
ArgFormatter
>::
format
(
const
Char
*
BasicFormatter
<
Char
,
ArgFormatter
>::
format
(
const
Char
*&
format_str
,
const
internal
::
Arg
&
arg
)
const
Char
*&
format_str
,
const
internal
::
Arg
&
arg
)
{
{
using
internal
::
Arg
;
using
internal
::
Arg
;
const
Char
*
s
=
format_str
;
const
Char
*
s
=
format_str
;
FormatSpec
spec
;
FormatSpec
spec
;
if
(
*
s
==
':'
)
if
(
*
s
==
':'
)
{
{
if
(
arg
.
type
==
Arg
::
CUSTOM
)
{
if
(
arg
.
type
==
Arg
::
CUSTOM
)
{
arg
.
custom
.
format
(
this
,
arg
.
custom
.
value
,
&
s
);
arg
.
custom
.
format
(
this
,
arg
.
custom
.
value
,
&
s
);
return
s
;
return
s
;
}
}
++
s
;
++
s
;
// Parse fill and alignment.
// Parse fill and alignment.
if
(
Char
c
=
*
s
)
if
(
Char
c
=
*
s
)
{
{
const
Char
*
p
=
s
+
1
;
const
Char
*
p
=
s
+
1
;
spec
.
align_
=
ALIGN_DEFAULT
;
spec
.
align_
=
ALIGN_DEFAULT
;
do
do
{
{
switch
(
*
p
)
{
switch
(
*
p
)
{
case
'<'
:
case
'<'
:
spec
.
align_
=
ALIGN_LEFT
;
spec
.
align_
=
ALIGN_LEFT
;
break
;
break
;
...
@@ -4130,28 +3594,23 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
...
@@ -4130,28 +3594,23 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
spec
.
align_
=
ALIGN_CENTER
;
spec
.
align_
=
ALIGN_CENTER
;
break
;
break
;
}
}
if
(
spec
.
align_
!=
ALIGN_DEFAULT
)
if
(
spec
.
align_
!=
ALIGN_DEFAULT
)
{
{
if
(
p
!=
s
)
{
if
(
p
!=
s
)
{
if
(
c
==
'}'
)
break
;
if
(
c
==
'}'
)
break
;
if
(
c
==
'{'
)
if
(
c
==
'{'
)
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
;
}
}
}
}
while
(
--
p
>=
s
);
while
(
--
p
>=
s
);
}
}
// Parse sign.
// Parse sign.
switch
(
*
s
)
switch
(
*
s
)
{
{
case
'+'
:
case
'+'
:
check_sign
(
s
,
arg
);
check_sign
(
s
,
arg
);
spec
.
flags_
|=
SIGN_FLAG
|
PLUS_FLAG
;
spec
.
flags_
|=
SIGN_FLAG
|
PLUS_FLAG
;
...
@@ -4166,16 +3625,14 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
...
@@ -4166,16 +3625,14 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
break
;
break
;
}
}
if
(
*
s
==
'#'
)
if
(
*
s
==
'#'
)
{
{
require_numeric_argument
(
arg
,
'#'
);
require_numeric_argument
(
arg
,
'#'
);
spec
.
flags_
|=
HASH_FLAG
;
spec
.
flags_
|=
HASH_FLAG
;
++
s
;
++
s
;
}
}
// Parse zero flag.
// Parse zero flag.
if
(
*
s
==
'0'
)
if
(
*
s
==
'0'
)
{
{
require_numeric_argument
(
arg
,
'0'
);
require_numeric_argument
(
arg
,
'0'
);
spec
.
align_
=
ALIGN_NUMERIC
;
spec
.
align_
=
ALIGN_NUMERIC
;
spec
.
fill_
=
'0'
;
spec
.
fill_
=
'0'
;
...
@@ -4183,20 +3640,16 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
...
@@ -4183,20 +3640,16 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
}
}
// Parse width.
// Parse width.
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
{
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'{'
)
{
else
if
(
*
s
==
'{'
)
{
++
s
;
++
s
;
Arg
width_arg
=
internal
::
is_name_start
(
*
s
)
?
Arg
width_arg
=
internal
::
is_name_start
(
*
s
)
?
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
if
(
*
s
++
!=
'}'
)
if
(
*
s
++
!=
'}'
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
FMT_THROW
(
FormatError
(
"invalid format string"
));
ULongLong
value
=
0
;
ULongLong
value
=
0
;
switch
(
width_arg
.
type
)
switch
(
width_arg
.
type
)
{
{
case
Arg
:
:
INT
:
case
Arg
:
:
INT
:
if
(
width_arg
.
int_value
<
0
)
if
(
width_arg
.
int_value
<
0
)
FMT_THROW
(
FormatError
(
"negative width"
));
FMT_THROW
(
FormatError
(
"negative width"
));
...
@@ -4222,24 +3675,19 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
...
@@ -4222,24 +3675,19 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
}
}
// Parse precision.
// Parse precision.
if
(
*
s
==
'.'
)
if
(
*
s
==
'.'
)
{
{
++
s
;
++
s
;
spec
.
precision_
=
0
;
spec
.
precision_
=
0
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
{
spec
.
precision_
=
internal
::
parse_nonnegative_int
(
s
);
spec
.
precision_
=
internal
::
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'{'
)
{
else
if
(
*
s
==
'{'
)
{
++
s
;
++
s
;
Arg
precision_arg
=
internal
::
is_name_start
(
*
s
)
?
Arg
precision_arg
=
internal
::
is_name_start
(
*
s
)
?
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
parse_arg_name
(
s
)
:
parse_arg_index
(
s
);
if
(
*
s
++
!=
'}'
)
if
(
*
s
++
!=
'}'
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
FMT_THROW
(
FormatError
(
"invalid format string"
));
ULongLong
value
=
0
;
ULongLong
value
=
0
;
switch
(
precision_arg
.
type
)
switch
(
precision_arg
.
type
)
{
{
case
Arg
:
:
INT
:
case
Arg
:
:
INT
:
if
(
precision_arg
.
int_value
<
0
)
if
(
precision_arg
.
int_value
<
0
)
FMT_THROW
(
FormatError
(
"negative precision"
));
FMT_THROW
(
FormatError
(
"negative precision"
));
...
@@ -4262,13 +3710,10 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
...
@@ -4262,13 +3710,10 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
if
(
value
>
(
std
::
numeric_limits
<
int
>::
max
)())
if
(
value
>
(
std
::
numeric_limits
<
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
)
{
{
FMT_THROW
(
FormatError
(
FMT_THROW
(
FormatError
(
fmt
::
format
(
"precision not allowed in {} format specifier"
,
fmt
::
format
(
"precision not allowed in {} format specifier"
,
arg
.
type
==
Arg
::
POINTER
?
"pointer"
:
"integer"
)));
arg
.
type
==
Arg
::
POINTER
?
"pointer"
:
"integer"
)));
...
@@ -4289,16 +3734,13 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
...
@@ -4289,16 +3734,13 @@ const Char *BasicFormatter<Char, ArgFormatter>::format(
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
void
BasicFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
void
BasicFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
{
{
const
Char
*
s
=
format_str
.
c_str
();
const
Char
*
s
=
format_str
.
c_str
();
const
Char
*
start
=
s
;
const
Char
*
start
=
s
;
while
(
*
s
)
while
(
*
s
)
{
{
Char
c
=
*
s
++
;
Char
c
=
*
s
++
;
if
(
c
!=
'{'
&&
c
!=
'}'
)
continue
;
if
(
c
!=
'{'
&&
c
!=
'}'
)
continue
;
if
(
*
s
==
c
)
if
(
*
s
==
c
)
{
{
write
(
writer_
,
start
,
s
);
write
(
writer_
,
start
,
s
);
start
=
++
s
;
start
=
++
s
;
continue
;
continue
;
...
@@ -4315,40 +3757,33 @@ void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -4315,40 +3757,33 @@ void BasicFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
}
// namespace fmt
}
// namespace fmt
#if FMT_USE_USER_DEFINED_LITERALS
#if FMT_USE_USER_DEFINED_LITERALS
namespace
fmt
namespace
fmt
{
{
namespace
internal
{
namespace
internal
{
template
<
typename
Char
>
template
<
typename
Char
>
struct
UdlFormat
struct
UdlFormat
{
{
const
Char
*
str
;
const
Char
*
str
;
template
<
typename
...
Args
>
template
<
typename
...
Args
>
auto
operator
()(
Args
&&
...
args
)
const
auto
operator
()(
Args
&&
...
args
)
const
->
decltype
(
format
(
str
,
std
::
forward
<
Args
>
(
args
)...))
->
decltype
(
format
(
str
,
std
::
forward
<
Args
>
(
args
)...))
{
{
return
format
(
str
,
std
::
forward
<
Args
>
(
args
)...);
return
format
(
str
,
std
::
forward
<
Args
>
(
args
)...);
}
}
};
};
template
<
typename
Char
>
template
<
typename
Char
>
struct
UdlArg
struct
UdlArg
{
{
const
Char
*
str
;
const
Char
*
str
;
template
<
typename
T
>
template
<
typename
T
>
NamedArg
<
Char
>
operator
=
(
T
&&
value
)
const
NamedArg
<
Char
>
operator
=
(
T
&&
value
)
const
{
{
return
{
str
,
std
::
forward
<
T
>
(
value
)};
return
{
str
,
std
::
forward
<
T
>
(
value
)};
}
}
};
};
}
// namespace internal
}
// namespace internal
inline
namespace
literals
inline
namespace
literals
{
{
/**
/**
\rst
\rst
...
@@ -4361,15 +3796,9 @@ inline namespace literals
...
@@ -4361,15 +3796,9 @@ inline namespace literals
\endrst
\endrst
*/
*/
inline
internal
::
UdlFormat
<
char
>
inline
internal
::
UdlFormat
<
char
>
operator
""
_format
(
const
char
*
s
,
std
::
size_t
)
operator
""
_format
(
const
char
*
s
,
std
::
size_t
)
{
return
{
s
};
}
{
return
{
s
};
}
inline
internal
::
UdlFormat
<
wchar_t
>
inline
internal
::
UdlFormat
<
wchar_t
>
operator
""
_format
(
const
wchar_t
*
s
,
std
::
size_t
)
operator
""
_format
(
const
wchar_t
*
s
,
std
::
size_t
)
{
return
{
s
};
}
{
return
{
s
};
}
/**
/**
\rst
\rst
...
@@ -4382,15 +3811,9 @@ operator"" _format(const wchar_t *s, std::size_t)
...
@@ -4382,15 +3811,9 @@ operator"" _format(const wchar_t *s, std::size_t)
\endrst
\endrst
*/
*/
inline
internal
::
UdlArg
<
char
>
inline
internal
::
UdlArg
<
char
>
operator
""
_a
(
const
char
*
s
,
std
::
size_t
)
operator
""
_a
(
const
char
*
s
,
std
::
size_t
)
{
return
{
s
};
}
{
return
{
s
};
}
inline
internal
::
UdlArg
<
wchar_t
>
inline
internal
::
UdlArg
<
wchar_t
>
operator
""
_a
(
const
wchar_t
*
s
,
std
::
size_t
)
operator
""
_a
(
const
wchar_t
*
s
,
std
::
size_t
)
{
return
{
s
};
}
{
return
{
s
};
}
}
// inline namespace literals
}
// inline namespace literals
}
// namespace fmt
}
// namespace fmt
...
...
include/spdlog/fmt/bundled/ostream.cc
View file @
6312748c
...
@@ -7,15 +7,13 @@
...
@@ -7,15 +7,13 @@
For the license information refer to format.h.
For the license information refer to format.h.
*/
*/
// Commented out by spdlog to use header only
// Commented out by spdlog to use header only
// #include "fmt/ostream.h"
// #include "fmt/ostream.h"
// #include "fmt/printf.h"
namespace
fmt
{
namespace
fmt
{
namespace
{
namespace
internal
{
// Write the content of w to os.
FMT_FUNC
void
write
(
std
::
ostream
&
os
,
Writer
&
w
)
{
void
write
(
std
::
ostream
&
os
,
Writer
&
w
)
{
const
char
*
data
=
w
.
data
();
const
char
*
data
=
w
.
data
();
typedef
internal
::
MakeUnsigned
<
std
::
streamsize
>::
Type
UnsignedStreamSize
;
typedef
internal
::
MakeUnsigned
<
std
::
streamsize
>::
Type
UnsignedStreamSize
;
UnsignedStreamSize
size
=
w
.
size
();
UnsignedStreamSize
size
=
w
.
size
();
...
@@ -33,13 +31,6 @@ void write(std::ostream &os, Writer &w) {
...
@@ -33,13 +31,6 @@ void write(std::ostream &os, Writer &w) {
FMT_FUNC
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
{
FMT_FUNC
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
{
MemoryWriter
w
;
MemoryWriter
w
;
w
.
write
(
format_str
,
args
);
w
.
write
(
format_str
,
args
);
write
(
os
,
w
);
internal
::
write
(
os
,
w
);
}
FMT_FUNC
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format
,
ArgList
args
)
{
MemoryWriter
w
;
printf
(
w
,
format
,
args
);
write
(
os
,
w
);
return
static_cast
<
int
>
(
w
.
size
());
}
}
}
// namespace fmt
}
// namespace fmt
include/spdlog/fmt/bundled/ostream.h
View file @
6312748c
...
@@ -14,32 +14,26 @@
...
@@ -14,32 +14,26 @@
// #include "fmt/format.h"
// #include "fmt/format.h"
#include <ostream>
#include <ostream>
namespace
fmt
namespace
fmt
{
{
namespace
internal
namespace
internal
{
{
template
<
class
Char
>
template
<
class
Char
>
class
FormatBuf
:
public
std
::
basic_streambuf
<
Char
>
class
FormatBuf
:
public
std
::
basic_streambuf
<
Char
>
{
{
private
:
private
:
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
int_type
int_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
typedef
typename
std
::
basic_streambuf
<
Char
>::
traits_type
traits_type
;
Buffer
<
Char
>
&
buffer_
;
Buffer
<
Char
>
&
buffer_
;
Char
*
start_
;
Char
*
start_
;
public
:
public
:
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
),
start_
(
&
buffer
[
0
])
FormatBuf
(
Buffer
<
Char
>
&
buffer
)
:
buffer_
(
buffer
),
start_
(
&
buffer
[
0
])
{
{
this
->
setp
(
start_
,
start_
+
buffer_
.
capacity
());
this
->
setp
(
start_
,
start_
+
buffer_
.
capacity
());
}
}
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
int_type
overflow
(
int_type
ch
=
traits_type
::
eof
())
{
{
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
{
if
(
!
traits_type
::
eq_int_type
(
ch
,
traits_type
::
eof
()))
{
size_t
buf_size
=
size
();
size_t
buf_size
=
size
();
buffer_
.
resize
(
buf_size
);
buffer_
.
resize
(
buf_size
);
buffer_
.
reserve
(
buf_size
*
2
);
buffer_
.
reserve
(
buf_size
*
2
);
...
@@ -51,16 +45,14 @@ public:
...
@@ -51,16 +45,14 @@ public:
return
ch
;
return
ch
;
}
}
size_t
size
()
const
size_t
size
()
const
{
{
return
to_unsigned
(
this
->
pptr
()
-
start_
);
return
to_unsigned
(
this
->
pptr
()
-
start_
);
}
}
};
};
Yes
&
convert
(
std
::
ostream
&
);
Yes
&
convert
(
std
::
ostream
&
);
struct
DummyStream
:
std
::
ostream
struct
DummyStream
:
std
::
ostream
{
{
DummyStream
();
// Suppress a bogus warning in MSVC.
DummyStream
();
// Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
// Hide all operator<< overloads from std::ostream.
void
operator
<<
(
Null
<>
);
void
operator
<<
(
Null
<>
);
...
@@ -69,21 +61,21 @@ struct DummyStream : std::ostream
...
@@ -69,21 +61,21 @@ struct DummyStream : std::ostream
No
&
operator
<<
(
std
::
ostream
&
,
int
);
No
&
operator
<<
(
std
::
ostream
&
,
int
);
template
<
typename
T
>
template
<
typename
T
>
struct
ConvertToIntImpl
<
T
,
true
>
struct
ConvertToIntImpl
<
T
,
true
>
{
{
// Convert to int only if T doesn't have an overloaded operator<<.
// Convert to int only if T doesn't have an overloaded operator<<.
enum
enum
{
{
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
value
=
sizeof
(
convert
(
get
<
DummyStream
>
()
<<
get
<
T
>
()))
==
sizeof
(
No
)
};
};
};
};
// Write the content of w to os.
void
write
(
std
::
ostream
&
os
,
Writer
&
w
);
}
// namespace internal
}
// namespace internal
// Formats a value.
// Formats a value.
template
<
typename
Char
,
typename
ArgFormatter
,
typename
T
>
template
<
typename
Char
,
typename
ArgFormatter
,
typename
T
>
void
format
(
BasicFormatter
<
Char
,
ArgFormatter
>
&
f
,
void
format_arg
(
BasicFormatter
<
Char
,
ArgFormatter
>
&
f
,
const
Char
*&
format_str
,
const
T
&
value
)
const
Char
*&
format_str
,
const
T
&
value
)
{
{
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
>
buffer
;
internal
::
MemoryBuffer
<
Char
,
internal
::
INLINE_BUFFER_SIZE
>
buffer
;
internal
::
FormatBuf
<
Char
>
format_buf
(
buffer
);
internal
::
FormatBuf
<
Char
>
format_buf
(
buffer
);
...
@@ -106,18 +98,6 @@ void format(BasicFormatter<Char, ArgFormatter> &f,
...
@@ -106,18 +98,6 @@ void format(BasicFormatter<Char, ArgFormatter> &f,
*/
*/
FMT_API
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
FMT_API
void
print
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
FMT_VARIADIC
(
void
,
print
,
std
::
ostream
&
,
CStringRef
)
FMT_VARIADIC
(
void
,
print
,
std
::
ostream
&
,
CStringRef
)
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
FMT_API
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
);
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
}
// namespace fmt
}
// namespace fmt
#ifdef FMT_HEADER_ONLY
#ifdef FMT_HEADER_ONLY
...
...
include/spdlog/fmt/bundled/printf.h
View file @
6312748c
...
@@ -13,56 +13,41 @@
...
@@ -13,56 +13,41 @@
#include <algorithm> // std::fill_n
#include <algorithm> // std::fill_n
#include <limits> // std::numeric_limits
#include <limits> // std::numeric_limits
#include "fmt/
format
.h"
#include "fmt/
ostream
.h"
namespace
fmt
namespace
fmt
{
{
namespace
internal
{
namespace
internal
{
// Checks if a value fits in int - used to avoid warnings about comparing
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
// signed and unsigned integers.
template
<
bool
IsSigned
>
template
<
bool
IsSigned
>
struct
IntChecker
struct
IntChecker
{
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
static
bool
fits_in_int
(
T
value
)
{
{
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
unsigned
max
=
std
::
numeric_limits
<
int
>::
max
();
return
value
<=
max
;
return
value
<=
max
;
}
}
static
bool
fits_in_int
(
bool
)
static
bool
fits_in_int
(
bool
)
{
return
true
;
}
{
return
true
;
}
};
};
template
<>
template
<>
struct
IntChecker
<
true
>
struct
IntChecker
<
true
>
{
{
template
<
typename
T
>
template
<
typename
T
>
static
bool
fits_in_int
(
T
value
)
static
bool
fits_in_int
(
T
value
)
{
{
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
return
value
>=
std
::
numeric_limits
<
int
>::
min
()
&&
value
<=
std
::
numeric_limits
<
int
>::
max
();
value
<=
std
::
numeric_limits
<
int
>::
max
();
}
}
static
bool
fits_in_int
(
int
)
static
bool
fits_in_int
(
int
)
{
return
true
;
}
{
return
true
;
}
};
};
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
class
PrecisionHandler
:
public
ArgVisitor
<
PrecisionHandler
,
int
>
{
{
public
:
public
:
void
report_unhandled_arg
()
{
void
report_unhandled_arg
()
{
FMT_THROW
(
FormatError
(
"precision is not integer"
));
FMT_THROW
(
FormatError
(
"precision is not integer"
));
}
}
template
<
typename
T
>
template
<
typename
T
>
int
visit_any_int
(
T
value
)
int
visit_any_int
(
T
value
)
{
{
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
if
(
!
IntChecker
<
std
::
numeric_limits
<
T
>::
is_signed
>::
fits_in_int
(
value
))
FMT_THROW
(
FormatError
(
"number is too big"
));
FMT_THROW
(
FormatError
(
"number is too big"
));
return
static_cast
<
int
>
(
value
);
return
static_cast
<
int
>
(
value
);
...
@@ -70,25 +55,19 @@ public:
...
@@ -70,25 +55,19 @@ public:
};
};
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
class
IsZeroInt
:
public
ArgVisitor
<
IsZeroInt
,
bool
>
{
{
public
:
public
:
template
<
typename
T
>
template
<
typename
T
>
bool
visit_any_int
(
T
value
)
bool
visit_any_int
(
T
value
)
{
return
value
==
0
;
}
{
return
value
==
0
;
}
};
};
template
<
typename
T
,
typename
U
>
template
<
typename
T
,
typename
U
>
struct
is_same
struct
is_same
{
{
enum
{
value
=
0
};
enum
{
value
=
0
};
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
is_same
<
T
,
T
>
struct
is_same
<
T
,
T
>
{
{
enum
{
value
=
1
};
enum
{
value
=
1
};
};
};
...
@@ -97,58 +76,46 @@ struct is_same<T, T>
...
@@ -97,58 +76,46 @@ struct is_same<T, T>
// corresponding signed or unsigned type depending on the type specifier:
// corresponding signed or unsigned type depending on the type specifier:
// 'd' and 'i' - signed, other - unsigned)
// 'd' and 'i' - signed, other - unsigned)
template
<
typename
T
=
void
>
template
<
typename
T
=
void
>
class
ArgConverter
:
public
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
class
ArgConverter
:
public
ArgVisitor
<
ArgConverter
<
T
>
,
void
>
{
{
private
:
private
:
internal
::
Arg
&
arg_
;
internal
::
Arg
&
arg_
;
wchar_t
type_
;
wchar_t
type_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
ArgConverter
);
public
:
public
:
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
ArgConverter
(
internal
::
Arg
&
arg
,
wchar_t
type
)
:
arg_
(
arg
),
type_
(
type
)
{}
:
arg_
(
arg
),
type_
(
type
)
{}
void
visit_bool
(
bool
value
)
void
visit_bool
(
bool
value
)
{
{
if
(
type_
!=
's'
)
if
(
type_
!=
's'
)
visit_any_int
(
value
);
visit_any_int
(
value
);
}
}
template
<
typename
U
>
template
<
typename
U
>
void
visit_any_int
(
U
value
)
void
visit_any_int
(
U
value
)
{
{
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
bool
is_signed
=
type_
==
'd'
||
type_
==
'i'
;
using
internal
::
Arg
;
using
internal
::
Arg
;
typedef
typename
internal
::
Conditional
<
typedef
typename
internal
::
Conditional
<
is_same
<
T
,
void
>::
value
,
U
,
T
>::
type
TargetType
;
is_same
<
T
,
void
>::
value
,
U
,
T
>::
type
TargetType
;
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
if
(
sizeof
(
TargetType
)
<=
sizeof
(
int
))
{
{
// Extra casts are used to silence warnings.
// Extra casts are used to silence warnings.
if
(
is_signed
)
if
(
is_signed
)
{
{
arg_
.
type
=
Arg
::
INT
;
arg_
.
type
=
Arg
::
INT
;
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
arg_
.
int_value
=
static_cast
<
int
>
(
static_cast
<
TargetType
>
(
value
));
}
}
else
{
else
{
arg_
.
type
=
Arg
::
UINT
;
arg_
.
type
=
Arg
::
UINT
;
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
typedef
typename
internal
::
MakeUnsigned
<
TargetType
>::
Type
Unsigned
;
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
));
arg_
.
uint_value
=
static_cast
<
unsigned
>
(
static_cast
<
Unsigned
>
(
value
));
}
}
}
}
else
{
else
if
(
is_signed
)
{
{
if
(
is_signed
)
{
arg_
.
type
=
Arg
::
LONG_LONG
;
arg_
.
type
=
Arg
::
LONG_LONG
;
// glibc's printf doesn't sign extend arguments of smaller types:
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
// but we don't have to do the same because it's a UB.
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
arg_
.
long_long_value
=
static_cast
<
LongLong
>
(
value
);
}
}
else
{
else
{
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
type
=
Arg
::
ULONG_LONG
;
arg_
.
ulong_long_value
=
arg_
.
ulong_long_value
=
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
static_cast
<
typename
internal
::
MakeUnsigned
<
U
>::
Type
>
(
value
);
...
@@ -158,19 +125,17 @@ public:
...
@@ -158,19 +125,17 @@ public:
};
};
// Converts an integer argument to char for printf.
// Converts an integer argument to char for printf.
class
CharConverter
:
public
ArgVisitor
<
CharConverter
,
void
>
class
CharConverter
:
public
ArgVisitor
<
CharConverter
,
void
>
{
{
private
:
private
:
internal
::
Arg
&
arg_
;
internal
::
Arg
&
arg_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
CharConverter
);
public
:
public
:
explicit
CharConverter
(
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
{}
explicit
CharConverter
(
internal
::
Arg
&
arg
)
:
arg_
(
arg
)
{}
template
<
typename
T
>
template
<
typename
T
>
void
visit_any_int
(
T
value
)
void
visit_any_int
(
T
value
)
{
{
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
type
=
internal
::
Arg
::
CHAR
;
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
arg_
.
int_value
=
static_cast
<
char
>
(
value
);
}
}
...
@@ -178,28 +143,24 @@ public:
...
@@ -178,28 +143,24 @@ public:
// Checks if an argument is a valid printf width specifier and sets
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
// left alignment if it is negative.
class
WidthHandler
:
public
ArgVisitor
<
WidthHandler
,
unsigned
>
class
WidthHandler
:
public
ArgVisitor
<
WidthHandler
,
unsigned
>
{
{
private
:
private
:
FormatSpec
&
spec_
;
FormatSpec
&
spec_
;
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
FMT_DISALLOW_COPY_AND_ASSIGN
(
WidthHandler
);
public
:
public
:
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
explicit
WidthHandler
(
FormatSpec
&
spec
)
:
spec_
(
spec
)
{}
void
report_unhandled_arg
()
void
report_unhandled_arg
()
{
{
FMT_THROW
(
FormatError
(
"width is not integer"
));
FMT_THROW
(
FormatError
(
"width is not integer"
));
}
}
template
<
typename
T
>
template
<
typename
T
>
unsigned
visit_any_int
(
T
value
)
unsigned
visit_any_int
(
T
value
)
{
{
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
typedef
typename
internal
::
IntTraits
<
T
>::
MainType
UnsignedType
;
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
UnsignedType
width
=
static_cast
<
UnsignedType
>
(
value
);
if
(
internal
::
is_negative
(
value
))
if
(
internal
::
is_negative
(
value
))
{
{
spec_
.
align_
=
ALIGN_LEFT
;
spec_
.
align_
=
ALIGN_LEFT
;
width
=
0
-
width
;
width
=
0
-
width
;
}
}
...
@@ -229,18 +190,16 @@ public:
...
@@ -229,18 +190,16 @@ public:
\endrst
\endrst
*/
*/
template
<
typename
Impl
,
typename
Char
>
template
<
typename
Impl
,
typename
Char
>
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
class
BasicPrintfArgFormatter
:
public
internal
::
ArgFormatterBase
<
Impl
,
Char
>
{
{
private
:
private
:
void
write_null_pointer
()
{
void
write_null_pointer
()
{
this
->
spec
().
type_
=
0
;
this
->
spec
().
type_
=
0
;
this
->
write
(
"(nil)"
);
this
->
write
(
"(nil)"
);
}
}
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
typedef
internal
::
ArgFormatterBase
<
Impl
,
Char
>
Base
;
public
:
public
:
/**
/**
\rst
\rst
Constructs an argument formatter object.
Constructs an argument formatter object.
...
@@ -252,8 +211,7 @@ public:
...
@@ -252,8 +211,7 @@ public:
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
writer
,
spec
)
{}
:
internal
::
ArgFormatterBase
<
Impl
,
Char
>
(
writer
,
spec
)
{}
/** Formats an argument of type ``bool``. */
/** Formats an argument of type ``bool``. */
void
visit_bool
(
bool
value
)
void
visit_bool
(
bool
value
)
{
{
FormatSpec
&
fmt_spec
=
this
->
spec
();
FormatSpec
&
fmt_spec
=
this
->
spec
();
if
(
fmt_spec
.
type_
!=
's'
)
if
(
fmt_spec
.
type_
!=
's'
)
return
this
->
visit_any_int
(
value
);
return
this
->
visit_any_int
(
value
);
...
@@ -262,38 +220,30 @@ public:
...
@@ -262,38 +220,30 @@ public:
}
}
/** Formats a character. */
/** Formats a character. */
void
visit_char
(
int
value
)
void
visit_char
(
int
value
)
{
{
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
const
FormatSpec
&
fmt_spec
=
this
->
spec
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
BasicWriter
<
Char
>
&
w
=
this
->
writer
();
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
if
(
fmt_spec
.
type_
&&
fmt_spec
.
type_
!=
'c'
)
w
.
write_int
(
value
,
fmt_spec
);
w
.
write_int
(
value
,
fmt_spec
);
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
typedef
typename
BasicWriter
<
Char
>::
CharPtr
CharPtr
;
CharPtr
out
=
CharPtr
();
CharPtr
out
=
CharPtr
();
if
(
fmt_spec
.
width_
>
1
)
if
(
fmt_spec
.
width_
>
1
)
{
{
Char
fill
=
' '
;
Char
fill
=
' '
;
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
out
=
w
.
grow_buffer
(
fmt_spec
.
width_
);
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
if
(
fmt_spec
.
align_
!=
ALIGN_LEFT
)
{
{
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
std
::
fill_n
(
out
,
fmt_spec
.
width_
-
1
,
fill
);
out
+=
fmt_spec
.
width_
-
1
;
out
+=
fmt_spec
.
width_
-
1
;
}
}
else
{
else
{
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
std
::
fill_n
(
out
+
1
,
fmt_spec
.
width_
-
1
,
fill
);
}
}
}
}
else
{
else
{
out
=
w
.
grow_buffer
(
1
);
out
=
w
.
grow_buffer
(
1
);
}
}
*
out
=
static_cast
<
Char
>
(
value
);
*
out
=
static_cast
<
Char
>
(
value
);
}
}
/** Formats a null-terminated C string. */
/** Formats a null-terminated C string. */
void
visit_cstring
(
const
char
*
value
)
void
visit_cstring
(
const
char
*
value
)
{
{
if
(
value
)
if
(
value
)
Base
::
visit_cstring
(
value
);
Base
::
visit_cstring
(
value
);
else
if
(
this
->
spec
().
type_
==
'p'
)
else
if
(
this
->
spec
().
type_
==
'p'
)
...
@@ -303,8 +253,7 @@ public:
...
@@ -303,8 +253,7 @@ public:
}
}
/** Formats a pointer. */
/** Formats a pointer. */
void
visit_pointer
(
const
void
*
value
)
void
visit_pointer
(
const
void
*
value
)
{
{
if
(
value
)
if
(
value
)
return
Base
::
visit_pointer
(
value
);
return
Base
::
visit_pointer
(
value
);
this
->
spec
().
type_
=
0
;
this
->
spec
().
type_
=
0
;
...
@@ -312,8 +261,7 @@ public:
...
@@ -312,8 +261,7 @@ public:
}
}
/** Formats an argument of a custom (user-defined) type. */
/** Formats an argument of a custom (user-defined) type. */
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
void
visit_custom
(
internal
::
Arg
::
CustomValue
c
)
{
{
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
BasicFormatter
<
Char
>
formatter
(
ArgList
(),
this
->
writer
());
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
format_str
[]
=
{
'}'
,
0
};
const
Char
*
format
=
format_str
;
const
Char
*
format
=
format_str
;
...
@@ -324,9 +272,8 @@ public:
...
@@ -324,9 +272,8 @@ public:
/** The default printf argument formatter. */
/** The default printf argument formatter. */
template
<
typename
Char
>
template
<
typename
Char
>
class
PrintfArgFormatter
class
PrintfArgFormatter
:
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
:
public
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
{
{
public
:
public
:
/** Constructs an argument formatter object. */
/** Constructs an argument formatter object. */
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
PrintfArgFormatter
(
BasicWriter
<
Char
>
&
w
,
FormatSpec
&
s
)
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
:
BasicPrintfArgFormatter
<
PrintfArgFormatter
<
Char
>
,
Char
>
(
w
,
s
)
{}
...
@@ -334,9 +281,8 @@ public:
...
@@ -334,9 +281,8 @@ public:
/** This template formats data and writes the output to a writer. */
/** This template formats data and writes the output to a writer. */
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
template
<
typename
Char
,
typename
ArgFormatter
=
PrintfArgFormatter
<
Char
>
>
class
PrintfFormatter
:
private
internal
::
FormatterBase
class
PrintfFormatter
:
private
internal
::
FormatterBase
{
{
private
:
private
:
BasicWriter
<
Char
>
&
writer_
;
BasicWriter
<
Char
>
&
writer_
;
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
void
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
);
...
@@ -350,7 +296,7 @@ private:
...
@@ -350,7 +296,7 @@ private:
// Parses argument index, flags and width and returns the argument index.
// Parses argument index, flags and width and returns the argument index.
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
unsigned
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
);
public
:
public
:
/**
/**
\rst
\rst
Constructs a ``PrintfFormatter`` object. References to the arguments and
Constructs a ``PrintfFormatter`` object. References to the arguments and
...
@@ -366,12 +312,9 @@ public:
...
@@ -366,12 +312,9 @@ public:
};
};
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
void
PrintfFormatter
<
Char
,
AF
>::
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
)
void
PrintfFormatter
<
Char
,
AF
>::
parse_flags
(
FormatSpec
&
spec
,
const
Char
*&
s
)
{
{
for
(;;)
{
for
(;;)
switch
(
*
s
++
)
{
{
switch
(
*
s
++
)
{
case
'-'
:
case
'-'
:
spec
.
align_
=
ALIGN_LEFT
;
spec
.
align_
=
ALIGN_LEFT
;
break
;
break
;
...
@@ -396,8 +339,7 @@ void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
...
@@ -396,8 +339,7 @@ void PrintfFormatter<Char, AF>::parse_flags(FormatSpec &spec, const Char *&s)
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
internal
::
Arg
PrintfFormatter
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
internal
::
Arg
PrintfFormatter
<
Char
,
AF
>::
get_arg
(
const
Char
*
s
,
unsigned
arg_index
)
unsigned
arg_index
)
{
{
(
void
)
s
;
(
void
)
s
;
const
char
*
error
=
0
;
const
char
*
error
=
0
;
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
internal
::
Arg
arg
=
arg_index
==
std
::
numeric_limits
<
unsigned
>::
max
()
?
...
@@ -409,26 +351,20 @@ internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
...
@@ -409,26 +351,20 @@ internal::Arg PrintfFormatter<Char, AF>::get_arg(const Char *s,
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
unsigned
PrintfFormatter
<
Char
,
AF
>::
parse_header
(
unsigned
PrintfFormatter
<
Char
,
AF
>::
parse_header
(
const
Char
*&
s
,
FormatSpec
&
spec
)
const
Char
*&
s
,
FormatSpec
&
spec
)
{
{
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
unsigned
arg_index
=
std
::
numeric_limits
<
unsigned
>::
max
();
Char
c
=
*
s
;
Char
c
=
*
s
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
if
(
c
>=
'0'
&&
c
<=
'9'
)
{
{
// Parse an argument index (if followed by '$') or a width possibly
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
// preceded with '0' flag(s).
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
unsigned
value
=
internal
::
parse_nonnegative_int
(
s
);
if
(
*
s
==
'$'
)
// value is an argument index
if
(
*
s
==
'$'
)
{
// value is an argument index
{
++
s
;
++
s
;
arg_index
=
value
;
arg_index
=
value
;
}
}
else
{
else
{
if
(
c
==
'0'
)
if
(
c
==
'0'
)
spec
.
fill_
=
'0'
;
spec
.
fill_
=
'0'
;
if
(
value
!=
0
)
if
(
value
!=
0
)
{
{
// Nonzero value means that we parsed width and don't need to
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
// parse it or flags again, so return now.
spec
.
width_
=
value
;
spec
.
width_
=
value
;
...
@@ -438,12 +374,9 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
...
@@ -438,12 +374,9 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
}
}
parse_flags
(
spec
,
s
);
parse_flags
(
spec
,
s
);
// Parse width.
// Parse width.
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
if
(
*
s
>=
'0'
&&
*
s
<=
'9'
)
{
{
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
spec
.
width_
=
internal
::
parse_nonnegative_int
(
s
);
}
}
else
if
(
*
s
==
'*'
)
{
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
spec
.
width_
=
internal
::
WidthHandler
(
spec
).
visit
(
get_arg
(
s
));
}
}
...
@@ -451,16 +384,13 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
...
@@ -451,16 +384,13 @@ unsigned PrintfFormatter<Char, AF>::parse_header(
}
}
template
<
typename
Char
,
typename
AF
>
template
<
typename
Char
,
typename
AF
>
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
void
PrintfFormatter
<
Char
,
AF
>::
format
(
BasicCStringRef
<
Char
>
format_str
)
{
{
const
Char
*
start
=
format_str
.
c_str
();
const
Char
*
start
=
format_str
.
c_str
();
const
Char
*
s
=
start
;
const
Char
*
s
=
start
;
while
(
*
s
)
while
(
*
s
)
{
{
Char
c
=
*
s
++
;
Char
c
=
*
s
++
;
if
(
c
!=
'%'
)
continue
;
if
(
c
!=
'%'
)
continue
;
if
(
*
s
==
c
)
if
(
*
s
==
c
)
{
{
write
(
writer_
,
start
,
s
);
write
(
writer_
,
start
,
s
);
start
=
++
s
;
start
=
++
s
;
continue
;
continue
;
...
@@ -474,15 +404,11 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -474,15 +404,11 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
unsigned
arg_index
=
parse_header
(
s
,
spec
);
unsigned
arg_index
=
parse_header
(
s
,
spec
);
// Parse precision.
// Parse precision.
if
(
*
s
==
'.'
)
if
(
*
s
==
'.'
)
{
{
++
s
;
++
s
;
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
if
(
'0'
<=
*
s
&&
*
s
<=
'9'
)
{
{
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
spec
.
precision_
=
static_cast
<
int
>
(
internal
::
parse_nonnegative_int
(
s
));
}
}
else
if
(
*
s
==
'*'
)
{
else
if
(
*
s
==
'*'
)
{
++
s
;
++
s
;
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
spec
.
precision_
=
internal
::
PrecisionHandler
().
visit
(
get_arg
(
s
));
}
}
...
@@ -492,8 +418,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -492,8 +418,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
Arg
arg
=
get_arg
(
s
,
arg_index
);
Arg
arg
=
get_arg
(
s
,
arg_index
);
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
if
(
spec
.
flag
(
HASH_FLAG
)
&&
internal
::
IsZeroInt
().
visit
(
arg
))
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
spec
.
flags_
&=
~
internal
::
to_unsigned
<
int
>
(
HASH_FLAG
);
if
(
spec
.
fill_
==
'0'
)
if
(
spec
.
fill_
==
'0'
)
{
{
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
if
(
arg
.
type
<=
Arg
::
LAST_NUMERIC_TYPE
)
spec
.
align_
=
ALIGN_NUMERIC
;
spec
.
align_
=
ALIGN_NUMERIC
;
else
else
...
@@ -502,8 +427,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -502,8 +427,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
// Parse length and convert the argument to the required type.
// Parse length and convert the argument to the required type.
using
internal
::
ArgConverter
;
using
internal
::
ArgConverter
;
switch
(
*
s
++
)
switch
(
*
s
++
)
{
{
case
'h'
:
case
'h'
:
if
(
*
s
==
'h'
)
if
(
*
s
==
'h'
)
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
ArgConverter
<
signed
char
>
(
arg
,
*++
s
).
visit
(
arg
);
...
@@ -538,13 +462,10 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -538,13 +462,10 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
if
(
!*
s
)
if
(
!*
s
)
FMT_THROW
(
FormatError
(
"invalid format string"
));
FMT_THROW
(
FormatError
(
"invalid format string"
));
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
spec
.
type_
=
static_cast
<
char
>
(
*
s
++
);
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
if
(
arg
.
type
<=
Arg
::
LAST_INTEGER_TYPE
)
{
{
// Normalize type.
// Normalize type.
switch
(
spec
.
type_
)
switch
(
spec
.
type_
)
{
{
case
'i'
:
case
'u'
:
case
'i'
:
case
'u'
:
spec
.
type_
=
'd'
;
spec
.
type_
=
'd'
;
break
;
break
;
case
'c'
:
case
'c'
:
...
@@ -563,8 +484,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
...
@@ -563,8 +484,7 @@ void PrintfFormatter<Char, AF>::format(BasicCStringRef<Char> format_str)
}
}
template
<
typename
Char
>
template
<
typename
Char
>
void
printf
(
BasicWriter
<
Char
>
&
w
,
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
void
printf
(
BasicWriter
<
Char
>
&
w
,
BasicCStringRef
<
Char
>
format
,
ArgList
args
)
{
{
PrintfFormatter
<
Char
>
(
args
,
w
).
format
(
format
);
PrintfFormatter
<
Char
>
(
args
,
w
).
format
(
format
);
}
}
...
@@ -577,16 +497,14 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args)
...
@@ -577,16 +497,14 @@ void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args)
std::string message = fmt::sprintf("The answer is %d", 42);
std::string message = fmt::sprintf("The answer is %d", 42);
\endrst
\endrst
*/
*/
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
inline
std
::
string
sprintf
(
CStringRef
format
,
ArgList
args
)
{
{
MemoryWriter
w
;
MemoryWriter
w
;
printf
(
w
,
format
,
args
);
printf
(
w
,
format
,
args
);
return
w
.
str
();
return
w
.
str
();
}
}
FMT_VARIADIC
(
std
::
string
,
sprintf
,
CStringRef
)
FMT_VARIADIC
(
std
::
string
,
sprintf
,
CStringRef
)
inline
std
::
wstring
sprintf
(
WCStringRef
format
,
ArgList
args
)
inline
std
::
wstring
sprintf
(
WCStringRef
format
,
ArgList
args
)
{
{
WMemoryWriter
w
;
WMemoryWriter
w
;
printf
(
w
,
format
,
args
);
printf
(
w
,
format
,
args
);
return
w
.
str
();
return
w
.
str
();
...
@@ -614,11 +532,27 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
...
@@ -614,11 +532,27 @@ FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef)
fmt::printf("Elapsed time: %.2f seconds", 1.23);
fmt::printf("Elapsed time: %.2f seconds", 1.23);
\endrst
\endrst
*/
*/
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
inline
int
printf
(
CStringRef
format
,
ArgList
args
)
{
{
return
fprintf
(
stdout
,
format
,
args
);
return
fprintf
(
stdout
,
format
,
args
);
}
}
FMT_VARIADIC
(
int
,
printf
,
CStringRef
)
FMT_VARIADIC
(
int
,
printf
,
CStringRef
)
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
inline
int
fprintf
(
std
::
ostream
&
os
,
CStringRef
format_str
,
ArgList
args
)
{
MemoryWriter
w
;
printf
(
w
,
format_str
,
args
);
internal
::
write
(
os
,
w
);
return
static_cast
<
int
>
(
w
.
size
());
}
FMT_VARIADIC
(
int
,
fprintf
,
std
::
ostream
&
,
CStringRef
)
}
// namespace fmt
}
// namespace fmt
#endif // FMT_PRINTF_H_
#endif // FMT_PRINTF_H_
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