1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <functional> 20 #include <optional> 21 22 namespace android::binder::impl { 23 24 template <typename F> 25 class scope_guard; 26 27 template <typename F> 28 scope_guard<F> make_scope_guard(F f); 29 30 template <typename F> 31 class scope_guard { 32 public: ~scope_guard()33 inline ~scope_guard() { 34 if (f_.has_value()) std::move(f_.value())(); 35 } release()36 inline void release() { f_.reset(); } 37 38 private: 39 friend scope_guard<F> android::binder::impl::make_scope_guard<>(F); 40 scope_guard(F && f)41 inline scope_guard(F&& f) : f_(std::move(f)) {} 42 43 std::optional<F> f_; 44 }; 45 46 template <typename F> make_scope_guard(F f)47inline scope_guard<F> make_scope_guard(F f) { 48 return scope_guard<F>(std::move(f)); 49 } 50 51 template <typename F> assert_small_callable()52constexpr void assert_small_callable() { 53 // While this buffer (std::function::__func::__buf_) is an implementation detail generally not 54 // accessible to users, it's a good bet to assume its size to be around 3 pointers. 55 constexpr size_t kFunctionBufferSize = 3 * sizeof(void*); 56 57 static_assert(sizeof(F) <= kFunctionBufferSize, 58 "Supplied callable is larger than std::function optimization buffer. " 59 "Try using std::ref, but make sure lambda lives long enough to be called."); 60 } 61 62 template <typename T> 63 class SmallFunction : public std::function<T> { 64 public: 65 template <typename F> SmallFunction(F && f)66 SmallFunction(F&& f) : std::function<T>(f) { 67 assert_small_callable<F>(); 68 } 69 }; 70 71 } // namespace android::binder::impl 72