class Print
{
public:
virtual void write(uint8_t);
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size);
void print(const String &s);
void print(char c) { write((uint8_t)c); }
void print(const char s[]) { write(s); }
void print(const __FlashStringHelper *f);
void print(uint8_t b) { write(b); }
void print(int n) { print((long)n); }
void print(unsigned int n) { printNumber(n, 10, 0); }
void print(long n);
void print(unsigned long n) { printNumber(n, 10, 0); }
void print(unsigned char n, int base) { printNumber(n, base, 0); }
void print(int n, int base) { (base == 10) ? print(n) : printNumber(n, base, 0); }
void print(unsigned int n, int base) { printNumber(n, base, 0); }
void print(long n, int base) { (base == 10) ? print(n) : printNumber(n, base, 0); }
void print(unsigned long n, int base) { printNumber(n, base, 0); }
void print(double n, int digits = 2) { printFloat(n, digits); }
void println(void);
void println(const String &s) { print(s); println(); }
void println(char c) { print(c); println(); }
void println(const char s[]) { print(s); println(); }
void println(const __FlashStringHelper *f) { print(f); println(); }
void println(uint8_t b) { print(b); println(); }
void println(int n) { print(n); println(); }
void println(unsigned int n) { print(n); println(); }
void println(long n) { print(n); println(); }
void println(unsigned long n) { print(n); println(); }
void println(unsigned char n, int base) { print(n, base); println(); }
void println(int n, int base) { print(n, base); println(); }
void println(unsigned int n, int base) { print(n, base); println(); }
void println(long n, int base) { print(n, base); println(); }
void println(unsigned long n, int base) { print(n, base); println(); }
void println(double n, int digits = 2) { print(n, digits); println(); }
private:
void printNumber(unsigned long n, uint8_t base, uint8_t sign);
void printFloat(double n, uint8_t digits);
};