| /* |
| Formatting library for C++ - std::ostream support |
| |
| Copyright (c) 2012 - 2016, Victor Zverovich |
| All rights reserved. |
| |
| For the license information refer to format.h. |
| */ |
| |
| #ifndef FMT_OSTREAM_H_ |
| #define FMT_OSTREAM_H_ |
| |
| #include "format.h" |
| #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; |
| |
| Buffer<Char> &buffer_; |
| |
| public: |
| FormatBuf(Buffer<Char> &buffer) : buffer_(buffer) {} |
| |
| 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 |
| // disadvantage is that each call to sputc always results in a (virtual) call |
| // 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 { |
| 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 { |
| buffer_.append(s, s + count); |
| return count; |
| } |
| }; |
| |
| Yes &convert(std::ostream &); |
| |
| struct DummyStream : std::ostream { |
| DummyStream(); // Suppress a bogus warning in MSVC. |
| |
| // Hide all operator<< overloads from std::ostream. |
| template <typename T> |
| typename EnableIf<sizeof(T) == 0>::type operator<<(const T &); |
| }; |
| |
| No &operator<<(std::ostream &, int); |
| |
| template <typename T> |
| struct ConvertToIntImpl<T, true> { |
| // Convert to int only if T doesn't have an overloaded operator<<. |
| enum { |
| value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No) |
| }; |
| }; |
| |
| // Write the content of w to os. |
| FMT_API void write(std::ostream &os, Writer &w); |
| } // namespace internal |
| |
| // Formats a value. |
| template <typename Char, typename ArgFormatter_, typename T> |
| void format_arg(BasicFormatter<Char, ArgFormatter_> &f, |
| const Char *&format_str, const T &value) { |
| internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer; |
| |
| 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; |
| |
| BasicStringRef<Char> str(&buffer[0], buffer.size()); |
| typedef internal::MakeArg< BasicFormatter<Char> > MakeArg; |
| format_str = f.format(format_str, MakeArg(str)); |
| } |
| |
| /** |
| \rst |
| Prints formatted data to the stream *os*. |
| |
| **Example**:: |
| |
| print(cerr, "Don't {}!", "panic"); |
| \endrst |
| */ |
| FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args); |
| FMT_VARIADIC(void, print, std::ostream &, CStringRef) |
| } // namespace fmt |
| |
| #ifdef FMT_HEADER_ONLY |
| # include "ostream.cc" |
| #endif |
| |
| #endif // FMT_OSTREAM_H_ |