127 lines
2.9 KiB
C
Raw Normal View History

2016-10-20 12:14:25 +03:00
/*
Formatting library for C++ - std::ostream support
2016-10-20 12:14:25 +03:00
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
2016-10-20 12:14:25 +03:00
For the license information refer to format.h.
*/
2016-10-20 12:14:25 +03:00
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include "format.h"
2016-10-20 12:14:25 +03:00
#include <ostream>
2017-03-28 02:08:18 +03:00
namespace fmt
{
2016-11-18 17:17:09 +02:00
2017-03-28 02:08:18 +03:00
namespace internal
{
2016-11-18 17:17:09 +02:00
template <class Char>
2017-03-28 02:08:18 +03:00
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_;
Char *start_;
public:
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0])
{
this->setp(start_, start_ + buffer_.capacity());
2016-11-18 17:17:09 +02:00
}
2017-03-28 02:08:18 +03:00
int_type overflow(int_type ch = traits_type::eof())
{
if (!traits_type::eq_int_type(ch, traits_type::eof()))
{
size_t buf_size = size();
buffer_.resize(buf_size);
buffer_.reserve(buf_size * 2);
start_ = &buffer_[0];
start_[buf_size] = traits_type::to_char_type(ch);
this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
}
return ch;
}
size_t size() const
{
return to_unsigned(this->pptr() - start_);
}
2016-11-18 17:17:09 +02:00
};
Yes &convert(std::ostream &);
2017-03-28 02:08:18 +03:00
struct DummyStream : std::ostream
{
DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
void operator<<(Null<>);
2016-11-18 17:17:09 +02:00
};
No &operator<<(std::ostream &, int);
template<typename T>
2017-03-28 02:08:18 +03:00
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)
};
2016-11-18 17:17:09 +02:00
};
} // namespace internal
// Formats a value.
template <typename Char, typename ArgFormatter, typename T>
void format(BasicFormatter<Char, ArgFormatter> &f,
2017-03-28 02:08:18 +03:00
const Char *&format_str, const T &value)
{
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
2017-03-28 02:08:18 +03:00
internal::FormatBuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf);
output << value;
2017-03-28 02:08:18 +03:00
BasicStringRef<Char> str(&buffer[0], format_buf.size());
typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
format_str = f.format(format_str, MakeArg(str));
2016-11-18 17:17:09 +02:00
}
/**
\rst
Prints formatted data to the stream *os*.
2016-11-18 17:17:09 +02:00
**Example**::
2016-11-18 17:17:09 +02:00
print(cerr, "Don't {}!", "panic");
\endrst
*/
2016-11-18 17:17:09 +02:00
FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
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)
2016-10-20 12:14:25 +03:00
} // namespace fmt
#ifdef FMT_HEADER_ONLY
# include "ostream.cc"
#endif
#endif // FMT_OSTREAM_H_