Line data Source code
1 : /*
2 : * Copyright (c) 2021 Project CHIP Authors
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 <string.h>
20 : #include <type_traits>
21 :
22 : #include <lib/core/CHIPConfig.h>
23 :
24 : namespace chip {
25 :
26 : class LambdaBridge
27 : {
28 : public:
29 : // Use initialize instead of constructor because this class has to be trivial
30 : template <typename Lambda>
31 61 : void Initialize(const Lambda & lambda)
32 : {
33 : // memcpy is used to move the lambda into the event queue, so it must be trivially copyable
34 : static_assert(std::is_trivially_copyable<Lambda>::value, "lambda must be trivially copyable");
35 : static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE, "lambda too large");
36 : static_assert(CHIP_CONFIG_LAMBDA_EVENT_ALIGN % alignof(Lambda) == 0, "lambda align too large");
37 :
38 : // Implicit cast a capture-less lambda into a raw function pointer.
39 85 : mLambdaProxy = [](const LambdaStorage & body) { (*reinterpret_cast<const Lambda *>(&body))(); };
40 61 : ::memcpy(&mLambdaBody, &lambda, sizeof(Lambda));
41 61 : }
42 :
43 24 : void operator()() const { mLambdaProxy(mLambdaBody); }
44 :
45 : private:
46 : using LambdaStorage = std::aligned_storage_t<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN>;
47 : void (*mLambdaProxy)(const LambdaStorage & body);
48 : LambdaStorage mLambdaBody;
49 : };
50 :
51 : static_assert(std::is_trivial<LambdaBridge>::value, "LambdaBridge is not trivial");
52 :
53 : } // namespace chip
|