| | #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 |
| |
|