From bde38f86337d6f49b34b38016ab088d2f48ec371 Mon Sep 17 00:00:00 2001 From: Alexey Rusakov Date: Mon, 1 Aug 2022 18:09:47 +0200 Subject: concept EventClass Constrain types to derive from Event (or the chosen class), where applicable. --- lib/events/event.h | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'lib/events') diff --git a/lib/events/event.h b/lib/events/event.h index 9d7c61a9..d0b63085 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -64,7 +64,11 @@ struct QUOTIENT_API EventTypeRegistry { class Event; -template +// TODO: move over to std::derived_from once it's available everywhere +template +concept EventClass = std::is_base_of_v; + +template bool is(const Event& e); //! \brief The base class for event metatypes @@ -206,13 +210,13 @@ private: //! //! This should not be used to load events from JSON - use loadEvent() for that. //! \sa loadEvent -template +template inline event_ptr_tt makeEvent(ArgTs&&... args) { return std::make_unique(std::forward(args)...); } -template +template constexpr const auto& mostSpecificMetaType() { if constexpr (requires { EventT::MetaType; }) @@ -226,7 +230,7 @@ constexpr const auto& mostSpecificMetaType() //! Use this factory template to detect the type from the JSON object //! contents (the detected event type should derive from the template //! parameter type) and create an event object of that type. -template +template inline event_ptr_tt loadEvent(const QJsonObject& fullJson) { return mostSpecificMetaType().loadFrom( @@ -238,7 +242,7 @@ inline event_ptr_tt loadEvent(const QJsonObject& fullJson) //! Use this template to resolve the C++ type from the Matrix type string in //! \p matrixType and create an event of that type by passing all parameters //! to BaseEventT::basicJson(). -template +template inline event_ptr_tt loadEvent(const QString& matrixType, const auto&... otherBasicJsonParams) { @@ -246,7 +250,7 @@ inline event_ptr_tt loadEvent(const QString& matrixType, EventT::basicJson(matrixType, otherBasicJsonParams...), matrixType); } -template +template struct JsonConverter> : JsonObjectUnpacker> { // No dump() to avoid any ambiguity on whether a given export to JSON uses @@ -295,7 +299,7 @@ public: //! the returned value will be different. QString matrixType() const; - template + template bool is() const { return Quotient::is(*this); @@ -377,7 +381,7 @@ private: }; using EventPtr = event_ptr_tt; -template +template using EventsArray = std::vector>; using Events = EventsArray; @@ -400,8 +404,10 @@ using Events = EventsArray; //! your class will likely be clearer and more concise. //! \sa https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern //! \sa DEFINE_SIMPLE_EVENT -template +template class EventTemplate : public BaseEventT { + // Above: can't constrain EventT to be EventClass because it's incomplete + // by CRTP definition. public: static_assert( !std::is_same_v, @@ -522,7 +528,7 @@ public: // === is<>(), eventCast<>() and switchOnType<>() === -template +template inline bool is(const Event& e) { if constexpr (requires { EventT::MetaType; }) { @@ -544,7 +550,7 @@ inline bool is(const Event& e) //! can be either "dumb" (BaseEventT*) or "smart" (`event_ptr_tt<>`). This //! overload doesn't affect the event ownership - if the original pointer owns //! the event it must outlive the downcast pointer to keep it from dangling. -template +template inline auto eventCast(const BasePtrT& eptr) -> decltype(static_cast(&*eptr)) { @@ -567,7 +573,7 @@ inline auto eventCast(const BasePtrT& eptr) //! after calling this overload; if it is a temporary, this normally //! leads to the event getting deleted along with the end of //! the temporary's lifetime. -template +template inline auto eventCast(event_ptr_tt&& eptr) { return eptr && is>(*eptr) @@ -576,12 +582,15 @@ inline auto eventCast(event_ptr_tt&& eptr) } namespace _impl { - template - concept Invocable_With_Downcast = + template + concept Invocable_With_Downcast = requires + { + requires EventClass; std::is_base_of_v>>; + }; } -template +template inline auto switchOnType(const BaseT& event, TailT&& tail) { if constexpr (std::is_invocable_v) { @@ -596,7 +605,7 @@ inline auto switchOnType(const BaseT& event, TailT&& tail) } } -template +template inline auto switchOnType(const BaseT& event, FnT1&& fn1, FnTs&&... fns) { using event_type1 = fn_arg_t; @@ -605,7 +614,7 @@ inline auto switchOnType(const BaseT& event, FnT1&& fn1, FnTs&&... fns) return switchOnType(event, std::forward(fns)...); } -template +template [[deprecated("The new name for visit() is switchOnType()")]] // inline auto visit(const BaseT& event, FnTs&&... fns) { -- cgit v1.2.3