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
59
String.cpp
59
String.cpp
@ -33,6 +33,7 @@ String& String::operator=(String other) // take parameter by value: can bind
|
|||||||
|
|
||||||
String::~String()
|
String::~String()
|
||||||
{
|
{
|
||||||
|
if (_str)
|
||||||
_str->operator--(); // the ref-counting is done by StringValue, no need to do that here
|
_str->operator--(); // the ref-counting is done by StringValue, no need to do that here
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,23 +71,69 @@ String& String::operator+=(const String& other)
|
|||||||
return *this;
|
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
|
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
|
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[]
|
// reuse const operator[]
|
||||||
char& String::operator[](size_t index)
|
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
|
size_t String::size() const
|
||||||
{ return _str->size(); }
|
{
|
||||||
|
if (_str)
|
||||||
|
return _str->size();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char* String::c_str() const
|
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)
|
std::istream& operator>>(std::istream& is, String& str)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user