Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <type_traits> 7 : #include <typeinfo> 8 : #include <utility> 9 : 10 : #include "TypeTraits/FastPointerCast.hpp" 11 : #include "Utilities/ErrorHandling/Error.hpp" 12 : #include "Utilities/PrettyType.hpp" 13 : #include "Utilities/Requires.hpp" 14 : #include "Utilities/TMPL.hpp" 15 : 16 : /// \ingroup UtilitiesGroup 17 : /// \brief Call a functor with the derived type of a base class pointer. 18 : /// 19 : /// \details Calls functor with obj cast to type `T*` where T is the 20 : /// dynamic type of `*obj`. The decay type of `T` must be in the 21 : /// provided list of classes. 22 : /// 23 : /// Extra arguments can be passed by `const&` to the functor. 24 : /// 25 : /// \tparam Result the return type 26 : /// \tparam Classes the typelist of derived classes 27 : template <typename Result, typename Classes, typename Base, typename Callable, 28 : typename... Args> 29 1 : Result call_with_dynamic_type(Base* const obj, Callable&& f, Args&&... args) { 30 : if constexpr (tmpl::size<Classes>::value != 0) { 31 : using Derived = tmpl::front<Classes>; 32 : using DerivedPointer = tmpl::conditional_t<std::is_const<Base>::value, 33 : Derived const*, Derived*>; 34 : return typeid(*obj) == typeid(Derived) 35 : ? std::forward<Callable>(f)( 36 : tt::fast_pointer_cast<DerivedPointer>(obj), 37 : std::forward<Args>(args)...) 38 : : call_with_dynamic_type<Result, tmpl::pop_front<Classes>>( 39 : obj, std::forward<Callable>(f), 40 : std::forward<Args>(args)...); 41 : } else { 42 : ERROR("Class " << pretty_type::get_runtime_type_name(*obj) 43 : << " is not registered with " 44 : << pretty_type::get_name<std::remove_const_t<Base>>()); 45 : } 46 : }