#include "tensorflow/core/lib/gtl/manual_constructor.h" #include #include "tensorflow/core/platform/logging.h" #include namespace tensorflow { namespace { static int constructor_count_ = 0; template struct TestN { TestN() { ++constructor_count_; } ~TestN() { --constructor_count_; } char a[kSize]; }; typedef TestN<1> Test1; typedef TestN<2> Test2; typedef TestN<3> Test3; typedef TestN<4> Test4; typedef TestN<5> Test5; typedef TestN<9> Test9; typedef TestN<15> Test15; } // namespace namespace { TEST(ManualConstructorTest, Sizeof) { CHECK_EQ(sizeof(ManualConstructor), sizeof(Test1)); CHECK_EQ(sizeof(ManualConstructor), sizeof(Test2)); CHECK_EQ(sizeof(ManualConstructor), sizeof(Test3)); CHECK_EQ(sizeof(ManualConstructor), sizeof(Test4)); CHECK_EQ(sizeof(ManualConstructor), sizeof(Test5)); CHECK_EQ(sizeof(ManualConstructor), sizeof(Test9)); CHECK_EQ(sizeof(ManualConstructor), sizeof(Test15)); CHECK_EQ(constructor_count_, 0); ManualConstructor mt[4]; CHECK_EQ(sizeof(mt), 4); CHECK_EQ(constructor_count_, 0); mt[0].Init(); CHECK_EQ(constructor_count_, 1); mt[0].Destroy(); } TEST(ManualConstructorTest, Alignment) { // We want to make sure that ManualConstructor aligns its memory properly // on a word barrier. Otherwise, it might be unexpectedly slow, since // memory access will be unaligned. struct { char a; ManualConstructor b; } test1; struct { char a; void* b; } control1; // TODO(bww): Make these tests more direct with C++11 alignment_of::value. EXPECT_EQ(reinterpret_cast(test1.b.get()) - &test1.a, reinterpret_cast(&control1.b) - &control1.a); EXPECT_EQ(reinterpret_cast(test1.b.get()) % sizeof(control1.b), 0); struct { char a; ManualConstructor b; } test2; struct { char a; long double b; } control2; EXPECT_EQ(reinterpret_cast(test2.b.get()) - &test2.a, reinterpret_cast(&control2.b) - &control2.a); #ifdef ARCH_K8 EXPECT_EQ(reinterpret_cast(test2.b.get()) % 16, 0); #endif #ifdef ARCH_PIII EXPECT_EQ(reinterpret_cast(test2.b.get()) % 4, 0); #endif } TEST(ManualConstructorTest, DefaultInitialize) { struct X { X() : x(123) {} int x; }; union { ManualConstructor x; ManualConstructor y; } u; *u.y = -1; u.x.Init(); // should default-initialize u.x EXPECT_EQ(123, u.x->x); } TEST(ManualConstructorTest, ZeroInitializePOD) { union { ManualConstructor x; ManualConstructor y; } u; *u.y = -1; u.x.Init(); // should not zero-initialize u.x EXPECT_EQ(-1, *u.y); } } // namespace } // namespace tensorflow