From 1dec4febccd61a3f763a5edcb5a882ffcd7112c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kjist=C3=B3f?= Date: Sun, 23 Oct 2016 14:12:56 +0200 Subject: [PATCH] implemented remaining methods and added checks to neccessary methods (some methods, like size() could segfault on empty Strings) --- String.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/String.cpp b/String.cpp index 0297387..4cab9db 100644 --- a/String.cpp +++ b/String.cpp @@ -33,7 +33,8 @@ String& String::operator=(String other) // take parameter by value: can bind String::~String() { - _str->operator--(); // the ref-counting is done by StringValue, no need to do that here + if (_str) + _str->operator--(); // the ref-counting is done by StringValue, no need to do that here } void swap(String& s1, String& s2) noexcept @@ -70,23 +71,69 @@ String& String::operator+=(const String& other) return *this; } -// TODO: continue implementing missing stuff from the middle +String String::operator+(char c) const +{ + auto data = new char[this->size() + 2]; // new char + null terminator + std::strcpy(data, this->c_str()); + data[this->size()] = c; + data[this->size()+1] = '\0'; + + String ret; + ret._str = new StringValue(data); + + return ret; +} + +String& String::operator+=(char c) +{ + auto data = new char[this->size() + 2]; // new char + null terminator + std::strcpy(data, this->c_str()); + data[this->size()] = c; + data[this->size()+1] = '\0'; + + _str->operator--(); + _str = new StringValue(data); + + return *this; +} bool String::operator==(const String& other) const -{ return static_cast(std::strcmp(this->c_str(), other.c_str())); } // explicit cast to silence warning +{ + if (_str) + return !static_cast(std::strcmp(this->c_str(), other.c_str())); // explicit cast to silence warning + else + throw std::runtime_error("You cannot compare uninitialized Strings!"); +} const char& String::operator[](size_t index) const -{ return (const_cast(_str))->operator[](index); } // cast to use const operator[] +{ + if (_str) + return (const_cast(_str))->operator[](index); // cast to use const operator[] + else + throw std::runtime_error("You cannot index an uninitialized String!"); +} // reuse const operator[] char& String::operator[](size_t index) -{ return const_cast(const_cast(_str)->operator[](index)); } +{ + return const_cast(const_cast(this)->operator[](index)); +} size_t String::size() const -{ return _str->size(); } +{ + if (_str) + return _str->size(); + else + return 0; +} const char* String::c_str() const -{ return *_str; } // invokes StringValue::operator const char*() +{ + if (_str) + return *_str; // invokes StringValue::operator const char*() + else + throw std::runtime_error("You cannot get the content of an uninitialized string!"); +} std::istream& operator>>(std::istream& is, String& str) {