Commit 3771d129 authored by gabime's avatar gabime

Upgraded to fmt ver 5.2.0

parent f4ac67ae
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -14,22 +14,18 @@
FMT_BEGIN_NAMESPACE
namespace internal {
template<class Char>
class formatbuf : public std::basic_streambuf<Char>
{
private:
template <class Char>
class formatbuf : public std::basic_streambuf<Char> {
private:
typedef typename std::basic_streambuf<Char>::int_type int_type;
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
basic_buffer<Char> &buffer_;
public:
formatbuf(basic_buffer<Char> &buffer)
: buffer_(buffer)
{
}
public:
formatbuf(basic_buffer<Char> &buffer) : buffer_(buffer) {}
protected:
protected:
// The put-area is actually always empty. This makes the implementation
// simpler and has the advantage that the streambuf and the buffer are always
// in sync and sputc never writes into uninitialized memory. The obvious
......@@ -37,69 +33,53 @@ protected:
// to overflow. There is no disadvantage here for sputn since this always
// results in a call to xsputn.
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE
{
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
if (!traits_type::eq_int_type(ch, traits_type::eof()))
buffer_.push_back(static_cast<Char>(ch));
return ch;
}
std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE
{
std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
buffer_.append(s, s + count);
return count;
}
};
template<typename Char>
struct test_stream : std::basic_ostream<Char>
{
private:
template <typename Char>
struct test_stream : std::basic_ostream<Char> {
private:
struct null;
// Hide all operator<< from std::basic_ostream<Char>.
void operator<<(null);
};
// Checks if T has a user-defined operator<< (e.g. not a member of
// std::ostream).
template<typename T, typename Char>
class is_streamable
{
private:
template<typename U>
static decltype(internal::declval<test_stream<Char> &>() << internal::declval<U>(), std::true_type()) test(int);
// Checks if T has a user-defined operator<< (e.g. not a member of std::ostream).
template <typename T, typename Char>
class is_streamable {
private:
template <typename U>
static decltype(
internal::declval<test_stream<Char>&>()
<< internal::declval<U>(), std::true_type()) test(int);
template<typename>
template <typename>
static std::false_type test(...);
typedef decltype(test<T>(0)) result;
public:
// std::string operator<< is not considered user-defined because we handle
// strings
// specially.
static const bool value = result::value && !std::is_same<T, std::string>::value;
};
// Disable conversion to int if T has an overloaded operator<< which is a free
// function (not a member of std::ostream).
template<typename T, typename Char>
class convert_to_int<T, Char, true>
{
public:
static const bool value = convert_to_int<T, Char, false>::value && !is_streamable<T, Char>::value;
public:
static const bool value = result::value;
};
// Write the content of buf to os.
template<typename Char>
void write(std::basic_ostream<Char> &os, basic_buffer<Char> &buf)
{
template <typename Char>
void write(std::basic_ostream<Char> &os, basic_buffer<Char> &buf) {
const Char *data = buf.data();
typedef std::make_unsigned<std::streamsize>::type UnsignedStreamSize;
UnsignedStreamSize size = buf.size();
UnsignedStreamSize max_size = internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
do
{
UnsignedStreamSize max_size =
internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
do {
UnsignedStreamSize n = size <= max_size ? size : max_size;
os.write(data, static_cast<std::streamsize>(n));
data += n;
......@@ -107,43 +87,47 @@ void write(std::basic_ostream<Char> &os, basic_buffer<Char> &buf)
} while (size != 0);
}
template<typename Char, typename T>
void format_value(basic_buffer<Char> &buffer, const T &value)
{
template <typename Char, typename T>
void format_value(basic_buffer<Char> &buffer, const T &value) {
internal::formatbuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf);
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
output << value;
buffer.resize(buffer.size());
}
} // namespace internal
// Disable builtin formatting of enums and use operator<< instead.
template<typename T>
struct format_enum<T, typename std::enable_if<std::is_enum<T>::value>::type> : std::false_type
{
// Disable conversion to int if T has an overloaded operator<< which is a free
// function (not a member of std::ostream).
template <typename T, typename Char>
struct convert_to_int<T, Char, void> {
static const bool value =
convert_to_int<T, Char, int>::value &&
!internal::is_streamable<T, Char>::value;
};
} // namespace internal
// Formats an object of type T that has an overloaded ostream operator<<.
template<typename T, typename Char>
struct formatter<T, Char, typename std::enable_if<internal::is_streamable<T, Char>::value>::type> : formatter<basic_string_view<Char>, Char>
{
template<typename Context>
auto format(const T &value, Context &ctx) -> decltype(ctx.out())
{
template <typename T, typename Char>
struct formatter<T, Char,
typename std::enable_if<
internal::is_streamable<T, Char>::value &&
!internal::format_type<
typename buffer_context<Char>::type, T>::value>::type>
: formatter<basic_string_view<Char>, Char> {
template <typename Context>
auto format(const T &value, Context &ctx) -> decltype(ctx.out()) {
basic_memory_buffer<Char> buffer;
internal::format_value(buffer, value);
basic_string_view<Char> str(buffer.data(), buffer.size());
formatter<basic_string_view<Char>, Char>::format(str, ctx);
return ctx.out();
return formatter<basic_string_view<Char>, Char>::format(str, ctx);
}
};
template<typename Char>
inline void vprint(
std::basic_ostream<Char> &os, basic_string_view<Char> format_str, basic_format_args<typename buffer_context<Char>::type> args)
{
template <typename Char>
inline void vprint(std::basic_ostream<Char> &os,
basic_string_view<Char> format_str,
basic_format_args<typename buffer_context<Char>::type> args) {
basic_memory_buffer<Char> buffer;
vformat_to(buffer, format_str, args);
internal::write(os, buffer);
......@@ -157,15 +141,15 @@ inline void vprint(
fmt::print(cerr, "Don't {}!", "panic");
\endrst
*/
template<typename... Args>
inline void print(std::ostream &os, string_view format_str, const Args &... args)
{
template <typename... Args>
inline void print(std::ostream &os, string_view format_str,
const Args & ... args) {
vprint<char>(os, format_str, make_format_args<format_context>(args...));
}
template<typename... Args>
inline void print(std::wostream &os, wstring_view format_str, const Args &... args)
{
template <typename... Args>
inline void print(std::wostream &os, wstring_view format_str,
const Args & ... args) {
vprint<wchar_t>(os, format_str, make_format_args<wformat_context>(args...));
}
FMT_END_NAMESPACE
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -13,66 +13,43 @@
FMT_BEGIN_NAMESPACE
namespace internal {
inline null<> localtime_r(...)
{
return null<>();
}
inline null<> localtime_s(...)
{
return null<>();
}
inline null<> gmtime_r(...)
{
return null<>();
}
inline null<> gmtime_s(...)
{
return null<>();
// Prevents expansion of a preceding token as a function-style macro.
// Usage: f FMT_NOMACRO()
#define FMT_NOMACRO
namespace internal{
inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); }
inline null<> localtime_s(...) { return null<>(); }
inline null<> gmtime_r(...) { return null<>(); }
inline null<> gmtime_s(...) { return null<>(); }
}
} // namespace internal
// Thread-safe replacement for std::localtime
inline std::tm localtime(std::time_t time)
{
struct dispatcher
{
inline std::tm localtime(std::time_t time) {
struct dispatcher {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t)
: time_(t)
{
}
dispatcher(std::time_t t): time_(t) {}
bool run()
{
bool run() {
using namespace fmt::internal;
return handle(localtime_r(&time_, &tm_));
}
bool handle(std::tm *tm)
{
return tm != FMT_NULL;
}
bool handle(std::tm *tm) { return tm != FMT_NULL; }
bool handle(internal::null<>)
{
bool handle(internal::null<>) {
using namespace fmt::internal;
return fallback(localtime_s(&tm_, &time_));
}
bool fallback(int res)
{
return res == 0;
}
bool fallback(int res) { return res == 0; }
bool fallback(internal::null<>)
{
bool fallback(internal::null<>) {
using namespace fmt::internal;
std::tm *tm = std::localtime(&time_);
if (tm)
tm_ = *tm;
if (tm) tm_ = *tm;
return tm != FMT_NULL;
}
};
......@@ -84,45 +61,30 @@ inline std::tm localtime(std::time_t time)
}
// Thread-safe replacement for std::gmtime
inline std::tm gmtime(std::time_t time)
{
struct dispatcher
{
inline std::tm gmtime(std::time_t time) {
struct dispatcher {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t)
: time_(t)
{
}
dispatcher(std::time_t t): time_(t) {}
bool run()
{
bool run() {
using namespace fmt::internal;
return handle(gmtime_r(&time_, &tm_));
}
bool handle(std::tm *tm)
{
return tm != FMT_NULL;
}
bool handle(std::tm *tm) { return tm != FMT_NULL; }
bool handle(internal::null<>)
{
bool handle(internal::null<>) {
using namespace fmt::internal;
return fallback(gmtime_s(&tm_, &time_));
}
bool fallback(int res)
{
return res == 0;
}
bool fallback(int res) { return res == 0; }
bool fallback(internal::null<>)
{
bool fallback(internal::null<>) {
std::tm *tm = std::gmtime(&time_);
if (tm)
tm_ = *tm;
if (tm) tm_ = *tm;
return tm != FMT_NULL;
}
};
......@@ -134,23 +96,21 @@ inline std::tm gmtime(std::time_t time)
}
namespace internal {
inline std::size_t strftime(char *str, std::size_t count, const char *format, const std::tm *time)
{
inline std::size_t strftime(char *str, std::size_t count, const char *format,
const std::tm *time) {
return std::strftime(str, count, format, time);
}
inline std::size_t strftime(wchar_t *str, std::size_t count, const wchar_t *format, const std::tm *time)
{
inline std::size_t strftime(wchar_t *str, std::size_t count,
const wchar_t *format, const std::tm *time) {
return std::wcsftime(str, count, format, time);
}
} // namespace internal
template<typename Char>
struct formatter<std::tm, Char>
{
template<typename ParseContext>
auto parse(ParseContext &ctx) -> decltype(ctx.begin())
{
}
template <typename Char>
struct formatter<std::tm, Char> {
template <typename ParseContext>
auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
auto it = internal::null_terminating_iterator<Char>(ctx);
if (*it == ':')
++it;
......@@ -164,22 +124,19 @@ struct formatter<std::tm, Char>
return pointer_from(end);
}
template<typename FormatContext>
auto format(const std::tm &tm, FormatContext &ctx) -> decltype(ctx.out())
{
template <typename FormatContext>
auto format(const std::tm &tm, FormatContext &ctx) -> decltype(ctx.out()) {
internal::basic_buffer<Char> &buf = internal::get_container(ctx.out());
std::size_t start = buf.size();
for (;;)
{
for (;;) {
std::size_t size = buf.capacity() - start;
std::size_t count = internal::strftime(&buf[start], size, &tm_format[0], &tm);
if (count != 0)
{
std::size_t count =
internal::strftime(&buf[start], size, &tm_format[0], &tm);
if (count != 0) {
buf.resize(start + count);
break;
}
if (size >= tm_format.size() * 256)
{
if (size >= tm_format.size() * 256) {
// If the buffer is 256 times larger than the format string, assume
// that `strftime` gives an empty result. There doesn't seem to be a
// better way to distinguish the two cases:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment