Downcasting facility refactored so the user does not have to write the boilerplate code anymore
This commit is contained in:
1 parent
ad69f338b8
commit
2e1ce83024
28 files changed
+348
-299
No files matched your search
@@ -30,6 +30,7 @@ namespace units {
|
||||
template<typename BaseType>
|
||||
struct downcast_base {
|
||||
using base_type = BaseType;
|
||||
friend auto downcast_guide(downcast_base);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -39,13 +40,33 @@ namespace units {
|
||||
} &&
|
||||
std::derived_from<T, downcast_base<typename T::base_type>>;
|
||||
|
||||
template<typename Target, Downcastable T>
|
||||
struct downcast_helper : T {
|
||||
friend auto downcast_guide(typename downcast_helper::downcast_base) { return Target(); }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
concept bool has_downcast = requires {
|
||||
downcast_guide(std::declval<downcast_base<T>>());
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr auto downcast_target_impl()
|
||||
{
|
||||
if constexpr(has_downcast<T>)
|
||||
return decltype(downcast_guide(std::declval<downcast_base<T>>()))();
|
||||
else
|
||||
return T();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<Downcastable T>
|
||||
using downcast_target = decltype(detail::downcast_target_impl<T>());
|
||||
|
||||
template<Downcastable T>
|
||||
using downcast_base_t = T::base_type;
|
||||
|
||||
template<Downcastable T>
|
||||
struct downcast_traits : std::type_identity<T> {};
|
||||
|
||||
template<Downcastable T>
|
||||
using downcast_traits_t = downcast_traits<T>::type;
|
||||
|
||||
} // namespace units
|
||||
Reference in new issue
Block a user