Skip to content

Commit 78e5153

Browse files
committed
String: removing implicit numeric conversions and new approach to "if (s)".
This makes explicit the String constructors that take numeric types and chars and removes the versions of concat() and operator=() and operator+() that accept numberic types. It also replaces the operator bool() with a operator that converts to a function pointer. This allows for uses like "if (s)" but not "s + 123". See: http://www.artima.com/cppsource/safebool.html. This allowed removing the disambiguating operator+() functions and relying solely on StringSumHelper and anonymous temporaries once again. Also, now treating unsigned char's like int when constructing Strings from them, i.e. String(byte(65)) is now "65" not "A". This is consistent with the new behavior of Serial.print(byte).
1 parent c87b5ab commit 78e5153

File tree

2 files changed

+24
-163
lines changed

2 files changed

+24
-163
lines changed

hardware/arduino/cores/arduino/WString.cpp

Lines changed: 10 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,21 @@ String::String(StringSumHelper &&rval)
5454
String::String(char c)
5555
{
5656
init();
57-
*this = c;
57+
char buf[2];
58+
buf[0] = c;
59+
buf[1] = 0;
60+
*this = buf;
5861
}
5962

60-
String::String(unsigned char c)
63+
String::String(unsigned char value, unsigned char base)
6164
{
6265
init();
63-
*this = (char)c;
66+
char buf[9];
67+
utoa(value, buf, base);
68+
*this = buf;
6469
}
6570

66-
String::String(const int value, unsigned char base)
71+
String::String(int value, unsigned char base)
6772
{
6873
init();
6974
char buf[18];
@@ -75,7 +80,7 @@ String::String(unsigned int value, unsigned char base)
7580
{
7681
init();
7782
char buf[17];
78-
utoa(value, buf, base);
83+
utoa(value, buf, base);
7984
*this = buf;
8085
}
8186

@@ -209,14 +214,6 @@ String & String::operator = (const char *cstr)
209214
return *this;
210215
}
211216

212-
String & String::operator = (char c)
213-
{
214-
char buf[2];
215-
buf[0] = c;
216-
buf[1] = 0;
217-
return copy(buf, 1);
218-
}
219-
220217
/*********************************************/
221218
/* concat */
222219
/*********************************************/
@@ -243,42 +240,6 @@ unsigned char String::concat(const char *cstr)
243240
return concat(cstr, strlen(cstr));
244241
}
245242

246-
unsigned char String::concat(char c)
247-
{
248-
char buf[2];
249-
buf[0] = c;
250-
buf[1] = 0;
251-
return concat(buf, 1);
252-
}
253-
254-
unsigned char String::concat(int num)
255-
{
256-
char buf[7];
257-
itoa(num, buf, 10);
258-
return concat(buf, strlen(buf));
259-
}
260-
261-
unsigned char String::concat(unsigned int num)
262-
{
263-
char buf[6];
264-
utoa(num, buf, 10);
265-
return concat(buf, strlen(buf));
266-
}
267-
268-
unsigned char String::concat(long num)
269-
{
270-
char buf[12];
271-
ltoa(num, buf, 10);
272-
return concat(buf, strlen(buf));
273-
}
274-
275-
unsigned char String::concat(unsigned long num)
276-
{
277-
char buf[11];
278-
ultoa(num, buf, 10);
279-
return concat(buf, strlen(buf));
280-
}
281-
282243
/*********************************************/
283244
/* Concatenate */
284245
/*********************************************/
@@ -297,57 +258,10 @@ StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
297258
return a;
298259
}
299260

300-
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
301-
{
302-
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
303-
if (!a.concat(c)) a.invalidate();
304-
return a;
305-
}
306-
307-
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c)
308-
{
309-
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
310-
if (!a.concat(c)) a.invalidate();
311-
return a;
312-
}
313-
314-
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
315-
{
316-
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
317-
if (!a.concat(num)) a.invalidate();
318-
return a;
319-
}
320-
321-
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
322-
{
323-
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
324-
if (!a.concat(num)) a.invalidate();
325-
return a;
326-
}
327-
328-
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
329-
{
330-
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
331-
if (!a.concat(num)) a.invalidate();
332-
return a;
333-
}
334-
335-
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
336-
{
337-
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
338-
if (!a.concat(num)) a.invalidate();
339-
return a;
340-
}
341-
342261
/*********************************************/
343262
/* Comparison */
344263
/*********************************************/
345264

346-
String::operator bool() const
347-
{
348-
return !!buffer;
349-
}
350-
351265
int String::compareTo(const String &s) const
352266
{
353267
if (!buffer || !s.buffer) {

hardware/arduino/cores/arduino/WString.h

Lines changed: 14 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class StringSumHelper;
4141
// The string class
4242
class String
4343
{
44+
// use a function pointer to allow for "if (s)" without the
45+
// complications of an operator bool(). for more information, see:
46+
// http://www.artima.com/cppsource/safebool.html
47+
typedef void (String::*StringIfHelperType)() const;
48+
void StringIfHelper() const {}
49+
4450
public:
4551
// constructors
4652
// creates a copy of the initial value.
@@ -53,12 +59,12 @@ class String
5359
String(String &&rval);
5460
String(StringSumHelper &&rval);
5561
#endif
56-
String(char c);
57-
String(unsigned char c);
58-
String(int, unsigned char base=10);
59-
String(unsigned int, unsigned char base=10);
60-
String(long, unsigned char base=10);
61-
String(unsigned long, unsigned char base=10);
62+
explicit String(char c);
63+
explicit String(unsigned char, unsigned char base=10);
64+
explicit String(int, unsigned char base=10);
65+
explicit String(unsigned int, unsigned char base=10);
66+
explicit String(long, unsigned char base=10);
67+
explicit String(unsigned long, unsigned char base=10);
6268
~String(void);
6369

6470
// memory management
@@ -77,44 +83,26 @@ class String
7783
String & operator = (String &&rval);
7884
String & operator = (StringSumHelper &&rval);
7985
#endif
80-
String & operator = (char c);
8186

8287
// concat
8388
// returns true on success, false on failure (in which case, the string
8489
// is left unchanged). if the argument is null or invalid, the
8590
// concatenation is considered unsucessful.
8691
unsigned char concat(const String &str);
8792
unsigned char concat(const char *cstr);
88-
unsigned char concat(char c);
89-
unsigned char concat(unsigned char c) {return concat((char)c);}
90-
unsigned char concat(int num);
91-
unsigned char concat(unsigned int num);
92-
unsigned char concat(long num);
93-
unsigned char concat(unsigned long num);
9493

9594
// if there's not enough memory for the concatenated value, the string
9695
// will be left unchanged (but this isn't signalled in any way)
9796
String & operator += (const String &rhs) {concat(rhs); return (*this);}
9897
String & operator += (const char *cstr) {concat(cstr); return (*this);}
99-
String & operator += (char c) {concat(c); return (*this);}
100-
String & operator += (unsigned char c) {concat((char)c); return (*this);}
101-
String & operator += (int num) {concat(num); return (*this);}
102-
String & operator += (unsigned int num) {concat(num); return (*this);}
103-
String & operator += (long num) {concat(num); return (*this);}
104-
String & operator += (unsigned long num) {concat(num); return (*this);}
10598

10699
// concatenate
107100
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
108101
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
109-
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
110-
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c);
111-
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
112-
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
113-
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
114-
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
115102

116103
// comparison
117-
operator bool() const;
104+
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
105+
118106
int compareTo(const String &s) const;
119107
unsigned char equals(const String &s) const;
120108
unsigned char equals(const char *cstr) const;
@@ -185,48 +173,7 @@ class StringSumHelper : public String
185173
public:
186174
StringSumHelper(const String &s) : String(s) {}
187175
StringSumHelper(const char *p) : String(p) {}
188-
StringSumHelper(char c) : String(c) {}
189-
StringSumHelper(unsigned char c) : String(c) {}
190-
StringSumHelper(int num) : String(num, 10) {}
191-
StringSumHelper(unsigned int num) : String(num, 10) {}
192-
StringSumHelper(long num) : String(num, 10) {}
193-
StringSumHelper(unsigned long num) : String(num, 10) {}
194176
};
195177

196-
inline StringSumHelper operator + (const String &lhs, const String &rhs)
197-
{ return StringSumHelper(lhs) + rhs; }
198-
199-
inline StringSumHelper operator + (const String &lhs, const char *cstr)
200-
{ return StringSumHelper(lhs) + cstr; }
201-
inline StringSumHelper operator + (const String &lhs, char c)
202-
{ return StringSumHelper(lhs) + c; }
203-
inline StringSumHelper operator + (const String &lhs, unsigned char c)
204-
{ return StringSumHelper(lhs) + c; }
205-
inline StringSumHelper operator + (const String &lhs, int num)
206-
{ return StringSumHelper(lhs) + num; }
207-
inline StringSumHelper operator + (const String &lhs, unsigned int num)
208-
{ return StringSumHelper(lhs) + num; }
209-
inline StringSumHelper operator + (const String &lhs, long num)
210-
{ return StringSumHelper(lhs) + num; }
211-
inline StringSumHelper operator + (const String &lhs, unsigned long num)
212-
{ return StringSumHelper(lhs) + num; }
213-
214-
inline StringSumHelper operator + (const char *cstr, const String &rhs)
215-
{ return StringSumHelper(cstr) + rhs; }
216-
inline StringSumHelper operator + (char c, const String &rhs)
217-
{ return StringSumHelper(c) + rhs; }
218-
inline StringSumHelper operator + (unsigned char c, const String &rhs)
219-
{ return StringSumHelper(c) + rhs; }
220-
inline StringSumHelper operator + (int num, const String &rhs)
221-
{ return StringSumHelper(num) + rhs; }
222-
inline StringSumHelper operator + (unsigned int num, const String &rhs)
223-
{ return StringSumHelper(num) + rhs; }
224-
inline StringSumHelper operator + (long num, const String &rhs)
225-
{ return StringSumHelper(num) + rhs; }
226-
inline StringSumHelper operator + (unsigned long num, const String &rhs)
227-
{ return StringSumHelper(num) + rhs; }
228-
229-
230-
231178
#endif // __cplusplus
232179
#endif // String_class_h

0 commit comments

Comments
 (0)