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 }