|
#ifndef UTIL_FAKE_OSTREAM_H |
|
#define UTIL_FAKE_OSTREAM_H |
|
|
|
#include "float_to_string.hh" |
|
#include "integer_to_string.hh" |
|
#include "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 |
|
|