class StrBlobPtr;
class const_StrBlobPtr;
class StrBlob
{
friend class StrBlobPtr;
friend class const_StrBlobPtr;
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob(std::initializer_list<std::string> il)://这里为什么不能是引用?
data(std::make_shared<std::vector<std::string>>(il)) {}
StrBlob(): data(std::make_shared<std::vector<std::string>>()) {}
std::string &front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const std::string &front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
std::string &back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const std::string &back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const std::string &s) { data->push_back(s); }
void pop_back() { data->pop_back(); }
StrBlobPtr begin();
StrBlobPtr end();
const_StrBlobPtr begin() const;
const_StrBlobPtr end() const;
const_StrBlobPtr cbegin() const;
const_StrBlobPtr cend() const;
private:
std::shared_ptr<std::vector<std::string>> data;
void check(size_type i, const std::string &msg) const
{ if (i >= size()) throw std::out_of_range(msg); }
};
class StrBlobPtr
{
public:
StrBlobPtr(StrBlob &sb, StrBlob::size_type sz = 0):
wptr(sb.data), curr(sz) {}
StrBlobPtr(): curr(0) {}
std::string &deref() const
{
return (*check(curr, "dereference past end"))[curr];
}
StrBlobPtr &incr()
{
check(curr, "increment past end of StrBoldPtr");
++curr;
return *this;
}
bool compare(const StrBlobPtr &sp)
{return (wptr.lock() == sp.wptr.lock())&&(curr == sp.curr); }
private:
std::shared_ptr<std::vector<std::string>>
check(StrBlob::size_type pos, const std::string &msg) const
{
auto ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound StrBlobPtr");
if (pos >= ret->size())
throw std::out_of_range(msg);
return ret;
}
std::weak_ptr<std::vector<std::string>> wptr;
StrBlob::size_type curr;
};
class const_StrBlobPtr
{
public:
const_StrBlobPtr(const StrBlob &sb, StrBlob::size_type sz = 0):
wptr(sb.data), curr(sz) {}
const_StrBlobPtr(): curr(0) {}
const std::string &deref() const
{
return (*check(curr, "dereference past end"))[curr];
}
const_StrBlobPtr &incr()
{
check(curr, "increment past end of StrBoldPtr");
++curr;
return *this;
}
bool compare(const const_StrBlobPtr &sp) const
{return (wptr.lock() == sp.wptr.lock())&&(curr == sp.curr); }
private:
std::shared_ptr<const std::vector<std::string>>
check(StrBlob::size_type pos, const std::string &msg) const
{
auto ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound StrBlobPtr");
if (pos >= ret->size())
throw std::out_of_range(msg);
return ret;
}
std::weak_ptr<const std::vector<std::string>> wptr;
StrBlob::size_type curr;
};
inline StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this); }
inline StrBlobPtr StrBlob::end() { return StrBlobPtr(*this, size()); }
inline const_StrBlobPtr StrBlob::begin() const
{ return const_StrBlobPtr(*this); }
inline const_StrBlobPtr StrBlob::end() const
{ return const_StrBlobPtr(*this, size()); }
inline const_StrBlobPtr StrBlob::cbegin() const
{ return const_StrBlobPtr(*this); }
inline const_StrBlobPtr StrBlob::cend() const
{ return const_StrBlobPtr(*this, size()); }
/×顺便大家吐槽一下有没有什么改进的地方,其实就是cpp_primer的练习12.22,格式好像有点乱啊,不想看别看了。。。×/
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.