// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef SUPPORT_VARIANT_TEST_HELPERS_H
#define SUPPORT_VARIANT_TEST_HELPERS_H

#include <type_traits>
#include <utility>
#include <cassert>

#include "test_macros.h"
#include "type_id.h"

#if TEST_STD_VER <= 14
#error This file requires C++17
#endif

// FIXME: Currently the variant<T&> tests are disabled using this macro.
#define TEST_VARIANT_HAS_NO_REFERENCES
#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
# define TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS
#endif

#ifdef TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS
constexpr bool VariantAllowsNarrowingConversions = true;
#else
constexpr bool VariantAllowsNarrowingConversions = false;
#endif

#ifndef TEST_HAS_NO_EXCEPTIONS
struct CopyThrows {
  CopyThrows() = default;
  CopyThrows(CopyThrows const&) { throw 42; }
  CopyThrows& operator=(CopyThrows const&) { throw 42; }
};

struct MoveThrows {
  static int alive;
  MoveThrows() { ++alive; }
  MoveThrows(MoveThrows const&) {++alive;}
  MoveThrows(MoveThrows&&) {  throw 42; }
  MoveThrows& operator=(MoveThrows const&) { return *this; }
  MoveThrows& operator=(MoveThrows&&) { throw 42; }
  ~MoveThrows() { --alive; }
};

int MoveThrows::alive = 0;

struct MakeEmptyT {
  static int alive;
  MakeEmptyT() { ++alive; }
  MakeEmptyT(MakeEmptyT const&) {
      ++alive;
      // Don't throw from the copy constructor since variant's assignment
      // operator performs a copy before committing to the assignment.
  }
  MakeEmptyT(MakeEmptyT &&) {
      throw 42;
  }
  MakeEmptyT& operator=(MakeEmptyT const&) {
      throw 42;
  }
  MakeEmptyT& operator=(MakeEmptyT&&) {
      throw 42;
  }
   ~MakeEmptyT() { --alive; }
};
static_assert(std::is_swappable_v<MakeEmptyT>, ""); // required for test

int MakeEmptyT::alive = 0;

template <class Variant>
void makeEmpty(Variant& v) {
    Variant v2(std::in_place_type<MakeEmptyT>);
    try {
        v = std::move(v2);
        assert(false);
    } catch (...) {
        assert(v.valueless_by_exception());
    }
}
#endif // TEST_HAS_NO_EXCEPTIONS

enum CallType : unsigned {
  CT_None,
  CT_NonConst = 1,
  CT_Const = 2,
  CT_LValue = 4,
  CT_RValue = 8
};

inline constexpr CallType operator|(CallType LHS, CallType RHS) {
  return static_cast<CallType>(static_cast<unsigned>(LHS) |
                               static_cast<unsigned>(RHS));
}

struct ForwardingCallObject {

  template <class... Args>
  ForwardingCallObject& operator()(Args&&...) & {
    set_call<Args &&...>(CT_NonConst | CT_LValue);
    return *this;
  }

  template <class... Args>
  const ForwardingCallObject& operator()(Args&&...) const & {
    set_call<Args &&...>(CT_Const | CT_LValue);
    return *this;
  }

  template <class... Args>
  ForwardingCallObject&& operator()(Args&&...) && {
    set_call<Args &&...>(CT_NonConst | CT_RValue);
    return std::move(*this);
  }

  template <class... Args>
  const ForwardingCallObject&& operator()(Args&&...) const && {
    set_call<Args &&...>(CT_Const | CT_RValue);
    return std::move(*this);
  }

  template <class... Args> static void set_call(CallType type) {
    assert(last_call_type == CT_None);
    assert(last_call_args == nullptr);
    last_call_type = type;
    last_call_args = std::addressof(makeArgumentID<Args...>());
  }

  template <class... Args> static bool check_call(CallType type) {
    bool result = last_call_type == type && last_call_args &&
                  *last_call_args == makeArgumentID<Args...>();
    last_call_type = CT_None;
    last_call_args = nullptr;
    return result;
  }

  // To check explicit return type for visit<R>
  constexpr operator int() const
  {
    return 0;
  }

  static CallType last_call_type;
  static const TypeID *last_call_args;
};

CallType ForwardingCallObject::last_call_type = CT_None;
const TypeID *ForwardingCallObject::last_call_args = nullptr;

struct ReturnFirst {
  template <class... Args> constexpr int operator()(int f, Args &&...) const {
    return f;
  }
};

struct ReturnArity {
  template <class... Args> constexpr int operator()(Args &&...) const {
    return sizeof...(Args);
  }
};

#endif // SUPPORT_VARIANT_TEST_HELPERS_H
