1c6f20d70SScott Linder //===- STLForwardCompatTest.cpp - Unit tests for STLForwardCompat ---------===//
2c6f20d70SScott Linder //
3c6f20d70SScott Linder // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c6f20d70SScott Linder // See https://llvm.org/LICENSE.txt for license information.
5c6f20d70SScott Linder // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c6f20d70SScott Linder //
7c6f20d70SScott Linder //===----------------------------------------------------------------------===//
8c6f20d70SScott Linder
9c6f20d70SScott Linder #include "llvm/ADT/STLForwardCompat.h"
10*68716573Sc8ef #include "CountCopyAndMove.h"
11c6f20d70SScott Linder #include "gtest/gtest.h"
12c6f20d70SScott Linder
13c6f20d70SScott Linder namespace {
14c6f20d70SScott Linder
15f3026d8bSScott Linder template <typename T>
16f3026d8bSScott Linder class STLForwardCompatRemoveCVRefTest : public ::testing::Test {};
17f3026d8bSScott Linder
18f3026d8bSScott Linder using STLForwardCompatRemoveCVRefTestTypes = ::testing::Types<
19f3026d8bSScott Linder // clang-format off
20f3026d8bSScott Linder std::pair<int, int>,
21f3026d8bSScott Linder std::pair<int &, int>,
22f3026d8bSScott Linder std::pair<const int, int>,
23f3026d8bSScott Linder std::pair<volatile int, int>,
24f3026d8bSScott Linder std::pair<const volatile int &, int>,
25f3026d8bSScott Linder std::pair<int *, int *>,
26f3026d8bSScott Linder std::pair<int *const, int *>,
27f3026d8bSScott Linder std::pair<const int *, const int *>,
28f3026d8bSScott Linder std::pair<int *&, int *>
29f3026d8bSScott Linder // clang-format on
30f3026d8bSScott Linder >;
31f3026d8bSScott Linder
32d4d80a29SBenjamin Kramer TYPED_TEST_SUITE(STLForwardCompatRemoveCVRefTest,
3305de4b41SBenjamin Kramer STLForwardCompatRemoveCVRefTestTypes, );
34f3026d8bSScott Linder
TYPED_TEST(STLForwardCompatRemoveCVRefTest,RemoveCVRef)35f3026d8bSScott Linder TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRef) {
36f3026d8bSScott Linder using From = typename TypeParam::first_type;
37f3026d8bSScott Linder using To = typename TypeParam::second_type;
38f3026d8bSScott Linder EXPECT_TRUE(
39f3026d8bSScott Linder (std::is_same<typename llvm::remove_cvref<From>::type, To>::value));
40f3026d8bSScott Linder }
41f3026d8bSScott Linder
TYPED_TEST(STLForwardCompatRemoveCVRefTest,RemoveCVRefT)42f3026d8bSScott Linder TYPED_TEST(STLForwardCompatRemoveCVRefTest, RemoveCVRefT) {
43f3026d8bSScott Linder using From = typename TypeParam::first_type;
44f3026d8bSScott Linder EXPECT_TRUE((std::is_same<typename llvm::remove_cvref<From>::type,
45f3026d8bSScott Linder llvm::remove_cvref_t<From>>::value));
46f3026d8bSScott Linder }
47f3026d8bSScott Linder
TEST(TransformTest,TransformStd)4821a34475SKazu Hirata TEST(TransformTest, TransformStd) {
4921a34475SKazu Hirata std::optional<int> A;
5021a34475SKazu Hirata
5121a34475SKazu Hirata std::optional<int> B = llvm::transformOptional(A, [&](int N) { return N + 1; });
5221a34475SKazu Hirata EXPECT_FALSE(B.has_value());
5321a34475SKazu Hirata
5421a34475SKazu Hirata A = 3;
5521a34475SKazu Hirata std::optional<int> C = llvm::transformOptional(A, [&](int N) { return N + 1; });
5621a34475SKazu Hirata EXPECT_TRUE(C.has_value());
5767ba5c50SFangrui Song EXPECT_EQ(4, *C);
5821a34475SKazu Hirata }
5921a34475SKazu Hirata
TEST(TransformTest,MoveTransformStd)6021a34475SKazu Hirata TEST(TransformTest, MoveTransformStd) {
61*68716573Sc8ef using llvm::CountCopyAndMove;
6221a34475SKazu Hirata
63*68716573Sc8ef std::optional<CountCopyAndMove> A;
6421a34475SKazu Hirata
65*68716573Sc8ef CountCopyAndMove::ResetCounts();
6621a34475SKazu Hirata std::optional<int> B = llvm::transformOptional(
67*68716573Sc8ef std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
6821a34475SKazu Hirata EXPECT_FALSE(B.has_value());
69*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
70*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
71*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
72*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::Destructions);
7321a34475SKazu Hirata
74*68716573Sc8ef A = CountCopyAndMove(5);
75*68716573Sc8ef CountCopyAndMove::ResetCounts();
7621a34475SKazu Hirata std::optional<int> C = llvm::transformOptional(
77*68716573Sc8ef std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
7821a34475SKazu Hirata EXPECT_TRUE(C.has_value());
7967ba5c50SFangrui Song EXPECT_EQ(7, *C);
80*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
81*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
82*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
83*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::Destructions);
8421a34475SKazu Hirata }
8521a34475SKazu Hirata
TEST(TransformTest,TransformLlvm)8621a34475SKazu Hirata TEST(TransformTest, TransformLlvm) {
8777c90c8cSKazu Hirata std::optional<int> A;
8821a34475SKazu Hirata
8977c90c8cSKazu Hirata std::optional<int> B =
9077c90c8cSKazu Hirata llvm::transformOptional(A, [&](int N) { return N + 1; });
9121a34475SKazu Hirata EXPECT_FALSE(B.has_value());
9221a34475SKazu Hirata
9321a34475SKazu Hirata A = 3;
9477c90c8cSKazu Hirata std::optional<int> C =
9577c90c8cSKazu Hirata llvm::transformOptional(A, [&](int N) { return N + 1; });
9621a34475SKazu Hirata EXPECT_TRUE(C.has_value());
9767ba5c50SFangrui Song EXPECT_EQ(4, *C);
9821a34475SKazu Hirata }
9921a34475SKazu Hirata
TEST(TransformTest,MoveTransformLlvm)10021a34475SKazu Hirata TEST(TransformTest, MoveTransformLlvm) {
101*68716573Sc8ef using llvm::CountCopyAndMove;
10221a34475SKazu Hirata
103*68716573Sc8ef std::optional<CountCopyAndMove> A;
10421a34475SKazu Hirata
105*68716573Sc8ef CountCopyAndMove::ResetCounts();
10677c90c8cSKazu Hirata std::optional<int> B = llvm::transformOptional(
107*68716573Sc8ef std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
10821a34475SKazu Hirata EXPECT_FALSE(B.has_value());
109*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
110*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
111*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
112*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::Destructions);
11321a34475SKazu Hirata
114*68716573Sc8ef A = CountCopyAndMove(5);
115*68716573Sc8ef CountCopyAndMove::ResetCounts();
11677c90c8cSKazu Hirata std::optional<int> C = llvm::transformOptional(
117*68716573Sc8ef std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
11821a34475SKazu Hirata EXPECT_TRUE(C.has_value());
11967ba5c50SFangrui Song EXPECT_EQ(7, *C);
120*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
121*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
122*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
123*68716573Sc8ef EXPECT_EQ(0, CountCopyAndMove::Destructions);
12421a34475SKazu Hirata }
12521a34475SKazu Hirata
TEST(TransformTest,ToUnderlying)126d0caa4eeSVlad Serebrennikov TEST(TransformTest, ToUnderlying) {
127d0caa4eeSVlad Serebrennikov enum E { A1 = 0, B1 = -1 };
128d0caa4eeSVlad Serebrennikov static_assert(llvm::to_underlying(A1) == 0);
129d0caa4eeSVlad Serebrennikov static_assert(llvm::to_underlying(B1) == -1);
130d0caa4eeSVlad Serebrennikov
131d0caa4eeSVlad Serebrennikov enum E2 : unsigned char { A2 = 0, B2 };
132d0caa4eeSVlad Serebrennikov static_assert(
133d0caa4eeSVlad Serebrennikov std::is_same_v<unsigned char, decltype(llvm::to_underlying(A2))>);
134d0caa4eeSVlad Serebrennikov static_assert(llvm::to_underlying(A2) == 0);
135d0caa4eeSVlad Serebrennikov static_assert(llvm::to_underlying(B2) == 1);
136d0caa4eeSVlad Serebrennikov
137d0caa4eeSVlad Serebrennikov enum class E3 { A3 = -1, B3 };
138d0caa4eeSVlad Serebrennikov static_assert(std::is_same_v<int, decltype(llvm::to_underlying(E3::A3))>);
139d0caa4eeSVlad Serebrennikov static_assert(llvm::to_underlying(E3::A3) == -1);
140d0caa4eeSVlad Serebrennikov static_assert(llvm::to_underlying(E3::B3) == 0);
141d0caa4eeSVlad Serebrennikov }
142d0caa4eeSVlad Serebrennikov
143c6f20d70SScott Linder } // namespace
144