static_assert( __cplusplus > 2020'99 ); #pragma once #include #include namespace Alepha::Hydrogen::Utility ::detail:: derived_pointer_cast_m { inline namespace exports { template< typename Target, typename Source > std::unique_ptr< Target > derived_pointer_cast( std::unique_ptr< Source > source ); } template< typename Target, typename Source > std::unique_ptr< Target > exports::derived_pointer_cast( std::unique_ptr< Source > source ) { if( Target *const conv= dynamic_cast< Target * >( source.get() ); not conv ) { // TODO: More precise Alepha exception here. throw std::bad_cast{}; } else { // It's safe to release here, because we're taking ownership below. source.release(); // We reuse the conversion pointer so we can avoid a double-trip thru the // RTTI pathway. return std::unique_ptr< Target >{ conv }; } } } namespace Alepha::Hydrogen::Utility::inline exports::inline derived_pointer_cast_m { using namespace detail::derived_pointer_cast_m::exports; }