blob: c837d61367c75b7ec3bf3cda7f38e175079da77d [file] [log] [blame]
// Copyright 2023 The Pigweed 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
//
// https://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 <cpp-type/member_pointer_traits.h>
#include <type_traits>
#include "pw_unit_test/framework.h"
namespace bt_lib_cpp_type {
namespace {
TEST(TypeTest, MemberPointerTraits) {
struct Foo {
bool scalar_bool_member;
double scalar_double_member;
double array_double_member[1];
struct InnerStruct {
int nested_scalar_int_member;
} struct_member;
};
static_assert(
std::is_same_v<Foo,
MemberPointerTraits<&Foo::scalar_bool_member>::ClassType>);
static_assert(std::is_same_v<
Foo,
MemberPointerTraits<&Foo::scalar_double_member>::ClassType>);
static_assert(std::is_same_v<
Foo,
MemberPointerTraits<&Foo::array_double_member>::ClassType>);
static_assert(
std::is_same_v<Foo, MemberPointerTraits<&Foo::struct_member>::ClassType>);
static_assert(std::is_same_v<
Foo::InnerStruct,
MemberPointerTraits<
&Foo::InnerStruct::nested_scalar_int_member>::ClassType>);
static_assert(std::is_same_v<
bool,
MemberPointerTraits<&Foo::scalar_bool_member>::MemberType>);
static_assert(std::is_same_v<
double,
MemberPointerTraits<&Foo::scalar_double_member>::MemberType>);
static_assert(std::is_same_v<
double[1],
MemberPointerTraits<&Foo::array_double_member>::MemberType>);
static_assert(
std::is_same_v<Foo::InnerStruct,
MemberPointerTraits<&Foo::struct_member>::MemberType>);
static_assert(std::is_same_v<
int,
MemberPointerTraits<
&Foo::InnerStruct::nested_scalar_int_member>::MemberType>);
EXPECT_EQ(offsetof(Foo, scalar_bool_member),
MemberPointerTraits<&Foo::scalar_bool_member>::offset());
EXPECT_EQ(offsetof(Foo, scalar_double_member),
MemberPointerTraits<&Foo::scalar_double_member>::offset());
EXPECT_EQ(offsetof(Foo, array_double_member),
MemberPointerTraits<&Foo::array_double_member>::offset());
EXPECT_EQ(offsetof(Foo, struct_member),
MemberPointerTraits<&Foo::struct_member>::offset());
// offsetof can be used with non-anonymous nested members because it refers to
// member identifiers, not types.
EXPECT_LT(0U, offsetof(Foo, struct_member.nested_scalar_int_member));
// |Foo::InnerStruct| is the qualified name of a type so
// |nested_scalar_int_member|'s offset within it is 0.
EXPECT_EQ(0U,
MemberPointerTraits<
&Foo::InnerStruct::nested_scalar_int_member>::offset());
}
} // namespace
} // namespace bt_lib_cpp_type