| #ifndef UTIL_FAKE_OSTREAM_H |
| #define UTIL_FAKE_OSTREAM_H |
|
|
| #include "util/float_to_string.hh" |
| #include "util/integer_to_string.hh" |
| #include "util/string_piece.hh" |
|
|
| #include <cassert> |
| #include <limits> |
|
|
| #include <stdint.h> |
|
|
| namespace util { |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| template <class Derived> class FakeOStream { |
| public: |
| FakeOStream() {} |
|
|
| |
| Derived &operator<<(StringPiece str) { |
| return C().write(str.data(), str.size()); |
| } |
|
|
| |
| private: |
| template <class Arg> struct EnableIfKludge { |
| typedef Derived type; |
| }; |
| template <class From, unsigned Length = sizeof(From), bool Signed = std::numeric_limits<From>::is_signed, bool IsInteger = std::numeric_limits<From>::is_integer> struct Coerce {}; |
|
|
| template <class From> struct Coerce<From, 2, false, true> { typedef uint16_t To; }; |
| template <class From> struct Coerce<From, 4, false, true> { typedef uint32_t To; }; |
| template <class From> struct Coerce<From, 8, false, true> { typedef uint64_t To; }; |
|
|
| template <class From> struct Coerce<From, 2, true, true> { typedef int16_t To; }; |
| template <class From> struct Coerce<From, 4, true, true> { typedef int32_t To; }; |
| template <class From> struct Coerce<From, 8, true, true> { typedef int64_t To; }; |
| public: |
| template <class From> typename EnableIfKludge<typename Coerce<From>::To>::type &operator<<(const From value) { |
| return CallToString(static_cast<typename Coerce<From>::To>(value)); |
| } |
|
|
| |
| Derived &operator<<(char val) { return put(val); } |
| Derived &operator<<(signed char val) { return put(static_cast<char>(val)); } |
| Derived &operator<<(unsigned char val) { return put(static_cast<char>(val)); } |
|
|
| Derived &operator<<(bool val) { return put(val + '0'); } |
| |
| Derived &operator<<(int val) { return CallToString(static_cast<typename Coerce<int>::To>(val)); } |
|
|
| Derived &operator<<(float val) { return CallToString(val); } |
| Derived &operator<<(double val) { return CallToString(val); } |
|
|
| |
| Derived &operator<<(const void *value) { return CallToString(value); } |
| |
| Derived &operator<<(const char *value) { return *this << StringPiece(value); } |
| Derived &operator<<(char *value) { return *this << StringPiece(value); } |
|
|
| Derived &put(char val) { |
| char *c = C().Ensure(1); |
| *c = val; |
| C().AdvanceTo(++c); |
| return C(); |
| } |
|
|
| char widen(char val) const { return val; } |
|
|
| private: |
| |
| Derived &C() { |
| return *static_cast<Derived*>(this); |
| } |
|
|
| const Derived &C() const { |
| return *static_cast<const Derived*>(this); |
| } |
|
|
| |
| |
| template <class T> Derived &CallToString(const T value) { |
| C().AdvanceTo(ToString(value, C().Ensure(ToStringBuf<T>::kBytes))); |
| return C(); |
| } |
| }; |
|
|
| } |
|
|
| #endif |
|
|