1// RUN: %check_clang_tidy %s abseil-cleanup-ctad -std=c++17 %t
2
3namespace std {
4
5template <typename, typename>
6struct is_same {
7 static const bool value = false;
8};
9
10template <typename T>
11struct is_same<T, T> { static const bool value = true; };
12
13template <typename>
14class function {
15public:
16 template <typename T>
17 function(T) {}
18 function(const function &) {}
19};
20
21} // namespace std
22
23namespace absl {
24
25namespace cleanup_internal {
26
27struct Tag {};
28
29template <typename Callback>
30class Storage {
31public:
32 Storage() = delete;
33
34 explicit Storage(Callback callback) {}
35
36 Storage(Storage &&other) {}
37
38 Storage(const Storage &other) = delete;
39
40 Storage &operator=(Storage &&other) = delete;
41
42 Storage &operator=(const Storage &other) = delete;
43
44private:
45 bool is_callback_engaged_;
46 alignas(Callback) char callback_buffer_[sizeof(Callback)];
47};
48
49} // namespace cleanup_internal
50
51template <typename Arg, typename Callback = void()>
52class Cleanup final {
53public:
54 Cleanup(Callback callback) // NOLINT
55 : storage_(static_cast<Callback &&>(callback)) {}
56
57 Cleanup(Cleanup &&other) = default;
58
59 void Cancel() &&;
60
61 void Invoke() &&;
62
63 ~Cleanup();
64
65private:
66 cleanup_internal::Storage<Callback> storage_;
67};
68
69template <typename Callback>
70Cleanup(Callback callback) -> Cleanup<cleanup_internal::Tag, Callback>;
71
72template <typename... Args, typename Callback>
73absl::Cleanup<cleanup_internal::Tag, Callback> MakeCleanup(Callback callback) {
74 return {static_cast<Callback &&>(callback)};
75}
76
77} // namespace absl
78
79void test() {
80 auto a = absl::MakeCleanup(callback: [] {});
81 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher
82 // CHECK-FIXES: {{^}} absl::Cleanup a = [] {};{{$}}
83
84 auto b = absl::MakeCleanup(callback: std::function<void()>([] {}));
85 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup{{.*}}C++17 and higher
86 // CHECK-FIXES: {{^}} absl::Cleanup b = std::function<void()>([] {});{{$}}
87
88 const auto c = absl::MakeCleanup(callback: [] {});
89 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup{{.*}}C++17 and higher
90 // CHECK-FIXES: {{^}} const absl::Cleanup c = [] {};{{$}}
91
92 const auto d = absl::MakeCleanup(callback: std::function<void()>([] {}));
93 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup{{.*}}C++17 and higher
94 // CHECK-FIXES: {{^}} const absl::Cleanup d = std::function<void()>([] {});{{$}}
95
96 // Preserves extra parens
97 auto e = absl::MakeCleanup(callback: ([] {}));
98 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup{{.*}}C++17 and higher
99 // CHECK-FIXES: {{^}} absl::Cleanup e = ([] {});{{$}}
100
101 // Preserves comments
102 auto f = /* a */ absl::MakeCleanup(/* b */ callback: [] { /* c */ } /* d */) /* e */;
103 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup{{.*}}C++17 and higher
104 // CHECK-FIXES: {{^}} absl::Cleanup f = /* a */ /* b */ [] { /* c */ } /* d */ /* e */;{{$}}
105}
106

source code of clang-tools-extra/test/clang-tidy/checkers/abseil/cleanup-ctad.cpp