fmtlegacy/include/fmt/ostream.h

138 lines
3.8 KiB
C
Raw Normal View History

2018-01-06 17:09:50 +00:00
// Formatting library for C++ - std::ostream support
//
// Copyright (c) 2012 - 2016, Victor Zverovich
// All rights reserved.
//
// For the license information refer to format.h.
2016-05-06 14:37:20 +00:00
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include "fmt/format.h"
2016-05-06 14:37:20 +00:00
#include <ostream>
namespace fmt {
namespace internal {
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;
2017-02-14 17:08:37 +00:00
basic_buffer<Char> &buffer_;
2016-05-06 14:37:20 +00:00
Char *start_;
public:
2017-02-14 17:08:37 +00:00
FormatBuf(basic_buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) {
2016-05-06 14:37:20 +00:00
this->setp(start_, start_ + buffer_.capacity());
}
int_type overflow(int_type ch = traits_type::eof()) {
if (!traits_type::eq_int_type(ch, traits_type::eof())) {
2016-05-07 14:03:21 +00:00
size_t buf_size = size();
buffer_.resize(buf_size);
buffer_.reserve(buf_size * 2);
2016-05-06 14:37:20 +00:00
start_ = &buffer_[0];
2016-05-07 14:03:21 +00:00
start_[buf_size] = traits_type::to_char_type(ch);
this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
2016-05-06 14:37:20 +00:00
}
return ch;
}
size_t size() const {
return to_unsigned(this->pptr() - start_);
}
};
2017-02-19 16:41:38 +00:00
yes &convert(std::ostream &);
2016-05-06 14:37:20 +00:00
struct DummyStream : std::ostream {
DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
2017-02-19 16:41:38 +00:00
void operator<<(null<>);
2016-05-06 14:37:20 +00:00
};
2017-02-19 16:41:38 +00:00
no &operator<<(std::ostream &, int);
2016-05-06 14:37:20 +00:00
template<typename T>
2017-02-19 16:41:38 +00:00
struct convert_to_int_impl<T, true> {
2016-05-06 14:37:20 +00:00
// Convert to int only if T doesn't have an overloaded operator<<.
enum {
value = sizeof(convert(std::declval<DummyStream&>() << std::declval<T>()))
== sizeof(no)
2016-05-06 14:37:20 +00:00
};
};
2016-08-03 15:52:05 +00:00
// Write the content of buf to os.
2017-12-17 17:33:12 +00:00
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 n = size <= max_size ? size : max_size;
os.write(data, static_cast<std::streamsize>(n));
data += n;
size -= n;
} while (size != 0);
}
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 << value;
buffer.resize(format_buf.size());
}
2017-08-13 20:09:02 +00:00
// 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 {};
2016-05-06 14:37:20 +00:00
} // namespace internal
2017-08-13 20:09:02 +00:00
// Formats an object of type T that has an overloaded ostream operator<<.
template <typename T, typename Char>
struct formatter<T, Char,
2017-08-20 17:02:08 +00:00
typename std::enable_if<!internal::format_type<T>::value>::type>
2017-08-13 20:09:02 +00:00
: formatter<basic_string_view<Char>, Char> {
2018-01-06 17:09:50 +00:00
template <typename Context>
2018-01-14 19:00:27 +00:00
auto format(const T &value, Context &ctx) -> decltype(ctx.begin()) {
2017-08-13 20:09:02 +00:00
basic_memory_buffer<Char> buffer;
internal::format_value(buffer, value);
basic_string_view<Char> str(buffer.data(), buffer.size());
2018-01-06 17:09:50 +00:00
formatter<basic_string_view<Char>, Char>::format(str, ctx);
2018-01-14 19:00:27 +00:00
return ctx.begin();
2017-08-13 20:09:02 +00:00
}
};
2016-05-06 14:37:20 +00:00
2017-12-17 17:33:12 +00:00
inline void vprint(std::ostream &os, string_view format_str, format_args args) {
memory_buffer buffer;
vformat_to(buffer, format_str, args);
internal::write(os, buffer);
}
2016-08-27 00:23:13 +00:00
2016-05-06 14:37:20 +00:00
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
print(cerr, "Don't {}!", "panic");
\endrst
*/
2016-08-27 00:23:13 +00:00
template <typename... Args>
inline void print(std::ostream &os, string_view format_str,
2016-08-27 00:23:13 +00:00
const Args & ... args) {
2017-02-05 14:41:39 +00:00
vprint(os, format_str, make_args(args...));
2016-08-27 00:23:13 +00:00
}
2016-05-06 14:37:20 +00:00
} // namespace fmt
#endif // FMT_OSTREAM_H_