strblob.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #ifndef STRBLOB_H
  2. #define STRBLOB_H
  3. #include <algorithm>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <memory>
  8. class StrBlobPtr;
  9. class StrBlob {
  10. friend class StrBlobPtr;
  11. public:
  12. typedef std::vector<std::string>::size_type size_type;
  13. StrBlob();
  14. StrBlob(std::initializer_list<std::string> il);
  15. void push_back(const std::string &s) { data->push_back(s); }
  16. void pop_back();
  17. std::string &front();
  18. const std::string &front() const;
  19. std::string &back();
  20. const std::string &back() const;
  21. StrBlobPtr begin();
  22. StrBlobPtr begin() const;
  23. StrBlobPtr end();
  24. StrBlobPtr end() const;
  25. size_type size() const { return data->size(); }
  26. bool empty() const { return data->empty(); }
  27. private:
  28. std::shared_ptr<std::vector<std::string>> data;
  29. void check(size_type i, const std::string &msg) const;
  30. }; // !StrBlob
  31. // functions of StrBlob
  32. inline StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
  33. inline StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {}
  34. inline void StrBlob::check(size_type i, const std::string &msg) const {
  35. if (i >= data->size())
  36. throw std::out_of_range(msg);
  37. }
  38. inline const std::string &StrBlob::front() const {
  39. check(0, "front on empty StrBlob");
  40. return data->front();
  41. }
  42. inline std::string &StrBlob::front() {
  43. check(0, "front on empty StrBlob");
  44. return data->front();
  45. }
  46. inline const std::string &StrBlob::back() const {
  47. check(0, "back on empty StrBlob");
  48. return data->back();
  49. }
  50. inline std::string &StrBlob::back() {
  51. check(0, "back on empty StrBlob");
  52. return data->back();
  53. }
  54. class StrBlobPtr {
  55. public:
  56. StrBlobPtr() : curr(0) {}
  57. StrBlobPtr(StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) {}
  58. StrBlobPtr(const StrBlob &a, std::size_t sz = 0) : wptr(a.data), curr(sz) {}
  59. std::string &deref() const;
  60. StrBlobPtr &incr();
  61. bool equal(const StrBlobPtr &);
  62. private:
  63. std::shared_ptr<std::vector<std::string>> check(std::size_t, const std::string &msg) const;
  64. std::weak_ptr<std::vector<std::string>> wptr;
  65. std::size_t curr;
  66. }; // !StrBlobPtr
  67. // functions of StrBlobPtr
  68. inline std::string &StrBlobPtr::deref() const {
  69. auto p = check(curr, "deref pass end");
  70. return (*p)[curr];
  71. }
  72. inline StrBlobPtr &StrBlobPtr::incr() {
  73. ++curr;
  74. return *this;
  75. }
  76. inline bool StrBlobPtr::equal(const StrBlobPtr &sbp) {
  77. return (*this).curr == sbp.curr;
  78. }
  79. inline std::shared_ptr<std::vector<std::string>> StrBlobPtr::check(std::size_t i, const std::string &msg) const {
  80. auto ret = wptr.lock();
  81. if (!ret)
  82. throw std::runtime_error("unbound StrBlob");
  83. if (i >= ret->size())
  84. throw std::out_of_range(msg);
  85. return ret;
  86. }
  87. // functions of StrBlob
  88. StrBlobPtr StrBlob::begin() {
  89. return StrBlobPtr(*this);
  90. }
  91. StrBlobPtr StrBlob::begin() const {
  92. return StrBlobPtr(*this);
  93. }
  94. StrBlobPtr StrBlob::end() {
  95. return StrBlobPtr(*this, data->size());
  96. }
  97. StrBlobPtr StrBlob::end() const {
  98. return StrBlobPtr(*this, data->size());
  99. }
  100. #endif // !STRBLOB_H