template <typename T, size_t MaxSize>
class CircularBuffer {
  public:
    CircularBuffer() : size_(0), readIndex_(0), writeIndex_(0) {}

    void push(const T& value) {
      data_[writeIndex_] = value;
      writeIndex_ = (writeIndex_ + 1) % (MaxSize + 1); // Increment writeIndex
      if (size_ < MaxSize) {
        size_++;
      } else {
        readIndex_ = (readIndex_ + 1) % (MaxSize + 1); // Adjust readIndex for full buffer
      }
    }

    size_t size() const {
      return size_;
    }

    class Iterator {
      public:
        Iterator(CircularBuffer& buffer, size_t index) : buffer_(buffer), index_(index) {}

        T& operator*() {
          return buffer_.data_[index_];
        }

        Iterator& operator++() {
          if (++index_ > MaxSize)index_ = 0;
          return *this;
        }

        Iterator& operator--() {
          if (index_ == 0) index_ = MaxSize;
          else index_--;
          return *this;
        }

        bool operator!=(const Iterator& other) {
          return &buffer_ != &other.buffer_ || index_ != other.index_;
        }

      private:
        CircularBuffer& buffer_;
        size_t index_;
    };

    Iterator begin() {
      if (size_ == 0) {
        return Iterator(*this, writeIndex_);
      } else {
        return Iterator(*this, readIndex_);
      }
    }

    Iterator end() {
      return Iterator(*this, writeIndex_);
    }

  private:
    T data_[MaxSize + 1]; // Increase array size by 1
    size_t size_;
    size_t readIndex_;
    size_t writeIndex_;
};

const size_t bufferSize = 5;
CircularBuffer<int, bufferSize> buffer;

void setup() {
  Serial.begin(115200);
}

void loop() {
  buffer.push(analogRead(A0));

  Serial.print("Buffer Contents:");
  for (auto it = buffer.begin(); it != buffer.end(); ++it) {
    Serial.print(*it);
    Serial.write(' ');
  }
  Serial.println();
  delay(500);
}