1 /* 2 Formatting library for C++ - std::ostream support 3 4 Copyright (c) 2012 - 2016, Victor Zverovich 5 All rights reserved. 6 7 For the license information refer to format.h. 8 */ 9 10 #ifndef FMT_OSTREAM_H_ 11 #define FMT_OSTREAM_H_ 12 13 #include "format.h" 14 #include <ostream> 15 16 namespace fmt { 17 18 namespace internal { 19 20 template <class Char> 21 class FormatBuf : public std::basic_streambuf<Char> { 22 private: 23 typedef typename std::basic_streambuf<Char>::int_type int_type; 24 typedef typename std::basic_streambuf<Char>::traits_type traits_type; 25 26 Buffer<Char> &buffer_; 27 Char *start_; 28 29 public: FormatBuf(Buffer<Char> & buffer)30 FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) { 31 this->setp(start_, start_ + buffer_.capacity()); 32 } 33 34 int_type overflow(int_type ch = traits_type::eof()) { 35 if (!traits_type::eq_int_type(ch, traits_type::eof())) { 36 size_t buf_size = size(); 37 buffer_.resize(buf_size); 38 buffer_.reserve(buf_size * 2); 39 40 start_ = &buffer_[0]; 41 start_[buf_size] = traits_type::to_char_type(ch); 42 this->setp(start_+ buf_size + 1, start_ + buf_size * 2); 43 } 44 return ch; 45 } 46 size()47 size_t size() const { 48 return to_unsigned(this->pptr() - start_); 49 } 50 }; 51 52 Yes &convert(std::ostream &); 53 54 struct DummyStream : std::ostream { 55 DummyStream(); // Suppress a bogus warning in MSVC. 56 // Hide all operator<< overloads from std::ostream. 57 void operator<<(Null<>); 58 }; 59 60 No &operator<<(std::ostream &, int); 61 62 template<typename T> 63 struct ConvertToIntImpl<T, true> { 64 // Convert to int only if T doesn't have an overloaded operator<<. 65 enum { 66 value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No) 67 }; 68 }; 69 70 // Write the content of w to os. 71 void write(std::ostream &os, Writer &w); 72 } // namespace internal 73 74 // Formats a value. 75 template <typename Char, typename ArgFormatter, typename T> 76 void format_arg(BasicFormatter<Char, ArgFormatter> &f, 77 const Char *&format_str, const T &value) { 78 internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer; 79 80 internal::FormatBuf<Char> format_buf(buffer); 81 std::basic_ostream<Char> output(&format_buf); 82 output << value; 83 84 BasicStringRef<Char> str(&buffer[0], format_buf.size()); 85 typedef internal::MakeArg< BasicFormatter<Char> > MakeArg; 86 format_str = f.format(format_str, MakeArg(str)); 87 } 88 89 /** 90 \rst 91 Prints formatted data to the stream *os*. 92 93 **Example**:: 94 95 print(cerr, "Don't {}!", "panic"); 96 \endrst 97 */ 98 FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args); 99 FMT_VARIADIC(void, print, std::ostream &, CStringRef) 100 } // namespace fmt 101 102 #ifdef FMT_HEADER_ONLY 103 # include "ostream.cc" 104 #endif 105 106 #endif // FMT_OSTREAM_H_ 107