diff --git a/String.h b/String.h new file mode 100644 index 0000000..70b5981 --- /dev/null +++ b/String.h @@ -0,0 +1,41 @@ +#pragma once +#include +#include "StringValue.h" + + + +/* Design decisions: + * - Everything related to ref-counting is the responsibility of the StringValue class + * - Anything dynamically allocated is owned (and thus once deleted) by the StringValue class + * (including itself -- this is possible because of the reference counting mechanism) */ +class String +{ +private: + + StringValue* _str; + +public: + + String(); + String(const char*); + String(const String&); + String& operator=(String); + String(String&&); + ~String(); + + friend void swap(String&, String&) noexcept; + String operator+(const String&) const; + String& operator+=(const String&); + String operator+(char) const; + String& operator+=(char); + bool operator==(const String&) const; + const char& operator[](size_t) const; + char& operator[](size_t); + + size_t size() const; // does not include null-terminator + const char* c_str() const; + + friend std::istream& operator>>(std::istream&, String&); +}; + +std::ostream& operator<<(std::ostream&, const String&); \ No newline at end of file diff --git a/StringValue.h b/StringValue.h new file mode 100644 index 0000000..1a65bba --- /dev/null +++ b/StringValue.h @@ -0,0 +1,31 @@ +#pragma once +#include + + + +/* This class claims ownership of: + * + * - The char* passed to it in its ctor + * - Itself (sounds funny) -> When no longer referenced the object deletes it's own memory, + * therefore objects from this class should only be constructed + * via operator new. This might seem like an odd design choice, + * but */ + +class StringValue +{ +private: + + char* _data; + size_t _size; // with null-terminator + size_t _refs; + +public: + + StringValue(char* data); + void operator++(); + void operator--(); + const char& operator[](size_t index) const; + char& operator[](size_t index); + operator const char*() const; + size_t size() const; +}; \ No newline at end of file