Skip to content

Instantly share code, notes, and snippets.

@mcspr
Created December 15, 2020 15:32
Show Gist options
  • Save mcspr/aab2d925b20af22282ee0959b840d3e1 to your computer and use it in GitHub Desktop.
Save mcspr/aab2d925b20af22282ee0959b840d3e1 to your computer and use it in GitHub Desktop.
diff --git a/cores/esp8266/WString.cpp b/cores/esp8266/WString.cpp
index 07ab99b..81175fa 100644
--- a/cores/esp8266/WString.cpp
+++ b/cores/esp8266/WString.cpp
@@ -36,6 +36,7 @@ String::String(const char *cstr) {
}
String::String(const String &value) {
+ Serial.printf("%p copy from %p\n", this, &value);
init();
*this = value;
}
@@ -46,11 +47,7 @@ String::String(const __FlashStringHelper *pstr) {
}
String::String(String &&rval) noexcept {
- init();
- move(rval);
-}
-
-String::String(StringSumHelper &&rval) noexcept {
+ Serial.printf("%p move from %p\n", this, &rval);
init();
move(rval);
}
@@ -339,87 +336,6 @@ unsigned char String::concat(const __FlashStringHelper *str) {
return 1;
}
-/*********************************************/
-/* Concatenate */
-/*********************************************/
-
-StringSumHelper &operator +(const StringSumHelper &lhs, const String &rhs) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(rhs.buffer(), rhs.len()))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, const char *cstr) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!cstr || !a.concat(cstr, strlen(cstr)))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, char c) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(c))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, unsigned char num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, int num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, unsigned int num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, long num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, float num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, double num) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(num))
- a.invalidate();
- return a;
-}
-
-StringSumHelper &operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs) {
- StringSumHelper &a = const_cast<StringSumHelper &>(lhs);
- if (!a.concat(rhs))
- a.invalidate();
- return a;
-}
-
/*********************************************/
/* Comparison */
/*********************************************/
diff --git a/cores/esp8266/WString.h b/cores/esp8266/WString.h
index dcb0982..b8c3913 100644
--- a/cores/esp8266/WString.h
+++ b/cores/esp8266/WString.h
@@ -27,10 +27,7 @@
#include <string.h>
#include <ctype.h>
#include <pgmspace.h>
-
-// An inherited class for holding the result of a concatenation. These
-// result objects are assumed to be writable by subsequent concatenations.
-class StringSumHelper;
+#include <type_traits>
// an abstract class used as a means to proide a unique pointer type
// but really has no body
@@ -60,7 +57,6 @@ class String {
String(const String &str);
String(const __FlashStringHelper *str);
String(String &&rval) noexcept;
- String(StringSumHelper &&rval) noexcept;
explicit String(char c) {
sso.buff[0] = c;
sso.buff[1] = 0;
@@ -100,9 +96,6 @@ class String {
String &operator =(const char *cstr);
String &operator =(const __FlashStringHelper *str);
String &operator =(String &&rval) noexcept;
- String &operator =(StringSumHelper &&rval) noexcept {
- return operator =((String &&)rval);
- }
// concatenate (works w/ built-in types)
@@ -125,6 +118,7 @@ class String {
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String &operator +=(const String &rhs) {
+ printf("%p += %p\n", this, &rhs);
concat(rhs);
return *this;
}
@@ -168,18 +162,11 @@ class String {
concat(str);
return *this;
}
-
- friend StringSumHelper &operator +(const StringSumHelper &lhs, const String &rhs);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, const char *cstr);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, char c);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned char num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, int num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned int num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, long num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, float num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, double num);
- friend StringSumHelper &operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
+ String &operator +=(String &&rhs) {
+ printf("%p += (&&) %p\n", this, &rhs);
+ concat(rhs);
+ return *this;
+ }
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const {
@@ -285,6 +272,13 @@ class String {
float toFloat(void) const;
double toDouble(void) const;
+ friend String operator+(const String& lhs, const String& rhs);
+ friend String operator+(String&& lhs, const String& rhs);
+ friend String operator+(const String& lhs, String&& rhs);
+ friend String operator+(String&& lhs, String&& rhs);
+ friend String operator+(const String& lhs, const char* rhs);
+ friend String operator+(String&& lhs, const char* rhs);
+
protected:
// Contains the string info when we're not in SSO mode
struct _ptr {
@@ -349,42 +343,52 @@ class String {
void move(String &rhs) noexcept;
};
-class StringSumHelper: public String {
- public:
- StringSumHelper(const String &s) :
- String(s) {
- }
- StringSumHelper(const char *p) :
- String(p) {
- }
- StringSumHelper(char c) :
- String(c) {
- }
- StringSumHelper(unsigned char num) :
- String(num) {
- }
- StringSumHelper(int num) :
- String(num) {
- }
- StringSumHelper(unsigned int num) :
- String(num) {
- }
- StringSumHelper(long num) :
- String(num) {
- }
- StringSumHelper(unsigned long num) :
- String(num) {
- }
- StringSumHelper(float num) :
- String(num) {
- }
- StringSumHelper(double num) :
- String(num) {
- }
- StringSumHelper(const __FlashStringHelper *s) :
- String(s) {
- }
-};
+// contatenation
+
+inline String operator+(const String& lhs, const String& rhs) {
+ String out;
+ out.reserve(lhs.length() + rhs.length() + 2);
+ out += lhs;
+ out += rhs;
+ return out;
+}
+
+inline String operator+(String&& lhs, const String& rhs) {
+ lhs.concat(rhs);
+ return std::move(lhs);
+}
+
+// TODO: fallback to basic copy, can't insert + shift existing string :<
+inline String operator+(const String& lhs, String&& rhs) {
+ return lhs + rhs;
+}
+
+inline String operator+(String&& lhs, String&& rhs) {
+ lhs.concat(rhs);
+ return std::move(lhs);
+}
+
+inline String operator+(const String& lhs, const char* rhs) {
+ if (!rhs) {
+ return {};
+ }
+
+ String out;
+ out.reserve(lhs.length() + strlen_P(rhs) + 2);
+ out += lhs;
+ out += rhs;
+ return out;
+}
+
+inline String operator+(String&& lhs, const char* rhs) {
+ if (!rhs) {
+ lhs.invalidate();
+ return {};
+ }
+
+ lhs += rhs;
+ return std::move(lhs);
+}
extern const String emptyString;
#include <Arduino.h>
void loop() {
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
String a("12345");
String b("56789");
String c("56789");
String d = a + b + c;
Serial.printf("%s %s %s %s\n", a.c_str(), b.c_str(), c.c_str(), d.c_str());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment