1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| #ifndef STRING_H #define STRING_H
#include <memory> #include <string> #include <cstring> #include <algorithm> #include <iostream> const int size = 1000; char _temp_arr[size];
class String { friend std::ostream& operator << (std::ostream&,const String&); friend std::istream& operator >> (std::istream&,String&);
friend String& operator += (String& lhs,const String& rhs); friend char* operator + (String& lhs,String& rhs);
public: String():_begin(nullptr),_first_free(nullptr),_end(nullptr) {} String(const char*); String(const std::string&); String& operator= (const String&); ~String();
char& operator[](const size_t&); const char* c_str() const { return _begin; } size_t size() const { return _first_free-_begin; } bool empty() const { return _first_free-_begin?0:1; } char* begin() const { return _begin; } char* end() const { return _end; } size_t capacity() const { return _end-_begin; } size_t remain() const { return _end-_first_free; }
private: static std::allocator<char> alloc; void free(); void reallocate(); std::pair<char*,char*> alloc_n_copy(const char*,const char*);
char* _begin; char* _first_free; char* _end; }; std::ostream& operator<<(std::ostream& out,const String& rhs) { out << rhs._begin; return out; } std::istream& operator>>(std::istream& in,String& rhs) { char p[size]; in >> p; rhs = p; return in; }
String& operator+=(String& lhs,const String& rhs) { if (lhs.remain() > rhs.size()) { auto dest = rhs._begin; for (size_t i=0; i<rhs.size(); ++i) lhs.alloc.construct(lhs._first_free++,*dest++); } else { lhs.reallocate(); auto dest = rhs._begin; for (size_t i=0; i<rhs.size(); ++i) lhs.alloc.construct(lhs._first_free++,*dest++); } return lhs; }
char* operator+(String& lhs,String& rhs) { strcpy(_temp_arr,lhs._begin); auto temp_ptr = _temp_arr + strlen(_temp_arr); strcpy(temp_ptr,rhs._begin); return _temp_arr; }
char& String::operator[](const size_t& index) { if (index < size()) return *(_begin + index); }
std::pair<char*,char*> String::alloc_n_copy(const char* b,const char* c) { auto newdata = alloc.allocate(c-b); return {newdata,std::uninitialized_copy(b,c,newdata)}; } String::String(const char* p) { int len = strlen(p); auto newdata = alloc_n_copy(p,p+len); _begin = newdata.first; _end = _first_free = newdata.second; } String::String(const std::string& s) { int len = s.size(); auto newdata = alloc_n_copy(&s[0],&s[len]); _begin = newdata.first; _end = _first_free = newdata.second; } void String::free() { std::for_each(_begin,_end, [](char& p){ alloc.destroy(&p); }); alloc.deallocate(_begin,_end-_begin); } String::~String() { free(); }
String& String::operator= (const String& rhs) { auto newdata = alloc_n_copy(rhs.begin(),rhs.end()); free(); _begin = newdata.first; _end = _first_free = newdata.second; return *this; } void String::reallocate() { auto newcapacity = size() ? 2*size() : 1; auto newdata = alloc.allocate(newcapacity);
auto dest = newdata; auto elem = _begin; for (size_t i=0; i<size(); ++i) alloc.construct(dest++,std::move(*elem++)); free(); _begin = newdata; _first_free = dest; _end = _begin + newcapacity; } #endif
|