/* * Copyright (c) 2021 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include namespace chip { class LambdaBridge { public: // Use initialize instead of constructor because this class has to be trivial template void Initialize(const Lambda & lambda) { // memcpy is used to move the lambda into the event queue, so it must be trivially copyable static_assert(std::is_trivially_copyable::value, "lambda must be trivially copyable"); static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE, "lambda too large"); static_assert(CHIP_CONFIG_LAMBDA_EVENT_ALIGN % alignof(Lambda) == 0, "lambda align too large"); // Implicit cast a capture-less lambda into a raw function pointer. mLambdaProxy = [](const LambdaStorage & body) { (*reinterpret_cast(&body))(); }; ::memcpy(&mLambdaBody, &lambda, sizeof(Lambda)); } void operator()() const { mLambdaProxy(mLambdaBody); } private: using LambdaStorage = std::aligned_storage_t; void (*mLambdaProxy)(const LambdaStorage & body); LambdaStorage mLambdaBody; }; static_assert(std::is_trivial::value, "LambdaBridge is not trivial"); } // namespace chip