/*
 * Copyright ©2026 Soham Pardeshi. All rights reserved.
 * Permission is hereby granted to students registered for University of
 * Washington CSE 333 for use solely during Summer Quarter 2026 for
 * purposes of the course. No other use, copying, distribution, or
 * modification is permitted without prior written consent. Copyrights
 * for third-party components of this work must be honored. Instructors
 * interested in reusing these course materials should contact the author.
 */

#include <iostream>
#include <vector>

using std::cout;
using std::endl;

// Iterators are generalized pointers into a container.  The range is
// half-open: [begin, end), where end() is one PAST the last element and
// is never dereferenced.  See lecture 12 slides 55-57.
int main(int argc, char** argv) {
  std::vector<int> v = {10, 20, 30};

  // 1. The verbose, explicit iterator type.
  cout << "explicit iterator: ";
  for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
    cout << *it << " ";  // * dereferences the iterator
  }
  cout << endl;

  // 2. auto infers the (long) iterator type (C++11).
  cout << "auto iterator:     ";
  for (auto it = v.begin(); it != v.end(); ++it) {
    cout << *it << " ";
  }
  cout << endl;

  // 3. range-for hides the iterator entirely.  Use const auto& to walk the
  //    container without copying each element.
  cout << "range-for:         ";
  for (const auto& x : v) {
    cout << x << " ";
  }
  cout << endl;

  // An empty container has begin() == end(), so the loop runs zero times.
  std::vector<int> empty;
  cout << "empty range runs " << (empty.begin() == empty.end() ? "0" : "some")
       << " times" << endl;

  return EXIT_SUCCESS;
}