1#include <c10/util/typeid.h>
2#include <gtest/gtest.h>
3
4using std::string;
5
6namespace caffe2 {
7namespace {
8
9class TypeMetaTestFoo {};
10class TypeMetaTestBar {};
11} // namespace
12
13CAFFE_KNOWN_TYPE_NOEXPORT(TypeMetaTestFoo);
14CAFFE_KNOWN_TYPE_NOEXPORT(TypeMetaTestBar);
15
16namespace {
17
18TEST(TypeMetaTest, TypeMetaStatic) {
19 EXPECT_EQ(TypeMeta::ItemSize<int>(), sizeof(int));
20 EXPECT_EQ(TypeMeta::ItemSize<float>(), sizeof(float));
21 EXPECT_EQ(TypeMeta::ItemSize<TypeMetaTestFoo>(), sizeof(TypeMetaTestFoo));
22 EXPECT_EQ(TypeMeta::ItemSize<TypeMetaTestBar>(), sizeof(TypeMetaTestBar));
23 EXPECT_NE(TypeMeta::Id<int>(), TypeMeta::Id<float>());
24 EXPECT_NE(TypeMeta::Id<int>(), TypeMeta::Id<TypeMetaTestFoo>());
25 EXPECT_NE(TypeMeta::Id<TypeMetaTestFoo>(), TypeMeta::Id<TypeMetaTestBar>());
26 EXPECT_EQ(TypeMeta::Id<int>(), TypeMeta::Id<int>());
27 EXPECT_EQ(TypeMeta::Id<TypeMetaTestFoo>(), TypeMeta::Id<TypeMetaTestFoo>());
28}
29
30TEST(TypeMetaTest, Names) {
31 TypeMeta null_meta;
32 EXPECT_EQ("nullptr (uninitialized)", null_meta.name());
33 TypeMeta int_meta = TypeMeta::Make<int>();
34 EXPECT_EQ("int", int_meta.name());
35 TypeMeta string_meta = TypeMeta::Make<string>();
36 EXPECT_TRUE(c10::string_view::npos != string_meta.name().find("string"));
37}
38
39TEST(TypeMetaTest, TypeMeta) {
40 TypeMeta int_meta = TypeMeta::Make<int>();
41 TypeMeta float_meta = TypeMeta::Make<float>();
42 TypeMeta foo_meta = TypeMeta::Make<TypeMetaTestFoo>();
43 TypeMeta bar_meta = TypeMeta::Make<TypeMetaTestBar>();
44
45 TypeMeta another_int_meta = TypeMeta::Make<int>();
46 TypeMeta another_foo_meta = TypeMeta::Make<TypeMetaTestFoo>();
47
48 EXPECT_EQ(int_meta, another_int_meta);
49 EXPECT_EQ(foo_meta, another_foo_meta);
50 EXPECT_NE(int_meta, float_meta);
51 EXPECT_NE(int_meta, foo_meta);
52 EXPECT_NE(foo_meta, bar_meta);
53 EXPECT_TRUE(int_meta.Match<int>());
54 EXPECT_TRUE(foo_meta.Match<TypeMetaTestFoo>());
55 EXPECT_FALSE(int_meta.Match<float>());
56 EXPECT_FALSE(int_meta.Match<TypeMetaTestFoo>());
57 EXPECT_FALSE(foo_meta.Match<int>());
58 EXPECT_FALSE(foo_meta.Match<TypeMetaTestBar>());
59 EXPECT_EQ(int_meta.id(), TypeMeta::Id<int>());
60 EXPECT_EQ(float_meta.id(), TypeMeta::Id<float>());
61 EXPECT_EQ(foo_meta.id(), TypeMeta::Id<TypeMetaTestFoo>());
62 EXPECT_EQ(bar_meta.id(), TypeMeta::Id<TypeMetaTestBar>());
63 EXPECT_EQ(int_meta.itemsize(), TypeMeta::ItemSize<int>());
64 EXPECT_EQ(float_meta.itemsize(), TypeMeta::ItemSize<float>());
65 EXPECT_EQ(foo_meta.itemsize(), TypeMeta::ItemSize<TypeMetaTestFoo>());
66 EXPECT_EQ(bar_meta.itemsize(), TypeMeta::ItemSize<TypeMetaTestBar>());
67 EXPECT_EQ(int_meta.name(), "int");
68 EXPECT_EQ(float_meta.name(), "float");
69 EXPECT_NE(foo_meta.name().find("TypeMetaTestFoo"), c10::string_view::npos);
70 EXPECT_NE(bar_meta.name().find("TypeMetaTestBar"), c10::string_view::npos);
71}
72
73class ClassAllowAssignment {
74 public:
75 ClassAllowAssignment() : x(42) {}
76 ClassAllowAssignment(const ClassAllowAssignment& src) = default;
77 ClassAllowAssignment& operator=(const ClassAllowAssignment& src) = default;
78 int x;
79};
80
81class ClassNoAssignment {
82 public:
83 ClassNoAssignment() : x(42) {}
84 ClassNoAssignment(const ClassNoAssignment& src) = delete;
85 ClassNoAssignment& operator=(const ClassNoAssignment& src) = delete;
86 int x;
87};
88} // namespace
89
90CAFFE_KNOWN_TYPE_NOEXPORT(ClassAllowAssignment);
91CAFFE_KNOWN_TYPE_NOEXPORT(ClassNoAssignment);
92
93namespace {
94
95TEST(TypeMetaTest, CtorDtorAndCopy) {
96 TypeMeta fundamental_meta = TypeMeta::Make<int>();
97 EXPECT_EQ(fundamental_meta.placementNew(), nullptr);
98 EXPECT_EQ(fundamental_meta.placementDelete(), nullptr);
99 EXPECT_EQ(fundamental_meta.copy(), nullptr);
100
101 TypeMeta meta_a = TypeMeta::Make<ClassAllowAssignment>();
102 EXPECT_TRUE(meta_a.placementNew() != nullptr);
103 EXPECT_TRUE(meta_a.placementDelete() != nullptr);
104 EXPECT_TRUE(meta_a.copy() != nullptr);
105 ClassAllowAssignment src;
106 src.x = 10;
107 ClassAllowAssignment dst;
108 EXPECT_EQ(dst.x, 42);
109 meta_a.copy()(&src, &dst, 1);
110 EXPECT_EQ(dst.x, 10);
111
112 TypeMeta meta_b = TypeMeta::Make<ClassNoAssignment>();
113
114 EXPECT_TRUE(meta_b.placementNew() != nullptr);
115 EXPECT_TRUE(meta_b.placementDelete() != nullptr);
116#ifndef __clang__
117 // gtest seems to have some problem with function pointers and
118 // clang right now... Disabling it.
119 // TODO: figure out the real cause.
120 EXPECT_EQ(meta_b.copy(), &(detail::_CopyNotAllowed<ClassNoAssignment>));
121#endif
122}
123
124TEST(TypeMetaTest, Float16IsNotUint16) {
125 EXPECT_NE(TypeMeta::Id<uint16_t>(), TypeMeta::Id<at::Half>());
126}
127
128} // namespace
129} // namespace caffe2
130