-- Leo's gemini proxy

-- Connecting to republic.circumlunar.space:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

C++ iterator wrapper/adaptor example


Series: Iterator, Iterator Wrapper, Non-1-1 Wrapper


If you want to wrap an iterable range with another that transforms the underlying iterators in some way and allows looping or constructing other objects:


Iterator

Non-1-1 Wrapper


for (auto ch : Upper("abcdef"))
{
   // Prints "ABCDEF"
   std::cout << ch;
}
Upper up(std::string("fOo"));
std::string newfoo(std::begin(up), std::end(up));
assert(newfoo == "FOO");


then, similar to an ordinary iterable range you will need to make a range class and a iterator class:


an ordinary iterable range


class myit
{
private:
   std::string::const_iterator wrapped_;
   class charholder
   {
       const char value_;
   public:
       charholder(const char value) : value_(value) {}
       char operator*() const { return value_; }
   };
public:
   // Previously provided by std::iterator
   typedef int                     value_type;
   typedef std::ptrdiff_t          difference_type;
   typedef int*                    pointer;
   typedef int&                    reference;
   typedef std::input_iterator_tag iterator_category;

   explicit myit(std::string::const_iterator wrapped) : wrapped_(wrapped) {}
   value_type operator*() const { return std::toupper(*wrapped_); }
   bool operator==(const myit& other) const { return wrapped_ == other.wrapped_; }
   bool operator!=(const myit& other) const { return !(*this == other); }
   charholder operator++(int)
   {
       charholder ret(std::toupper(*wrapped_));
       ++wrapped_;
       return ret;
   }
   myit& operator++()
   {
       ++wrapped_;
       return *this;
   }
};

class Upper
{
private:
   const std::string str_;
public:
   Upper(const std::string str) : str_(str) {}
   myit begin() { return myit(std::begin(str_)); }
   myit end()   { return myit(std::end(str_)); }
};


Notice the need to call the transforming/adapting function std::toupper in two places.


Update: std::iterator is deprecated in C++17, so removed.


Originally posted at 2017-05-12 06:10:58+00:00. Automatically generated from the original post : apologies for the errors introduced.


original post

-- Response ended

-- Page fetched on Sun May 19 07:04:10 2024