#include #include #include #include #include #include "gtest/gtest.h" #include "libpmr/new.h" TEST(pmr_new, regular_sizeof) { ASSERT_EQ(pmr::regular_sizeof(), pmr::regular_head_size + 8); ASSERT_EQ(pmr::regular_sizeof(), pmr::regular_head_size + 8); ASSERT_EQ(pmr::regular_sizeof(), pmr::regular_head_size + 8); ASSERT_EQ(pmr::regular_sizeof(), pmr::regular_head_size + 8); ASSERT_EQ((pmr::regular_sizeof>()), ::LIBIMP::round_up(pmr::regular_head_size + 10 , 8)); ASSERT_EQ((pmr::regular_sizeof>()), ::LIBIMP::round_up(pmr::regular_head_size + 100 , 8)); ASSERT_EQ((pmr::regular_sizeof>()), ::LIBIMP::round_up(pmr::regular_head_size + 1000 , 128)); ASSERT_EQ((pmr::regular_sizeof>()), ::LIBIMP::round_up(pmr::regular_head_size + 10000, 8192)); ASSERT_EQ((pmr::regular_sizeof>()), (std::numeric_limits::max)()); } TEST(pmr_new, new$) { auto p = pmr::new$(); ASSERT_NE(p, nullptr); *p = -1; ASSERT_EQ(*p, -1); pmr::delete$(p); } TEST(pmr_new, new$value) { auto p = pmr::new$((std::numeric_limits::max)()); ASSERT_NE(p, nullptr); ASSERT_EQ(*p, (std::numeric_limits::max)()); pmr::delete$(p); } namespace { template void test_new$array() { std::array pts; using T = std::array; for (int i = 0; i < (int)pts.size(); ++i) { auto p = pmr::new$(); pts[i] = p; std::memset(p, i, sizeof(T)); } for (int i = 0; i < (int)pts.size(); ++i) { T tmp; std::memset(&tmp, i, sizeof(T)); ASSERT_EQ(std::memcmp(pts[i], &tmp, sizeof(T)), 0); pmr::delete$(static_cast(pts[i])); } } } // namespace TEST(pmr_new, new$array) { test_new$array<1000, 10>(); test_new$array<1000, 100>(); test_new$array<1000, 1000>(); test_new$array<1000, 10000>(); test_new$array<1000, 100000>(); // test_new$array<1000, 1000000>(); } namespace { int construct_count__ = 0; class Base { public: virtual ~Base() = default; virtual int get() const = 0; }; class Derived : public Base { public: Derived(int value) : value_(value) { construct_count__ = value_; } ~Derived() override { construct_count__ = 0; } int get() const override { return value_; } private: int value_; }; class Derived64K : public Derived { public: using Derived::Derived; private: std::array padding_; }; } // namespace TEST(pmr_new, delete$poly) { Base *p = pmr::new$(-1); ASSERT_NE(p, nullptr); ASSERT_EQ(p->get(), -1); ASSERT_EQ(construct_count__, -1); pmr::delete$(p); ASSERT_EQ(construct_count__, 0); ASSERT_EQ(p, pmr::new$((std::numeric_limits::max)())); ASSERT_EQ(p->get(), (std::numeric_limits::max)()); ASSERT_EQ(construct_count__, (std::numeric_limits::max)()); pmr::delete$(p); ASSERT_EQ(construct_count__, 0); } TEST(pmr_new, delete$poly64k) { Base *p = pmr::new$(-1); ASSERT_NE(p, nullptr); ASSERT_EQ(p->get(), -1); ASSERT_EQ(construct_count__, -1); pmr::delete$(p); ASSERT_EQ(construct_count__, 0); Base *q = pmr::new$((std::numeric_limits::max)()); ASSERT_EQ(q->get(), (std::numeric_limits::max)()); ASSERT_EQ(construct_count__, (std::numeric_limits::max)()); pmr::delete$(q); ASSERT_EQ(construct_count__, 0); } TEST(pmr_new, delete$null) { Base *p = nullptr; pmr::delete$(p); SUCCEED(); } TEST(pmr_new, multi_thread) { std::array threads; for (auto &t : threads) { t = std::thread([] { for (int i = 0; i < 10000; ++i) { auto p = pmr::new$(); *p = i; pmr::delete$(p); } std::array pts; for (int i = 0; i < 10000; ++i) { auto p = pmr::new$>(); pts[i] = p; std::memset(p, i, sizeof(std::array)); } for (int i = 0; i < 10000; ++i) { std::array tmp; std::memset(&tmp, i, sizeof(std::array)); ASSERT_EQ(std::memcmp(pts[i], &tmp, sizeof(std::array)), 0); pmr::delete$(static_cast *>(pts[i])); } }); } for (auto &t : threads) { t.join(); } SUCCEED(); }