Skip to content

Commit e59f96d

Browse files
Add support for variadic Serial.print(...)
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.
1 parent fc896db commit e59f96d

File tree

4 files changed

+90
-218
lines changed

4 files changed

+90
-218
lines changed

Diff for: hardware/arduino/avr/cores/arduino/Print.cpp

+1-93
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,7 @@ size_t Print::print(char c)
6969
return write(c);
7070
}
7171

72-
size_t Print::print(unsigned char b, int base)
73-
{
74-
return print((unsigned long) b, base);
75-
}
76-
77-
size_t Print::print(int n, int base)
78-
{
79-
return print((long) n, base);
80-
}
81-
82-
size_t Print::print(unsigned int n, int base)
83-
{
84-
return print((unsigned long) n, base);
85-
}
86-
87-
size_t Print::print(long n, int base)
72+
size_t Print::print(signed long n, int base)
8873
{
8974
if (base == 0) {
9075
return write(n);
@@ -111,13 +96,6 @@ size_t Print::print(double n, int digits)
11196
return printFloat(n, digits);
11297
}
11398

114-
size_t Print::println(const __FlashStringHelper *ifsh)
115-
{
116-
size_t n = print(ifsh);
117-
n += println();
118-
return n;
119-
}
120-
12199
size_t Print::print(const Printable& x)
122100
{
123101
return x.printTo(*this);
@@ -128,76 +106,6 @@ size_t Print::println(void)
128106
return write("\r\n");
129107
}
130108

131-
size_t Print::println(const String &s)
132-
{
133-
size_t n = print(s);
134-
n += println();
135-
return n;
136-
}
137-
138-
size_t Print::println(const char c[])
139-
{
140-
size_t n = print(c);
141-
n += println();
142-
return n;
143-
}
144-
145-
size_t Print::println(char c)
146-
{
147-
size_t n = print(c);
148-
n += println();
149-
return n;
150-
}
151-
152-
size_t Print::println(unsigned char b, int base)
153-
{
154-
size_t n = print(b, base);
155-
n += println();
156-
return n;
157-
}
158-
159-
size_t Print::println(int num, int base)
160-
{
161-
size_t n = print(num, base);
162-
n += println();
163-
return n;
164-
}
165-
166-
size_t Print::println(unsigned int num, int base)
167-
{
168-
size_t n = print(num, base);
169-
n += println();
170-
return n;
171-
}
172-
173-
size_t Print::println(long num, int base)
174-
{
175-
size_t n = print(num, base);
176-
n += println();
177-
return n;
178-
}
179-
180-
size_t Print::println(unsigned long num, int base)
181-
{
182-
size_t n = print(num, base);
183-
n += println();
184-
return n;
185-
}
186-
187-
size_t Print::println(double num, int digits)
188-
{
189-
size_t n = print(num, digits);
190-
n += println();
191-
return n;
192-
}
193-
194-
size_t Print::println(const Printable& x)
195-
{
196-
size_t n = print(x);
197-
n += println();
198-
return n;
199-
}
200-
201109
// Private Methods /////////////////////////////////////////////////////////////
202110

203111
size_t Print::printNumber(unsigned long n, uint8_t base)

Diff for: hardware/arduino/avr/cores/arduino/Print.h

+44-16
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define OCT 8
3232
#define BIN 2
3333

34+
#define INLINE __attribute__ ((__always_inline__)) inline // undefined at end
35+
3436
class Print
3537
{
3638
private:
@@ -59,26 +61,52 @@ class Print
5961
size_t print(const String &);
6062
size_t print(const char[]);
6163
size_t print(char);
62-
size_t print(unsigned char, int = DEC);
63-
size_t print(int, int = DEC);
64-
size_t print(unsigned int, int = DEC);
65-
size_t print(long, int = DEC);
64+
size_t print(signed long, int = DEC);
6665
size_t print(unsigned long, int = DEC);
6766
size_t print(double, int = 2);
6867
size_t print(const Printable&);
69-
70-
size_t println(const __FlashStringHelper *);
71-
size_t println(const String &s);
72-
size_t println(const char[]);
73-
size_t println(char);
74-
size_t println(unsigned char, int = DEC);
75-
size_t println(int, int = DEC);
76-
size_t println(unsigned int, int = DEC);
77-
size_t println(long, int = DEC);
78-
size_t println(unsigned long, int = DEC);
79-
size_t println(double, int = 2);
80-
size_t println(const Printable&);
68+
69+
INLINE size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
70+
INLINE size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
71+
INLINE size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
72+
INLINE size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
73+
INLINE size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
74+
INLINE size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
75+
INLINE size_t print( float n, int f = 2 ) { return print(( double ) n, f); }
76+
8177
size_t println(void);
78+
79+
#if __cplusplus >= 201103L
80+
template<typename ...Ts> INLINE size_t println(const Ts &...args) { size_t t = print(args...); return t + println(); }
81+
#else
82+
template<typename T> INLINE size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
83+
template<typename T> INLINE size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
84+
#endif // __cplusplus >= 201103L
85+
86+
87+
/** Variadic methods **/
88+
#if __cplusplus >= 201103L
89+
// Ensure there are at least two parameters to avoid infinite recursion.
90+
template<typename T, typename T2, typename ...Ts>
91+
INLINE size_t print(const T &arg, const T2 &arg2, const Ts &...args) {
92+
size_t t = print(arg);
93+
return t + print(arg2, args...);
94+
}
95+
// Some methods take an extra int parameter. If so, use these templates.
96+
// In a future, it would be nice to make the base/precision a special type.
97+
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...); }
98+
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...); }
99+
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...); }
100+
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...); }
101+
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...); }
102+
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...); }
103+
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...); }
104+
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...); }
105+
template<typename ...Ts> INLINE size_t print( float n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
106+
template<typename ...Ts> INLINE size_t print( double n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
107+
#endif // __cplusplus >= 201103L
82108
};
83109

110+
#undef INLINE
111+
84112
#endif

Diff for: hardware/arduino/sam/cores/arduino/Print.cpp

+1-93
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,7 @@ size_t Print::print(char c)
6161
return write(c);
6262
}
6363

64-
size_t Print::print(unsigned char b, int base)
65-
{
66-
return print((unsigned long) b, base);
67-
}
68-
69-
size_t Print::print(int n, int base)
70-
{
71-
return print((long) n, base);
72-
}
73-
74-
size_t Print::print(unsigned int n, int base)
75-
{
76-
return print((unsigned long) n, base);
77-
}
78-
79-
size_t Print::print(long n, int base)
64+
size_t Print::print(signed long n, int base)
8065
{
8166
if (base == 0) {
8267
return write(n);
@@ -103,13 +88,6 @@ size_t Print::print(double n, int digits)
10388
return printFloat(n, digits);
10489
}
10590

106-
size_t Print::println(const __FlashStringHelper *ifsh)
107-
{
108-
size_t n = print(ifsh);
109-
n += println();
110-
return n;
111-
}
112-
11391
size_t Print::print(const Printable& x)
11492
{
11593
return x.printTo(*this);
@@ -120,76 +98,6 @@ size_t Print::println(void)
12098
return write("\r\n");
12199
}
122100

123-
size_t Print::println(const String &s)
124-
{
125-
size_t n = print(s);
126-
n += println();
127-
return n;
128-
}
129-
130-
size_t Print::println(const char c[])
131-
{
132-
size_t n = print(c);
133-
n += println();
134-
return n;
135-
}
136-
137-
size_t Print::println(char c)
138-
{
139-
size_t n = print(c);
140-
n += println();
141-
return n;
142-
}
143-
144-
size_t Print::println(unsigned char b, int base)
145-
{
146-
size_t n = print(b, base);
147-
n += println();
148-
return n;
149-
}
150-
151-
size_t Print::println(int num, int base)
152-
{
153-
size_t n = print(num, base);
154-
n += println();
155-
return n;
156-
}
157-
158-
size_t Print::println(unsigned int num, int base)
159-
{
160-
size_t n = print(num, base);
161-
n += println();
162-
return n;
163-
}
164-
165-
size_t Print::println(long num, int base)
166-
{
167-
size_t n = print(num, base);
168-
n += println();
169-
return n;
170-
}
171-
172-
size_t Print::println(unsigned long num, int base)
173-
{
174-
size_t n = print(num, base);
175-
n += println();
176-
return n;
177-
}
178-
179-
size_t Print::println(double num, int digits)
180-
{
181-
size_t n = print(num, digits);
182-
n += println();
183-
return n;
184-
}
185-
186-
size_t Print::println(const Printable& x)
187-
{
188-
size_t n = print(x);
189-
n += println();
190-
return n;
191-
}
192-
193101
// Private Methods /////////////////////////////////////////////////////////////
194102

195103
size_t Print::printNumber(unsigned long n, uint8_t base)

Diff for: hardware/arduino/sam/cores/arduino/Print.h

+44-16
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define OCT 8
3232
#define BIN 2
3333

34+
#define INLINE __attribute__ ((__always_inline__)) inline // undefined at end
35+
3436
class Print
3537
{
3638
private:
@@ -59,26 +61,52 @@ class Print
5961
size_t print(const String &);
6062
size_t print(const char[]);
6163
size_t print(char);
62-
size_t print(unsigned char, int = DEC);
63-
size_t print(int, int = DEC);
64-
size_t print(unsigned int, int = DEC);
65-
size_t print(long, int = DEC);
64+
size_t print(signed long, int = DEC);
6665
size_t print(unsigned long, int = DEC);
6766
size_t print(double, int = 2);
6867
size_t print(const Printable&);
69-
70-
size_t println(const __FlashStringHelper *);
71-
size_t println(const String &s);
72-
size_t println(const char[]);
73-
size_t println(char);
74-
size_t println(unsigned char, int = DEC);
75-
size_t println(int, int = DEC);
76-
size_t println(unsigned int, int = DEC);
77-
size_t println(long, int = DEC);
78-
size_t println(unsigned long, int = DEC);
79-
size_t println(double, int = 2);
80-
size_t println(const Printable&);
68+
69+
INLINE size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
70+
INLINE size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
71+
INLINE size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
72+
INLINE size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
73+
INLINE size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
74+
INLINE size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
75+
INLINE size_t print( float n, int f = 2 ) { return print(( double ) n, f); }
76+
8177
size_t println(void);
78+
79+
#if __cplusplus >= 201103L
80+
template<typename ...Ts> INLINE size_t println(const Ts &...args) { size_t t = print(args...); return t + println(); }
81+
#else
82+
template<typename T> INLINE size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
83+
template<typename T> INLINE size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
84+
#endif // __cplusplus >= 201103L
85+
86+
87+
/** Variadic methods **/
88+
#if __cplusplus >= 201103L
89+
// Ensure there are at least two parameters to avoid infinite recursion.
90+
template<typename T, typename T2, typename ...Ts>
91+
INLINE size_t print(const T &arg, const T2 &arg2, const Ts &...args) {
92+
size_t t = print(arg);
93+
return t + print(arg2, args...);
94+
}
95+
// Some methods take an extra int parameter. If so, use these templates.
96+
// In a future, it would be nice to make the base/precision a special type.
97+
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...); }
98+
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...); }
99+
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...); }
100+
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...); }
101+
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...); }
102+
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...); }
103+
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...); }
104+
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...); }
105+
template<typename ...Ts> INLINE size_t print( float n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
106+
template<typename ...Ts> INLINE size_t print( double n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
107+
#endif // __cplusplus >= 201103L
82108
};
83109

110+
#undef INLINE
111+
84112
#endif

0 commit comments

Comments
 (0)