#include "Gedeng/String.h" namespace Gedeng { String::String() : String("") { } String::String(const char *stringText) : length(strlen(stringText)), text(new char[length + sizeof(char)]) { memcpy(text, stringText, length + sizeof(char)); } String::String(const String &other) : length(other.get_length()), text(new char[length + sizeof(char)]) { memcpy(text, other.c_str(), length + sizeof(char)); } String &String::operator=(const String &other) { // TODO: We could also check whether the other string has the same capacity // as this one, and if so, reuse the // current char array. However, this would introduce another check which // might cost more performance than it gains (since the length will rarely // be the same) if (this != &other) { length = other.length; // Delete old text and create new delete[] text; text = new char[length + sizeof(char)]; // Copy text memcpy(text, other.c_str(), length + sizeof(char)); } return *this; } String::String(String &&other) : length(other.length), text(other.text) { other.text = nullptr; other.length = 0; } String &String::operator=(String &&other) { if (this != &other) { delete[] text; text = other.text; length = other.length; other.text = nullptr; other.length = 0; } return *this; } String &String::operator+=(const String &other) { concatenate(other); return *this; } String &String::operator+=(const char *other) { concatenate(other); return *this; } String operator+(String left, const String &right) { left += right; return left; } String operator+(String left, const char *right) { left += right; return left; } // TODO: Should cases like `"Hello" + String("World")` be handled? // I think not; it would be up to `const char *` to handle that, since getting // a String after adding something to a `const char *` is strange. It could // look like this however: // String operator+(const char *left, const String &right) { // String left_string = String(left); // left_string += right; // return left_string; //} String::operator const char *() const { return this->c_str(); } String::~String() { delete[] text; } void String::concatenate(const String &other) { concatenate(other.c_str()); } void String::concatenate(const char *other) { // Allocate the new text size_t newStringLength = strlen(other); char *newString = new char[length + newStringLength + sizeof(char)]; // Copy current string, and other string after it memcpy(newString, text, length); memcpy(newString + length, other, newStringLength + sizeof(char)); delete[] text; text = newString; length += newStringLength; } const char *String::c_str() const { return text; } size_t String::get_length() const { return length; } } // namespace Gedeng