2016-10-23 01:46:28 +00:00
|
|
|
#include "StringValue.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-10-25 12:22:50 +00:00
|
|
|
StringValue::StringValue(char* data) noexcept
|
2016-10-23 01:46:28 +00:00
|
|
|
:_data(data), _size(std::strlen(data) + 1), _refs(1)
|
|
|
|
{}
|
|
|
|
|
2016-10-25 12:22:50 +00:00
|
|
|
void StringValue::operator++() noexcept
|
2016-10-23 01:46:28 +00:00
|
|
|
{ _refs++; }
|
|
|
|
|
2016-10-25 12:22:50 +00:00
|
|
|
void StringValue::operator--() noexcept
|
2016-10-23 01:46:28 +00:00
|
|
|
{
|
|
|
|
_refs--;
|
|
|
|
if (_refs == 0)
|
|
|
|
{
|
|
|
|
delete[] _data;
|
|
|
|
delete this;
|
|
|
|
/* This might seem scary, but StringValues are dynamically allocated and own themselves,
|
|
|
|
* thus when no longer referenced the object can -- and should -- commit suicide. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char& StringValue::operator[](size_t index) const
|
|
|
|
{
|
2016-10-23 12:12:13 +00:00
|
|
|
if (index > _size - 2)
|
2016-10-23 01:46:28 +00:00
|
|
|
throw std::out_of_range("Index out of range!");
|
|
|
|
return _data[index];
|
|
|
|
}
|
|
|
|
|
2016-10-29 18:08:55 +00:00
|
|
|
// reuse const operator[]
|
2016-10-23 01:46:28 +00:00
|
|
|
char& StringValue::operator[](size_t index)
|
|
|
|
{ return const_cast<char&>(const_cast<const StringValue*>(this)->operator[](index)); }
|
|
|
|
|
2016-10-25 12:22:50 +00:00
|
|
|
StringValue::operator const char*() const noexcept
|
2016-10-23 01:46:28 +00:00
|
|
|
{ return _data; }
|
|
|
|
|
2016-10-25 12:22:50 +00:00
|
|
|
size_t StringValue::size() const noexcept
|
2016-10-23 13:28:28 +00:00
|
|
|
{ return _size - 1; }
|
|
|
|
|
|
|
|
size_t StringValue::index_of(char* c) const
|
|
|
|
{
|
2016-10-26 14:37:18 +00:00
|
|
|
size_t index = c - _data; // this is totally safe as long as I don't do anything with it
|
|
|
|
if (index <= this->size()) // if it is within our data it is safe to use
|
2016-10-23 13:28:28 +00:00
|
|
|
return index;
|
|
|
|
else
|
|
|
|
throw std::invalid_argument("char* not within held data!");
|
|
|
|
}
|