brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · bd183f2 Raw
175 lines · cpp
1//===- llvm/unittest/Support/AnyTest.cpp - Any tests ---===//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 "llvm/ADT/Any.h"10#include "gtest/gtest.h"11#include <cstdlib>12 13using namespace llvm;14 15namespace {16 17// Make sure we can construct, copy-construct, move-construct, and assign Any's.18TEST(AnyTest, ConstructionAndAssignment) {19  llvm::Any A;20  llvm::Any B{7};21  llvm::Any C{8};22  llvm::Any D{"hello"};23  llvm::Any E{3.7};24 25  // An empty Any is not anything.26  EXPECT_FALSE(A.has_value());27  EXPECT_FALSE(llvm::any_cast<int>(&A));28 29  // An int is an int but not something else.30  EXPECT_TRUE(B.has_value());31  EXPECT_TRUE(llvm::any_cast<int>(&B));32  EXPECT_FALSE(llvm::any_cast<float>(&B));33 34  EXPECT_TRUE(C.has_value());35  EXPECT_TRUE(llvm::any_cast<int>(&C));36 37  // A const char * is a const char * but not an int.38  EXPECT_TRUE(D.has_value());39  EXPECT_TRUE(llvm::any_cast<const char *>(&D));40  EXPECT_FALSE(llvm::any_cast<int>(&D));41 42  // A double is a double but not a float.43  EXPECT_TRUE(E.has_value());44  EXPECT_TRUE(llvm::any_cast<double>(&E));45  EXPECT_FALSE(llvm::any_cast<float>(&E));46 47  // After copy constructing from an int, the new item and old item are both48  // ints.49  llvm::Any F(B);50  EXPECT_TRUE(B.has_value());51  EXPECT_TRUE(F.has_value());52  EXPECT_TRUE(llvm::any_cast<int>(&F));53  EXPECT_TRUE(llvm::any_cast<int>(&B));54 55  // After move constructing from an int, the new item is an int and the old one56  // isn't.57  llvm::Any G(std::move(C));58  EXPECT_FALSE(C.has_value());59  EXPECT_TRUE(G.has_value());60  EXPECT_TRUE(llvm::any_cast<int>(&G));61  EXPECT_FALSE(llvm::any_cast<int>(&C));62 63  // After copy-assigning from an int, the new item and old item are both ints.64  A = F;65  EXPECT_TRUE(A.has_value());66  EXPECT_TRUE(F.has_value());67  EXPECT_TRUE(llvm::any_cast<int>(&A));68  EXPECT_TRUE(llvm::any_cast<int>(&F));69 70  // After move-assigning from an int, the new item and old item are both ints.71  B = std::move(G);72  EXPECT_TRUE(B.has_value());73  EXPECT_FALSE(G.has_value());74  EXPECT_TRUE(llvm::any_cast<int>(&B));75  EXPECT_FALSE(llvm::any_cast<int>(&G));76}77 78TEST(AnyTest, GoodAnyCast) {79  llvm::Any A;80  llvm::Any B{7};81  llvm::Any C{8};82  llvm::Any D{"hello"};83  llvm::Any E{'x'};84 85  // Check each value twice to make sure it isn't damaged by the cast.86  EXPECT_EQ(7, llvm::any_cast<int>(B));87  EXPECT_EQ(7, llvm::any_cast<int>(B));88 89  EXPECT_STREQ("hello", llvm::any_cast<const char *>(D));90  EXPECT_STREQ("hello", llvm::any_cast<const char *>(D));91 92  EXPECT_EQ('x', llvm::any_cast<char>(E));93  EXPECT_EQ('x', llvm::any_cast<char>(E));94 95  llvm::Any F(B);96  EXPECT_EQ(7, llvm::any_cast<int>(F));97  EXPECT_EQ(7, llvm::any_cast<int>(F));98 99  llvm::Any G(std::move(C));100  EXPECT_EQ(8, llvm::any_cast<int>(G));101  EXPECT_EQ(8, llvm::any_cast<int>(G));102 103  A = F;104  EXPECT_EQ(7, llvm::any_cast<int>(A));105  EXPECT_EQ(7, llvm::any_cast<int>(A));106 107  E = std::move(G);108  EXPECT_EQ(8, llvm::any_cast<int>(E));109  EXPECT_EQ(8, llvm::any_cast<int>(E));110 111  // Make sure we can any_cast from an rvalue and that it's properly destroyed112  // in the process.113  EXPECT_EQ(8, llvm::any_cast<int>(std::move(E)));114  EXPECT_TRUE(E.has_value());115 116  // Make sure moving from pointers gives back pointers, and that we can modify117  // the underlying value through those pointers.118  EXPECT_EQ(7, *llvm::any_cast<int>(&A));119  int *N = llvm::any_cast<int>(&A);120  *N = 42;121  EXPECT_EQ(42, llvm::any_cast<int>(A));122 123  // Make sure that we can any_cast to a reference and this is considered a good124  // cast, resulting in an lvalue which can be modified.125  llvm::any_cast<int &>(A) = 43;126  EXPECT_EQ(43, llvm::any_cast<int>(A));127}128 129TEST(AnyTest, CopiesAndMoves) {130  struct TestType {131    TestType() = default;132    TestType(const TestType &Other)133        : Copies(Other.Copies + 1), Moves(Other.Moves) {}134    TestType(TestType &&Other) : Copies(Other.Copies), Moves(Other.Moves + 1) {}135    int Copies = 0;136    int Moves = 0;137  };138 139  // One move to get TestType into the Any, and one move on the cast.140  TestType T1 = llvm::any_cast<TestType>(Any{TestType()});141  EXPECT_EQ(0, T1.Copies);142  EXPECT_EQ(2, T1.Moves);143 144  // One move to get TestType into the Any, and one copy on the cast.145  Any A{TestType()};146  TestType T2 = llvm::any_cast<TestType>(A);147  EXPECT_EQ(1, T2.Copies);148  EXPECT_EQ(1, T2.Moves);149 150  // One move to get TestType into the Any, and one move on the cast.151  TestType T3 = llvm::any_cast<TestType>(std::move(A));152  EXPECT_EQ(0, T3.Copies);153  EXPECT_EQ(2, T3.Moves);154}155 156TEST(AnyTest, BadAnyCast) {157  llvm::Any A;158  llvm::Any B{7};159  llvm::Any C{"hello"};160  llvm::Any D{'x'};161 162#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST163  EXPECT_DEATH(llvm::any_cast<int>(A), "");164 165  EXPECT_DEATH(llvm::any_cast<float>(B), "");166  EXPECT_DEATH(llvm::any_cast<int *>(B), "");167 168  EXPECT_DEATH(llvm::any_cast<std::string>(C), "");169 170  EXPECT_DEATH(llvm::any_cast<unsigned char>(D), "");171#endif172}173 174} // anonymous namespace175