From da6f897140e5f8d3c98af78cb1c9c920ef96e82f Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 24 Jul 2018 21:25:21 +0300 Subject: [core] Added mbgl::util::TypeID --- cmake/core-files.cmake | 1 + include/mbgl/util/typeid.hpp | 25 +++++++++++++++++++++++++ include/mbgl/util/unique_any.hpp | 22 ++++++++++++---------- test/util/unique_any.test.cpp | 40 +++++++++++++++++++++------------------- 4 files changed, 59 insertions(+), 29 deletions(-) create mode 100644 include/mbgl/util/typeid.hpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index d2244d14a8..7fe64df9bb 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -690,6 +690,7 @@ set(MBGL_CORE_FILES include/mbgl/util/traits.hpp include/mbgl/util/tuple.hpp include/mbgl/util/type_list.hpp + include/mbgl/util/typeid.hpp include/mbgl/util/unique_any.hpp include/mbgl/util/unitbezier.hpp include/mbgl/util/util.hpp diff --git a/include/mbgl/util/typeid.hpp b/include/mbgl/util/typeid.hpp new file mode 100644 index 0000000000..4161b99489 --- /dev/null +++ b/include/mbgl/util/typeid.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace mbgl { +namespace util { + +class TypeID { +public: + template + static uint32_t getID() { + static std::atomic count(increment()); + return count; + } + +private: + static uint32_t increment() { + static std::atomic count(0); + return count++; + } + +}; + +} // namespace util +} // namespace mbgl diff --git a/include/mbgl/util/unique_any.hpp b/include/mbgl/util/unique_any.hpp index c7dc8b38ea..0f99ba0d57 100644 --- a/include/mbgl/util/unique_any.hpp +++ b/include/mbgl/util/unique_any.hpp @@ -1,17 +1,19 @@ #pragma once -#include +#include + #include #include namespace mbgl { namespace util { -class bad_any_cast : public std::bad_cast { +class bad_any_cast : public std::exception { public: const char* what() const noexcept override { return "bad any_cast<>()"; } }; + /** * A variant of `std::any` for non-copyable types. * @@ -100,8 +102,8 @@ public: } } - const std::type_info& type() const { - return !has_value()? typeid(void) : vtable->type(); + uint32_t type() const { + return !has_value()? TypeID::getID() : vtable->type(); } bool has_value() const { @@ -129,7 +131,7 @@ private: virtual ~VTable() = default; virtual void move(Storage&& src, Storage& dest) = 0; virtual void destroy(Storage&) = 0; - virtual const std::type_info& type() = 0; + virtual uint32_t type() = 0; }; template @@ -143,8 +145,8 @@ private: delete reinterpret_cast(s.dynamic); } - const std::type_info& type() override { - return typeid(ValueType); + uint32_t type() override { + return TypeID::getID(); } }; @@ -159,8 +161,8 @@ private: reinterpret_cast(s.stack).~ValueType(); } - const std::type_info& type() override { - return typeid(ValueType); + uint32_t type() override { + return TypeID::getID(); } }; @@ -217,7 +219,7 @@ inline const ValueType* any_cast(const unique_any* any) template inline ValueType* any_cast(unique_any* any) { - if(any == nullptr || any->type() != typeid(ValueType)) + if(any == nullptr || any->type() != TypeID::getID()) return nullptr; else return any->cast(); diff --git a/test/util/unique_any.test.cpp b/test/util/unique_any.test.cpp index 9b622cd284..ffd9e87be6 100644 --- a/test/util/unique_any.test.cpp +++ b/test/util/unique_any.test.cpp @@ -1,6 +1,7 @@ #include #include +#include using namespace mbgl::util; @@ -31,59 +32,59 @@ bool IsStackAllocated (const unique_any& a, const void* obj1) { TEST(UniqueAny, Empty) { EXPECT_FALSE(unique_any().has_value()); - EXPECT_TRUE(unique_any().type() == typeid(void)); + EXPECT_TRUE(unique_any().type() == TypeID::getID()); EXPECT_THROW(any_cast(unique_any()), bad_any_cast); } TEST(UniqueAny, BasicTypes) { unique_any i = 3; EXPECT_TRUE(i.has_value()); - EXPECT_TRUE(i.type() == typeid(int)); + EXPECT_TRUE(i.type() == TypeID::getID()); EXPECT_TRUE(IsStackAllocated(i, any_cast(&i))); auto iValue = any_cast(i); EXPECT_TRUE(iValue == 3); EXPECT_TRUE(unique_any(4).has_value()); - EXPECT_TRUE(unique_any(4).type() == typeid(int)); + EXPECT_TRUE(unique_any(4).type() == TypeID::getID()); unique_any f = 6.2f; EXPECT_TRUE(f.has_value()); - EXPECT_TRUE(f.type() == typeid(float)); + EXPECT_TRUE(f.type() == TypeID::getID()); EXPECT_TRUE(IsStackAllocated(f, any_cast(&f))); const float fValue = any_cast(f); EXPECT_TRUE(fValue == 6.2f); EXPECT_TRUE(unique_any(1.0f).has_value()); - EXPECT_TRUE(unique_any(1.0f).type() == typeid(float)); + EXPECT_TRUE(unique_any(1.0f).type() == TypeID::getID()); unique_any c = 'z'; EXPECT_TRUE(c.has_value()); - EXPECT_TRUE(c.type() == typeid(char)); + EXPECT_TRUE(c.type() == TypeID::getID()); EXPECT_TRUE(IsStackAllocated(c, any_cast(&c))); EXPECT_THROW(any_cast(c), bad_any_cast); EXPECT_TRUE(unique_any('4').has_value()); - EXPECT_TRUE(unique_any('4').type() == typeid(char)); + EXPECT_TRUE(unique_any('4').type() == TypeID::getID()); } TEST(UniqueAny, BasicTypes_Move) { unique_any i = 3; EXPECT_TRUE(i.has_value()); - EXPECT_TRUE(i.type() == typeid(int)); + EXPECT_TRUE(i.type() == TypeID::getID()); unique_any f = 6.2f; EXPECT_TRUE(f.has_value()); - EXPECT_TRUE(f.type() == typeid(float)); + EXPECT_TRUE(f.type() == TypeID::getID()); f = std::move(i); EXPECT_FALSE(i.has_value()); - EXPECT_TRUE(i.type() == typeid(void)); + EXPECT_TRUE(i.type() == TypeID::getID()); EXPECT_TRUE(f.has_value()); - EXPECT_TRUE(f.type() == typeid(int)); + EXPECT_TRUE(f.type() == TypeID::getID()); } @@ -124,15 +125,15 @@ TEST(UniqueAny, LargeType) { TestType t1; unique_any u1 = unique_any(std::move(t1)); EXPECT_TRUE(u1.has_value()); - EXPECT_TRUE(u1.type() == typeid(TestType)); + EXPECT_TRUE(u1.type() == TypeID::getID()); EXPECT_FALSE(IsStackAllocated(u1, any_cast(&u1))); //TestType should be moved into owning unique_any EXPECT_EQ(any_cast(&u1)->i1, 1); auto u2(std::move(u1)); - EXPECT_TRUE(u2.type() == typeid(TestType)); - EXPECT_TRUE(u1.type() == typeid(void)); + EXPECT_TRUE(u2.type() == TypeID::getID()); + EXPECT_TRUE(u1.type() == TypeID::getID()); //TestType should not be moved when owning unique_any is moved; EXPECT_EQ(any_cast(&u2)->i1, 1); @@ -142,7 +143,7 @@ TEST(UniqueAny, LargeType) { // First out of the unique_any, and then in the return statement auto t2 = any_cast(std::move(u2)); EXPECT_EQ(t2.i1, 3); - EXPECT_TRUE(u2.type() == typeid(void)); + EXPECT_TRUE(u2.type() == TypeID::getID()); } TEST(UniqueAny, Pointer) { @@ -150,7 +151,8 @@ TEST(UniqueAny, Pointer) { auto u1 = unique_any(std::move(t1)); EXPECT_TRUE(u1.has_value()); - EXPECT_TRUE(u1.type() == typeid(TestType *)); + EXPECT_TRUE(u1.type() == TypeID::getID()); + EXPECT_FALSE(u1.type() == TypeID::getID()); EXPECT_TRUE(IsStackAllocated(u1, any_cast(&u1))); //Only the pointer should be moved @@ -161,10 +163,10 @@ TEST(UniqueAny, Pointer) { std::swap(u2, u1); EXPECT_TRUE(u1.has_value()); - EXPECT_TRUE(u1.type() == typeid(int)); + EXPECT_TRUE(u1.type() == TypeID::getID()); EXPECT_TRUE(u2.has_value()); - EXPECT_TRUE(u2.type() == typeid(TestType *)); + EXPECT_TRUE(u2.type() == TypeID::getID()); t2 = *any_cast(&u2); EXPECT_EQ(t2->i1, 0); @@ -178,7 +180,7 @@ TEST(UniqueAny, UniquePtr) { EXPECT_EQ(t1.get(), nullptr); EXPECT_TRUE(u1.has_value()); - EXPECT_TRUE(u1.type() == typeid(std::unique_ptr)); + EXPECT_TRUE(u1.type() == TypeID::getID>()); EXPECT_TRUE(IsStackAllocated(u1, any_cast>(&u1))); -- cgit v1.2.1