You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			182 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
| #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<char>(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<long long>(ival);
 | |
| }
 | |
| 
 | |
| OutputStream& OutputStream::operator<<(unsigned short ival) {
 | |
|   return *this << static_cast<unsigned long long>(ival);
 | |
| }
 | |
| 
 | |
| OutputStream& OutputStream::operator<<(int ival) {
 | |
|   return *this << static_cast<long long>(ival);
 | |
| }
 | |
| 
 | |
| OutputStream& OutputStream::operator<<(unsigned int ival) {
 | |
|   return *this << static_cast<unsigned long long>(ival);
 | |
| }
 | |
| 
 | |
| OutputStream& OutputStream::operator<<(long ival) {
 | |
|   return *this << static_cast<long long>(ival);
 | |
| }
 | |
| 
 | |
| OutputStream& OutputStream::operator<<(unsigned long ival) {
 | |
|   return *this << static_cast<unsigned long long>(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<unsigned long long>(LONG_LONG_MAX -
 | |
|    * (LONG_LONG_MAX + LONG_LONG_MIN)); } else { return *this <<
 | |
|    * static_cast<unsigned long long>(-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<unsigned long long>(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<unsigned long long>(base);
 | |
|        div *= base) {
 | |
|   }
 | |
| 
 | |
|   // print number char by char
 | |
|   for (; div > 0; div /= static_cast<unsigned long long>(base)) {
 | |
|     auto digit = ival / div;
 | |
|     if (digit < 10) {
 | |
|       put(static_cast<char>('0' + digit));
 | |
|     } else {
 | |
|       put(static_cast<char>('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<uintptr_t>(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;
 | |
| }
 |