Skip to content

Commit 893bcc5

Browse files
BillyDonahuefacchinm
authored andcommitted
String relational operators
The String class has an incomplete set of relational operators with `const char*`. The 6 operators `==`,`!=`,`<`,`>`,`<=`,`>=` must be defined between String and String, but also between String and `const char*`. The motivation is to treat left and right operands symmetrically. str == "hello" works, but swapping arguments to "hello" == str doesn't, which is a potential user surprise. As String is implicitly convertible from `const char*`, but this incurs a "strdup". So it also makes sense to provide relational operators directly with const char* to avoid the expensive promotion of const char* to temporary String, just to do a string value comparison. Resolves: #7139
1 parent b99609e commit 893bcc5

File tree

2 files changed

+32
-28
lines changed

2 files changed

+32
-28
lines changed

Diff for: api/String.cpp

+10-20
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,16 @@ int String::compareTo(const String &s) const
443443
return strcmp(buffer, s.buffer);
444444
}
445445

446+
int String::compareTo(const char *cstr) const
447+
{
448+
if (!buffer || !cstr) {
449+
if (cstr && !*cstr) return 0 - *(unsigned char *)cstr;
450+
if (buffer && len > 0) return *(unsigned char *)buffer;
451+
return 0;
452+
}
453+
return strcmp(buffer, cstr);
454+
}
455+
446456
unsigned char String::equals(const String &s2) const
447457
{
448458
return (len == s2.len && compareTo(s2) == 0);
@@ -455,26 +465,6 @@ unsigned char String::equals(const char *cstr) const
455465
return strcmp(buffer, cstr) == 0;
456466
}
457467

458-
unsigned char String::operator<(const String &rhs) const
459-
{
460-
return compareTo(rhs) < 0;
461-
}
462-
463-
unsigned char String::operator>(const String &rhs) const
464-
{
465-
return compareTo(rhs) > 0;
466-
}
467-
468-
unsigned char String::operator<=(const String &rhs) const
469-
{
470-
return compareTo(rhs) <= 0;
471-
}
472-
473-
unsigned char String::operator>=(const String &rhs) const
474-
{
475-
return compareTo(rhs) >= 0;
476-
}
477-
478468
unsigned char String::equalsIgnoreCase( const String &s2 ) const
479469
{
480470
if (this == &s2) return 1;

Diff for: api/String.h

+22-8
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,30 @@ class String
141141
// comparison (only works w/ Strings and "strings")
142142
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
143143
int compareTo(const String &s) const;
144+
int compareTo(const char *cstr) const;
144145
unsigned char equals(const String &s) const;
145146
unsigned char equals(const char *cstr) const;
146-
unsigned char operator == (const String &rhs) const {return equals(rhs);}
147-
unsigned char operator == (const char *cstr) const {return equals(cstr);}
148-
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
149-
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
150-
unsigned char operator < (const String &rhs) const;
151-
unsigned char operator > (const String &rhs) const;
152-
unsigned char operator <= (const String &rhs) const;
153-
unsigned char operator >= (const String &rhs) const;
147+
148+
friend unsigned char operator == (const String &a, const String &b) { return a.equals(b); }
149+
friend unsigned char operator == (const String &a, const char *b) { return a.equals(b); }
150+
friend unsigned char operator == (const char *a, const String &b) { return b == a; }
151+
friend unsigned char operator < (const String &a, const String &b) { return a.compareTo(b) < 0; }
152+
friend unsigned char operator < (const String &a, const char *b) { return a.compareTo(b) < 0; }
153+
friend unsigned char operator < (const char *a, const String &b) { return b.compareTo(a) > 0; }
154+
155+
friend unsigned char operator != (const String &a, const String &b) { return !(a == b); }
156+
friend unsigned char operator != (const String &a, const char *b) { return !(a == b); }
157+
friend unsigned char operator != (const char *a, const String &b) { return !(a == b); }
158+
friend unsigned char operator > (const String &a, const String &b) { return b < a; }
159+
friend unsigned char operator > (const String &a, const char *b) { return b < a; }
160+
friend unsigned char operator > (const char *a, const String &b) { return b < a; }
161+
friend unsigned char operator <= (const String &a, const String &b) { return !(b < a); }
162+
friend unsigned char operator <= (const String &a, const char *b) { return !(b < a); }
163+
friend unsigned char operator <= (const char *a, const String &b) { return !(b < a); }
164+
friend unsigned char operator >= (const String &a, const String &b) { return !(a < b); }
165+
friend unsigned char operator >= (const String &a, const char *b) { return !(a < b); }
166+
friend unsigned char operator >= (const char *a, const String &b) { return !(a < b); }
167+
154168
unsigned char equalsIgnoreCase(const String &s) const;
155169
unsigned char startsWith( const String &prefix) const;
156170
unsigned char startsWith(const String &prefix, unsigned int offset) const;

0 commit comments

Comments
 (0)