From 1dc83108268d595f74e2b6f3c6dfc5f33a7ded7c Mon Sep 17 00:00:00 2001 From: Chris Glover Date: Fri, 15 Jul 2016 10:10:07 -0400 Subject: [PATCH] Optimization: Don't check all bases. --- include/boost/type_index/runtime_cast.hpp | 60 +++++++++-------------- test/runtime_cast_test.cpp | 2 + 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/include/boost/type_index/runtime_cast.hpp b/include/boost/type_index/runtime_cast.hpp index e8223be..e1e8ba5 100644 --- a/include/boost/type_index/runtime_cast.hpp +++ b/include/boost/type_index/runtime_cast.hpp @@ -27,64 +27,52 @@ namespace boost { namespace typeindex { namespace detail { -template +template struct find_type; -template -struct find_type { - void* operator()(Desired* p, type_index const& idx) const BOOST_NOEXCEPT { - if(idx == boost::typeindex::type_id()) - return p; +template +struct find_type { + template + void* operator()(T* p, type_index const& idx) const BOOST_NOEXCEPT { + if(idx == boost::typeindex::type_id()) + return nullptr; return nullptr; } }; -template +template struct find_type { template - Desired* check_results(T* t) const BOOST_NOEXCEPT { - if(t) - return static_cast(t); - return nullptr; + Current* check_current(T* p, type_index const& idx) const BOOST_NOEXCEPT{ + if(idx == boost::typeindex::type_id()) + return nullptr; + return nullptr; } - template - Desired* check_results(T* t, Rest... rest) const BOOST_NOEXCEPT { - if(t) - return static_cast(t); - return check_results(rest...); + template + void* check_bases(T* p, type_index const& idx) const BOOST_NOEXCEPT { + if(void* result = p->FirstBase::boost_type_index_find_instance_(idx)) + return result; + return check_bases(p, idx); } template void* operator()(T* p, type_index const& idx) const BOOST_NOEXCEPT { - if(auto result = check_results(p->BaseList::boost_type_index_find_instance_(idx)...)) { - return result; - } - else { - return find_type()(p, idx); - } + if(Current* current = check_current(p, idx)) + return p; + return check_bases(p, idx); } }; template -T* runtime_cast_impl(U* u, std::true_type) { - return u; -} - -template -T const* runtime_cast_impl(U const* u, std::true_type) { - return u; -} - -template -T* runtime_cast_impl(U* u, std::false_type) { +T* runtime_cast_impl(U* u) { return static_cast( u->boost_type_index_find_instance_(boost::typeindex::type_id()) ); } template -T const* runtime_cast_impl(U const* u, std::false_type) { +T const* runtime_cast_impl(U const* u) { return static_cast( const_cast(u)->boost_type_index_find_instance_(boost::typeindex::type_id()) ); @@ -106,12 +94,12 @@ T const* runtime_cast_impl(U const* u, std::false_type) { template T* runtime_cast(U* u) { - return detail::runtime_cast_impl(u, std::is_same()); + return detail::runtime_cast_impl(u); } template T const* runtime_cast(U const* u) { - return detail::runtime_cast_impl(u, std::is_same()); + return detail::runtime_cast_impl(u); } }} // namespace boost::typeindex diff --git a/test/runtime_cast_test.cpp b/test/runtime_cast_test.cpp index f304679..77aadb0 100644 --- a/test/runtime_cast_test.cpp +++ b/test/runtime_cast_test.cpp @@ -114,6 +114,8 @@ void virtual_base() int main() { no_base(); single_derived(); + multiple_base(); + virtual_base(); return boost::report_errors(); }