Compare commits
	
		
			No commits in common. "2da7623dd3e30f6ea6abb5da639fe9e74743f388" and "66cefdfd63fc25fc2b4cf4b2009fc7a59f74801e" have entirely different histories.
		
	
	
		
			2da7623dd3
			...
			66cefdfd63
		
	
		
					 5 changed files with 199 additions and 291 deletions
				
			
		|  | @ -1,18 +1,16 @@ | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include "miptstring.h" | #include "miptstring.cpp" | ||||||
| #include "miptstringview.h" | #include "miptstringview.cpp" | ||||||
|  | 
 | ||||||
| using namespace std; | using namespace std; | ||||||
| 
 | 
 | ||||||
| int main() { | int main() { | ||||||
|     mipt::String a = "abcd"; |         mipt::String str = "Meow!!"; | ||||||
|     mipt::String b = "abce"; |         cout << str << endl; | ||||||
|     mipt::StringView av = a; |         mipt::StringView sv = str; | ||||||
|     mipt::StringView bv = b; |         cout << "string view: " << sv << endl;  | ||||||
|     //cout << (b < a) << endl;
 |         char a[] = "nyaa!"; | ||||||
|     //cout << (bv < av) << endl;
 |         mipt::StringView sv1 = a; | ||||||
|     cout << av.substr(1,10) << endl;  |        cout << "string view: " << sv1 << endl;  | ||||||
|     av.remove_suffix(2); |        cout << sv1.at(200) << endl; | ||||||
|     cout << av << endl; |  | ||||||
|     mipt::String meow = av; |  | ||||||
|     cout << "sv to string: " << meow << endl; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include "miptstring.h" |  | ||||||
| #include "miptstringview.h" |  | ||||||
| using std::cout, std::cin, std::endl, std::size_t; | using std::cout, std::cin, std::endl, std::size_t; | ||||||
| 
 | 
 | ||||||
| namespace mipt{ | namespace mipt{ | ||||||
|  | @ -19,182 +19,185 @@ char* errorCheckedMalloc(size_t newCapacity) | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| String::String(const char* str)  | 
 | ||||||
|  | class String  | ||||||
| { | { | ||||||
|     size_t strSize = std::strlen(str); | private: | ||||||
|     resize(strSize); |  | ||||||
|     std::memcpy(mpData, str, mSize); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| String::String() : String("") {} |     size_t mSize        {0}; | ||||||
| String::String(const String& s) : String(s.cStr()) {} |     size_t mCapacity    {0}; | ||||||
| String::String(const StringView& sv) { |     char* mpData        {nullptr}; | ||||||
|         mSize = sv.size(); |  | ||||||
|         (*this).reserve(mSize); |  | ||||||
|         for(int i = 0; i < mSize; ++i) |  | ||||||
|             mpData[i] = sv[i]; |  | ||||||
|         mpData[mSize] = '\0'; |  | ||||||
| 
 | 
 | ||||||
| } | public: | ||||||
| 
 | 
 | ||||||
| String::String(size_t n, char a) |     String(const char* str)  | ||||||
| { |  | ||||||
|     resize(n); |  | ||||||
| 
 |  | ||||||
|     for (size_t i = 0; i < mSize; ++i) |  | ||||||
|         mpData[i] = a; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| String::~String() |  | ||||||
| { |  | ||||||
|     std::free(mpData); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void String::reserve(size_t capacity) |  | ||||||
| { |  | ||||||
|     if (capacity <= mCapacity) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     mCapacity = std::max(2 * mCapacity, capacity); |  | ||||||
|     char* newData = errorCheckedMalloc(mCapacity); |  | ||||||
| 
 |  | ||||||
|     if (mpData) |  | ||||||
|         std::memcpy(newData, mpData, mSize + 1); |  | ||||||
| 
 |  | ||||||
|     std::free(mpData); |  | ||||||
|     mpData = newData; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void String::resize(size_t size) |  | ||||||
| { |  | ||||||
|     reserve(size + 1); |  | ||||||
|     mSize = size; |  | ||||||
|     mpData[mSize] = '\0'; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| String& String::operator=(const String& right) |  | ||||||
| { |  | ||||||
|     if (this == &right) |  | ||||||
|         return *this; |  | ||||||
| 
 |  | ||||||
|     mSize = right.mSize; |  | ||||||
|     resize(mSize); |  | ||||||
| 
 |  | ||||||
|     std::memcpy(mpData, right.mpData, mSize + 1); |  | ||||||
| 
 |  | ||||||
|     return *this; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| String String::operator+(const String& b) |  | ||||||
| { |  | ||||||
|     String result; |  | ||||||
|     result.resize(mSize + b.mSize); |  | ||||||
| 
 |  | ||||||
|     std::memcpy(result.mpData, mpData, mSize); |  | ||||||
|     std::memcpy(result.mpData + mSize, b.mpData, b.mSize); |  | ||||||
|     result.mpData[result.mSize] = '\0'; |  | ||||||
| 
 |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| String& String::operator+=(const String& right) |  | ||||||
| { |  | ||||||
|     *this = *this + right; |  | ||||||
|     return *this; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool String::operator==(const String& right) const |  | ||||||
| { |  | ||||||
|     if (mSize != right.mSize) |  | ||||||
|         return false; |  | ||||||
| 
 |  | ||||||
|     size_t i = 0; |  | ||||||
|     while (i < mSize && mpData[i] == right.mpData[i]) |  | ||||||
|         i++; |  | ||||||
| 
 |  | ||||||
|     return i == mSize; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool String::operator<(const String& right) const |  | ||||||
| { |  | ||||||
|     size_t i = 0; |  | ||||||
|     while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) |  | ||||||
|         i++; |  | ||||||
| 
 |  | ||||||
|     return mpData[i] < right.mpData[i]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool String::operator<=(const String& right) const |  | ||||||
| { |  | ||||||
|     size_t i = 0; |  | ||||||
|     while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) |  | ||||||
|         i++; |  | ||||||
| 
 |  | ||||||
|     return mpData[i] <= right.mpData[i]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool String::operator!=(const String& right) const |  | ||||||
| { |  | ||||||
|     return !(*this == right); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool String::operator>(const String& right) const |  | ||||||
| { |  | ||||||
|     return !(*this <= right); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool String::operator>=(const String& right) const |  | ||||||
| { |  | ||||||
|     return !(*this < right); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| char& String::operator[](size_t i) |  | ||||||
| { |  | ||||||
|     return mpData[i]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| const char& String::operator[](size_t i) const |  | ||||||
| { |  | ||||||
|     return mpData[i]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| char& String::at(size_t i) |  | ||||||
| { |  | ||||||
|     if (i >= mSize) |  | ||||||
|     { |     { | ||||||
|         cout << "Error! Index is out of bounds." << endl; |         size_t strSize = std::strlen(str); | ||||||
|  |         resize(strSize); | ||||||
|  |         std::memcpy(mpData, str, mSize); | ||||||
|     } |     } | ||||||
|     return mpData[i]; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void String::clear() |     String() : String("") {} | ||||||
| { |     String(const String& s) : String(s.cStr()) {} | ||||||
|     std::free(mpData); |  | ||||||
| 
 | 
 | ||||||
|     mSize = 0; |     String(size_t n, char a) | ||||||
|     mCapacity = 1; |     { | ||||||
|     mpData = errorCheckedMalloc(mCapacity); |         resize(n); | ||||||
|     mpData[0] = '\0'; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void String::addCharacter(char c) |         for (size_t i = 0; i < mSize; ++i) | ||||||
| { |             mpData[i] = a; | ||||||
|     if (mSize + 1 == mCapacity) |     } | ||||||
|         reserve(2 * mCapacity); |  | ||||||
| 
 | 
 | ||||||
|     mpData[mSize] = c; |     ~String() | ||||||
|     resize(mSize + 1); |     { | ||||||
| } |         std::free(mpData); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void reserve(size_t capacity) | ||||||
|  |     { | ||||||
|  |         if (capacity <= mCapacity) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         mCapacity = std::max(2 * mCapacity, capacity); | ||||||
|  |         char* newData = errorCheckedMalloc(mCapacity); | ||||||
|  | 
 | ||||||
|  |         if (mpData) | ||||||
|  |             std::memcpy(newData, mpData, mSize + 1); | ||||||
|  | 
 | ||||||
|  |         std::free(mpData); | ||||||
|  |         mpData = newData; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| size_t String::getSize()        const   {return mSize;} |     void resize(size_t size) | ||||||
| size_t String::getCapacity()    const   {return mCapacity;} |     { | ||||||
| const char* String::cStr()      const   {return mpData;} |         reserve(size + 1); | ||||||
|  |         mSize = size; | ||||||
|  |         mpData[mSize] = '\0'; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     String& operator=(const String& right) | ||||||
|  |     { | ||||||
|  |         if (this == &right) | ||||||
|  |             return *this; | ||||||
|  | 
 | ||||||
|  |         mSize = right.mSize; | ||||||
|  |         resize(mSize); | ||||||
|  | 
 | ||||||
|  |         std::memcpy(mpData, right.mpData, mSize + 1); | ||||||
|  | 
 | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     String operator+(const String& b) | ||||||
|  |     { | ||||||
|  |         String result; | ||||||
|  |         result.resize(mSize + b.mSize); | ||||||
|  | 
 | ||||||
|  |         std::memcpy(result.mpData, mpData, mSize); | ||||||
|  |         std::memcpy(result.mpData + mSize, b.mpData, b.mSize); | ||||||
|  |         result.mpData[result.mSize] = '\0'; | ||||||
|  | 
 | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     String& operator+=(const String& right) | ||||||
|  |     { | ||||||
|  |         *this = *this + right; | ||||||
|  |         return *this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator==(const String& right) const | ||||||
|  |     { | ||||||
|  |         if (mSize != right.mSize) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         size_t i = 0; | ||||||
|  |         while (i < mSize && mpData[i] == right.mpData[i]) | ||||||
|  |             i++; | ||||||
|  | 
 | ||||||
|  |         return i == mSize; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator<(const String& right) const | ||||||
|  |     { | ||||||
|  |         size_t i = 0; | ||||||
|  |         while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) | ||||||
|  |             i++; | ||||||
|  | 
 | ||||||
|  |         return mpData[i] < right.mpData[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator<=(const String& right) const | ||||||
|  |     { | ||||||
|  |         size_t i = 0; | ||||||
|  |         while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) | ||||||
|  |             i++; | ||||||
|  | 
 | ||||||
|  |         return mpData[i] <= right.mpData[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator!=(const String& right) const | ||||||
|  |     { | ||||||
|  |         return !(*this == right); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator>(const String& right) const | ||||||
|  |     { | ||||||
|  |         return !(*this <= right); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool operator>=(const String& right) const | ||||||
|  |     { | ||||||
|  |         return !(*this < right); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     char& operator[](size_t i) | ||||||
|  |     { | ||||||
|  |         return mpData[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const char& operator[](size_t i) const | ||||||
|  |     { | ||||||
|  |         return mpData[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     char& at(size_t i) | ||||||
|  |     { | ||||||
|  |         if (i >= mSize) | ||||||
|  |         { | ||||||
|  |             cout << "Error! Index is out of bounds." << endl; | ||||||
|  |         } | ||||||
|  |         return mpData[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void clear() | ||||||
|  |     { | ||||||
|  |         std::free(mpData); | ||||||
|  | 
 | ||||||
|  |         mSize = 0; | ||||||
|  |         mCapacity = 1; | ||||||
|  |         mpData = errorCheckedMalloc(mCapacity); | ||||||
|  |         mpData[0] = '\0'; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void addCharacter(char c) | ||||||
|  |     { | ||||||
|  |         if (mSize + 1 == mCapacity) | ||||||
|  |             reserve(2 * mCapacity); | ||||||
|  | 
 | ||||||
|  |         mpData[mSize] = c; | ||||||
|  |         resize(mSize + 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     size_t getSize()        const   {return mSize;} | ||||||
|  |     size_t getCapacity()    const   {return mCapacity;} | ||||||
|  |     const char* cStr()      const   {return mpData;} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| std::ostream& operator<<(std::ostream& out, const String& s)  | std::ostream& operator<<(std::ostream& out, const String& s)  | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -1,43 +0,0 @@ | ||||||
| #pragma once |  | ||||||
| #include <iostream> |  | ||||||
| 
 |  | ||||||
| namespace mipt { |  | ||||||
| 
 |  | ||||||
| class StringView; |  | ||||||
| class String  |  | ||||||
| { |  | ||||||
| private: |  | ||||||
|     size_t mSize        {0}; |  | ||||||
|     size_t mCapacity    {0}; |  | ||||||
|     char* mpData        {nullptr}; |  | ||||||
| public: |  | ||||||
|     String(const char* str); |  | ||||||
|     String(); |  | ||||||
|     String(const String& s); |  | ||||||
|     String(const mipt::StringView& sv); |  | ||||||
|     String(size_t n, char a); |  | ||||||
|     ~String(); |  | ||||||
|     void reserve(size_t capacity); |  | ||||||
|     void resize(size_t size); |  | ||||||
|     String& operator=(const String& right); |  | ||||||
|     String operator+(const String& b); |  | ||||||
|     String& operator+=(const String& right); |  | ||||||
|     bool operator==(const String& right) const; |  | ||||||
|     bool operator<(const String& right) const; |  | ||||||
|     bool operator<=(const String& right) const; |  | ||||||
|     bool operator!=(const String& right) const; |  | ||||||
|     bool operator>(const String& right) const; |  | ||||||
|     bool operator>=(const String& right) const; |  | ||||||
|     char& operator[](size_t i); |  | ||||||
|     const char& operator[](size_t i) const; |  | ||||||
|     char& at(size_t i); |  | ||||||
|     void clear(); |  | ||||||
|     void addCharacter(char c); |  | ||||||
|     size_t getSize()        const;  |  | ||||||
|     size_t getCapacity()    const; |  | ||||||
|     const char* cStr()      const; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| std::ostream& operator<<(std::ostream& out, const String& s); |  | ||||||
| std::istream& operator>>(std::istream& in, String& s);  |  | ||||||
| } |  | ||||||
|  | @ -1,30 +1,37 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include "miptstring.h" |  | ||||||
| #include "miptstringview.h" |  | ||||||
| using std::cout, std::cin, std::endl, std::size_t; | using std::cout, std::cin, std::endl, std::size_t; | ||||||
| 
 | 
 | ||||||
| namespace mipt { | namespace mipt { | ||||||
| 
 | 
 | ||||||
|     StringView::StringView() {; | class StringView  | ||||||
|  | { | ||||||
|  | private: | ||||||
|  |     const char* mpData; | ||||||
|  |     size_t mSize; | ||||||
|  |    | ||||||
|  | public:   | ||||||
|  |     StringView() {; | ||||||
|         mSize = 0; |         mSize = 0; | ||||||
|         mpData = nullptr; |         mpData = nullptr; | ||||||
|     } |     } | ||||||
|     StringView::StringView(const StringView& str) { |     StringView(const StringView& str) { | ||||||
|         mSize = str.mSize; |         mSize = str.mSize; | ||||||
|         mpData = str.mpData; |         mpData = str.mpData; | ||||||
|     } |     } | ||||||
|     StringView::StringView(const mipt::String& s) { |     StringView(const mipt::String& s) { | ||||||
|         mSize = s.getSize(); |         mSize = s.getSize(); | ||||||
|         mpData = s.cStr();   |         mpData = s.cStr();   | ||||||
|     } |     } | ||||||
|     StringView::StringView(const char* s) { |     StringView(const char* s) { | ||||||
|         mpData = s; |         mpData = s; | ||||||
|         mSize = strlen(s);  |         mSize = strlen(s);  | ||||||
|     } |     } | ||||||
|     const char& StringView::at(size_t i) |     const char& at(size_t i) | ||||||
|     { |     { | ||||||
|         if (i >= mSize) |         if (i >= mSize) | ||||||
|         { |         { | ||||||
|  | @ -33,49 +40,20 @@ namespace mipt { | ||||||
|         } |         } | ||||||
|         return mpData[i]; |         return mpData[i]; | ||||||
|     } |     } | ||||||
|     const char& StringView::operator[](size_t i) const |     const char& operator[](size_t i) | ||||||
|     { |     { | ||||||
|         return mpData[i]; |         return mpData[i]; | ||||||
|     } |     } | ||||||
|     bool StringView::operator<(const StringView& right) const |     size_t size() { | ||||||
|     { |  | ||||||
|         size_t i = 0; |  | ||||||
|         while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) |  | ||||||
|             i++; |  | ||||||
| 
 |  | ||||||
|         return mpData[i] < right.mpData[i]; |  | ||||||
|     } |  | ||||||
|     size_t StringView::size() const { |  | ||||||
|         return mSize; |         return mSize; | ||||||
|     } |     } | ||||||
|     StringView StringView::substr(size_t pos, size_t count) { | 
 | ||||||
|         if (pos > mSize)  | }; | ||||||
|                 throw std::out_of_range("Error! Index is out of bounds."); | } | ||||||
|         if (pos + count > mSize) | 
 | ||||||
|               count = mSize - pos; | std::ostream& operator<<(std::ostream& out, mipt::StringView sv) { | ||||||
|         StringView result; |  | ||||||
|         result.mpData = mpData + pos; |  | ||||||
|         result.mSize = count; |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
|     void StringView::remove_prefix(size_t n) { |  | ||||||
|             mSize -= n; |  | ||||||
|     } |  | ||||||
|     void StringView::remove_suffix(size_t n) { |  | ||||||
|             mSize -= n; |  | ||||||
|             mpData += n; |  | ||||||
|     } |  | ||||||
| /*std::ostream& StringView::operator<<(std::ostream& out, mipt::StringView sv) {
 |  | ||||||
|     size_t size = sv.size(); |  | ||||||
|     for (int i = 0; i < size; ++i) |  | ||||||
|             out << sv[i]; |  | ||||||
|     return out;  |  | ||||||
| }*/ |  | ||||||
| std::ostream& operator<<(std::ostream& out, const mipt::StringView& sv) { |  | ||||||
|     size_t size = sv.size(); |     size_t size = sv.size(); | ||||||
|     for (int i = 0; i < size; ++i) |     for (int i = 0; i < size; ++i) | ||||||
|             out << sv[i]; |             out << sv[i]; | ||||||
|     return out;  |     return out;  | ||||||
| } | } | ||||||
| }; |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -1,28 +0,0 @@ | ||||||
| #pragma once |  | ||||||
| 
 |  | ||||||
| #include <iostream> |  | ||||||
| 
 |  | ||||||
| namespace mipt { |  | ||||||
| class String; |  | ||||||
| class StringView  |  | ||||||
| { |  | ||||||
| private: |  | ||||||
|     const char* mpData; |  | ||||||
|     size_t mSize; |  | ||||||
| public:   |  | ||||||
|     StringView(); |  | ||||||
|     StringView(const StringView& str); |  | ||||||
|     StringView(const mipt::String& s); |  | ||||||
|     StringView(const char* s); |  | ||||||
|     const char& at(size_t i); |  | ||||||
|     const char& operator[](size_t i) const; |  | ||||||
|     bool operator<(const StringView& right) const; |  | ||||||
|     size_t size() const; |  | ||||||
|     StringView substr(size_t pos, size_t count); |  | ||||||
|     void remove_prefix(size_t n);  |  | ||||||
|     void remove_suffix(size_t n); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| std::ostream& operator<<(std::ostream& out, const StringView& sv); |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
		Reference in a new issue