Skip to content

Commit

Permalink
use deduction guides when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
ydaveluy committed Sep 22, 2023
1 parent 380db23 commit f322561
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 92 deletions.
14 changes: 10 additions & 4 deletions include/Xsmp/Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <iterator>
#include <stdexcept>
#include <string>
#include <type_traits>

namespace Xsmp {

Expand All @@ -29,13 +30,13 @@ struct simpleArray {
};
} //namespace Annotation

template <typename Tp, std::size_t Nm>
template<typename Tp, std::size_t Nm>
struct _array_traits {
using type = Tp[Nm];
using is_nothrow_swappable = std::is_nothrow_swappable<Tp>;
};

template <typename Tp>
template<typename Tp>
struct _array_traits<Tp, 0> {
// Empty type used instead of Tp[0] for Xsmp::Array<Tp, 0>.
struct type {
Expand Down Expand Up @@ -86,8 +87,8 @@ struct Array {
std::fill_n(begin(), size(), _u);
}

constexpr void swap(Array &_other)
noexcept(_array_traits<Tp, Nm>::is_nothrow_swappable::value) {
constexpr void swap(Array &_other)
noexcept (_array_traits<Tp, Nm>::is_nothrow_swappable::value) {
std::swap_ranges(begin(), end(), _other.begin());
}

Expand Down Expand Up @@ -207,6 +208,11 @@ struct Array {
}
};

//deduction guide
template<class Tp, class ... Args, class = std::enable_if_t<
(std::is_same_v<Tp, Args> && ...), void> >
Array(Tp, Args...) -> Array<Tp, 1 + sizeof...(Args)>;

// Array comparisons.
template<typename Tp, std::size_t Nm, typename ... options>
[[nodiscard]] constexpr bool operator==(const Array<Tp, Nm, options...> &_one,
Expand Down
7 changes: 0 additions & 7 deletions include/Xsmp/EntryPoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@ class EntryPointPublisher;

class EntryPoint final: public Object, public ::Smp::IEntryPoint {
public:

template<typename ObjectType>
EntryPoint(::Smp::String8 name, ::Smp::String8 description,
ObjectType *parent, void (ObjectType::*callback)(void)) :
EntryPoint(name, description, parent, std::bind(callback, parent)) {
}

EntryPoint(::Smp::String8 name, ::Smp::String8 description,
::Xsmp::EntryPointPublisher *parent,
std::function<void()> &&callback);
Expand Down
59 changes: 19 additions & 40 deletions include/Xsmp/EventSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,34 +39,20 @@ class AbstractEventSink: public Object, public ::Smp::IEventSink {

template<typename T = void>
class EventSink final: public detail::AbstractEventSink {
using callbackType = std::function<void(::Smp::IObject *sender, T value)>;
public:

template<typename ObjectType>
EventSink(::Smp::String8 name, ::Smp::String8 description,
ObjectType *parent,
void (ObjectType::*callback)(::Smp::IObject*, T),
::Smp::PrimitiveTypeKind eventArgType) :
EventSink(name, description, parent,
std::bind(callback, parent, std::placeholders::_1,
std::placeholders::_2), eventArgType) {
}

template<typename Callable>
EventSink(::Smp::String8 name, ::Smp::String8 description,
::Smp::IObject *parent, Callable &&callback,
::Smp::IObject *parent, callbackType &&callback,
::Smp::PrimitiveTypeKind eventArgType) :
AbstractEventSink(name, description, parent), _callback(
std::forward<Callable>(callback)), _eventArgType(
eventArgType) {
std::move(callback)), _eventArgType(eventArgType) {
}

template<typename Callable>
EventSink(::Smp::String8 name, ::Smp::String8 description,
::Xsmp::EventConsumer *parent, Callable &&callback,
::Xsmp::EventConsumer *parent, callbackType &&callback,
::Smp::PrimitiveTypeKind eventArgType) :
AbstractEventSink(name, description, parent), _callback(
std::forward<Callable>(callback)), _eventArgType(
eventArgType) {
std::move(callback)), _eventArgType(eventArgType) {
}

::Smp::PrimitiveTypeKind GetEventArgType() const override {
Expand All @@ -77,43 +63,36 @@ class EventSink final: public detail::AbstractEventSink {
}

private:
std::function<void(::Smp::IObject *sender, T value)> _callback;
callbackType _callback;
::Smp::PrimitiveTypeKind _eventArgType;
};

/// specialization for void event (implemented in .cpp)
template<>
class EventSink<void> final: public detail::AbstractEventSink {
using callbackType = std::function<void(::Smp::IObject *sender)>;
public:

template<typename ObjectType>
EventSink(::Smp::String8 name, ::Smp::String8 description,
ObjectType *parent, void (ObjectType::*callback)(::Smp::IObject*)) :
EventSink(name, description, parent,
std::bind(callback, parent, std::placeholders::_1)) {
}

template<typename Callable>
EventSink(::Smp::String8 name, ::Smp::String8 description,
::Smp::IObject *parent, Callable &&callback) :
AbstractEventSink(name, description, parent), _callback(
std::forward<Callable>(callback)) {
}

template<typename Callable>
::Smp::IObject *parent, callbackType &&callback);
EventSink(::Smp::String8 name, ::Smp::String8 description,
::Xsmp::EventConsumer *parent, Callable &&callback) :
AbstractEventSink(name, description, parent), _callback(
std::forward<Callable>(callback)) {
}
::Xsmp::EventConsumer *parent, callbackType &&callback);
~EventSink() noexcept override = default;
::Smp::PrimitiveTypeKind GetEventArgType() const override;
void Notify(::Smp::IObject *sender, ::Smp::AnySimple value) override;

private:
std::function<void(::Smp::IObject *sender)> _callback;
callbackType _callback;
};

// deduction guide
EventSink(::Smp::String8 name, ::Smp::String8 description,
::Smp::IObject *parent,
std::function<void(::Smp::IObject *sender)> &&callback) ->
EventSink<void>;
EventSink(::Smp::String8 name, ::Smp::String8 description,
::Xsmp::EventConsumer *parent,
std::function<void(::Smp::IObject *sender)> &&callback) ->
EventSink<void>;
} // namespace Xsmp

#endif // XSMP_EVENTSINK_H_
18 changes: 11 additions & 7 deletions include/Xsmp/EventSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,11 @@ class AbstractEventSource: public Object, public ::Smp::IEventSource {
void Subscribe(::Smp::IEventSink *eventSink) final;
void Unsubscribe(::Smp::IEventSink *eventSink) final;
protected:
inline const std::set<::Smp::IEventSink*>& GetEventSinks() const noexcept {
return _event_sinks;
}
inline ::Smp::PrimitiveTypeKind GetEventArgType() const noexcept {
return _eventArgType;
}

void Emit(::Smp::IObject *sender, const ::Smp::AnySimple &value) const;
private:
std::set<::Smp::IEventSink*> _event_sinks { };
::Smp::PrimitiveTypeKind _eventArgType;
Expand Down Expand Up @@ -81,10 +80,9 @@ class EventSource final: public ::Xsmp::detail::AbstractEventSource {
/// @param sender component that emits the event
/// @param value event value to send
void Emit(::Smp::IObject *sender, T value) const {
for (auto &sink : GetEventSinks()) {
sink->Notify(sender,
AnySimpleConverter<T>::convert(GetEventArgType(), value));
}
AbstractEventSource::Emit(sender,
AnySimpleConverter<T>::convert(GetEventArgType(), value));

}

/// Emit the event to all connected events sinks
Expand Down Expand Up @@ -136,6 +134,12 @@ class EventSource<void> final: public ::Xsmp::detail::AbstractEventSource {
void operator()() const;
};

// deduction guide
EventSource(::Smp::String8 name, ::Smp::String8 description,
::Smp::IObject *parent) -> EventSource<void>;
EventSource(::Smp::String8 name, ::Smp::String8 description,
::Xsmp::EventProvider *parent) -> EventSource<void>;

} // namespace Xsmp

#endif // XSMP_EVENTSOURCE_H_
6 changes: 3 additions & 3 deletions src-gen/Xsmp/Services/XsmpSchedulerGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ XsmpSchedulerGen::XsmpSchedulerGen(::Smp::String8 name,
::Xsmp::Service(name, description, parent, simulator),
// EntryPoint: HoldEvent
HoldEvent { new ::Xsmp::EntryPoint("HoldEvent", "", this,
&XsmpSchedulerGen::_HoldEvent) },
std::bind(&XsmpSchedulerGen::_HoldEvent, this)) },
// EntryPoint: EnterExecuting
EnterExecuting { new ::Xsmp::EntryPoint("EnterExecuting", "", this,
&XsmpSchedulerGen::_EnterExecuting) },
std::bind(&XsmpSchedulerGen::_EnterExecuting, this)) },
// EntryPoint: LeaveExecuting
LeaveExecuting { new ::Xsmp::EntryPoint("LeaveExecuting", "", this,
&XsmpSchedulerGen::_LeaveExecuting) } {
std::bind(&XsmpSchedulerGen::_LeaveExecuting, this)) } {
}

/// Virtual destructor that is called by inherited classes as well.
Expand Down
4 changes: 2 additions & 2 deletions src-gen/Xsmp/Services/XsmpTimeKeeperGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ XsmpTimeKeeperGen::XsmpTimeKeeperGen(::Smp::String8 name,
::Xsmp::Service(name, description, parent, simulator),
// EntryPoint: PreSimTimeChange
PreSimTimeChange { new ::Xsmp::EntryPoint("PreSimTimeChange", "", this,
&XsmpTimeKeeperGen::_PreSimTimeChange) },
std::bind(&XsmpTimeKeeperGen::_PreSimTimeChange, this)) },
// EntryPoint: PostSimTimeChange
PostSimTimeChange { new ::Xsmp::EntryPoint("PostSimTimeChange", "",
this, &XsmpTimeKeeperGen::_PostSimTimeChange) } {
this, std::bind(&XsmpTimeKeeperGen::_PostSimTimeChange, this)) } {
}

/// Virtual destructor that is called by inherited classes as well.
Expand Down
60 changes: 42 additions & 18 deletions src-gen/Xsmp/Tests/ModelWithEventsGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,70 +36,94 @@ ModelWithEventsGen::ModelWithEventsGen(::Smp::String8 name,
// Base class initialization
::Xsmp::Model(name, description, parent, simulator),
// Event Sink: void_esi
void_esi { new ::Xsmp::EventSink<>("void_esi", "", this,
&ModelWithEventsGen::_void_esi) },
void_esi { new ::Xsmp::EventSink("void_esi", "", this,
std::bind(&ModelWithEventsGen::_void_esi, this,
std::placeholders::_1)) },
// Event Sink: bool_esi
bool_esi { new ::Xsmp::EventSink<::Smp::Bool>("bool_esi", "", this,
&ModelWithEventsGen::_bool_esi,
std::bind(&ModelWithEventsGen::_bool_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Bool) },
// Event Sink: char8_esi
char8_esi { new ::Xsmp::EventSink<::Smp::Char8>("char8_esi", "", this,
&ModelWithEventsGen::_char8_esi,
std::bind(&ModelWithEventsGen::_char8_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Char8) },
// Event Sink: dateTime_esi
dateTime_esi { new ::Xsmp::EventSink<::Smp::DateTime>("dateTime_esi",
"", this, &ModelWithEventsGen::_dateTime_esi,
"", this,
std::bind(&ModelWithEventsGen::_dateTime_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_DateTime) },
// Event Sink: duration_esi
duration_esi { new ::Xsmp::EventSink<::Smp::Duration>("duration_esi",
"", this, &ModelWithEventsGen::_duration_esi,
"", this,
std::bind(&ModelWithEventsGen::_duration_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Duration) },
// Event Sink: float32_esi
float32_esi { new ::Xsmp::EventSink<::Smp::Float32>("float32_esi", "",
this, &ModelWithEventsGen::_float32_esi,
this,
std::bind(&ModelWithEventsGen::_float32_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Float32) },
// Event Sink: float64_esi
float64_esi { new ::Xsmp::EventSink<::Smp::Float64>("float64_esi", "",
this, &ModelWithEventsGen::_float64_esi,
this,
std::bind(&ModelWithEventsGen::_float64_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Float64) },
// Event Sink: int16_esi
int16_esi { new ::Xsmp::EventSink<::Smp::Int16>("int16_esi", "", this,
&ModelWithEventsGen::_int16_esi,
std::bind(&ModelWithEventsGen::_int16_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Int16) },
// Event Sink: int32_esi
int32_esi { new ::Xsmp::EventSink<::Smp::Int32>("int32_esi", "", this,
&ModelWithEventsGen::_int32_esi,
std::bind(&ModelWithEventsGen::_int32_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Int32) },
// Event Sink: int64_esi
int64_esi { new ::Xsmp::EventSink<::Smp::Int64>("int64_esi", "", this,
&ModelWithEventsGen::_int64_esi,
std::bind(&ModelWithEventsGen::_int64_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Int64) },
// Event Sink: int8_esi
int8_esi { new ::Xsmp::EventSink<::Smp::Int8>("int8_esi", "", this,
&ModelWithEventsGen::_int8_esi,
std::bind(&ModelWithEventsGen::_int8_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_Int8) },
// Event Sink: string8_esi
string8_esi { new ::Xsmp::EventSink<::Smp::String8>("string8_esi", "",
this, &ModelWithEventsGen::_string8_esi,
this,
std::bind(&ModelWithEventsGen::_string8_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_String8) },
// Event Sink: uint16_esi
uint16_esi { new ::Xsmp::EventSink<::Smp::UInt16>("uint16_esi", "",
this, &ModelWithEventsGen::_uint16_esi,
this,
std::bind(&ModelWithEventsGen::_uint16_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_UInt16) },
// Event Sink: uint32_esi
uint32_esi { new ::Xsmp::EventSink<::Smp::UInt32>("uint32_esi", "",
this, &ModelWithEventsGen::_uint32_esi,
this,
std::bind(&ModelWithEventsGen::_uint32_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_UInt32) },
// Event Sink: uint64_esi
uint64_esi { new ::Xsmp::EventSink<::Smp::UInt64>("uint64_esi", "",
this, &ModelWithEventsGen::_uint64_esi,
this,
std::bind(&ModelWithEventsGen::_uint64_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_UInt64) },
// Event Sink: uint8_esi
uint8_esi { new ::Xsmp::EventSink<::Smp::UInt8>("uint8_esi", "", this,
&ModelWithEventsGen::_uint8_esi,
std::bind(&ModelWithEventsGen::_uint8_esi, this,
std::placeholders::_1, std::placeholders::_2),
::Smp::PrimitiveTypeKind::PTK_UInt8) },
// Event Source: void_eso
void_eso { new ::Xsmp::EventSource<>("void_eso", "", this) },
void_eso { new ::Xsmp::EventSource("void_eso", "", this) },
// Event Source: bool_eso
bool_eso { new ::Xsmp::EventSource<::Smp::Bool>("bool_eso", "", this,
::Smp::PrimitiveTypeKind::PTK_Bool) },
Expand Down
7 changes: 4 additions & 3 deletions src-gen/Xsmp/Tests/ModelWithSimpleFieldsGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ ModelWithSimpleFieldsGen::ModelWithSimpleFieldsGen(::Smp::String8 name,
// Base class initialization
::Xsmp::Model(name, description, parent, simulator),
// Event Sink: esi
esi { new ::Xsmp::EventSink<>("esi", "", this,
&ModelWithSimpleFieldsGen::_esi) },
esi { new ::Xsmp::EventSink("esi", "", this,
std::bind(&ModelWithSimpleFieldsGen::_esi, this,
std::placeholders::_1)) },
// Event Source: eso
eso { new ::Xsmp::EventSource<>("eso", "", this) },
eso { new ::Xsmp::EventSource("eso", "", this) },
// boolean initialization
boolean { },
// char8 initialization
Expand Down
11 changes: 11 additions & 0 deletions src/Xsmp/EventSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ ::Smp::PrimitiveTypeKind EventSink<void>::GetEventArgType() const {
return ::Smp::PrimitiveTypeKind::PTK_None;
}

EventSink<void>::EventSink(::Smp::String8 name, ::Smp::String8 description,
::Smp::IObject *parent, callbackType &&callback) :
AbstractEventSink(name, description, parent), _callback(
std::move(callback)) {
}
EventSink<void>::EventSink(::Smp::String8 name, ::Smp::String8 description,
::Xsmp::EventConsumer *parent, callbackType &&callback) :
AbstractEventSink(name, description, parent), _callback(
std::move(callback)) {
}

void EventSink<void>::Notify(::Smp::IObject *sender, ::Smp::AnySimple value) {
if (value.GetType() != GetEventArgType())
::Xsmp::Exception::throwInvalidAnyType(nullptr, value.GetType(),
Expand Down
Loading

0 comments on commit f322561

Please sign in to comment.