brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · f67cfa6 Raw
170 lines · cpp
1//===-- unique_function_test.cpp ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "unique_function.h"10#include "gtest/gtest.h"11 12using namespace orc_rt;13 14TEST(UniqueFunctionTest, Basic) {15  unique_function<int(int, int)> Sum = [](int A, int B) { return A + B; };16  EXPECT_EQ(Sum(1, 2), 3);17 18  unique_function<int(int, int)> Sum2 = std::move(Sum);19  EXPECT_EQ(Sum2(1, 2), 3);20 21  unique_function<int(int, int)> Sum3 = [](int A, int B) { return A + B; };22  Sum2 = std::move(Sum3);23  EXPECT_EQ(Sum2(1, 2), 3);24 25  Sum2 = unique_function<int(int, int)>([](int A, int B) { return A + B; });26  EXPECT_EQ(Sum2(1, 2), 3);27 28  // Explicit self-move test.29  *&Sum2 = std::move(Sum2);30  EXPECT_EQ(Sum2(1, 2), 3);31 32  Sum2 = unique_function<int(int, int)>();33  EXPECT_FALSE(Sum2);34 35  // Make sure we can forward through l-value reference parameters.36  unique_function<void(int &)> Inc = [](int &X) { ++X; };37  int X = 42;38  Inc(X);39  EXPECT_EQ(X, 43);40 41  // Make sure we can forward through r-value reference parameters with42  // move-only types.43  unique_function<int(std::unique_ptr<int> &&)> ReadAndDeallocByRef =44      [](std::unique_ptr<int> &&Ptr) {45        int V = *Ptr;46        Ptr.reset();47        return V;48      };49  std::unique_ptr<int> Ptr{new int(13)};50  EXPECT_EQ(ReadAndDeallocByRef(std::move(Ptr)), 13);51  EXPECT_FALSE((bool)Ptr);52 53  // Make sure we can pass a move-only temporary as opposed to a local variable.54  EXPECT_EQ(ReadAndDeallocByRef(std::unique_ptr<int>(new int(42))), 42);55 56  // Make sure we can pass a move-only type by-value.57  unique_function<int(std::unique_ptr<int>)> ReadAndDeallocByVal =58      [](std::unique_ptr<int> Ptr) {59        int V = *Ptr;60        Ptr.reset();61        return V;62      };63  Ptr.reset(new int(13));64  EXPECT_EQ(ReadAndDeallocByVal(std::move(Ptr)), 13);65  EXPECT_FALSE((bool)Ptr);66 67  EXPECT_EQ(ReadAndDeallocByVal(std::unique_ptr<int>(new int(42))), 42);68}69 70TEST(UniqueFunctionTest, Captures) {71  long A = 1, B = 2, C = 3, D = 4, E = 5;72 73  unique_function<long()> Tmp;74 75  unique_function<long()> C1 = [A]() { return A; };76  EXPECT_EQ(C1(), 1);77  Tmp = std::move(C1);78  EXPECT_EQ(Tmp(), 1);79 80  unique_function<long()> C2 = [A, B]() { return A + B; };81  EXPECT_EQ(C2(), 3);82  Tmp = std::move(C2);83  EXPECT_EQ(Tmp(), 3);84 85  unique_function<long()> C3 = [A, B, C]() { return A + B + C; };86  EXPECT_EQ(C3(), 6);87  Tmp = std::move(C3);88  EXPECT_EQ(Tmp(), 6);89 90  unique_function<long()> C4 = [A, B, C, D]() { return A + B + C + D; };91  EXPECT_EQ(C4(), 10);92  Tmp = std::move(C4);93  EXPECT_EQ(Tmp(), 10);94 95  unique_function<long()> C5 = [A, B, C, D, E]() { return A + B + C + D + E; };96  EXPECT_EQ(C5(), 15);97  Tmp = std::move(C5);98  EXPECT_EQ(Tmp(), 15);99}100 101TEST(UniqueFunctionTest, MoveOnly) {102  struct SmallCallable {103    std::unique_ptr<int> A = std::make_unique<int>(1);104    int operator()(int B) { return *A + B; }105  };106 107  unique_function<int(int)> Small = SmallCallable();108  EXPECT_EQ(Small(2), 3);109  unique_function<int(int)> Small2 = std::move(Small);110  EXPECT_EQ(Small2(2), 3);111}112 113TEST(UniqueFunctionTest, CountForwardingCopies) {114  struct CopyCounter {115    int &CopyCount;116 117    CopyCounter(int &CopyCount) : CopyCount(CopyCount) {}118    CopyCounter(const CopyCounter &Arg) : CopyCount(Arg.CopyCount) {119      ++CopyCount;120    }121  };122 123  unique_function<void(CopyCounter)> ByValF = [](CopyCounter) {};124  int CopyCount = 0;125  ByValF(CopyCounter(CopyCount));126  EXPECT_EQ(1, CopyCount);127 128  CopyCount = 0;129  {130    CopyCounter Counter{CopyCount};131    ByValF(Counter);132  }133  EXPECT_EQ(2, CopyCount);134 135  // Check that we don't generate a copy at all when we can bind a reference all136  // the way down, even if that reference could *in theory* allow copies.137  unique_function<void(const CopyCounter &)> ByRefF = [](const CopyCounter &) {138  };139  CopyCount = 0;140  ByRefF(CopyCounter(CopyCount));141  EXPECT_EQ(0, CopyCount);142 143  CopyCount = 0;144  {145    CopyCounter Counter{CopyCount};146    ByRefF(Counter);147  }148  EXPECT_EQ(0, CopyCount);149 150  // If we use a reference, we can make a stronger guarantee that *no* copy151  // occurs.152  struct Uncopyable {153    Uncopyable() = default;154    Uncopyable(const Uncopyable &) = delete;155  };156  unique_function<void(const Uncopyable &)> UncopyableF =157      [](const Uncopyable &) {};158  UncopyableF(Uncopyable());159  Uncopyable X;160  UncopyableF(X);161}162 163TEST(UniqueFunctionTest, BooleanConversion) {164  unique_function<void()> D;165  EXPECT_FALSE(D);166 167  unique_function<void()> F = []() {};168  EXPECT_TRUE(F);169}170