diff --git a/seminar03_initialization/07_placement/main.cpp b/seminar03_initialization/07_placement/main.cpp new file mode 100644 index 0000000..3516d15 --- /dev/null +++ b/seminar03_initialization/07_placement/main.cpp @@ -0,0 +1,22 @@ +#include +#include "miptstring.cpp" + +using std::cout, std::endl; + +int main() { + mipt::String stack{"Cat"}; + cout << stack << endl; + + mipt::String* heap = new mipt::String{"Dog"}; + cout << *heap << endl; + + char *x = (char*)malloc(sizeof(mipt::String)); + mipt::String* px = new(x) mipt::String{"Elephant"}; + + cout << *px << endl; + + px->~String(); + free(px); + delete heap; + +} diff --git a/seminar03_initialization/07_placement/miptstring.cpp b/seminar03_initialization/07_placement/miptstring.cpp new file mode 100644 index 0000000..f7e324e --- /dev/null +++ b/seminar03_initialization/07_placement/miptstring.cpp @@ -0,0 +1,215 @@ +#pragma once + +#include +#include + +namespace mipt{ + +class String +{ +private: + + std::size_t mSize {0}; + std::size_t mCapacity {0}; + char* mpData {nullptr}; + +public: + + String(const char* str) + { + std::size_t strSize = std::strlen(str); + resize(strSize); + std::memcpy(mpData, str, mSize); + + std::cout << "mipt::String Constructor (" << mpData << ")" << std::endl; + } + + String() : String("") {} + String(const String& s) : String(s.cStr()) {} + + String(std::size_t n, char a) + { + resize(n); + + for (std::size_t i = 0; i < mSize; ++i) + mpData[i] = a; + + std::cout << "mipt::String Constructor (" << mpData << ")" << std::endl; + } + + ~String() + { + std::cout << "mipt::String Destructor (" << mpData << ")" << std::endl; + delete [] mpData; + } + + void reserve(std::size_t capacity) + { + if (capacity <= mCapacity) + return; + + mCapacity = std::max(2 * mCapacity, capacity); + char* newData = new char[mCapacity]; // errorCheckedMalloc(mCapacity); + + if (mpData) + std::memcpy(newData, mpData, mSize + 1); + + delete [] mpData; + mpData = newData; + } + + + void resize(std::size_t size) + { + 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; + + std::size_t i = 0; + while (i < mSize && mpData[i] == right.mpData[i]) + i++; + + return i == mSize; + } + + bool operator<(const String& right) const + { + std::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 + { + std::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[](std::size_t i) + { + return mpData[i]; + } + + const char& operator[](std::size_t i) const + { + return mpData[i]; + } + + char& at(std::size_t i) + { + if (i >= mSize) + throw std::out_of_range{"mipt::String::at: index >= this->size()"}; + return mpData[i]; + } + + const char& at(std::size_t i) const + { + if (i >= mSize) + throw std::out_of_range{"mipt::String::at: index >= this->size()"}; + return mpData[i]; + } + + void clear() + { + delete [] mpData; + + mSize = 0; + mCapacity = 1; + mpData = new char[mCapacity]; + mpData[0] = '\0'; + } + + void addCharacter(char c) + { + if (mSize + 1 == mCapacity) + reserve(2 * mCapacity); + + mpData[mSize] = c; + resize(mSize + 1); + } + + + std::size_t getSize() const {return mSize;} + std::size_t getCapacity() const {return mCapacity;} + const char* cStr() const {return mpData;} +}; + + +std::ostream& operator<<(std::ostream& out, const String& s) +{ + out << s.cStr(); + return out; +} + +std::istream& operator>>(std::istream& in, String& s) +{ + s.clear(); + while (true) + { + char x = in.get(); + if (std::isspace(x)) + break; + s.addCharacter(x); + } + return in; +} +} \ No newline at end of file