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 <memory> 21 22 namespace android::binder::impl { 23 24 template <typename F> assert_small_callable()25constexpr void assert_small_callable() { 26 // While this buffer (std::function::__func::__buf_) is an implementation detail generally not 27 // accessible to users, it's a good bet to assume its size to be around 3 pointers. 28 constexpr size_t kFunctionBufferSize = 3 * sizeof(void*); 29 30 static_assert(sizeof(F) <= kFunctionBufferSize, 31 "Supplied callable is larger than std::function optimization buffer. " 32 "Try using std::ref, but make sure lambda lives long enough to be called."); 33 } 34 35 template <typename F> make_scope_guard(F && f)36std::unique_ptr<void, std::function<void(void*)>> make_scope_guard(F&& f) { 37 assert_small_callable<decltype(std::bind(f))>(); 38 return {reinterpret_cast<void*>(true), std::bind(f)}; 39 } 40 41 template <typename T> 42 class SmallFunction : public std::function<T> { 43 public: 44 template <typename F> SmallFunction(F && f)45 SmallFunction(F&& f) : std::function<T>(f) { 46 assert_small_callable<F>(); 47 } 48 }; 49 50 } // namespace android::binder::impl 51