File indexing completed on 2025-01-18 09:27:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_CLEANUP_INTERNAL_CLEANUP_H_
0016 #define ABSL_CLEANUP_INTERNAL_CLEANUP_H_
0017
0018 #include <new>
0019 #include <type_traits>
0020 #include <utility>
0021
0022 #include "absl/base/internal/invoke.h"
0023 #include "absl/base/macros.h"
0024 #include "absl/base/thread_annotations.h"
0025 #include "absl/utility/utility.h"
0026
0027 namespace absl {
0028 ABSL_NAMESPACE_BEGIN
0029
0030 namespace cleanup_internal {
0031
0032 struct Tag {};
0033
0034 template <typename Arg, typename... Args>
0035 constexpr bool WasDeduced() {
0036 return (std::is_same<cleanup_internal::Tag, Arg>::value) &&
0037 (sizeof...(Args) == 0);
0038 }
0039
0040 template <typename Callback>
0041 constexpr bool ReturnsVoid() {
0042 return (std::is_same<base_internal::invoke_result_t<Callback>, void>::value);
0043 }
0044
0045 template <typename Callback>
0046 class Storage {
0047 public:
0048 Storage() = delete;
0049
0050 explicit Storage(Callback callback) {
0051
0052
0053
0054 ::new (GetCallbackBuffer()) Callback(std::move(callback));
0055 is_callback_engaged_ = true;
0056 }
0057
0058 Storage(Storage&& other) {
0059 ABSL_HARDENING_ASSERT(other.IsCallbackEngaged());
0060
0061 ::new (GetCallbackBuffer()) Callback(std::move(other.GetCallback()));
0062 is_callback_engaged_ = true;
0063
0064 other.DestroyCallback();
0065 }
0066
0067 Storage(const Storage& other) = delete;
0068
0069 Storage& operator=(Storage&& other) = delete;
0070
0071 Storage& operator=(const Storage& other) = delete;
0072
0073 void* GetCallbackBuffer() { return static_cast<void*>(+callback_buffer_); }
0074
0075 Callback& GetCallback() {
0076 return *reinterpret_cast<Callback*>(GetCallbackBuffer());
0077 }
0078
0079 bool IsCallbackEngaged() const { return is_callback_engaged_; }
0080
0081 void DestroyCallback() {
0082 is_callback_engaged_ = false;
0083 GetCallback().~Callback();
0084 }
0085
0086 void InvokeCallback() ABSL_NO_THREAD_SAFETY_ANALYSIS {
0087 std::move(GetCallback())();
0088 }
0089
0090 private:
0091 bool is_callback_engaged_;
0092 alignas(Callback) char callback_buffer_[sizeof(Callback)];
0093 };
0094
0095 }
0096
0097 ABSL_NAMESPACE_END
0098 }
0099
0100 #endif