1 // Copyright 2023 The Abseil Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/utility/internal/if_constexpr.h"
16
17 #include <utility>
18
19 #include "gtest/gtest.h"
20
21 namespace {
22
23 struct Empty {};
24 struct HasFoo {
foo__anon83a38f9d0111::HasFoo25 int foo() const { return 1; }
26 };
27
TEST(IfConstexpr,Basic)28 TEST(IfConstexpr, Basic) {
29 int i = 0;
30 absl::utility_internal::IfConstexpr<false>(
31 [&](const auto& t) { i = t.foo(); }, Empty{});
32 EXPECT_EQ(i, 0);
33
34 absl::utility_internal::IfConstexpr<false>(
35 [&](const auto& t) { i = t.foo(); }, HasFoo{});
36 EXPECT_EQ(i, 0);
37
38 absl::utility_internal::IfConstexpr<true>(
39 [&](const auto& t) { i = t.foo(); }, HasFoo{});
40 EXPECT_EQ(i, 1);
41 }
42
TEST(IfConstexprElse,Basic)43 TEST(IfConstexprElse, Basic) {
44 EXPECT_EQ(absl::utility_internal::IfConstexprElse<false>(
45 [&](const auto& t) { return t.foo(); }, [&](const auto&) { return 2; },
46 Empty{}), 2);
47
48 EXPECT_EQ(absl::utility_internal::IfConstexprElse<false>(
49 [&](const auto& t) { return t.foo(); }, [&](const auto&) { return 2; },
50 HasFoo{}), 2);
51
52 EXPECT_EQ(absl::utility_internal::IfConstexprElse<true>(
53 [&](const auto& t) { return t.foo(); }, [&](const auto&) { return 2; },
54 HasFoo{}), 1);
55 }
56
57 struct HasFooRValue {
foo__anon83a38f9d0111::HasFooRValue58 int foo() && { return 1; }
59 };
60 struct RValueFunc {
operator ()__anon83a38f9d0111::RValueFunc61 void operator()(HasFooRValue&& t) && { *i = std::move(t).foo(); }
62
63 int* i = nullptr;
64 };
65
TEST(IfConstexpr,RValues)66 TEST(IfConstexpr, RValues) {
67 int i = 0;
68 RValueFunc func = {&i};
69 absl::utility_internal::IfConstexpr<false>(
70 std::move(func), HasFooRValue{});
71 EXPECT_EQ(i, 0);
72
73 func = RValueFunc{&i};
74 absl::utility_internal::IfConstexpr<true>(
75 std::move(func), HasFooRValue{});
76 EXPECT_EQ(i, 1);
77 }
78
79 } // namespace
80