| 
					
				 | 
			
			
				@@ -0,0 +1,128 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#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 
			 |