#include <iostream>
#include <type_traits>
#include <vector>

#include <cm/optional>
#include <cm/utility>

class EventLogger;

class Event
{
public:
  enum EventType
  {
    DEFAULT_CONSTRUCT,
    COPY_CONSTRUCT,
    MOVE_CONSTRUCT,
    VALUE_CONSTRUCT,

    DESTRUCT,

    COPY_ASSIGN,
    MOVE_ASSIGN,
    VALUE_ASSIGN,

    REFERENCE,
    CONST_REFERENCE,
    RVALUE_REFERENCE,
    CONST_RVALUE_REFERENCE,

    SWAP,

    COMPARE_EE_EQ,
    COMPARE_EE_NE,
    COMPARE_EE_LT,
    COMPARE_EE_LE,
    COMPARE_EE_GT,
    COMPARE_EE_GE,
  };

  EventType Type;
  const EventLogger* Logger1;
  const EventLogger* Logger2;
  int Value;

  bool operator==(const Event& other) const;
  bool operator!=(const Event& other) const;
};

bool Event::operator==(const Event& other) const
{
  return this->Type == other.Type && this->Logger1 == other.Logger1 &&
    this->Logger2 == other.Logger2 && this->Value == other.Value;
}

bool Event::operator!=(const Event& other) const
{
  return !(*this == other);
}

static std::vector<Event> events;

class EventLogger
{
public:
  EventLogger();
  EventLogger(const EventLogger& other);
  EventLogger(EventLogger&& other);
  EventLogger(int value);

  ~EventLogger();

  EventLogger& operator=(const EventLogger& other);
  EventLogger& operator=(EventLogger&& other);
  EventLogger& operator=(int value);

  void Reference() &;
  void Reference() const&;
  void Reference() &&;
  void Reference() const&&;

  int Value = 0;
};

#define ASSERT_TRUE(x)                                                        \
  do {                                                                        \
    if (!(x)) {                                                               \
      std::cout << "ASSERT_TRUE(" #x ") failed on line " << __LINE__ << "\n"; \
      return false;                                                           \
    }                                                                         \
  } while (false)

// Certain builds of GCC generate false -Wmaybe-uninitialized warnings when
// doing a release build with the system version of std::optional. These
// warnings do not manifest when using our own cm::optional implementation.
// Silence these false warnings.
#if defined(__GNUC__) && !defined(__clang__)
#  define BEGIN_IGNORE_UNINITIALIZED                                          \
    _Pragma("GCC diagnostic push")                                            \
      _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
#  define END_IGNORE_UNINITIALIZED _Pragma("GCC diagnostic pop")
#else
#  define BEGIN_IGNORE_UNINITIALIZED
#  define END_IGNORE_UNINITIALIZED
#endif

void swap(EventLogger& e1, EventLogger& e2)
{
  BEGIN_IGNORE_UNINITIALIZED
  events.push_back({ Event::SWAP, &e1, &e2, e2.Value });
  END_IGNORE_UNINITIALIZED
  auto tmp = e1.Value;
  e1.Value = e2.Value;
  e2.Value = tmp;
}

EventLogger::EventLogger()
  : Value(0)
{
  events.push_back({ Event::DEFAULT_CONSTRUCT, this, nullptr, 0 });
}

EventLogger::EventLogger(const EventLogger& other)
  : Value(other.Value)
{
  events.push_back({ Event::COPY_CONSTRUCT, this, &other, other.Value });
}

BEGIN_IGNORE_UNINITIALIZED
EventLogger::EventLogger(EventLogger&& other)
  : Value(other.Value)
{
  events.push_back({ Event::MOVE_CONSTRUCT, this, &other, other.Value });
}
END_IGNORE_UNINITIALIZED

EventLogger::EventLogger(int value)
  : Value(value)
{
  events.push_back({ Event::VALUE_CONSTRUCT, this, nullptr, value });
}

EventLogger::~EventLogger()
{
  BEGIN_IGNORE_UNINITIALIZED
  events.push_back({ Event::DESTRUCT, this, nullptr, this->Value });
  END_IGNORE_UNINITIALIZED
}

EventLogger& EventLogger::operator=(const EventLogger& other)
{
  events.push_back({ Event::COPY_ASSIGN, this, &other, other.Value });
  this->Value = other.Value;
  return *this;
}

EventLogger& EventLogger::operator=(EventLogger&& other)
{
  events.push_back({ Event::MOVE_ASSIGN, this, &other, other.Value });
  this->Value = other.Value;
  return *this;
}

EventLogger& EventLogger::operator=(int value)
{
  events.push_back({ Event::VALUE_ASSIGN, this, nullptr, value });
  this->Value = value;
  return *this;
}

bool operator==(const EventLogger& lhs, const EventLogger& rhs)
{
  events.push_back({ Event::COMPARE_EE_EQ, &lhs, &rhs, lhs.Value });
  return lhs.Value == rhs.Value;
}

bool operator!=(const EventLogger& lhs, const EventLogger& rhs)
{
  events.push_back({ Event::COMPARE_EE_NE, &lhs, &rhs, lhs.Value });
  return lhs.Value != rhs.Value;
}

bool operator<(const EventLogger& lhs, const EventLogger& rhs)
{
  events.push_back({ Event::COMPARE_EE_LT, &lhs, &rhs, lhs.Value });
  return lhs.Value < rhs.Value;
}

bool operator<=(const EventLogger& lhs, const EventLogger& rhs)
{
  events.push_back({ Event::COMPARE_EE_LE, &lhs, &rhs, lhs.Value });
  return lhs.Value <= rhs.Value;
}

bool operator>(const EventLogger& lhs, const EventLogger& rhs)
{
  events.push_back({ Event::COMPARE_EE_GT, &lhs, &rhs, lhs.Value });
  return lhs.Value > rhs.Value;
}

bool operator>=(const EventLogger& lhs, const EventLogger& rhs)
{
  events.push_back({ Event::COMPARE_EE_GE, &lhs, &rhs, lhs.Value });
  return lhs.Value >= rhs.Value;
}

void EventLogger::Reference() &
{
  events.push_back({ Event::REFERENCE, this, nullptr, this->Value });
}

void EventLogger::Reference() const&
{
  events.push_back({ Event::CONST_REFERENCE, this, nullptr, this->Value });
}

void EventLogger::Reference() &&
{
  events.push_back({ Event::RVALUE_REFERENCE, this, nullptr, this->Value });
}

void EventLogger::Reference() const&&
{
  events.push_back(
    { Event::CONST_RVALUE_REFERENCE, this, nullptr, this->Value });
}

static bool testDefaultConstruct(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o{};

  expected = {};
  return true;
}

static bool testNulloptConstruct(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o{ cm::nullopt };

  expected = {};
  return true;
}

static bool testValueConstruct(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o{ 4 };

  expected = {
    { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
    { Event::DESTRUCT, &*o, nullptr, 4 },
  };
  return true;
}

static bool testInPlaceConstruct(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o1{ cm::in_place, 4 };
  const cm::optional<EventLogger> o2{ cm::in_place_t{}, 4 };

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
    { Event::VALUE_CONSTRUCT, &*o2, nullptr, 4 },
    { Event::DESTRUCT, &*o2, nullptr, 4 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
  };
  return true;
}

static bool testCopyConstruct(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o1{ 4 };
  const cm::optional<EventLogger> o2{ o1 };
  const cm::optional<EventLogger> o3{};
  const cm::optional<EventLogger> o4{ o3 };

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
    { Event::COPY_CONSTRUCT, &*o2, &o1.value(), 4 },
    { Event::DESTRUCT, &*o2, nullptr, 4 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
  };
  return true;
}

static bool testMoveConstruct(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{ 4 };
  const cm::optional<EventLogger> o2{ std::move(o1) };
  cm::optional<EventLogger> o3{};
  const cm::optional<EventLogger> o4{ std::move(o3) };

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
    { Event::MOVE_CONSTRUCT, &*o2, &*o1, 4 },
    { Event::DESTRUCT, &*o2, nullptr, 4 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
  };
  return true;
}

static bool testNulloptAssign(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{ 4 };
  auto const* v1 = &*o1;
  o1 = cm::nullopt;
  cm::optional<EventLogger> o2{};
  o2 = cm::nullopt;

  expected = {
    { Event::VALUE_CONSTRUCT, v1, nullptr, 4 },
    { Event::DESTRUCT, v1, nullptr, 4 },
  };
  return true;
}

static bool testCopyAssign(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{};
  const cm::optional<EventLogger> o2{ 4 };
  auto const* v2 = &*o2;
  o1 = o2;
  auto const* v1 = &*o1;
  const cm::optional<EventLogger> o3{ 5 };
  auto const* v3 = &*o3;
  o1 = o3;
  const cm::optional<EventLogger> o4{};
  o1 = o4;
  o1 = o4; // Intentionally duplicated to test assigning an empty optional to
  // an empty optional

  expected = {
    { Event::VALUE_CONSTRUCT, v2, nullptr, 4 },
    { Event::COPY_CONSTRUCT, v1, v2, 4 },
    { Event::VALUE_CONSTRUCT, v3, nullptr, 5 },
    { Event::COPY_ASSIGN, v1, v3, 5 },
    { Event::DESTRUCT, v1, nullptr, 5 },
    { Event::DESTRUCT, v3, nullptr, 5 },
    { Event::DESTRUCT, v2, nullptr, 4 },
  };
  return true;
}

static bool testMoveAssign(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{};
  cm::optional<EventLogger> o2{ 4 };
  auto const* v2 = &*o2;
  o1 = std::move(o2);
  auto const* v1 = &*o1;
  cm::optional<EventLogger> o3{ 5 };
  auto const* v3 = &*o3;
  o1 = std::move(o3);
  cm::optional<EventLogger> o4{};
  o1 = std::move(o4);

  expected = {
    { Event::VALUE_CONSTRUCT, v2, nullptr, 4 },
    { Event::MOVE_CONSTRUCT, v1, v2, 4 },
    { Event::VALUE_CONSTRUCT, v3, nullptr, 5 },
    { Event::MOVE_ASSIGN, v1, v3, 5 },
    { Event::DESTRUCT, v1, nullptr, 5 },
    { Event::DESTRUCT, v3, nullptr, 5 },
    { Event::DESTRUCT, v2, nullptr, 4 },
  };
  return true;
}

static bool testPointer(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{ 4 };
  const cm::optional<EventLogger> o2{ 5 };

  o1->Reference();
  o2->Reference();

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
    { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
    { Event::REFERENCE, &*o1, nullptr, 4 },
    { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
    { Event::DESTRUCT, &*o2, nullptr, 5 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
  };
  return true;
}

#if !__GNUC__ || __GNUC__ > 4
#  define ALLOW_CONST_RVALUE
#endif

static bool testDereference(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{ 4 };
  auto const* v1 = &*o1;
  const cm::optional<EventLogger> o2{ 5 };
  auto const* v2 = &*o2;

  (*o1).Reference();
  (*o2).Reference();
  (*std::move(o1)).Reference();
#ifdef ALLOW_CONST_RVALUE
  (*std::move(o2)).Reference(); // Broken in GCC 4.9.0. Sigh...
#endif

  expected = {
    { Event::VALUE_CONSTRUCT, v1, nullptr, 4 },
    { Event::VALUE_CONSTRUCT, v2, nullptr, 5 },
    { Event::REFERENCE, v1, nullptr, 4 },
    { Event::CONST_REFERENCE, v2, nullptr, 5 },
    { Event::RVALUE_REFERENCE, v1, nullptr, 4 },
#ifdef ALLOW_CONST_RVALUE
    { Event::CONST_RVALUE_REFERENCE, v2, nullptr, 5 },
#endif
    { Event::DESTRUCT, v2, nullptr, 5 },
    { Event::DESTRUCT, v1, nullptr, 4 },
  };
  return true;
}

static bool testHasValue(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o1{ 4 };
  const cm::optional<EventLogger> o2{};

  ASSERT_TRUE(o1.has_value());
  ASSERT_TRUE(o1);
  ASSERT_TRUE(!o2.has_value());
  ASSERT_TRUE(!o2);

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
  };
  return true;
}

static bool testValue(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{ 4 };
  const cm::optional<EventLogger> o2{ 5 };
  cm::optional<EventLogger> o3{};
  const cm::optional<EventLogger> o4{};

  o1.value().Reference();
  o2.value().Reference();

  bool thrown = false;
  try {
    (void)o3.value();
  } catch (cm::bad_optional_access&) {
    thrown = true;
  }
  ASSERT_TRUE(thrown);

  thrown = false;
  try {
    (void)o4.value();
  } catch (cm::bad_optional_access&) {
    thrown = true;
  }
  ASSERT_TRUE(thrown);

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 4 },
    { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
    { Event::REFERENCE, &*o1, nullptr, 4 },
    { Event::CONST_REFERENCE, &*o2, nullptr, 5 },
    { Event::DESTRUCT, &*o2, nullptr, 5 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
  };
  return true;
}

static bool testValueOr()
{
  const cm::optional<EventLogger> o1{ 4 };
  cm::optional<EventLogger> o2{ 5 };
  const cm::optional<EventLogger> o3{};
  cm::optional<EventLogger> o4{};

  EventLogger e1{ 6 };
  EventLogger e2{ 7 };
  EventLogger e3{ 8 };
  EventLogger e4{ 9 };

  EventLogger r1 = o1.value_or(e1);
  ASSERT_TRUE(r1.Value == 4);
  EventLogger r2 = std::move(o2).value_or(e2);
  ASSERT_TRUE(r2.Value == 5);
  EventLogger r3 = o3.value_or(e3);
  ASSERT_TRUE(r3.Value == 8);
  EventLogger r4 = std::move(o4).value_or(e4);
  ASSERT_TRUE(r4.Value == 9);

  return true;
}

static bool testComparison(std::vector<Event>& expected)
{
  const cm::optional<EventLogger> o1{ 1 };
  const cm::optional<EventLogger> o2{ 2 };
  const cm::optional<EventLogger> o3{ 2 };
  const cm::optional<EventLogger> o4{};
  const cm::optional<EventLogger> o5{};
  const EventLogger e1{ 2 };

  ASSERT_TRUE(!(o1 == o2) && o1 != o2);
  ASSERT_TRUE(o1 < o2 && !(o1 >= o2));
  ASSERT_TRUE(!(o1 > o2) && o1 <= o2);

  ASSERT_TRUE(o2 == o3 && !(o2 != o3));
  ASSERT_TRUE(!(o2 < o3) && o2 >= o3);
  ASSERT_TRUE(!(o2 > o3) && o2 <= o3);

  ASSERT_TRUE(!(o3 == o4) && o3 != o4);
  ASSERT_TRUE(!(o3 < o4) && o3 >= o4);
  ASSERT_TRUE(o3 > o4 && !(o3 <= o4));

  ASSERT_TRUE(o4 == o5 && !(o4 != o5));
  ASSERT_TRUE(!(o4 < o5) && o4 >= o5);
  ASSERT_TRUE(!(o4 > o5) && o4 <= o5);

  ASSERT_TRUE(!(o1 == cm::nullopt) && o1 != cm::nullopt);
  ASSERT_TRUE(!(o1 < cm::nullopt) && o1 >= cm::nullopt);
  ASSERT_TRUE(o1 > cm::nullopt && !(o1 <= cm::nullopt));

  ASSERT_TRUE(!(cm::nullopt == o1) && cm::nullopt != o1);
  ASSERT_TRUE(cm::nullopt < o1 && !(cm::nullopt >= o1));
  ASSERT_TRUE(!(cm::nullopt > o1) && cm::nullopt <= o1);

  ASSERT_TRUE(o4 == cm::nullopt && !(o4 != cm::nullopt));
  ASSERT_TRUE(!(o4 < cm::nullopt) && o4 >= cm::nullopt);
  ASSERT_TRUE(!(o4 > cm::nullopt) && o4 <= cm::nullopt);

  ASSERT_TRUE(cm::nullopt == o4 && !(cm::nullopt != o4));
  ASSERT_TRUE(!(cm::nullopt < o4) && cm::nullopt >= o4);
  ASSERT_TRUE(!(cm::nullopt > o4) && cm::nullopt <= o4);

  ASSERT_TRUE(!(o1 == e1) && o1 != e1);
  ASSERT_TRUE(o1 < e1 && !(o1 >= e1));
  ASSERT_TRUE(!(o1 > e1) && o1 <= e1);

  ASSERT_TRUE(o2 == e1 && !(o2 != e1));
  ASSERT_TRUE(!(o2 < e1) && o2 >= e1);
  ASSERT_TRUE(!(o2 > e1) && o2 <= e1);

  ASSERT_TRUE(!(o4 == e1) && o4 != e1);
  ASSERT_TRUE(o4 < e1 && !(o4 >= e1));
  ASSERT_TRUE(!(o4 > e1) && o4 <= e1);

  ASSERT_TRUE(!(e1 == o1) && e1 != o1);
  ASSERT_TRUE(!(e1 < o1) && e1 >= o1);
  ASSERT_TRUE(e1 > o1 && !(e1 <= o1));

  ASSERT_TRUE(e1 == o2 && !(e1 != o2));
  ASSERT_TRUE(!(e1 < o2) && e1 >= o2);
  ASSERT_TRUE(!(e1 > o2) && e1 <= o2);

  ASSERT_TRUE(!(e1 == o4) && e1 != o4);
  ASSERT_TRUE(!(e1 < o4) && e1 >= o4);
  ASSERT_TRUE(e1 > o4 && !(e1 <= o4));

  expected = {
    { Event::VALUE_CONSTRUCT, &*o1, nullptr, 1 },
    { Event::VALUE_CONSTRUCT, &*o2, nullptr, 2 },
    { Event::VALUE_CONSTRUCT, &*o3, nullptr, 2 },
    { Event::VALUE_CONSTRUCT, &e1, nullptr, 2 },
    { Event::COMPARE_EE_EQ, &*o1, &*o2, 1 },
    { Event::COMPARE_EE_NE, &*o1, &*o2, 1 },
    { Event::COMPARE_EE_LT, &*o1, &*o2, 1 },
    { Event::COMPARE_EE_GE, &*o1, &*o2, 1 },
    { Event::COMPARE_EE_GT, &*o1, &*o2, 1 },
    { Event::COMPARE_EE_LE, &*o1, &*o2, 1 },
    { Event::COMPARE_EE_EQ, &*o2, &*o3, 2 },
    { Event::COMPARE_EE_NE, &*o2, &*o3, 2 },
    { Event::COMPARE_EE_LT, &*o2, &*o3, 2 },
    { Event::COMPARE_EE_GE, &*o2, &*o3, 2 },
    { Event::COMPARE_EE_GT, &*o2, &*o3, 2 },
    { Event::COMPARE_EE_LE, &*o2, &*o3, 2 },
    { Event::COMPARE_EE_EQ, &*o1, &e1, 1 },
    { Event::COMPARE_EE_NE, &*o1, &e1, 1 },
    { Event::COMPARE_EE_LT, &*o1, &e1, 1 },
    { Event::COMPARE_EE_GE, &*o1, &e1, 1 },
    { Event::COMPARE_EE_GT, &*o1, &e1, 1 },
    { Event::COMPARE_EE_LE, &*o1, &e1, 1 },
    { Event::COMPARE_EE_EQ, &*o2, &e1, 2 },
    { Event::COMPARE_EE_NE, &*o2, &e1, 2 },
    { Event::COMPARE_EE_LT, &*o2, &e1, 2 },
    { Event::COMPARE_EE_GE, &*o2, &e1, 2 },
    { Event::COMPARE_EE_GT, &*o2, &e1, 2 },
    { Event::COMPARE_EE_LE, &*o2, &e1, 2 },
    { Event::COMPARE_EE_EQ, &e1, &*o1, 2 },
    { Event::COMPARE_EE_NE, &e1, &*o1, 2 },
    { Event::COMPARE_EE_LT, &e1, &*o1, 2 },
    { Event::COMPARE_EE_GE, &e1, &*o1, 2 },
    { Event::COMPARE_EE_GT, &e1, &*o1, 2 },
    { Event::COMPARE_EE_LE, &e1, &*o1, 2 },
    { Event::COMPARE_EE_EQ, &e1, &*o2, 2 },
    { Event::COMPARE_EE_NE, &e1, &*o2, 2 },
    { Event::COMPARE_EE_LT, &e1, &*o2, 2 },
    { Event::COMPARE_EE_GE, &e1, &*o2, 2 },
    { Event::COMPARE_EE_GT, &e1, &*o2, 2 },
    { Event::COMPARE_EE_LE, &e1, &*o2, 2 },
    { Event::DESTRUCT, &e1, nullptr, 2 },
    { Event::DESTRUCT, &*o3, nullptr, 2 },
    { Event::DESTRUCT, &*o2, nullptr, 2 },
    { Event::DESTRUCT, &*o1, nullptr, 1 },
  };
  return true;
}

static bool testSwap(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o1{ 4 };
  auto const* v1 = &*o1;
  cm::optional<EventLogger> o2{};

  o1.swap(o2);
  auto const* v2 = &*o2;

  ASSERT_TRUE(!o1.has_value());
  ASSERT_TRUE(o2.has_value());
  ASSERT_TRUE(o2.value().Value == 4);

  o1.swap(o2);

  ASSERT_TRUE(o1.has_value());
  ASSERT_TRUE(o1.value().Value == 4);
  ASSERT_TRUE(!o2.has_value());

  o2.emplace(5);
  o1.swap(o2);

  ASSERT_TRUE(o1.has_value());
  ASSERT_TRUE(o1.value().Value == 5);
  ASSERT_TRUE(o2.has_value());
  ASSERT_TRUE(o2.value().Value == 4);

  o1.reset();
  o2.reset();
  o1.swap(o2);

  ASSERT_TRUE(!o1.has_value());
  ASSERT_TRUE(!o2.has_value());

  expected = {
    { Event::VALUE_CONSTRUCT, v1, nullptr, 4 },
    { Event::MOVE_CONSTRUCT, v2, v1, 4 },
    { Event::DESTRUCT, v1, nullptr, 4 },
    { Event::MOVE_CONSTRUCT, v1, v2, 4 },
    { Event::DESTRUCT, v2, nullptr, 4 },
    { Event::VALUE_CONSTRUCT, v2, nullptr, 5 },
    { Event::SWAP, v1, v2, 5 },
    { Event::DESTRUCT, v1, nullptr, 5 },
    { Event::DESTRUCT, v2, nullptr, 4 },
  };
  return true;
}

static bool testReset(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o{ 4 };
  auto const* v = &*o;

  o.reset();

  ASSERT_TRUE(!o.has_value());

  o.reset();

  expected = {
    { Event::VALUE_CONSTRUCT, v, nullptr, 4 },
    { Event::DESTRUCT, v, nullptr, 4 },
  };
  return true;
}

static bool testEmplace(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o{ 4 };

  o.emplace(5);
  o.reset();
  o.emplace();

  expected = {
    { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
    { Event::DESTRUCT, &*o, nullptr, 4 },
    { Event::VALUE_CONSTRUCT, &*o, nullptr, 5 },
    { Event::DESTRUCT, &*o, nullptr, 5 },
    { Event::DEFAULT_CONSTRUCT, &*o, nullptr, 0 },
    { Event::DESTRUCT, &*o, nullptr, 0 },
  };
  return true;
}

static bool testMakeOptional(std::vector<Event>& expected)
{
  EventLogger e{ 4 };
  cm::optional<EventLogger> o1 = cm::make_optional<EventLogger>(e);
  cm::optional<EventLogger> o2 = cm::make_optional<EventLogger>(5);

  expected = {
    { Event::VALUE_CONSTRUCT, &e, nullptr, 4 },
    { Event::COPY_CONSTRUCT, &*o1, &e, 4 },
    { Event::VALUE_CONSTRUCT, &*o2, nullptr, 5 },
    { Event::DESTRUCT, &*o2, nullptr, 5 },
    { Event::DESTRUCT, &*o1, nullptr, 4 },
    { Event::DESTRUCT, &e, nullptr, 4 },
  };
  return true;
}

static bool testMemoryRange(std::vector<Event>& expected)
{
  cm::optional<EventLogger> o{ 4 };

  auto* ostart = &o;
  auto* oend = ostart + 1;
  auto* estart = &o.value();
  auto* eend = estart + 1;

  ASSERT_TRUE(static_cast<void*>(estart) >= static_cast<void*>(ostart) &&
              static_cast<void*>(eend) <= static_cast<void*>(oend));

  expected = {
    { Event::VALUE_CONSTRUCT, &*o, nullptr, 4 },
    { Event::DESTRUCT, &*o, nullptr, 4 },
  };
  return true;
}

int testOptional(int /*unused*/, char* /*unused*/ [])
{
  int retval = 0;

#define DO_EVENT_TEST(name)                                                   \
  do {                                                                        \
    events.clear();                                                           \
    std::vector<Event> expected;                                              \
    if (!name(expected)) {                                                    \
      std::cout << "in " #name << std::endl;                                  \
      retval = 1;                                                             \
    } else if (expected != events) {                                          \
      std::cout << #name " did not produce expected events" << std::endl;     \
      retval = 1;                                                             \
    }                                                                         \
  } while (0)

#define DO_TEST(name)                                                         \
  do {                                                                        \
    if (!name()) {                                                            \
      std::cout << "in " #name << std::endl;                                  \
      retval = 1;                                                             \
    }                                                                         \
  } while (0)

  DO_EVENT_TEST(testDefaultConstruct);
  DO_EVENT_TEST(testNulloptConstruct);
  DO_EVENT_TEST(testValueConstruct);
  DO_EVENT_TEST(testInPlaceConstruct);
  DO_EVENT_TEST(testCopyConstruct);
  DO_EVENT_TEST(testMoveConstruct);
  DO_EVENT_TEST(testNulloptAssign);
  DO_EVENT_TEST(testCopyAssign);
  DO_EVENT_TEST(testMoveAssign);
  DO_EVENT_TEST(testPointer);
  DO_EVENT_TEST(testDereference);
  DO_EVENT_TEST(testHasValue);
  DO_EVENT_TEST(testValue);
  DO_TEST(testValueOr);
  DO_EVENT_TEST(testComparison);
  DO_EVENT_TEST(testSwap);
  DO_EVENT_TEST(testReset);
  DO_EVENT_TEST(testEmplace);
  DO_EVENT_TEST(testMakeOptional);
  DO_EVENT_TEST(testMemoryRange);

  return retval;
}
