#include <stdio.h>
#include <string.h>
class mystr {
private:
char *str;
size_t len, buflen;
int *refcount;
public:
const char *c_str() const { return str; }
size_t length() const { return len; }
mystr() {
str = NULL;
*this = "";
}
mystr(const char *s) {
str = NULL;
*this = s;
}
mystr(const mystr &s) {
str = NULL;
*this = s;
}
~mystr() {
unset(str);
}
void printn() const {
printf("%s\n", str);
}
private:
void set(const char *s, size_t newlen) {
char *old = str;
len = newlen;
if (!old || buflen < len) {
if (!old) buflen = 16;
while (buflen < len)
buflen += buflen;
str = new char[buflen + 1];
} else if (*refcount > 1) {
str = new char[buflen + 1];
}
if (str != s) strcpy(str, s);
if (old != str) {
unset(old);
refcount = new int(1);
}
}
void unset(char *str) {
if (str && --*refcount == 0) {
delete refcount;
delete[] str;
}
}
public:
mystr &operator+=(const char *s) {
int oldlen = len;
set(str, len + strlen(s));
strcpy(&str[oldlen], s);
return *this;
}
mystr &operator+=(const mystr &s) {
int oldlen = len;
set(str, len + s.len);
strcpy(&str[oldlen], s.str);
return *this;
}
mystr &operator=(const char *s) {
set(s, strlen(s));
return *this;
}
mystr &operator=(const mystr &s) {
unset(str);
str = s.str;
len = s.len;
buflen = s.buflen;
++*(refcount = s.refcount);
return *this;
}
mystr substr(int start, int len) const {
mystr ret;
ret.set("", len);
strncpy(ret.str, &str[start], len);
ret.str[len] = 0;
return ret;
}
};
mystr operator+(const mystr &s1, const mystr &s2) {
mystr ret = s1;
ret += s2;
return ret;
}
int main() {
mystr s1 = "abc", s2 = s1;
s1 += "def";
printf("s1[%d]%s\n", s1.length(), s1.c_str());
printf("s2[%d]%s\n", s2.length(), s2.c_str());
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCmNsYXNzIG15c3RyIHsKcHJpdmF0ZToKICAgIGNoYXIgKnN0cjsKICAgIHNpemVfdCBsZW4sIGJ1ZmxlbjsKICAgIGludCAqcmVmY291bnQ7CgpwdWJsaWM6CiAgICBjb25zdCBjaGFyICpjX3N0cigpIGNvbnN0IHsgcmV0dXJuIHN0cjsgfQogICAgc2l6ZV90IGxlbmd0aCgpIGNvbnN0IHsgcmV0dXJuIGxlbjsgfQoKICAgIG15c3RyKCkgewogICAgICAgIHN0ciA9IE5VTEw7CiAgICAgICAgKnRoaXMgPSAiIjsKICAgIH0KCiAgICBteXN0cihjb25zdCBjaGFyICpzKSB7CiAgICAgICAgc3RyID0gTlVMTDsKICAgICAgICAqdGhpcyA9IHM7CiAgICB9CgogICAgbXlzdHIoY29uc3QgbXlzdHIgJnMpIHsKICAgICAgICBzdHIgPSBOVUxMOwogICAgICAgICp0aGlzID0gczsKICAgIH0KCiAgICB+bXlzdHIoKSB7CiAgICAgICAgdW5zZXQoc3RyKTsKICAgIH0KCiAgICB2b2lkIHByaW50bigpIGNvbnN0IHsKICAgICAgICBwcmludGYoIiVzXG4iLCBzdHIpOwogICAgfQoKcHJpdmF0ZToKICAgIHZvaWQgc2V0KGNvbnN0IGNoYXIgKnMsIHNpemVfdCBuZXdsZW4pIHsKICAgICAgICBjaGFyICpvbGQgPSBzdHI7CiAgICAgICAgbGVuID0gbmV3bGVuOwogICAgICAgIGlmICghb2xkIHx8IGJ1ZmxlbiA8IGxlbikgewogICAgICAgICAgICBpZiAoIW9sZCkgYnVmbGVuID0gMTY7CiAgICAgICAgICAgIHdoaWxlIChidWZsZW4gPCBsZW4pCiAgICAgICAgICAgICAgICBidWZsZW4gKz0gYnVmbGVuOwogICAgICAgICAgICBzdHIgPSBuZXcgY2hhcltidWZsZW4gKyAxXTsKICAgICAgICB9IGVsc2UgaWYgKCpyZWZjb3VudCA+IDEpIHsKICAgICAgICAgICAgc3RyID0gbmV3IGNoYXJbYnVmbGVuICsgMV07CiAgICAgICAgfQogICAgICAgIGlmIChzdHIgIT0gcykgc3RyY3B5KHN0ciwgcyk7CiAgICAgICAgaWYgKG9sZCAhPSBzdHIpIHsKICAgICAgICAgICAgdW5zZXQob2xkKTsKICAgICAgICAgICAgcmVmY291bnQgPSBuZXcgaW50KDEpOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIHVuc2V0KGNoYXIgKnN0cikgewogICAgICAgIGlmIChzdHIgJiYgLS0qcmVmY291bnQgPT0gMCkgewogICAgICAgICAgICBkZWxldGUgcmVmY291bnQ7CiAgICAgICAgICAgIGRlbGV0ZVtdIHN0cjsKICAgICAgICB9CiAgICB9CgpwdWJsaWM6CiAgICBteXN0ciAmb3BlcmF0b3IrPShjb25zdCBjaGFyICpzKSB7CiAgICAgICAgaW50IG9sZGxlbiA9IGxlbjsKICAgICAgICBzZXQoc3RyLCBsZW4gKyBzdHJsZW4ocykpOwogICAgICAgIHN0cmNweSgmc3RyW29sZGxlbl0sIHMpOwogICAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICBteXN0ciAmb3BlcmF0b3IrPShjb25zdCBteXN0ciAmcykgewogICAgICAgIGludCBvbGRsZW4gPSBsZW47CiAgICAgICAgc2V0KHN0ciwgbGVuICsgcy5sZW4pOwogICAgICAgIHN0cmNweSgmc3RyW29sZGxlbl0sIHMuc3RyKTsKICAgICAgICByZXR1cm4gKnRoaXM7CiAgICB9CgogICAgbXlzdHIgJm9wZXJhdG9yPShjb25zdCBjaGFyICpzKSB7CiAgICAgICAgc2V0KHMsIHN0cmxlbihzKSk7CiAgICAgICAgcmV0dXJuICp0aGlzOwogICAgfQoKICAgIG15c3RyICZvcGVyYXRvcj0oY29uc3QgbXlzdHIgJnMpIHsKICAgICAgICB1bnNldChzdHIpOwogICAgICAgIHN0ciA9IHMuc3RyOwogICAgICAgIGxlbiA9IHMubGVuOwogICAgICAgIGJ1ZmxlbiA9IHMuYnVmbGVuOwogICAgICAgICsrKihyZWZjb3VudCA9IHMucmVmY291bnQpOwogICAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICBteXN0ciBzdWJzdHIoaW50IHN0YXJ0LCBpbnQgbGVuKSBjb25zdCB7CiAgICAgICAgbXlzdHIgcmV0OwogICAgICAgIHJldC5zZXQoIiIsIGxlbik7CiAgICAgICAgc3RybmNweShyZXQuc3RyLCAmc3RyW3N0YXJ0XSwgbGVuKTsKICAgICAgICByZXQuc3RyW2xlbl0gPSAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9Cn07CgpteXN0ciBvcGVyYXRvcisoY29uc3QgbXlzdHIgJnMxLCBjb25zdCBteXN0ciAmczIpIHsKICAgIG15c3RyIHJldCA9IHMxOwogICAgcmV0ICs9IHMyOwogICAgcmV0dXJuIHJldDsKfQoKaW50IG1haW4oKSB7CiAgICBteXN0ciBzMSA9ICJhYmMiLCBzMiA9IHMxOwogICAgczEgKz0gImRlZiI7CiAgICBwcmludGYoInMxWyVkXSVzXG4iLCBzMS5sZW5ndGgoKSwgczEuY19zdHIoKSk7CiAgICBwcmludGYoInMyWyVkXSVzXG4iLCBzMi5sZW5ndGgoKSwgczIuY19zdHIoKSk7Cn0K