#include "StringValue.h" StringValue::StringValue(char* data) noexcept :_data(data), _size(std::strlen(data) + 1), _refs(1) {} void StringValue::operator++() noexcept { _refs++; } void StringValue::operator--() noexcept { _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 { if (index > _size - 2) throw std::out_of_range("Index out of range!"); return _data[index]; } // reuse const operator[], just as Scott Meyers would char& StringValue::operator[](size_t index) { return const_cast(const_cast(this)->operator[](index)); } StringValue::operator const char*() const noexcept { return _data; } size_t StringValue::size() const noexcept { return _size - 1; } size_t StringValue::index_of(char* c) const { 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 return index; else throw std::invalid_argument("char* not within held data!"); }