@@ -60,28 +60,41 @@ class Print
60
60
return write ((const uint8_t *)buffer, size);
61
61
}
62
62
63
+
63
64
// default to zero, meaning "a single write may block"
64
65
// should be overriden by subclasses with buffering
65
66
virtual int availableForWrite () { return 0 ; }
66
67
67
- size_t print (const __FlashStringHelper *);
68
- size_t print (const String &);
69
- size_t print ( signed long , int = DEC);
70
- size_t print (unsigned long , int = DEC);
71
- size_t print (double , int = 2 );
72
-
73
- _always_inline size_t print (const char str[]) { return write (str); }
74
- _always_inline size_t print (const char c) { return write (c); }
75
- _always_inline size_t print (const Printable &x) { return x.printTo (*this ); }
68
+ size_t doPrint (const __FlashStringHelper *);
69
+ size_t doPrint (const String &);
70
+ size_t doPrint ( signed long , int = DEC);
71
+ size_t doPrint (unsigned long , int = DEC);
72
+ size_t doPrint (double , int = 2 );
76
73
77
- _always_inline size_t print ( signed char n, int f = DEC) { return print (( signed long ) n, f); }
78
- _always_inline size_t print ( signed short n, int f = DEC) { return print (( signed long ) n, f); }
79
- _always_inline size_t print ( signed int n, int f = DEC) { return print (( signed long ) n, f); }
80
- _always_inline size_t print (unsigned char n, int f = DEC) { return print ((unsigned long ) n, f); }
81
- _always_inline size_t print (unsigned short n, int f = DEC) { return print ((unsigned long ) n, f); }
82
- _always_inline size_t print (unsigned int n, int f = DEC) { return print ((unsigned long ) n, f); }
83
- _always_inline size_t print ( float n, int f = 2 ) { return print (( double ) n, f); }
74
+ _always_inline size_t doPrint (const char str[]) { return write (str); }
75
+ _always_inline size_t doPrint (const char c) { return write (c); }
76
+ _always_inline size_t doPrint (const Printable &x) { return x.printTo (*this ); }
84
77
78
+ _always_inline size_t doPrint ( signed char n, int f = DEC) { return doPrint (( signed long ) n, f); }
79
+ _always_inline size_t doPrint ( signed short n, int f = DEC) { return doPrint (( signed long ) n, f); }
80
+ _always_inline size_t doPrint ( signed int n, int f = DEC) { return doPrint (( signed long ) n, f); }
81
+ _always_inline size_t doPrint (unsigned char n, int f = DEC) { return doPrint ((unsigned long ) n, f); }
82
+ _always_inline size_t doPrint (unsigned short n, int f = DEC) { return doPrint ((unsigned long ) n, f); }
83
+ _always_inline size_t doPrint (unsigned int n, int f = DEC) { return doPrint ((unsigned long ) n, f); }
84
+ _always_inline size_t doPrint ( float n, int f = 2 ) { return doPrint (( double ) n, f); }
85
+
86
+ template <typename Check, typename T>
87
+ struct check_type {
88
+ using type = T;
89
+ };
90
+ template <typename Check, typename T> using check_type_t = typename check_type<Check, T>::type;
91
+
92
+ template <typename T, typename F>
93
+ _always_inline auto doPrint (T v, F f )
94
+ -> check_type_t <decltype (f.printTo (this , v)), size_t > {
95
+ return f.printTo (this , v);
96
+ }
97
+
85
98
size_t println (void );
86
99
87
100
virtual void flush () { /* Empty implementation for backward compatibility */ }
@@ -90,21 +103,26 @@ class Print
90
103
template <typename ...Ts > _always_inline size_t println (const Ts &...args ) { size_t t = print (args...); return t + println (); }
91
104
#else
92
105
template <typename T> _always_inline size_t println (const T &arg) { size_t t = print (arg); return t + println (); }
93
- template <typename T> _always_inline size_t println (const T &n, int f ) { size_t t = print (n, f ); return t + println (); }
106
+ template <typename T, typename T2 > _always_inline size_t println (const T &arg1, const T2& arg2 ) { size_t t = print (arg1, arg2 ); return t + println (); }
94
107
#endif // __cplusplus >= 201103L
95
108
109
+ _always_inline size_t print () { return 0 ; }
96
110
97
111
/* * Variadic methods **/
98
112
#if __cplusplus >= 201103L // requires C++11
99
- // Ensure there are at least two parameters to avoid infinite recursion.
100
- // e.g. `StringSumHelper s; print(s)` may be treated as `print(s, ...)`
101
- // with `...` being the empty list, thus calling `print(s)` again.
102
- // (This is because print(StringSumHelper) isn't explicitly defined.)
113
+ template <typename T, typename ...Ts >
114
+ _always_inline size_t print (const T &arg, const Ts &...args ) {
115
+ size_t t = doPrint (arg);
116
+ return t + print (args...);
117
+ }
118
+
103
119
template <typename T, typename T2, typename ...Ts >
104
- _always_inline size_t print (const T &arg, const T2 &arg2, const Ts &...args ) {
105
- size_t t = print (arg);
106
- return t + print (arg2, args...);
120
+ _always_inline auto print (const T &arg, const T2 &arg2, const Ts &...args )
121
+ -> check_type_t <decltype (doPrint (arg, arg2)), size_t > {
122
+ size_t t = doPrint (arg, arg2);
123
+ return t + print (args...);
107
124
}
125
+ /*
108
126
// Some methods take an extra int parameter. If so, use these templates.
109
127
// In a future, it would be nice to make the base/precision a special type.
110
128
template<typename ...Ts> _always_inline size_t print( signed char n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
@@ -117,6 +135,10 @@ class Print
117
135
template<typename ...Ts> _always_inline size_t print(unsigned long n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
118
136
template<typename ...Ts> _always_inline size_t print( float n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
119
137
template<typename ...Ts> _always_inline size_t print( double n, int f, const Ts &...args) { size_t t = print(n, f); return t + print(args...); }
138
+ */
139
+ #else
140
+ template <typename T> _always_inline size_t print (const T &arg) { return doPrint (arg); }
141
+ template <typename T, typename T2> _always_inline size_t print (const T &arg1, const T2& arg2) { return doPrint (arg1, arg2); }
120
142
#endif // __cplusplus >= 201103L
121
143
};
122
144
0 commit comments