Skip to content

Commit

Permalink
Add support for variadic Serial.print(...)
Browse files Browse the repository at this point in the history
Allows combining multiple arguments into a single call to Print::print[ln], like Serial.print("Answer=", 66, HEX).
This feature requires C++11 or newer to work, but if it is not available the old calls can still be used.
This change is backwards compatible: print(42, 16) prints "2A" as always, not "4216" (the latter can still be achieved with print(42, "", 16) ).
Many functions from Print.cpp have been removed and replaced by inline versions in Print.h, most notably the println(...) ones.  This results in a simplified (and thus easier to maintain) Print.cpp and slightly smaller executables.
  • Loading branch information
cousteaulecommandant committed Jan 9, 2017
1 parent fc896db commit e59f96d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 218 deletions.
94 changes: 1 addition & 93 deletions hardware/arduino/avr/cores/arduino/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,7 @@ size_t Print::print(char c)
return write(c);
}

size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}

size_t Print::print(int n, int base)
{
return print((long) n, base);
}

size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}

size_t Print::print(long n, int base)
size_t Print::print(signed long n, int base)
{
if (base == 0) {
return write(n);
Expand All @@ -111,13 +96,6 @@ size_t Print::print(double n, int digits)
return printFloat(n, digits);
}

size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}

size_t Print::print(const Printable& x)
{
return x.printTo(*this);
Expand All @@ -128,76 +106,6 @@ size_t Print::println(void)
return write("\r\n");
}

size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}

size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}

size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}

size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}

size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}

size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}

// Private Methods /////////////////////////////////////////////////////////////

size_t Print::printNumber(unsigned long n, uint8_t base)
Expand Down
60 changes: 44 additions & 16 deletions hardware/arduino/avr/cores/arduino/Print.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#define OCT 8
#define BIN 2

#define INLINE __attribute__ ((__always_inline__)) inline // undefined at end

class Print
{
private:
Expand Down Expand Up @@ -59,26 +61,52 @@ class Print
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(signed long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);

size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);

INLINE size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
INLINE size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
INLINE size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
INLINE size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
INLINE size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
INLINE size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
INLINE size_t print( float n, int f = 2 ) { return print(( double ) n, f); }

size_t println(void);

#if __cplusplus >= 201103L
template<typename ...Ts> INLINE size_t println(const Ts &...args) { size_t t = print(args...); return t + println(); }
#else
template<typename T> INLINE size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
template<typename T> INLINE size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
#endif // __cplusplus >= 201103L


/** Variadic methods **/
#if __cplusplus >= 201103L
// Ensure there are at least two parameters to avoid infinite recursion.
template<typename T, typename T2, typename ...Ts>
INLINE size_t print(const T &arg, const T2 &arg2, const Ts &...args) {
size_t t = print(arg);
return t + print(arg2, args...);
}
// Some methods take an extra int parameter. If so, use these templates.
// In a future, it would be nice to make the base/precision a special type.
template<typename ...Ts> INLINE size_t print( signed char n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( signed short n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( signed int n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( signed long n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned char n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned short n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned int n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned long n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( float n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( double n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
#endif // __cplusplus >= 201103L
};

#undef INLINE

#endif
94 changes: 1 addition & 93 deletions hardware/arduino/sam/cores/arduino/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,7 @@ size_t Print::print(char c)
return write(c);
}

size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}

size_t Print::print(int n, int base)
{
return print((long) n, base);
}

size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}

size_t Print::print(long n, int base)
size_t Print::print(signed long n, int base)
{
if (base == 0) {
return write(n);
Expand All @@ -103,13 +88,6 @@ size_t Print::print(double n, int digits)
return printFloat(n, digits);
}

size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}

size_t Print::print(const Printable& x)
{
return x.printTo(*this);
Expand All @@ -120,76 +98,6 @@ size_t Print::println(void)
return write("\r\n");
}

size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}

size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}

size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}

size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}

size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}

size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}

// Private Methods /////////////////////////////////////////////////////////////

size_t Print::printNumber(unsigned long n, uint8_t base)
Expand Down
60 changes: 44 additions & 16 deletions hardware/arduino/sam/cores/arduino/Print.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#define OCT 8
#define BIN 2

#define INLINE __attribute__ ((__always_inline__)) inline // undefined at end

class Print
{
private:
Expand Down Expand Up @@ -59,26 +61,52 @@ class Print
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(signed long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);

size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);

INLINE size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
INLINE size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
INLINE size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
INLINE size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
INLINE size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
INLINE size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
INLINE size_t print( float n, int f = 2 ) { return print(( double ) n, f); }

size_t println(void);

#if __cplusplus >= 201103L
template<typename ...Ts> INLINE size_t println(const Ts &...args) { size_t t = print(args...); return t + println(); }
#else
template<typename T> INLINE size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
template<typename T> INLINE size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
#endif // __cplusplus >= 201103L


/** Variadic methods **/
#if __cplusplus >= 201103L
// Ensure there are at least two parameters to avoid infinite recursion.
template<typename T, typename T2, typename ...Ts>
INLINE size_t print(const T &arg, const T2 &arg2, const Ts &...args) {
size_t t = print(arg);
return t + print(arg2, args...);
}
// Some methods take an extra int parameter. If so, use these templates.
// In a future, it would be nice to make the base/precision a special type.
template<typename ...Ts> INLINE size_t print( signed char n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( signed short n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( signed int n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( signed long n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned char n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned short n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned int n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print(unsigned long n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( float n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
template<typename ...Ts> INLINE size_t print( double n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
#endif // __cplusplus >= 201103L
};

#undef INLINE

#endif

0 comments on commit e59f96d

Please sign in to comment.