1 #ifndef HERBSTLUFT_ARGLIST_H 2 #define HERBSTLUFT_ARGLIST_H 3 4 #include <algorithm> 5 #include <initializer_list> 6 #include <iterator> 7 #include <memory> 8 #include <string> 9 #include <vector> 10 11 class ArgList { 12 13 public: 14 using Container = std::vector<std::string>; 15 16 //! a simple split(), as C++ doesn't have it 17 static Container split(const std::string &s, char delim = '.'); 18 19 ArgList(const std::initializer_list<std::string> &l); 20 ArgList(Container::const_iterator from, Container::const_iterator to); 21 ArgList(const ArgList &al); 22 ArgList(const Container &c); 23 // constructor that splits the given string 24 ArgList(const std::string &s, char delim = '.'); ~ArgList()25 virtual ~ArgList() {} 26 begin()27 Container::const_iterator begin() const { return begin_; } end()28 Container::const_iterator end() const { return container_->cend(); } front()29 const std::string& front() { return *begin_; } back()30 const std::string& back() { return container_->back(); } empty()31 bool empty() const { return begin_ == container_->end(); } size()32 Container::size_type size() const { 33 return std::distance(begin_, container_->cend()); 34 } 35 36 std::string join(char delim = '.'); 37 38 //! reset internal pointer to begin of arguments reset()39 void reset() { 40 begin_ = container_->cbegin(); 41 shiftedTooFar_ = false; 42 } 43 //! shift the internal pointer by amount 44 void shift(Container::difference_type amount = 1) { 45 begin_ += std::min(amount, std::distance(begin_, container_->cend())); 46 } toVector()47 Container toVector() const { 48 return Container(begin_, container_->cend()); 49 } 50 //! try read a value if possible 51 virtual ArgList& operator>>(std::string& val); 52 53 //! tell whether all previous operator>>() succeeded 54 operator bool() const { 55 return !shiftedTooFar_; 56 } 57 58 protected: 59 //! shift state pointing into container_ 60 Container::const_iterator begin_; 61 //! indicator that we attempted to shift too far (shift is at end()) 62 bool shiftedTooFar_ = false; 63 /*! Argument vector 64 * @note This is a shared pointer to make object copy-able: 65 * 1. payload is shared (no redundant copies) 66 * 2. begin_ stays valid 67 * 3. The C-style compatibility layer DEPENDS on the shared_ptr! 68 */ 69 std::shared_ptr<Container> container_; 70 }; 71 72 #endif 73