Source File: ex60.cpp

#include <fmt/core.h>
#include <chrono>
#include <thread>
#include <string>
#include <utility>
#include <ranges>

constexpr const int MAX_NAME=1024 * 10;

struct InsanePerson {
  char* name;

  public:

  explicit InsanePerson(const char* s = "") : name(nullptr)
  {
    if(s) {
      name = new char[MAX_NAME];
      std::strcpy(name, s);
    }
  }

  ~InsanePerson() {
    fmt::println("destroy runs! {:p}", name);
    delete[] name;
  }

  // copy
  InsanePerson(const InsanePerson& other)
    : InsanePerson(other.name) {}

  // move
  InsanePerson(InsanePerson&& other) noexcept
    : name(std::exchange(other.name, nullptr)) {}

  // copy assign
  InsanePerson& operator=(const InsanePerson& other) {
    return *this = InsanePerson(other);
  }

  // move assign
  InsanePerson& operator=(InsanePerson&& other) noexcept
  {
    std::swap(name, other.name);
    return *this;
  }


  void print() {
    fmt::println("I am {}.", name);
  }
};

int main(int argc, char* argv[]) {
  std::vector<InsanePerson> others;
  std::array<InsanePerson, 20> people;

  fmt::println("---- setup loop");
  for(size_t i = 0; i < 10; i++) {
    InsanePerson who("Test");
    // trigger copy
    others.push_back(who);
    fmt::println("name after copy: {:p}", who.name);

    // trigger move
    others.emplace_back(std::move(who));
    fmt::println("name after move: {:p}", who.name);
  }

  fmt::println("--- enumerate badness");
  for(auto [i, who] : std::views::enumerate(others)) {
    fmt::println("before move: {:p}", who.name);
    // trigger copy assign and move assign
    people[i] = who;
    fmt::println("after  move: {:p}", who.name);
  }

  fmt::println("--- print everyone");
  for(auto& who : people) {
    who.print();
  }

  fmt::println("!!!!!!!!!!! end");
}