#include "outputstream.h" // operator <<: Converts the value in given data type to a string // Print a single character (trivial) OutputStream& OutputStream::operator<<(char c) { put(c); return *this; } OutputStream& OutputStream::operator<<(unsigned char c) { return *this << static_cast(c); } // Printing a null-terminated string OutputStream& OutputStream::operator<<(const char* string) { while ((*string) != '\0') { put(*string); string++; } return *this; } OutputStream& OutputStream::operator<<(bool b) { return *this << (b ? "true" : "false"); } // Print integral numbers in number system base. // All signed types are promoted to long long, // all unsigned types to unsigned long long. OutputStream& OutputStream::operator<<(short ival) { return *this << static_cast(ival); } OutputStream& OutputStream::operator<<(unsigned short ival) { return *this << static_cast(ival); } OutputStream& OutputStream::operator<<(int ival) { return *this << static_cast(ival); } OutputStream& OutputStream::operator<<(unsigned int ival) { return *this << static_cast(ival); } OutputStream& OutputStream::operator<<(long ival) { return *this << static_cast(ival); } OutputStream& OutputStream::operator<<(unsigned long ival) { return *this << static_cast(ival); } // Print a signed , integral number. OutputStream& OutputStream::operator<<(long long ival) { /* Print '-' if number is negative * * In case ival is equal to LONG_LONG_MIN (0x8000000000000000), this * multiplication with -1 will overflow and, as for all signed overflows, * is not specified in C/C++. Thus, this operation will only work when * the system uses two's complement: * ~(0x8000000000000000) + 1 = 0x7fffffffffffffff + 1 = 0x8000000000000000 * * When casting 0x8000000000000000 to unsigned long long, the value will * be (correctly) interpreted as -(LONG_LONG_MIN). * * A solution conforming (more) to the standard could be: * if ((ival < 0) && (base == 10)) { * put('-'); * if (ival == LONG_LONG_MIN) { * return *this << static_cast(LONG_LONG_MAX - * (LONG_LONG_MAX + LONG_LONG_MIN)); } else { return *this << * static_cast(-ival); * } * (However it introduces additional overhead) */ if ((ival < 0) && (base == 10)) { put('-'); ival = -ival; } // Print the remaining positive number using the unsigned output return *this << static_cast(ival); } // Print a unsigned, integral number. OutputStream& OutputStream::operator<<(unsigned long long ival) { if (base == 0) { base = 16; } if (base == 2) { put('0'); put('b'); } else if (base == 8) { put('0'); // octal numbers are prefixed with 0 } else if (base == 16) { put('0'); // hexadecimal numbers are prefixed with 0x put('x'); } // Determine the largest potency in the number system used, which is // still smaller than the number to be printed unsigned long long div; for (div = 1; ival / div >= static_cast(base); div *= base) { } // print number char by char for (; div > 0; div /= static_cast(base)) { auto digit = ival / div; if (digit < 10) { put(static_cast('0' + digit)); } else { put(static_cast('a' + digit - 10)); } ival %= div; } return *this; } // Print a pointer as hexadecimal number OutputStream& OutputStream::operator<<(const void* ptr) { int oldbase = base; base = 16; *this << reinterpret_cast(ptr); base = oldbase; return *this; } // Calls one of the manipulator functions OutputStream& OutputStream::operator<<(OutputStream& (*f)(OutputStream&)) { return f(*this); } /* STREAM MANIPULATORS * * The functions below take and return a reference to an OutputStream object * and are called by OutputStream& operator << (OutputStream& (*f) * (OutputStream&)); The purpose of theses manipulator functions is modifying * the behavior of the stream the are executed on, such as changing the number * system. */ // flush: Explicit buffer flush OutputStream& flush(OutputStream& os) { os.flush(); return os; } // endl: Inserts a newline to the output OutputStream& endl(OutputStream& os) { os << '\n' << flush; return os; } // bin: Selects the binary number system OutputStream& bin(OutputStream& os) { os.base = 2; return os; } // oct: Selects the octal number system OutputStream& oct(OutputStream& os) { os.base = 8; return os; } // dec: Selects the decimal number system OutputStream& dec(OutputStream& os) { os.base = 10; return os; } // hex: Selects the hexadecimal number system OutputStream& hex(OutputStream& os) { os.base = 16; return os; }