diff --git a/src/core/include/openvino/core/type.hpp b/src/core/include/openvino/core/type.hpp index 4877b9ce02b251..812208855fa7f3 100644 --- a/src/core/include/openvino/core/type.hpp +++ b/src/core/include/openvino/core/type.hpp @@ -77,6 +77,10 @@ struct OPENVINO_API DiscreteTypeInfo { OPENVINO_API std::ostream& operator<<(std::ostream& s, const DiscreteTypeInfo& info); +#if defined(__ANDROID__) || defined(ANDROID) +# define OPENVINO_DYNAMIC_CAST +#endif + /// \brief Tests if value is a pointer/shared_ptr that can be statically cast to a /// Type*/shared_ptr template @@ -93,7 +97,11 @@ template typename std::enable_if(std::declval())), Type*>::value, Type*>::type as_type(Value value) { +#ifdef OPENVINO_DYNAMIC_CAST return ov::is_type(value) ? static_cast(value) : nullptr; +#else + return dynamic_cast(value); +#endif } namespace util { @@ -114,7 +122,11 @@ struct AsTypePtr> { /// Type, nullptr otherwise template auto as_type_ptr(const U& value) -> decltype(::ov::util::AsTypePtr::template call(value)) { +#ifdef OPENVINO_DYNAMIC_CAST return ::ov::util::AsTypePtr::template call(value); +#else + return std::dynamic_pointer_cast(value); +#endif } } // namespace ov diff --git a/src/core/tests/rtti.cpp b/src/core/tests/rtti.cpp index 1fd8787ee60f38..9cfa225f4a3010 100644 --- a/src/core/tests/rtti.cpp +++ b/src/core/tests/rtti.cpp @@ -5,10 +5,12 @@ #include "common_test_utils/test_tools.hpp" #include "gtest/gtest.h" #include "openvino/op/op.hpp" +#include "openvino/pass/matcher_pass.hpp" -using namespace ov; using namespace std; +namespace ov::test { + class OpType : public ov::op::Op { public: OPENVINO_OP("OpType"); @@ -88,3 +90,55 @@ TEST(rtti, op_with_type_version_parent_old) { ASSERT_NE(type_info.parent, nullptr); ASSERT_EQ(*type_info.parent, OpType::get_type_info_static()); } + +#if !defined(__ANDROID__) && !defined(ANDROID) + +class IncompleteRtti : public pass::MatcherPass { +public: + OPENVINO_RTTI("IncompleteRtti", "rtti_test"); +}; + +class DerivedIncompleteRtti : public IncompleteRtti { +public: + OPENVINO_RTTI("DerivedIncompleteRtti", "rtti_test", IncompleteRtti); +}; + +// Assert backward compatibility of RTTI definition without parent but casted with as_type or as_type_ptr pointer work. +TEST(rtti, assert_casting_without_parent) { + { + IncompleteRtti incomplete; + DerivedIncompleteRtti derived; + + auto pass_A = as_type(&incomplete); + auto pass_B = as_type(&derived); + auto pass_C = as_type(&derived); + + EXPECT_NE(nullptr, pass_A); + EXPECT_NE(nullptr, pass_B); + EXPECT_NE(nullptr, pass_C); + + EXPECT_NE(nullptr, as_type(pass_A)); + EXPECT_NE(nullptr, as_type(pass_B)); + EXPECT_NE(nullptr, as_type(pass_B)); + EXPECT_NE(nullptr, as_type(pass_C)); + } + { + auto incomplete = std::make_shared(); + auto derived = std::make_shared(); + + auto pass_A = as_type_ptr(incomplete); + auto pass_B = as_type_ptr(derived); + auto pass_C = as_type_ptr(derived); + + EXPECT_NE(nullptr, pass_A); + EXPECT_NE(nullptr, pass_B); + EXPECT_NE(nullptr, pass_C); + + EXPECT_NE(nullptr, as_type_ptr(pass_A)); + EXPECT_NE(nullptr, as_type_ptr(pass_B)); + EXPECT_NE(nullptr, as_type_ptr(pass_B)); + EXPECT_NE(nullptr, as_type_ptr(pass_C)); + } +} +#endif // ANDROID +} // namespace ov::test