forked from Alepha/Alepha
42 lines
1.0 KiB
C++
42 lines
1.0 KiB
C++
static_assert( __cplusplus > 2020'99 );
|
|
|
|
#pragma once
|
|
|
|
#include <Alepha/Alepha.h>
|
|
|
|
#include <memory>
|
|
|
|
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;
|
|
}
|