123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #ifndef STRBLOB_H
- #define STRBLOB_H
- #include <algorithm>
- #include <iostream>
- #include <string>
- #include <vector>
- #include <memory>
- class StrBlobPtr;
- class StrBlob {
- friend class StrBlobPtr;
- public:
- typedef std::vector<std::string>::size_type size_type;
- StrBlob();
- StrBlob(std::initializer_list<std::string> il);
- void push_back(const std::string &s) { data->push_back(s); }
- void pop_back();
- std::string &front();
- const std::string &front() const;
- std::string &back();
- const std::string &back() const;
- StrBlobPtr begin();
- StrBlobPtr begin() const;
- StrBlobPtr end();
- StrBlobPtr end() const;
- size_type size() const { return data->size(); }
- bool empty() const { return data->empty(); }
- private:
- std::shared_ptr<std::vector<std::string>> data;
- void check(size_type i, const std::string &msg) const;
- }; // !StrBlob
- // functions of StrBlob
- inline StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
- inline StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {}
- inline void StrBlob::check(size_type i, const std::string &msg) const {
- if (i >= data->size())
- throw std::out_of_range(msg);
- }
- inline const std::string &StrBlob::front() const {
- check(0, "front on empty StrBlob");
- return data->front();
- }
- inline std::string &StrBlob::front() {
- check(0, "front on empty StrBlob");
- return data->front();
- }
- inline const std::string &StrBlob::back() const {
- check(0, "back on empty StrBlob");
- return data->back();
- }
- inline std::string &StrBlob::back() {
- check(0, "back on empty StrBlob");
- return data->back();
- }
- class StrBlobPtr {
- public:
- StrBlobPtr() : curr(0) {}
- StrBlobPtr(StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) {}
- StrBlobPtr(const StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) {}
- std::string &deref() const;
- StrBlobPtr &incr();
- bool equal(const StrBlobPtr &);
- private:
- std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string &msg) const;
- std::weak_ptr<std::vector<std::string>> wptr;
- std::size_t curr;
- }; // !StrBlobPtr
- // functions of StrBlobPtr
- inline std::string &StrBlobPtr::deref() const {
- auto p = check(curr, "deref pass end");
- return (*p)[curr];
- }
- inline StrBlobPtr &StrBlobPtr::incr() {
- ++curr;
- return *this;
- }
- inline bool StrBlobPtr::equal(const StrBlobPtr &sbp) {
- return (*this).curr == sbp.curr;
- }
- inline std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string &msg) const {
- auto ret = wptr.lock();
- if (!ret)
- throw std::runtime_error("unbound StrBlob");
- if (i >= ret->size())
- throw std::out_of_range(msg);
- return ret;
- }
- // functions of StrBlob
- StrBlobPtr StrBlob::begin() {
- return StrBlobPtr(*this);
- }
- StrBlobPtr StrBlob::begin() const {
- return StrBlobPtr(*this);
- }
- StrBlobPtr StrBlob::end() {
- return StrBlobPtr(*this, data->size());
- }
- StrBlobPtr StrBlob::end() const {
- return StrBlobPtr(*this, data->size());
- }
- #endif // !STRBLOB_H
|