//===- FunctionExtrasTest.cpp - Unit tests for function type erasure ------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/FunctionExtras.h"
#include "gtest/gtest.h"

#include <memory>

using namespace llvm;

namespace {

TEST(UniqueFunctionTest, Basic) {
  unique_function<int(int, int)> Sum = [](int A, int B) { return A + B; };
  EXPECT_EQ(Sum(1, 2), 3);

  unique_function<int(int, int)> Sum2 = std::move(Sum);
  EXPECT_EQ(Sum2(1, 2), 3);

  unique_function<int(int, int)> Sum3 = [](int A, int B) { return A + B; };
  Sum2 = std::move(Sum3);
  EXPECT_EQ(Sum2(1, 2), 3);

  Sum2 = unique_function<int(int, int)>([](int A, int B) { return A + B; });
  EXPECT_EQ(Sum2(1, 2), 3);

  // Explicit self-move test.
  *&Sum2 = std::move(Sum2);
  EXPECT_EQ(Sum2(1, 2), 3);

  Sum2 = unique_function<int(int, int)>();
  EXPECT_FALSE(Sum2);

  // Make sure we can forward through l-value reference parameters.
  unique_function<void(int &)> Inc = [](int &X) { ++X; };
  int X = 42;
  Inc(X);
  EXPECT_EQ(X, 43);

  // Make sure we can forward through r-value reference parameters with
  // move-only types.
  unique_function<int(std::unique_ptr<int> &&)> ReadAndDeallocByRef =
      [](std::unique_ptr<int> &&Ptr) {
        int V = *Ptr;
        Ptr.reset();
        return V;
      };
  std::unique_ptr<int> Ptr{new int(13)};
  EXPECT_EQ(ReadAndDeallocByRef(std::move(Ptr)), 13);
  EXPECT_FALSE((bool)Ptr);

  // Make sure we can pass a move-only temporary as opposed to a local variable.
  EXPECT_EQ(ReadAndDeallocByRef(std::unique_ptr<int>(new int(42))), 42);

  // Make sure we can pass a move-only type by-value.
  unique_function<int(std::unique_ptr<int>)> ReadAndDeallocByVal =
      [](std::unique_ptr<int> Ptr) {
        int V = *Ptr;
        Ptr.reset();
        return V;
      };
  Ptr.reset(new int(13));
  EXPECT_EQ(ReadAndDeallocByVal(std::move(Ptr)), 13);
  EXPECT_FALSE((bool)Ptr);

  EXPECT_EQ(ReadAndDeallocByVal(std::unique_ptr<int>(new int(42))), 42);
}

TEST(UniqueFunctionTest, Captures) {
  long A = 1, B = 2, C = 3, D = 4, E = 5;

  unique_function<long()> Tmp;

  unique_function<long()> C1 = [A]() { return A; };
  EXPECT_EQ(C1(), 1);
  Tmp = std::move(C1);
  EXPECT_EQ(Tmp(), 1);

  unique_function<long()> C2 = [A, B]() { return A + B; };
  EXPECT_EQ(C2(), 3);
  Tmp = std::move(C2);
  EXPECT_EQ(Tmp(), 3);

  unique_function<long()> C3 = [A, B, C]() { return A + B + C; };
  EXPECT_EQ(C3(), 6);
  Tmp = std::move(C3);
  EXPECT_EQ(Tmp(), 6);

  unique_function<long()> C4 = [A, B, C, D]() { return A + B + C + D; };
  EXPECT_EQ(C4(), 10);
  Tmp = std::move(C4);
  EXPECT_EQ(Tmp(), 10);

  unique_function<long()> C5 = [A, B, C, D, E]() { return A + B + C + D + E; };
  EXPECT_EQ(C5(), 15);
  Tmp = std::move(C5);
  EXPECT_EQ(Tmp(), 15);
}

TEST(UniqueFunctionTest, MoveOnly) {
  struct SmallCallable {
    std::unique_ptr<int> A{new int(1)};

    int operator()(int B) { return *A + B; }
  };
  unique_function<int(int)> Small = SmallCallable();
  EXPECT_EQ(Small(2), 3);
  unique_function<int(int)> Small2 = std::move(Small);
  EXPECT_EQ(Small2(2), 3);

  struct LargeCallable {
    std::unique_ptr<int> A{new int(1)};
    std::unique_ptr<int> B{new int(2)};
    std::unique_ptr<int> C{new int(3)};
    std::unique_ptr<int> D{new int(4)};
    std::unique_ptr<int> E{new int(5)};

    int operator()() { return *A + *B + *C + *D + *E; }
  };
  unique_function<int()> Large = LargeCallable();
  EXPECT_EQ(Large(), 15);
  unique_function<int()> Large2 = std::move(Large);
  EXPECT_EQ(Large2(), 15);
}

TEST(UniqueFunctionTest, CountForwardingCopies) {
  struct CopyCounter {
    int &CopyCount;

    CopyCounter(int &CopyCount) : CopyCount(CopyCount) {}
    CopyCounter(const CopyCounter &Arg) : CopyCount(Arg.CopyCount) {
      ++CopyCount;
    }
  };

  unique_function<void(CopyCounter)> ByValF = [](CopyCounter) {};
  int CopyCount = 0;
  ByValF(CopyCounter(CopyCount));
  EXPECT_EQ(1, CopyCount);

  CopyCount = 0;
  {
    CopyCounter Counter{CopyCount};
    ByValF(Counter);
  }
  EXPECT_EQ(2, CopyCount);

  // Check that we don't generate a copy at all when we can bind a reference all
  // the way down, even if that reference could *in theory* allow copies.
  unique_function<void(const CopyCounter &)> ByRefF = [](const CopyCounter &) {
  };
  CopyCount = 0;
  ByRefF(CopyCounter(CopyCount));
  EXPECT_EQ(0, CopyCount);

  CopyCount = 0;
  {
    CopyCounter Counter{CopyCount};
    ByRefF(Counter);
  }
  EXPECT_EQ(0, CopyCount);

  // If we use a reference, we can make a stronger guarantee that *no* copy
  // occurs.
  struct Uncopyable {
    Uncopyable() = default;
    Uncopyable(const Uncopyable &) = delete;
  };
  unique_function<void(const Uncopyable &)> UncopyableF =
      [](const Uncopyable &) {};
  UncopyableF(Uncopyable());
  Uncopyable X;
  UncopyableF(X);
}

TEST(UniqueFunctionTest, CountForwardingMoves) {
  struct MoveCounter {
    int &MoveCount;

    MoveCounter(int &MoveCount) : MoveCount(MoveCount) {}
    MoveCounter(MoveCounter &&Arg) : MoveCount(Arg.MoveCount) { ++MoveCount; }
  };

  unique_function<void(MoveCounter)> ByValF = [](MoveCounter) {};
  int MoveCount = 0;
  ByValF(MoveCounter(MoveCount));
  EXPECT_EQ(1, MoveCount);

  MoveCount = 0;
  {
    MoveCounter Counter{MoveCount};
    ByValF(std::move(Counter));
  }
  EXPECT_EQ(2, MoveCount);

  // Check that when we use an r-value reference we get no spurious copies.
  unique_function<void(MoveCounter &&)> ByRefF = [](MoveCounter &&) {};
  MoveCount = 0;
  ByRefF(MoveCounter(MoveCount));
  EXPECT_EQ(0, MoveCount);

  MoveCount = 0;
  {
    MoveCounter Counter{MoveCount};
    ByRefF(std::move(Counter));
  }
  EXPECT_EQ(0, MoveCount);

  // If we use an r-value reference we can in fact make a stronger guarantee
  // with an unmovable type.
  struct Unmovable {
    Unmovable() = default;
    Unmovable(Unmovable &&) = delete;
  };
  unique_function<void(const Unmovable &)> UnmovableF = [](const Unmovable &) {
  };
  UnmovableF(Unmovable());
  Unmovable X;
  UnmovableF(X);
}

} // anonymous namespace
