implemented remaining methods and added checks to neccessary methods
(some methods, like size() could segfault on empty Strings)
This commit is contained in:
parent
06d045f457
commit
1dec4febcc
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user