summaryrefslogtreecommitdiff
path: root/absl/cleanup
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-02-01 14:09:21 -0800
committerGravatar Gennadiy Rozental <rogeeff@google.com>2021-02-02 05:36:53 -0500
commit20869f89edbc38139f46bdc49c8b6c3a1f7bee4c (patch)
treea8ee769172aba7c03f1ad6dc3d5b4ddc3a75eefc /absl/cleanup
parent184d2f8364bcb05e413ec4c72cad0cf86e712d1c (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.h51
-rw-r--r--absl/cleanup/internal/cleanup.h10
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