Downcasting facility refactored so the user does not have to write the boilerplate code anymore

This commit is contained in:
Mateusz Pusz committed 2019-09-26 22:30:57 +02:00
1 parent ad69f338b8
commit 2e1ce83024
28 files changed
+348 -299

No files matched your search

+27 -6
View File
@@ -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