implemented remaining methods and added checks to neccessary methods
(some methods, like size() could segfault on empty Strings)
This commit is contained in:
		
							
								
								
									
										61
									
								
								String.cpp
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								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<bool>(std::strcmp(this->c_str(), other.c_str())); }    // explicit cast to silence warning | ||||
| { | ||||
|     if (_str) | ||||
|         return !static_cast<bool>(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<const StringValue*>(_str))->operator[](index); }       // cast to use const operator[] | ||||
| { | ||||
|     if (_str) | ||||
|         return (const_cast<const StringValue*>(_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<char&>(const_cast<const StringValue*>(_str)->operator[](index)); } | ||||
| { | ||||
|     return const_cast<char&>(const_cast<const String*>(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) | ||||
| { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user