diff --git a/src/lib/support/OwnerOf.h b/src/lib/support/OwnerOf.h new file mode 100644 index 00000000000000..eac9ac674f7c60 --- /dev/null +++ b/src/lib/support/OwnerOf.h @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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 + +namespace chip { + +template +constexpr ClassType * OwnerOf(MemberType * ptr, const MemberType ClassType::*member) +{ + return reinterpret_cast(reinterpret_cast(ptr) - offsetof(ClassType, member)); +} + +} // namespace chip diff --git a/src/lib/support/tests/BUILD.gn b/src/lib/support/tests/BUILD.gn index 9e81fdb40af43e..1ffeeb0c1c8a13 100644 --- a/src/lib/support/tests/BUILD.gn +++ b/src/lib/support/tests/BUILD.gn @@ -29,6 +29,7 @@ chip_test_suite("tests") { "TestCHIPCounter.cpp", "TestCHIPMem.cpp", "TestErrorStr.cpp", + "TestOwnerOf.cpp", "TestPool.cpp", "TestPrivateHeap.cpp", "TestSafeInt.cpp", diff --git a/src/lib/support/tests/TestOwnerOf.cpp b/src/lib/support/tests/TestOwnerOf.cpp new file mode 100644 index 00000000000000..550a18b0b127f5 --- /dev/null +++ b/src/lib/support/tests/TestOwnerOf.cpp @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#include +#include + +#include + +using namespace chip; + +class Member +{ +}; + +class Base +{ +public: + uint32_t Offset0; + uint32_t Offset4; + Member member; +}; + +static void TestMemberOwner(nlTestSuite * inSuite, void * inContext) +{ + Base base; + Member * member = &base.member; + NL_TEST_ASSERT(inSuite, OwnerOf(member, &Base::member) == &base); + NL_TEST_ASSERT(inSuite, &OwnerOf(member, &Base::member)->member == member); +} + +#define NL_TEST_DEF_FN(fn) NL_TEST_DEF("Test " #fn, fn) +/** + * Test Suite. It lists all the test functions. + */ +static const nlTest sTests[] = { NL_TEST_DEF_FN(TestMemberOwner), NL_TEST_SENTINEL() }; + +int TestOwnerOf(void) +{ + nlTestSuite theSuite = { "CHIP OwnerOf tests", &sTests[0], nullptr, nullptr }; + + // Run test suit againt one context. + nlTestRunner(&theSuite, nullptr); + return nlTestRunnerStats(&theSuite); +} + +CHIP_REGISTER_TEST_SUITE(TestOwnerOf)