diff options
author | Abseil Team <absl-team@google.com> | 2021-02-01 14:09:21 -0800 |
---|---|---|
committer | Gennadiy Rozental <rogeeff@google.com> | 2021-02-02 05:36:53 -0500 |
commit | 20869f89edbc38139f46bdc49c8b6c3a1f7bee4c (patch) | |
tree | a8ee769172aba7c03f1ad6dc3d5b4ddc3a75eefc /absl/cleanup | |
parent | 184d2f8364bcb05e413ec4c72cad0cf86e712d1c (diff) |
Export of internal Abseil changes
--
cea62ebc5d31c62aabcb94c066d9be506f34baf6 by Abseil Team <absl-team@google.com>:
Fix typo in `Cord::EndsWith()` docs
PiperOrigin-RevId: 355023067
--
f89225a55476478ec167be50dea543f5414836f9 by Abseil Team <absl-team@google.com>:
Add set_cordz_info() and get_cordz_info() methods to InlineData
This change has preparations for future (optional) integration of CordzInfo sampling data into Cord's InlineData for non inlined cords.
PiperOrigin-RevId: 354965340
--
324057574aeb697bd3327cb905eb5bca16ade768 by Abseil Team <absl-team@google.com>:
Fix two comment typos.
PiperOrigin-RevId: 354952568
--
5bb93ca3d57ead3633e1efde4aa28718987ef64f by CJ Johnson <johnsoncj@google.com>:
Clarify doc comment for absl::Cleanup by using absl::Status return type and clarify the engaged state by surfacing the initial value in the public header.
PiperOrigin-RevId: 354935253
--
ec95424594b24a1aec9bf7972b2355f37285506a by Abseil Team <absl-team@google.com>:
Remove `preserve_most` attribute from CordRep::Destroy()
PiperOrigin-RevId: 354921927
GitOrigin-RevId: cea62ebc5d31c62aabcb94c066d9be506f34baf6
Change-Id: Ibe1d66197db7ce9554594e07b1c6e7c6dea3c9da
Diffstat (limited to 'absl/cleanup')
-rw-r--r-- | absl/cleanup/cleanup.h | 51 | ||||
-rw-r--r-- | absl/cleanup/internal/cleanup.h | 10 |
2 files changed, 36 insertions, 25 deletions
diff --git a/absl/cleanup/cleanup.h b/absl/cleanup/cleanup.h index f606b3f4..5a4bc546 100644 --- a/absl/cleanup/cleanup.h +++ b/absl/cleanup/cleanup.h @@ -16,35 +16,39 @@ // File: cleanup.h // ----------------------------------------------------------------------------- // -// `absl::Cleanup` implements the scope guard idiom, invoking `operator()() &&` -// on the callback it was constructed with, on scope exit. +// `absl::Cleanup` implements the scope guard idiom, invoking the contained +// callback's `operator()() &&` on scope exit. // // Example: // // ``` -// void CopyGoodData(const char* input_path, const char* output_path) { -// FILE* in_file = fopen(input_path, "r"); -// if (in_file == nullptr) return; +// absl::Status CopyGoodData(const char* source_path, const char* sink_path) { +// FILE* source_file = fopen(source_path, "r"); +// if (source_file == nullptr) { +// return absl::NotFoundError("No source file"); // No cleanups execute +// } // -// // C++17 style using class template argument deduction -// absl::Cleanup in_closer = [in_file] { fclose(in_file); }; +// // C++17 style cleanup using class template argument deduction +// absl::Cleanup source_closer = [source_file] { fclose(source_file); }; // -// FILE* out_file = fopen(output_path, "w"); -// if (out_file == nullptr) return; // `in_closer` will run +// FILE* sink_file = fopen(sink_path, "w"); +// if (sink_file == nullptr) { +// return absl::NotFoundError("No sink file"); // First cleanup executes +// } // -// // C++11 style using the factory function -// auto out_closer = absl::MakeCleanup([out_file] { fclose(out_file); }); +// // C++11 style cleanup using the factory function +// auto sink_closer = absl::MakeCleanup([sink_file] { fclose(sink_file); }); // // Data data; -// while (ReadData(in_file, &data)) { +// while (ReadData(source_file, &data)) { // if (data.IsBad()) { -// LOG(ERROR) << "Found bad data."; -// return; // `in_closer` and `out_closer` will run +// absl::Status result = absl::FailedPreconditionError("Read bad data"); +// return result; // Both cleanups execute // } -// SaveData(out_file, &data); +// SaveData(sink_file, &data); // } // -// // `in_closer` and `out_closer` will run +// return absl::OkStatus(); // Both cleanups execute // } // ``` // @@ -54,6 +58,12 @@ // // `std::move(cleanup).Invoke()` will execute the callback early, before // destruction, and prevent the callback from executing in the destructor. +// +// Usage: +// +// `absl::Cleanup` is not an interface type. It is only intended to be used +// within the body of a function. It is not a value type and instead models a +// control flow construct. Check out `defer` in Golang for something similar. #ifndef ABSL_CLEANUP_CLEANUP_H_ #define ABSL_CLEANUP_CLEANUP_H_ @@ -76,9 +86,10 @@ class ABSL_MUST_USE_RESULT Cleanup { "Callbacks that return values are not supported."); public: - Cleanup(Callback callback) : storage_(std::move(callback)) {} // NOLINT + Cleanup(Callback callback) // NOLINT + : storage_(std::move(callback), /*engaged=*/true) {} - Cleanup(Cleanup&& other) : storage_(std::move(other.storage_)) {} + Cleanup(Cleanup&& other) = default; void Cancel() && { ABSL_HARDENING_ASSERT(storage_.IsCallbackEngaged()); @@ -103,7 +114,7 @@ class ABSL_MUST_USE_RESULT Cleanup { // `absl::Cleanup c = /* callback */;` // -// C++17 type deduction API for creating an instance of `absl::Cleanup`. +// C++17 type deduction API for creating an instance of `absl::Cleanup` #if defined(ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) template <typename Callback> Cleanup(Callback callback) -> Cleanup<cleanup_internal::Tag, Callback>; @@ -111,7 +122,7 @@ Cleanup(Callback callback) -> Cleanup<cleanup_internal::Tag, Callback>; // `auto c = absl::MakeCleanup(/* callback */);` // -// C++11 type deduction API for creating an instance of `absl::Cleanup`. +// C++11 type deduction API for creating an instance of `absl::Cleanup` template <typename... Args, typename Callback> absl::Cleanup<cleanup_internal::Tag, Callback> MakeCleanup(Callback callback) { static_assert(cleanup_internal::WasDeduced<cleanup_internal::Tag, Args...>(), diff --git a/absl/cleanup/internal/cleanup.h b/absl/cleanup/internal/cleanup.h index 8fbca5bd..b68e3dd3 100644 --- a/absl/cleanup/internal/cleanup.h +++ b/absl/cleanup/internal/cleanup.h @@ -45,12 +45,12 @@ class Storage { public: Storage() = delete; - explicit Storage(Callback callback) - : engaged_(true), callback_(std::move(callback)) {} + Storage(Callback callback, bool engaged) + : callback_(std::move(callback)), engaged_(engaged) {} Storage(Storage&& other) - : engaged_(absl::exchange(other.engaged_, false)), - callback_(std::move(other.callback_)) {} + : callback_(std::move(other.callback_)), + engaged_(absl::exchange(other.engaged_, false)) {} Storage(const Storage& other) = delete; @@ -67,8 +67,8 @@ class Storage { } private: - bool engaged_; Callback callback_; + bool engaged_; }; } // namespace cleanup_internal |