1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <memory> 5 #include <algorithm> 6 #include <initializer_list> 7 #include <memory> 8 #include <vector> 9 #include <stdexcept> 10 #include <fstream> 11 #include <sstream> 12 using namespace std; 13 14 #ifndef STRBLOB_H_ 15 #define STRBLOB_H_ 16 17 class StrBlobPtr; 18 22 class StrBlob 23 { 24 public: 25 friend class StrBlobPtr; 26 friend void inp(StrBlob& str, ifstream& input); 27 typedef std::vector<std::string>::size_type size_type; 28 StrBlob(); 29 StrBlob(std::initializer_list<std::string> il); 30 size_type size() const { return data->size(); } 31 bool empty() const { return data->empty(); } 32 void push_back(const std::string& t) { data->push_back(t); } 33 void pop_back(); 34 std::string& front(); 35 std::string& back(); 36 const std::string& front() const; 37 const std::string& back() const; 38 StrBlobPtr begin(); 39 StrBlobPtr end(); 40 private: 41 std::shared_ptr<std::vector<std::string>> data; 42 void check(size_type i, const std::string& msg) const; 43 }; 44 45 class StrBlobPtr 46 { 47 public: 48 friend void inp(StrBlob& str, ifstream& input); 49 StrBlobPtr() : curr(0) {}; 50 StrBlobPtr(StrBlob& a, size_t sz = 0) : wptr(a.data), curr(sz) {} 51 std::string& deref() const; 52 StrBlobPtr& incr(); 53 friend bool eq(const StrBlobPtr& lhs, const StrBlobPtr& rhs); 54 private: 55 std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string&) const; 56 std::weak_ptr<std::vector<std::string>> wptr; 57 std::size_t curr; 58 }; 59 60 std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string& msg) const 61 { 62 auto ret = wptr.lock(); 63 if (!ret) 64 throw std::runtime_error("unbound StrBlobPtr"); 65 if (i >= ret->size()) 66 throw std::out_of_range(msg); 67 return ret; 68 } 69 70 std::string& StrBlobPtr::deref() const 71 { 72 auto p = check(curr, "dereference past end"); 73 return (*p)[curr]; 74 } 75 76 StrBlobPtr& StrBlobPtr::incr() 77 { 78 check(curr, "increment past end of StrBlobPtr"); 79 ++curr; 80 return *this; 81 } 82 83 StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {} 84 StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {} 85 86 void StrBlob::check(size_type i, const std::string& msg) const 87 { 88 if (i >= data->size()) 89 throw std::out_of_range(msg); 90 } 91 92 std::string& StrBlob::front() 93 { 94 check(0, "front on empty StrBlob"); 95 return data->front(); 96 } 97 98 std::string& StrBlob::back() 99 { 100 check(0, "back on empty StrBlob"); 101 return data->back(); 102 } 103 104 const std::string& StrBlob::front() const 105 { 106 check(0, "front on empty StrBlob"); 107 return data->front(); 108 } 109 110 const std::string& StrBlob::back() const 111 { 112 check(0, "back on empty StrBlob"); 113 return data->back(); 114 } 115 116 void StrBlob::pop_back() 117 { 118 check(0, "pop_back on empty StrBlob"); 119 data->pop_back(); 120 } 121 122 StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this); } 123 124 StrBlobPtr StrBlob::end() 125 { 126 auto ret = StrBlobPtr(*this, data->size()); 127 return ret; 128 } 129 130 #endif 131 132 bool eq(const StrBlobPtr& lhs, const StrBlobPtr& rhs) { 133 auto lp = lhs.wptr.lock(), rp = rhs.wptr.lock(); 134 if (lp == rp) { 135 return (!lp || lhs.curr == rhs.curr); 136 } 137 else { 138 return false; 139 } 140 } 141 142 void inp(StrBlob &str, ifstream &input) 143 { 144 //存入类中 145 string text; 146 while (getline(input, text)) 147 { 148 istringstream stream(text); 149 string word; 150 while (stream >> word) 151 { 152 str.push_back(word); 153 } 154 } 155 //打印类中元素 156 for (StrBlobPtr cur = str.begin(); !eq(cur,str.end()); cur.incr()) 157 { 158 string out = cur.deref(); 159 cout << out << ""; 160 } 161 162 }
标签:std,const,string,StrBlobPtr,back,C++,primer,StrBlob From: https://www.cnblogs.com/lihaoxiang/p/17191329.html