#include "String.h" #include #include #include #include namespace ecci { const size_t String::npos = static_cast(-1); #ifdef TESTING size_t String::instanceCount = 0; #endif // ---------------------------- Construction ---------------------------- String::String(const char *cstr) : str(nullptr) , len(0) { // Given C-string pointer must never be null assert(cstr != nullptr); // First pass for the original C-string len = strlen(cstr); // Storage is asked in dynamic memory str = (char*) malloc(len + 1); // Verify there was enough memory for storing a copy of the given string assert(str); // Copy original string in the dynamic memory, second pass for the original string strcpy(str, cstr); #ifdef TESTING instanceCount++; #endif } String::String(size_t initialLength) : str( (char*) malloc(initialLength + 1)) , len(0) { assert(str); *str = '\0'; #ifdef TESTING instanceCount++; #endif } String::String(const String& other) : str( nullptr ) , len( other.len ) { str = (char*) malloc(len + 1); assert(str); strcpy( str, other.str ); #ifdef TESTING instanceCount++; #endif } String::String(String&& temp) : str(temp.str) , len(temp.len) { temp.str = nullptr; temp.len = 0; #ifdef TESTING instanceCount++; #endif } const String& String::operator=(const String& other) { // Avoid this object to overwrite itself if ( this != &other ) { len = other.len; free(str); str = (char*) malloc(len + 1); assert(str); strcpy( str, other.str ); } return *this; } const String& String::operator=(String &&temp) { if ( this != &temp ) { delete [] this->str; this->str = temp.str; this->len = temp.len; temp.str = nullptr; temp.len = 0; } return *this; } String::~String() { free(str); } // ---------------------------- Comparison ---------------------------- bool String::operator==(const String& other) const { return len == other.len && strcmp(str, other.str) == 0; } // ---------------------------- Concatenation ---------------------------- String operator+(const String& a, const String& b) { String result( a.len + b.len ); strcpy(result.str, a.str); strcpy(result.str + a.len, b.str); result.len = a.len + b.len; return result; } String String::operator+(const char *cstr) const { size_t newLength = len + strlen(cstr); String result( newLength ); strcpy(result.str, this->str); strcpy(result.str + this->len, cstr); result.len = newLength; return result; } String operator+(const char* cstr, const String& string) { size_t cstrLength = strlen(cstr); size_t newLength = cstrLength + string.len; String result( newLength ); strcpy(result.str, cstr); strcpy(result.str + cstrLength, string.str); result.len = newLength; return result; } String operator+(const String& string, int num) { char buffer[128]; sprintf(buffer, "%i", num); //std::itoa(num, buffer, 10); return string + buffer; } String operator+(int num, const String& string) { char buffer[128]; //itoa(num, buffer, 10); sprintf(buffer, "%i", num); return buffer + string; } } // namespace ecci