/*
 * 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 <string>

#include "Box.h"
#include "Pair.h"
#include "compare.h"

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

int main(int argc, char** argv) {
  // ---- Function template: compare (slides 39-40) -----------------------
  cout << "compare(10, 20)   = " << compare(10, 20) << endl;      // -1
  cout << "compare(3.14, 2.7)= " << compare(3.14, 2.7) << endl;   //  1
  string s1 = "Hello", s2 = "World";
  cout << "compare(s1, s2)   = " << compare(s1, s2) << endl;      // -1

  // ---- smaller: type inference and its traps (slides 43-44) ------------
  cout << "\nsmaller(4, 9)     = " << smaller(4, 9) << endl;       // int -> 4
  cout << "smaller('Z', 'A') = " << smaller('Z', 'A') << endl;    // char -> A
  // smaller(3, 2.5) would be a compile error: T can't be both int and
  // double.  Name T explicitly to fix it:
  cout << "smaller<double>(3, 2.5) = " << smaller<double>(3, 2.5) << endl;

  // ---- Class template: Box (slide 46) ----------------------------------
  Box<double> a(7);  // T = double
  Box<int> b(7);     // T = int (a different, unrelated class)
  cout << "\nBox<double> a(7): a.Get()/2 = " << a.Get() / 2 << endl;  // 3.5
  cout << "Box<int>    b(7): b.Get()/2 = " << b.Get() / 2 << endl;    // 3

  // ---- Class template: Pair (slide 49) ---------------------------------
  Pair<string> names("Alice", "Bob");
  names.Swap();
  cout << "\nPair<string> after Swap: First() = " << names.First() << endl;  // Bob

  Pair<int> point(3, 4);  // a fresh, unrelated instantiation
  cout << "Pair<int>: Second() = " << point.Second() << endl;  // 4

  return EXIT_SUCCESS;
}