#include <iostream>
using namespace std;

class RC
{
public:
   RC(int s, int e, int t) : start(s), end(e), step(t), value(s) {}

   int operator*() const { return value; }

   int getValue() const { return value; }

   RC& operator++()      // ++x / Prae-Increment
   {
      next();
      return *this;
   }

   // Post-Increment Return Semantik nicht implementiert
   void operator++(int)   // x++ / Post-Increment
   {
      ++(*this);
   }

protected:
   virtual void next() = 0;

   int start;
   int end;
   int step;
   int value;
};


class RC1 : public RC
{
public:
   using RC::RC;

protected:
   void next() override
   {
      value += step;
      if (value > end)
      {
         value = start;
      }
   }
};


class RC2 : public RC
{
public:
   using RC::RC;

protected:
   void next() override
   {
      value += step;
      if (step > 0 && value > end)
      {
         value = end;
         step = -step;
      }
      if (step < 0 && value < start)
      {
         value = start;
         step = -step;
      }
   }
};

void doit(RC& rc)
{
   cout << "doit: ";
   for (int i = 0; i < 20; ++i)
   {
      cout << *rc << ' ';
      ++rc;
   }
   cout << '\n';
}


int main()
{
   cout << "RingCounter 1\n\n";

   cout << "RC1\n";
   RC1 rc1(2, 9, 3);
   cout << "2: " << *rc1 << '\n';
   ++rc1;
   cout << "5: " << *rc1 << '\n';
   ++rc1;
   cout << "8: " << *rc1 << '\n';
   ++rc1;
   cout << "2: " << *rc1 << '\n';
   ++rc1;
   cout << "5: " << *rc1 << '\n';
   ++++rc1;  // rc1.operator++().operator++();
   cout << "2: " << *rc1 << '\n';
   rc1++;
   cout << "5: " << *rc1 << '\n';
   rc1++;
   cout << "8: " << *rc1 << '\n';
   rc1++;
   cout << "2: " << *rc1 << '\n';

   cout << "\nRC2\n";
   RC2 rc2(1, 5, 1);
   for (int i = 0; i < 20; ++i)
   {
      cout << *rc2 << ' ';
      ++rc2;
   }
   cout << '\n';

   doit(rc1);
   doit(rc2);
}
