106 lines · cpp
1// RUN: %check_clang_tidy %s abseil-cleanup-ctad -std=c++17 %t2 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 std22 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_internal50 51template <typename Arg, typename Callback = void()>52class Cleanup final {53public:54 Cleanup(Callback callback) // NOLINT55 : 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 absl78 79void test() {80 auto a = absl::MakeCleanup([] {});81 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup's class template argument deduction pattern in C++17 and higher82 // CHECK-FIXES: absl::Cleanup a = [] {};83 84 auto b = absl::MakeCleanup(std::function<void()>([] {}));85 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup{{.*}}C++17 and higher86 // CHECK-FIXES: absl::Cleanup b = std::function<void()>([] {});87 88 const auto c = absl::MakeCleanup([] {});89 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup{{.*}}C++17 and higher90 // CHECK-FIXES: const absl::Cleanup c = [] {};91 92 const auto d = absl::MakeCleanup(std::function<void()>([] {}));93 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: prefer absl::Cleanup{{.*}}C++17 and higher94 // CHECK-FIXES: const absl::Cleanup d = std::function<void()>([] {});95 96 // Preserves extra parens97 auto e = absl::MakeCleanup(([] {}));98 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup{{.*}}C++17 and higher99 // CHECK-FIXES: absl::Cleanup e = ([] {});100 101 // Preserves comments102 auto f = /* a */ absl::MakeCleanup(/* b */ [] { /* c */ } /* d */) /* e */;103 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: prefer absl::Cleanup{{.*}}C++17 and higher104 // CHECK-FIXES: absl::Cleanup f = /* a */ /* b */ [] { /* c */ } /* d */ /* e */;105}106