SlideShare a Scribd company logo
1 of 108
Download to read offline
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 1/108
Mateusz Pusz
April 12, 2019
E ective replacement of dynamic
polymorphism with
std::variant
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 2/108
Why?
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 3/108
• Time required to perform some action or to produce some result
• Measured in units of time like hours, minutes, seconds, nanoseconds or clock periods
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Why?
LATENCY
3
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 4/108
• Time required to perform some action or to produce some result
• Measured in units of time like hours, minutes, seconds, nanoseconds or clock periods
• In capital markets, the use of algorithmic trading to react to market events faster than the competition
to increase profitability of trades
• Many use cases where predictability of latency in message delivery is just as important, if not more
important than achieving a low average latency
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Why?
LATENCY
LOW LATENCY
3
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 5/108
• In Low Latency system we care a lot about
WCET (Worst Case Execution Time)
• In order to limit WCET we should limit the
usage of specific C++ language features
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
How NOT to develop software that have predictable
performance?
4
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 6/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 7/108
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 8/108
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
• Throwing exceptions on a likely code path
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 9/108
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
• Throwing exceptions on a likely code path
• Dynamic polymorphism
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 10/108
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
• Throwing exceptions on a likely code path
• Dynamic polymorphism
• Multiple inheritance
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 11/108
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
• Throwing exceptions on a likely code path
• Dynamic polymorphism
• Multiple inheritance
• RTTI
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 12/108
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
• Throwing exceptions on a likely code path
• Dynamic polymorphism
• Multiple inheritance
• RTTI
• Dynamic memory allocations
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
5
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 13/108
• Dynamic polymorphism
• Dynamic memory allocations
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Things to avoid on the fast path
• C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function)
• Throwing exceptions on a likely code path
• Multiple inheritance
• RTTI
6
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 14/108
How?
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 15/108
class base : noncopyable {
public:
virtual ~base() = default;
virtual void foo() = 0;
};
class x : public base {
public:
void foo() override;
};
class y : public base {
public:
void foo() override;
};
std::unique_ptr<base> b = std::make_unique<x>();
b->foo();
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
How?
DYNAMIC POLYMORPHISM
8
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 16/108
class base : noncopyable {
public:
virtual ~base() = default;
virtual void foo() = 0;
};
class x : public base {
public:
void foo() override;
};
class y : public base {
public:
void foo() override;
};
std::unique_ptr<base> b = std::make_unique<x>();
b->foo();
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
How?
DYNAMIC POLYMORPHISM
8
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 17/108
class base : noncopyable {
public:
virtual ~base() = default;
virtual void foo() = 0;
};
class x : public base {
public:
void foo() override;
};
class y : public base {
public:
void foo() override;
};
std::unique_ptr<base> b = std::make_unique<x>();
b->foo();
struct x { void foo(); };
struct y { void foo(); };
std::variant<x, y> b;
std::visit([](auto&& v){ v.foo(); }, b);
• Shorter
• Faster
• Value semantics
• Works on unrelated classes
• More flexible thanks to duck typing
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
How?
DYNAMIC POLYMORPHISM VARIANT
8
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 18/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
THE END
T H A N K Y O U !
9
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 19/108
Bonus slides
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 20/108
Abstract machine that can be in exactly one of a finite number of
states at any given time.
-- Wikipedia
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Finite State Machine
11
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 21/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Finite State Machine
12
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 22/108
• State changes to another in a response to
some external inputs called events
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Finite State Machine
12
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 23/108
• State changes to another in a response to
some external inputs called events
• The change from one state to another is
called a transition
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Finite State Machine
12
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 24/108
• State changes to another in a response to
some external inputs called events
• The change from one state to another is
called a transition
• A FSM is defined by
– a list of states
– its initial state
– the conditions for each transition
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Finite State Machine
12
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 25/108
Single dynamic dispatch
CASE #1
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 26/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Class diagram
14
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 27/108
template<typename Event>
class state : noncopyable {
public:
virtual ~state() = default;
virtual std::unique_ptr<state> on_event(Event) = 0;
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
15
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 28/108
template<typename Event>
class state : noncopyable {
public:
virtual ~state() = default;
virtual std::unique_ptr<state> on_event(Event) = 0;
};
template<typename Event>
class fsm {
std::unique_ptr<state<Event>> state_;
public:
explicit fsm(std::unique_ptr<state<Event>> state) : state_(std::move(state)) {}
void dispatch(Event e)
{
auto new_state = state_->on_event(e);
if(new_state)
state_ = std::move(new_state);
}
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
15
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 29/108
template<typename Event>
class state : noncopyable {
public:
virtual ~state() = default;
virtual std::unique_ptr<state> on_event(Event) = 0;
};
template<typename Event>
class fsm {
std::unique_ptr<state<Event>> state_;
public:
explicit fsm(std::unique_ptr<state<Event>> state) : state_(std::move(state)) {}
void dispatch(Event e)
{
auto new_state = state_->on_event(e);
if(new_state)
state_ = std::move(new_state);
}
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
16
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 30/108
class connection_fsm : public fsm<event> {
public:
connection_fsm():
fsm<event>(std::make_unique<state_idle>()) {}
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Connection FSM
17
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 31/108
class connection_fsm : public fsm<event> {
public:
connection_fsm():
fsm<event>(std::make_unique<state_idle>()) {}
};
using s = state<event>;
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Connection FSM
17
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 32/108
class connection_fsm : public fsm<event> {
public:
connection_fsm():
fsm<event>(std::make_unique<state_idle>()) {}
};
using s = state<event>;
class state_idle final : public s {
public:
std::unique_ptr<s> on_event(event e) override;
};
class state_connecting final : public s {
static constexpr int n_max = 3;
int n = 0;
public:
std::unique_ptr<s> on_event(event e) override;
};
class state_connected final : public s {
public:
std::unique_ptr<s> on_event(event e) override;
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Connection FSM
17
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 33/108
std::unique_ptr<s> state_idle::on_event(event e)
{
}
std::unique_ptr<s> state_connecting::on_event(event e)
{
}
std::unique_ptr<s> state_connected::on_event(event e)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
18
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 34/108
std::unique_ptr<s> state_idle::on_event(event e)
{
if(e == event::connect)
return std::make_unique<state_connecting>();
return nullptr;
}
std::unique_ptr<s> state_connecting::on_event(event e)
{
}
std::unique_ptr<s> state_connected::on_event(event e)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
18
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 35/108
std::unique_ptr<s> state_idle::on_event(event e)
{
if(e == event::connect)
return std::make_unique<state_connecting>();
return nullptr;
}
std::unique_ptr<s> state_connecting::on_event(event e)
{
switch(e) {
case event::connected:
return std::make_unique<state_connected>();
case event::timeout:
return ++n < n_max ?
nullptr : std::make_unique<state_idle>();
default:
return nullptr;
}
}
std::unique_ptr<s> state_connected::on_event(event e)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
18
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 36/108
std::unique_ptr<s> state_idle::on_event(event e)
{
if(e == event::connect)
return std::make_unique<state_connecting>();
return nullptr;
}
std::unique_ptr<s> state_connecting::on_event(event e)
{
switch(e) {
case event::connected:
return std::make_unique<state_connected>();
case event::timeout:
return ++n < n_max ?
nullptr : std::make_unique<state_idle>();
default:
return nullptr;
}
}
std::unique_ptr<s> state_connected::on_event(event e)
{
if(e == event::disconnect)
return std::make_unique<state_idle>();
return nullptr;
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
18
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 37/108
std::unique_ptr<s> state_idle::on_event(event e)
{
if(e == event::connect)
return std::make_unique<state_connecting>();
return nullptr;
}
std::unique_ptr<s> state_connecting::on_event(event e)
{
switch(e) {
case event::connected:
return std::make_unique<state_connected>();
case event::timeout:
return ++n < n_max ?
nullptr : std::make_unique<state_idle>();
default:
return nullptr;
}
}
std::unique_ptr<s> state_connected::on_event(event e)
{
if(e == event::disconnect)
return std::make_unique<state_idle>();
return nullptr;
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
The slow part
19
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 38/108
• Fold expressions come handy ;-)
template<typename Fsm, typename... Events>
void dispatch(Fsm& fsm, Events... events)
{
(fsm.dispatch(events), ...);
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Testing transitions
20
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 39/108
• Fold expressions come handy ;-)
template<typename Fsm, typename... Events>
void dispatch(Fsm& fsm, Events... events)
{
(fsm.dispatch(events), ...);
}
• Simple message flow
connection_fsm fsm;
dispatch(fsm, event::connect, event::timeout, event::connected, event::disconnect);
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Testing transitions
20
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 40/108
• Open to new alternatives
– new derived types may be added by clients at any point of time (long a er base class
implementation is finished)
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
21
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 41/108
• Open to new alternatives
– new derived types may be added by clients at any point of time (long a er base class
implementation is finished)
• Closed to new operations
– clients cannot add new operations to dynamic dispatch
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
21
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 42/108
• Open to new alternatives
– new derived types may be added by clients at any point of time (long a er base class
implementation is finished)
• Closed to new operations
– clients cannot add new operations to dynamic dispatch
• Multi-level
– many levels of inheritance possible
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
21
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 43/108
• Open to new alternatives
– new derived types may be added by clients at any point of time (long a er base class
implementation is finished)
• Closed to new operations
– clients cannot add new operations to dynamic dispatch
• Multi-level
– many levels of inheritance possible
• Object Oriented
– whole framework is based on objects
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Single dynamic dispatch
21
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 44/108
Double dynamic dispatch
CASE #2
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 45/108
class event : noncopyable {
public:
virtual ~event() = default;
};
class event_connect final : public event {
std::string_view address_;
public:
explicit event_connect(std::string_view address): address_(address) {}
std::string_view address() const { return address_; }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
What if we want our events to pass data?
23
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 46/108
class event : noncopyable {
public:
virtual ~event() = default;
};
class event_connect final : public event {
std::string_view address_;
public:
explicit event_connect(std::string_view address): address_(address) {}
std::string_view address() const { return address_; }
};
std::unique_ptr<state> state_idle::on_event(const event& e)
{
if(auto ptr = dynamic_cast<const event_connect*>(&e)) { /* ... */ }
else { /* ... */ }
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
What if we want our events to pass data?
23
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 47/108
class event : noncopyable {
public:
virtual ~event() = default;
};
class event_connect final : public event {
std::string_view address_;
public:
explicit event_connect(std::string_view address): address_(address) {}
std::string_view address() const { return address_; }
};
std::unique_ptr<state> state_idle::on_event(const event& e)
{
if(auto ptr = dynamic_cast<const event_connect*>(&e)) { /* ... */ }
else { /* ... */ }
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
What if we want our events to pass data?
A really bad idea :-(
23
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 48/108
Special form of multiple dispatch, and a mechanism that
dispatches a function call to di erent concrete functions
depending on the runtime types of two objects involved in the call
-- Wikipedia
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dispatch (aka Visitor Pattern)
24
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 49/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dispatch (aka Visitor Pattern)
25
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 50/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
template<typename State, typename Event>
class fsm {
std::unique_ptr<State> state_;
public:
explicit fsm(std::unique_ptr<State> state) : state_(std::move(state)) {}
void dispatch(const Event& e)
{
auto new_state = e.dispatch(*state_);
if(new_state)
state_ = std::move(new_state);
}
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dispatch (aka Visitor Pattern)
25
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 51/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
struct event_connect final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
// ...
};
struct event_connected final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
};
struct event_disconnect final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
};
struct event_timeout final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dispatch (aka Visitor Pattern)
26
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 52/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
class state : noncopyable {
public:
virtual ~state() = default;
virtual std::unique_ptr<state> on_event(const event_connect&) { return nullptr; }
virtual std::unique_ptr<state> on_event(const event_connected&) { return nullptr; }
virtual std::unique_ptr<state> on_event(const event_disconnect&) { return nullptr; }
virtual std::unique_ptr<state> on_event(const event_timeout&) { return nullptr; }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dispatch (aka Visitor Pattern)
27
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 53/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
class state : noncopyable {
public:
virtual ~state() = default;
virtual std::unique_ptr<state> on_event(const event_connect&) { return nullptr; }
virtual std::unique_ptr<state> on_event(const event_connected&) { return nullptr; }
virtual std::unique_ptr<state> on_event(const event_disconnect&) { return nullptr; }
virtual std::unique_ptr<state> on_event(const event_timeout&) { return nullptr; }
};
class state_idle final : public state {
public:
using state::on_event;
std::unique_ptr<state> on_event(const event_connect& e) override
{
return std::make_unique<state_connecting>(std::string(e.address()));
}
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dispatch (aka Visitor Pattern)
27
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 54/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Class diagram
28
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 55/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
struct event_connect final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
// ...
};
struct event_connected final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
};
struct event_disconnect final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
};
struct event_timeout final : public event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Curiously Recurring Template Pattern (CRTP)
29
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 56/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
template<typename Child>
struct event_crtp : event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*static_cast<const Child*>(this)); }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Curiously Recurring Template Pattern (CRTP)
30
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 57/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
template<typename Child>
struct event_crtp : event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*static_cast<const Child*>(this)); }
};
struct event_connect final : public event_crtp<event_connect> {
// ...
};
struct event_connected final : public event_crtp<event_connected> {};
struct event_disconnect final : public event_crtp<event_disconnect> {};
struct event_timeout final : public event_crtp<event_timeout> {};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Curiously Recurring Template Pattern (CRTP)
30
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 58/108
template<typename State>
struct event : private noncopyable {
virtual ~event() = default;
virtual std::unique_ptr<State> dispatch(State& s) const = 0;
};
template<typename Child>
struct event_crtp : event<state> {
std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*static_cast<const Child*>(this)); }
};
struct event_connect final : public event_crtp<event_connect> {
explicit event_connect(std::string_view address): address_(address) {}
std::string_view address() const { return address_; }
private:
std::string_view address_;
};
struct event_connected final : public event_crtp<event_connected> {};
struct event_disconnect final : public event_crtp<event_disconnect> {};
struct event_timeout final : public event_crtp<event_timeout> {};
• Hey look ma, now all fits on one slide ;-)
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Curiously Recurring Template Pattern (CRTP)
31
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 59/108
std::unique_ptr<state>
state_idle::on_event(const event_connect& e)
{
}
std::unique_ptr<state>
state_connecting::on_event(const event_connected&)
{
}
std::unique_ptr<state>
state_connecting::on_event(const event_timeout&)
{
}
std::unique_ptr<state>
state_connected::on_event(const event_disconnect&)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
32
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 60/108
std::unique_ptr<state>
state_idle::on_event(const event_connect& e)
{
return std::make_unique<state_connecting>(
std::string{e.address()});
}
std::unique_ptr<state>
state_connecting::on_event(const event_connected&)
{
}
std::unique_ptr<state>
state_connecting::on_event(const event_timeout&)
{
}
std::unique_ptr<state>
state_connected::on_event(const event_disconnect&)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
32
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 61/108
std::unique_ptr<state>
state_idle::on_event(const event_connect& e)
{
return std::make_unique<state_connecting>(
std::string{e.address()});
}
std::unique_ptr<state>
state_connecting::on_event(const event_connected&)
{
return std::make_unique<state_connected>();
}
std::unique_ptr<state>
state_connecting::on_event(const event_timeout&)
{
}
std::unique_ptr<state>
state_connected::on_event(const event_disconnect&)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
32
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 62/108
std::unique_ptr<state>
state_idle::on_event(const event_connect& e)
{
return std::make_unique<state_connecting>(
std::string{e.address()});
}
std::unique_ptr<state>
state_connecting::on_event(const event_connected&)
{
return std::make_unique<state_connected>();
}
std::unique_ptr<state>
state_connecting::on_event(const event_timeout&)
{
return ++n < n_max ?
nullptr : std::make_unique<state_idle>();
}
std::unique_ptr<state>
state_connected::on_event(const event_disconnect&)
{
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
32
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 63/108
std::unique_ptr<state>
state_idle::on_event(const event_connect& e)
{
return std::make_unique<state_connecting>(
std::string{e.address()});
}
std::unique_ptr<state>
state_connecting::on_event(const event_connected&)
{
return std::make_unique<state_connected>();
}
std::unique_ptr<state>
state_connecting::on_event(const event_timeout&)
{
return ++n < n_max ?
nullptr : std::make_unique<state_idle>();
}
std::unique_ptr<state>
state_connected::on_event(const event_disconnect&)
{
return std::make_unique<state_idle>();
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
32
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 64/108
std::unique_ptr<state>
state_idle::on_event(const event_connect& e)
{
return std::make_unique<state_connecting>(
std::string{e.address()});
}
std::unique_ptr<state>
state_connecting::on_event(const event_connected&)
{
return std::make_unique<state_connected>();
}
std::unique_ptr<state>
state_connecting::on_event(const event_timeout&)
{
return ++n < n_max ?
nullptr : std::make_unique<state_idle>();
}
std::unique_ptr<state>
state_connected::on_event(const event_disconnect&)
{
return std::make_unique<state_idle>();
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
The slow part
33
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 65/108
template<typename Fsm, typename... Events>
void dispatch(Fsm& fsm, const Events&... events)
{
(fsm.dispatch(*events), ...);
}
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Testing transitions
34
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 66/108
template<typename Fsm, typename... Events>
void dispatch(Fsm& fsm, const Events&... events)
{
(fsm.dispatch(*events), ...);
}
dispatch(fsm,
std::make_unique<event_connect>("train-it.eu"),
std::make_unique<event_timeout>(),
std::make_unique<event_connected>(),
std::make_unique<event_disconnect>());
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Testing transitions
34
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 67/108
template<typename Fsm, typename... Events>
void dispatch(Fsm& fsm, const Events&... events)
{
(fsm.dispatch(*events), ...);
}
dispatch(fsm,
std::make_unique<event_connect>("train-it.eu"),
std::make_unique<event_timeout>(),
std::make_unique<event_connected>(),
std::make_unique<event_disconnect>());
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
The slow part
35
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 68/108
• Open to new alternatives
• Closed to new alternatives
– one of class hierarchies fixed at design time and cannot be extended by clients
• Closed to new operations
– clients cannot add new operations to dynamic dispatch
• Multi-level
– many levels of inheritance possible
• Object Oriented
– whole framework is based on objects
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Double dynamic dispatch (aka Visitor Pattern)
36
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 69/108
Variant + external transitions
CASE #3
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 70/108
struct event_connect { std::string_view address; };
struct event_connected {};
struct event_disconnect {};
struct event_timeout {};
using event = std::variant<event_connect, event_connected, event_disconnect, event_timeout>;
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Events and states
EVENTS
38
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 71/108
struct event_connect { std::string_view address; };
struct event_connected {};
struct event_disconnect {};
struct event_timeout {};
using event = std::variant<event_connect, event_connected, event_disconnect, event_timeout>;
struct state_idle {};
struct state_connecting {
static constexpr int n_max = 3;
int n = 0;
std::string address;
};
struct state_connected {};
using state = std::variant<state_idle, state_connecting, state_connected>;
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Events and states
EVENTS
STATES
38
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 72/108
struct transitions {
optional<state> operator()(state_idle&,
const event_connect& e)
{ }
optional<state> operator()(state_connecting&,
const event_connected&)
{ }
optional<state> operator()(state_connecting& s,
const event_timeout&)
{
}
optional<state> operator()(state_connected&,
const event_disconnect&)
{ }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
39
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 73/108
struct transitions {
optional<state> operator()(state_idle&,
const event_connect& e)
{ return state_connecting{std::string(e.address)}; }
optional<state> operator()(state_connecting&,
const event_connected&)
{ }
optional<state> operator()(state_connecting& s,
const event_timeout&)
{
}
optional<state> operator()(state_connected&,
const event_disconnect&)
{ }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
39
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 74/108
struct transitions {
optional<state> operator()(state_idle&,
const event_connect& e)
{ return state_connecting{std::string(e.address)}; }
optional<state> operator()(state_connecting&,
const event_connected&)
{ return state_connected{}; }
optional<state> operator()(state_connecting& s,
const event_timeout&)
{
}
optional<state> operator()(state_connected&,
const event_disconnect&)
{ }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
39
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 75/108
struct transitions {
optional<state> operator()(state_idle&,
const event_connect& e)
{ return state_connecting{std::string(e.address)}; }
optional<state> operator()(state_connecting&,
const event_connected&)
{ return state_connected{}; }
optional<state> operator()(state_connecting& s,
const event_timeout&)
{
return ++s.n < state_connecting::n_max ?
std::nullopt : optional<state>(state_idle{});
}
optional<state> operator()(state_connected&,
const event_disconnect&)
{ }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
39
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 76/108
struct transitions {
optional<state> operator()(state_idle&,
const event_connect& e)
{ return state_connecting{std::string(e.address)}; }
optional<state> operator()(state_connecting&,
const event_connected&)
{ return state_connected{}; }
optional<state> operator()(state_connecting& s,
const event_timeout&)
{
return ++s.n < state_connecting::n_max ?
std::nullopt : optional<state>(state_idle{});
}
optional<state> operator()(state_connected&,
const event_disconnect&)
{ return state_idle{}; }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
39
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 77/108
struct transitions {
optional<state> operator()(state_idle&,
const event_connect& e)
{ return state_connecting{std::string(e.address)}; }
optional<state> operator()(state_connecting&,
const event_connected&)
{ return state_connected{}; }
optional<state> operator()(state_connecting& s,
const event_timeout&)
{
return ++s.n < state_connecting::n_max ?
std::nullopt : optional<state>(state_idle{});
}
optional<state> operator()(state_connected&,
const event_disconnect&)
{ return state_idle{}; }
template<typename State, typename Event>
optional<state> operator()(State&,
const Event&) const
{ return std::nullopt; }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions
39
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 78/108
template<typename StateVariant, typename EventVariant, typename Transitions>
class fsm {
StateVariant state_;
public:
void dispatch(const EventVariant& event)
{
std::optional<StateVariant> new_state = std::visit(Transitions{}, state_, event);
if(new_state)
state_ = *std::move(new_state);
}
};
using connection_fsm = fsm<state, event, transitions>;
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
FSM engine
40
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 79/108
template<typename StateVariant, typename EventVariant, typename Transitions>
class fsm {
StateVariant state_;
public:
void dispatch(const EventVariant& event)
{
std::optional<StateVariant> new_state = std::visit(Transitions{}, state_, event);
if(new_state)
state_ = *std::move(new_state);
}
};
using connection_fsm = fsm<state, event, transitions>;
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
FSM engine
41
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 80/108
template<typename StateVariant, typename EventVariant, typename Transitions>
class fsm {
StateVariant state_;
public:
void dispatch(const EventVariant& event)
{
std::optional<StateVariant> new_state = std::visit(Transitions{}, state_, event);
if(new_state)
state_ = *std::move(new_state);
}
};
using connection_fsm = fsm<state, event, transitions>;
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
FSM engine
42
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 81/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Class diagram
43
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 82/108
template<typename Fsm, typename... Events>
void dispatch(Fsm& fsm, Events&&... events)
{
(fsm.dispatch(std::forward<Events>(events)), ...);
}
dispatch(fsm,
event_connect{"train-it.eu"},
event_timeout{},
event_connected{},
event_disconnect{});
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Testing transitions
44
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 83/108
Variant + transitions in FSM
CASE #4
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 84/108
template<typename Derived, typename StateVariant, typename EventVariant>
class fsm {
StateVariant state_;
public:
void dispatch(const EventVariant& event)
{
auto new_state = std::visit(
state_, event);
if(new_state)
state_ = *std::move(new_state);
}
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
FSM engine
46
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 85/108
template<typename Derived, typename StateVariant, typename EventVariant>
class fsm {
StateVariant state_;
public:
void dispatch(const EventVariant& event)
{
Derived& child = static_cast<Derived&>(*this);
auto new_state = std::visit(
[&](auto& s, const auto& e) -> std::optional<StateVariant>
{ return child.on_event(s, e); },
state_, event);
if(new_state)
state_ = *std::move(new_state);
}
};
• CRTP again ;-)
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
FSM engine
46
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 86/108
template<typename Derived, typename StateVariant>
class fsm {
StateVariant state_;
public:
template<typename Event>
void dispatch(Event&& event)
{
Derived& child = static_cast<Derived&>(*this);
auto new_state = std::visit(
[&](auto& s) -> std::optional<StateVariant>
{ return child.on_event(s, std::forward<Event>(event)); },
state_);
if(new_state)
state_ = *std::move(new_state);
}
};
• Visitation on a StateVariant only
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
FSM engine: dispatch() as an overload set
47
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 87/108
class connection_fsm
: public fsm<connection_fsm, state> {
public:
auto on_event(state_idle&,
const event_connect& e)
{ }
auto on_event(state_connecting&,
const event_connected&)
{ }
auto on_event(state_connecting& s,
const event_timeout&)
{
}
auto on_event(state_connected&,
const event_disconnect&)
{ }
template<typename State, typename Event>
auto on_event(State&, const Event&)
{ }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions de ned by the FSM itself
48
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 88/108
class connection_fsm
: public fsm<connection_fsm, state> {
public:
auto on_event(state_idle&,
const event_connect& e)
{ return state_connecting{std::string(e.address)}; }
auto on_event(state_connecting&,
const event_connected&)
{ return state_connected{}; }
auto on_event(state_connecting& s,
const event_timeout&)
{
return ++s.n < state_connecting::n_max ?
std::nullopt : std::optional<state>(state_idle{});
}
auto on_event(state_connected&,
const event_disconnect&)
{ return state_idle{}; }
template<typename State, typename Event>
auto on_event(State&, const Event&)
{ return std::nullopt; }
};
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Transitions de ned by the FSM itself
48
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 89/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
Class diagram
49
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 90/108
What about performance?
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 91/108
CLOSED(Start)
LISTEN/-
CLOSE/-
LISTEN
SYN
RECEIVED
SYN
SENT
CONNECT/ (Step 1 of the 3-way-handshake)SYN
SYN/SYN+ACK(Step 2 of the 3-way-handshake)
unusual event
client/receiver path
server/sender path
RST/-
SYN/SYN+ACK (simultaneous open)
SYN+ACK/ACK
(Step 3 of the 3-way-handshake)
Data exchange occurs
ESTABLISHED
FIN/ACK
ACK/-
CLOSE/-
SEND/SYN
CLOSE/FIN
CLOSE/FIN
CLOSING
TIME WAIT
CLOSED
FIN WAIT 1
FIN WAIT 2
CLOSE WAIT
LAST ACK
CLOSE/FIN
FIN/ACK
FIN+ACK/ACK
ACK/-
FIN/ACK
Timeout
(Go back to start)
Active CLOSE Passive CLOSE
ACK/-
ACK/-
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
TCP state diagram
51
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 92/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
TCP FSM Performance
52
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 93/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
TCP FSM Performance
52
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 94/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
TCP FSM Performance
52
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 95/108
Summary
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 96/108
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 97/108
• Open/Closed to new alternatives • Closed to new alternatives
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 98/108
• Open/Closed to new alternatives
• Closed to new operations
• Closed to new alternatives
• Open to new operations
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 99/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• Closed to new alternatives
• Open to new operations
• Single level
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 100/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 101/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Pointer semantics
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
• Value semantics
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 102/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Pointer semantics
• Design forced by the implementation details
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
• Value semantics
• Many design choices possible
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 103/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Pointer semantics
• Design forced by the implementation details
• Forces dynamic memory allocations
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
• Value semantics
• Many design choices possible
• No dynamic memory allocations
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 104/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Pointer semantics
• Design forced by the implementation details
• Forces dynamic memory allocations
• Strict interfaces
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
• Value semantics
• Many design choices possible
• No dynamic memory allocations
• Duck typing
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 105/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Pointer semantics
• Design forced by the implementation details
• Forces dynamic memory allocations
• Strict interfaces
• Complex
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
• Value semantics
• Many design choices possible
• No dynamic memory allocations
• Duck typing
• Simple
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 106/108
• Open/Closed to new alternatives
• Closed to new operations
• Multi-level
• OO
• Pointer semantics
• Design forced by the implementation details
• Forces dynamic memory allocations
• Strict interfaces
• Complex
• Slower
• Closed to new alternatives
• Open to new operations
• Single level
• Functional
• Value semantics
• Many design choices possible
• No dynamic memory allocations
• Duck typing
• Simple
• Faster
ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant
std::variant<Types...> vs inheritance
INHERITANCE VARIANT
54
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 107/108
12.04.2019 Effective replacement of dynamic polymorphism with std::variant
file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 108/108

More Related Content

Similar to Effective replacement of dynamic polymorphism with std::variant

APEX Interactive Grid API Essentials: The Stuff You Will Really Use
APEX Interactive Grid API Essentials:  The Stuff You Will Really UseAPEX Interactive Grid API Essentials:  The Stuff You Will Really Use
APEX Interactive Grid API Essentials: The Stuff You Will Really UseKaren Cannell
 
The future of thermoplastics in the automotive industry and process technolog...
The future of thermoplastics in the automotive industry and process technolog...The future of thermoplastics in the automotive industry and process technolog...
The future of thermoplastics in the automotive industry and process technolog...Torben Haagh
 
S100294 bcdr-seven-tiers-orlando-v1804a
S100294 bcdr-seven-tiers-orlando-v1804aS100294 bcdr-seven-tiers-orlando-v1804a
S100294 bcdr-seven-tiers-orlando-v1804aTony Pearson
 
Feedback Driven Development
Feedback Driven DevelopmentFeedback Driven Development
Feedback Driven DevelopmentHarini Gunabalan
 
Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...
Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...
Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...inside-BigData.com
 
A challenge for thread parallelism on OpenFOAM
A challenge for thread parallelism on OpenFOAMA challenge for thread parallelism on OpenFOAM
A challenge for thread parallelism on OpenFOAMFixstars Corporation
 
Backend Cloud Storage Access in Video Streaming
Backend Cloud Storage Access in Video StreamingBackend Cloud Storage Access in Video Streaming
Backend Cloud Storage Access in Video StreamingRufael Mekuria
 
Towards Automated Boundary Value Testing with Program Derivatives and Search
Towards Automated Boundary Value Testing with Program Derivatives and SearchTowards Automated Boundary Value Testing with Program Derivatives and Search
Towards Automated Boundary Value Testing with Program Derivatives and SearchFelix Dobslaw
 
Planning/Scheduling with CP Optimizer
Planning/Scheduling with CP OptimizerPlanning/Scheduling with CP Optimizer
Planning/Scheduling with CP OptimizerPhilippe Laborie
 
The application of carbon fibre reinforced plastic in the automotive industry
The application of carbon fibre reinforced plastic in the automotive industryThe application of carbon fibre reinforced plastic in the automotive industry
The application of carbon fibre reinforced plastic in the automotive industryTorben Haagh
 
S016386 business-continuity-melbourne-v1708c
S016386 business-continuity-melbourne-v1708cS016386 business-continuity-melbourne-v1708c
S016386 business-continuity-melbourne-v1708cTony Pearson
 
S014072 business-continuity-orlando-v1705e
S014072 business-continuity-orlando-v1705eS014072 business-continuity-orlando-v1705e
S014072 business-continuity-orlando-v1705eTony Pearson
 
IBM XL Compilers Performance Tuning 2016-11-18
IBM XL Compilers Performance Tuning 2016-11-18IBM XL Compilers Performance Tuning 2016-11-18
IBM XL Compilers Performance Tuning 2016-11-18Yaoqing Gao
 
Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...
Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...
Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...EUDAT
 
Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...
Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...
Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...Pooyan Jamshidi
 
Sustainable applied innovation pankaj shah and bipin patwardhan cwin18 india
Sustainable applied innovation pankaj shah and bipin patwardhan cwin18 indiaSustainable applied innovation pankaj shah and bipin patwardhan cwin18 india
Sustainable applied innovation pankaj shah and bipin patwardhan cwin18 indiaCapgemini
 
Collective Mind: a collaborative curation tool for program optimization
Collective Mind: a collaborative curation tool for program optimizationCollective Mind: a collaborative curation tool for program optimization
Collective Mind: a collaborative curation tool for program optimizationGrigori Fursin
 
CK: from ad hoc computer engineering to collaborative and reproducible data s...
CK: from ad hoc computer engineering to collaborative and reproducible data s...CK: from ad hoc computer engineering to collaborative and reproducible data s...
CK: from ad hoc computer engineering to collaborative and reproducible data s...Grigori Fursin
 
Simatic comunicaciones e
Simatic comunicaciones eSimatic comunicaciones e
Simatic comunicaciones eEver Cesar
 
Simatic comunicaciones e
Simatic comunicaciones eSimatic comunicaciones e
Simatic comunicaciones eEver Cesar
 

Similar to Effective replacement of dynamic polymorphism with std::variant (20)

APEX Interactive Grid API Essentials: The Stuff You Will Really Use
APEX Interactive Grid API Essentials:  The Stuff You Will Really UseAPEX Interactive Grid API Essentials:  The Stuff You Will Really Use
APEX Interactive Grid API Essentials: The Stuff You Will Really Use
 
The future of thermoplastics in the automotive industry and process technolog...
The future of thermoplastics in the automotive industry and process technolog...The future of thermoplastics in the automotive industry and process technolog...
The future of thermoplastics in the automotive industry and process technolog...
 
S100294 bcdr-seven-tiers-orlando-v1804a
S100294 bcdr-seven-tiers-orlando-v1804aS100294 bcdr-seven-tiers-orlando-v1804a
S100294 bcdr-seven-tiers-orlando-v1804a
 
Feedback Driven Development
Feedback Driven DevelopmentFeedback Driven Development
Feedback Driven Development
 
Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...
Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...
Characteristics of Remote Persistent Memory – Performance, Capacity, or Local...
 
A challenge for thread parallelism on OpenFOAM
A challenge for thread parallelism on OpenFOAMA challenge for thread parallelism on OpenFOAM
A challenge for thread parallelism on OpenFOAM
 
Backend Cloud Storage Access in Video Streaming
Backend Cloud Storage Access in Video StreamingBackend Cloud Storage Access in Video Streaming
Backend Cloud Storage Access in Video Streaming
 
Towards Automated Boundary Value Testing with Program Derivatives and Search
Towards Automated Boundary Value Testing with Program Derivatives and SearchTowards Automated Boundary Value Testing with Program Derivatives and Search
Towards Automated Boundary Value Testing with Program Derivatives and Search
 
Planning/Scheduling with CP Optimizer
Planning/Scheduling with CP OptimizerPlanning/Scheduling with CP Optimizer
Planning/Scheduling with CP Optimizer
 
The application of carbon fibre reinforced plastic in the automotive industry
The application of carbon fibre reinforced plastic in the automotive industryThe application of carbon fibre reinforced plastic in the automotive industry
The application of carbon fibre reinforced plastic in the automotive industry
 
S016386 business-continuity-melbourne-v1708c
S016386 business-continuity-melbourne-v1708cS016386 business-continuity-melbourne-v1708c
S016386 business-continuity-melbourne-v1708c
 
S014072 business-continuity-orlando-v1705e
S014072 business-continuity-orlando-v1705eS014072 business-continuity-orlando-v1705e
S014072 business-continuity-orlando-v1705e
 
IBM XL Compilers Performance Tuning 2016-11-18
IBM XL Compilers Performance Tuning 2016-11-18IBM XL Compilers Performance Tuning 2016-11-18
IBM XL Compilers Performance Tuning 2016-11-18
 
Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...
Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...
Introduction to HPC Programming Models - EUDAT Summer School (Stefano Markidi...
 
Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...
Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...
Machine Learning Meets Quantitative Planning: Enabling Self-Adaptation in Aut...
 
Sustainable applied innovation pankaj shah and bipin patwardhan cwin18 india
Sustainable applied innovation pankaj shah and bipin patwardhan cwin18 indiaSustainable applied innovation pankaj shah and bipin patwardhan cwin18 india
Sustainable applied innovation pankaj shah and bipin patwardhan cwin18 india
 
Collective Mind: a collaborative curation tool for program optimization
Collective Mind: a collaborative curation tool for program optimizationCollective Mind: a collaborative curation tool for program optimization
Collective Mind: a collaborative curation tool for program optimization
 
CK: from ad hoc computer engineering to collaborative and reproducible data s...
CK: from ad hoc computer engineering to collaborative and reproducible data s...CK: from ad hoc computer engineering to collaborative and reproducible data s...
CK: from ad hoc computer engineering to collaborative and reproducible data s...
 
Simatic comunicaciones e
Simatic comunicaciones eSimatic comunicaciones e
Simatic comunicaciones e
 
Simatic comunicaciones e
Simatic comunicaciones eSimatic comunicaciones e
Simatic comunicaciones e
 

More from Mateusz Pusz

Free Lunch is Over: Why is C++ so Important in the Modern World?
Free Lunch is Over: Why is C++ so Important in the Modern World?Free Lunch is Over: Why is C++ so Important in the Modern World?
Free Lunch is Over: Why is C++ so Important in the Modern World?Mateusz Pusz
 
A Physical Units Library for the Next C++
A Physical Units Library for the Next C++A Physical Units Library for the Next C++
A Physical Units Library for the Next C++Mateusz Pusz
 
Striving for ultimate Low Latency
Striving for ultimate Low LatencyStriving for ultimate Low Latency
Striving for ultimate Low LatencyMateusz Pusz
 
Rethinking the Way We do Templates in C++
Rethinking the Way We do Templates in C++Rethinking the Way We do Templates in C++
Rethinking the Way We do Templates in C++Mateusz Pusz
 
C++11 Was Only the Beginning
C++11 Was Only the BeginningC++11 Was Only the Beginning
C++11 Was Only the BeginningMateusz Pusz
 
C++ Concepts and Ranges - How to use them?
C++ Concepts and Ranges - How to use them?C++ Concepts and Ranges - How to use them?
C++ Concepts and Ranges - How to use them?Mateusz Pusz
 
Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?Mateusz Pusz
 
Pointless Pointers - How to make our interfaces efficient?
Pointless Pointers - How to make our interfaces efficient?Pointless Pointers - How to make our interfaces efficient?
Pointless Pointers - How to make our interfaces efficient?Mateusz Pusz
 
Striving for ultimate Low Latency
Striving for ultimate Low LatencyStriving for ultimate Low Latency
Striving for ultimate Low LatencyMateusz Pusz
 
Small Lie in Big O
Small Lie in Big OSmall Lie in Big O
Small Lie in Big OMateusz Pusz
 
std::shared_ptr<T> - (not so) Smart hammer for every pointy nail
std::shared_ptr<T> - (not so) Smart hammer for every pointy nailstd::shared_ptr<T> - (not so) Smart hammer for every pointy nail
std::shared_ptr<T> - (not so) Smart hammer for every pointy nailMateusz Pusz
 

More from Mateusz Pusz (12)

Free Lunch is Over: Why is C++ so Important in the Modern World?
Free Lunch is Over: Why is C++ so Important in the Modern World?Free Lunch is Over: Why is C++ so Important in the Modern World?
Free Lunch is Over: Why is C++ so Important in the Modern World?
 
A Physical Units Library for the Next C++
A Physical Units Library for the Next C++A Physical Units Library for the Next C++
A Physical Units Library for the Next C++
 
Striving for ultimate Low Latency
Striving for ultimate Low LatencyStriving for ultimate Low Latency
Striving for ultimate Low Latency
 
Rethinking the Way We do Templates in C++
Rethinking the Way We do Templates in C++Rethinking the Way We do Templates in C++
Rethinking the Way We do Templates in C++
 
C++11 Was Only the Beginning
C++11 Was Only the BeginningC++11 Was Only the Beginning
C++11 Was Only the Beginning
 
C++ Concepts and Ranges - How to use them?
C++ Concepts and Ranges - How to use them?C++ Concepts and Ranges - How to use them?
C++ Concepts and Ranges - How to use them?
 
Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?
 
Beyond C++17
Beyond C++17Beyond C++17
Beyond C++17
 
Pointless Pointers - How to make our interfaces efficient?
Pointless Pointers - How to make our interfaces efficient?Pointless Pointers - How to make our interfaces efficient?
Pointless Pointers - How to make our interfaces efficient?
 
Striving for ultimate Low Latency
Striving for ultimate Low LatencyStriving for ultimate Low Latency
Striving for ultimate Low Latency
 
Small Lie in Big O
Small Lie in Big OSmall Lie in Big O
Small Lie in Big O
 
std::shared_ptr<T> - (not so) Smart hammer for every pointy nail
std::shared_ptr<T> - (not so) Smart hammer for every pointy nailstd::shared_ptr<T> - (not so) Smart hammer for every pointy nail
std::shared_ptr<T> - (not so) Smart hammer for every pointy nail
 

Recently uploaded

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Victor Rentea
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityWSO2
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...caitlingebhard1
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceIES VE
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxMarkSteadman7
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingWSO2
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....rightmanforbloodline
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 

Recently uploaded (20)

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational Performance
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Quantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation ComputingQuantum Leap in Next-Generation Computing
Quantum Leap in Next-Generation Computing
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 

Effective replacement of dynamic polymorphism with std::variant

  • 1. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 1/108 Mateusz Pusz April 12, 2019 E ective replacement of dynamic polymorphism with std::variant
  • 2. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 2/108 Why?
  • 3. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 3/108 • Time required to perform some action or to produce some result • Measured in units of time like hours, minutes, seconds, nanoseconds or clock periods ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Why? LATENCY 3
  • 4. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 4/108 • Time required to perform some action or to produce some result • Measured in units of time like hours, minutes, seconds, nanoseconds or clock periods • In capital markets, the use of algorithmic trading to react to market events faster than the competition to increase profitability of trades • Many use cases where predictability of latency in message delivery is just as important, if not more important than achieving a low average latency ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Why? LATENCY LOW LATENCY 3
  • 5. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 5/108 • In Low Latency system we care a lot about WCET (Worst Case Execution Time) • In order to limit WCET we should limit the usage of specific C++ language features ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant How NOT to develop software that have predictable performance? 4
  • 6. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 6/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 7. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 7/108 • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 8. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 8/108 • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) • Throwing exceptions on a likely code path ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 9. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 9/108 • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) • Throwing exceptions on a likely code path • Dynamic polymorphism ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 10. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 10/108 • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) • Throwing exceptions on a likely code path • Dynamic polymorphism • Multiple inheritance ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 11. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 11/108 • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) • Throwing exceptions on a likely code path • Dynamic polymorphism • Multiple inheritance • RTTI ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 12. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 12/108 • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) • Throwing exceptions on a likely code path • Dynamic polymorphism • Multiple inheritance • RTTI • Dynamic memory allocations ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path 5
  • 13. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 13/108 • Dynamic polymorphism • Dynamic memory allocations ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Things to avoid on the fast path • C++ tools that trade performance for usability (e.g. std::shared_ptr, std::function) • Throwing exceptions on a likely code path • Multiple inheritance • RTTI 6
  • 14. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 14/108 How?
  • 15. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 15/108 class base : noncopyable { public: virtual ~base() = default; virtual void foo() = 0; }; class x : public base { public: void foo() override; }; class y : public base { public: void foo() override; }; std::unique_ptr<base> b = std::make_unique<x>(); b->foo(); ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant How? DYNAMIC POLYMORPHISM 8
  • 16. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 16/108 class base : noncopyable { public: virtual ~base() = default; virtual void foo() = 0; }; class x : public base { public: void foo() override; }; class y : public base { public: void foo() override; }; std::unique_ptr<base> b = std::make_unique<x>(); b->foo(); ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant How? DYNAMIC POLYMORPHISM 8
  • 17. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 17/108 class base : noncopyable { public: virtual ~base() = default; virtual void foo() = 0; }; class x : public base { public: void foo() override; }; class y : public base { public: void foo() override; }; std::unique_ptr<base> b = std::make_unique<x>(); b->foo(); struct x { void foo(); }; struct y { void foo(); }; std::variant<x, y> b; std::visit([](auto&& v){ v.foo(); }, b); • Shorter • Faster • Value semantics • Works on unrelated classes • More flexible thanks to duck typing ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant How? DYNAMIC POLYMORPHISM VARIANT 8
  • 18. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 18/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant THE END T H A N K Y O U ! 9
  • 19. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 19/108 Bonus slides
  • 20. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 20/108 Abstract machine that can be in exactly one of a finite number of states at any given time. -- Wikipedia ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Finite State Machine 11
  • 21. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 21/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Finite State Machine 12
  • 22. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 22/108 • State changes to another in a response to some external inputs called events ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Finite State Machine 12
  • 23. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 23/108 • State changes to another in a response to some external inputs called events • The change from one state to another is called a transition ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Finite State Machine 12
  • 24. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 24/108 • State changes to another in a response to some external inputs called events • The change from one state to another is called a transition • A FSM is defined by – a list of states – its initial state – the conditions for each transition ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Finite State Machine 12
  • 25. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 25/108 Single dynamic dispatch CASE #1
  • 26. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 26/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Class diagram 14
  • 27. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 27/108 template<typename Event> class state : noncopyable { public: virtual ~state() = default; virtual std::unique_ptr<state> on_event(Event) = 0; }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 15
  • 28. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 28/108 template<typename Event> class state : noncopyable { public: virtual ~state() = default; virtual std::unique_ptr<state> on_event(Event) = 0; }; template<typename Event> class fsm { std::unique_ptr<state<Event>> state_; public: explicit fsm(std::unique_ptr<state<Event>> state) : state_(std::move(state)) {} void dispatch(Event e) { auto new_state = state_->on_event(e); if(new_state) state_ = std::move(new_state); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 15
  • 29. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 29/108 template<typename Event> class state : noncopyable { public: virtual ~state() = default; virtual std::unique_ptr<state> on_event(Event) = 0; }; template<typename Event> class fsm { std::unique_ptr<state<Event>> state_; public: explicit fsm(std::unique_ptr<state<Event>> state) : state_(std::move(state)) {} void dispatch(Event e) { auto new_state = state_->on_event(e); if(new_state) state_ = std::move(new_state); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 16
  • 30. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 30/108 class connection_fsm : public fsm<event> { public: connection_fsm(): fsm<event>(std::make_unique<state_idle>()) {} }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Connection FSM 17
  • 31. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 31/108 class connection_fsm : public fsm<event> { public: connection_fsm(): fsm<event>(std::make_unique<state_idle>()) {} }; using s = state<event>; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Connection FSM 17
  • 32. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 32/108 class connection_fsm : public fsm<event> { public: connection_fsm(): fsm<event>(std::make_unique<state_idle>()) {} }; using s = state<event>; class state_idle final : public s { public: std::unique_ptr<s> on_event(event e) override; }; class state_connecting final : public s { static constexpr int n_max = 3; int n = 0; public: std::unique_ptr<s> on_event(event e) override; }; class state_connected final : public s { public: std::unique_ptr<s> on_event(event e) override; }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Connection FSM 17
  • 33. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 33/108 std::unique_ptr<s> state_idle::on_event(event e) { } std::unique_ptr<s> state_connecting::on_event(event e) { } std::unique_ptr<s> state_connected::on_event(event e) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 18
  • 34. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 34/108 std::unique_ptr<s> state_idle::on_event(event e) { if(e == event::connect) return std::make_unique<state_connecting>(); return nullptr; } std::unique_ptr<s> state_connecting::on_event(event e) { } std::unique_ptr<s> state_connected::on_event(event e) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 18
  • 35. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 35/108 std::unique_ptr<s> state_idle::on_event(event e) { if(e == event::connect) return std::make_unique<state_connecting>(); return nullptr; } std::unique_ptr<s> state_connecting::on_event(event e) { switch(e) { case event::connected: return std::make_unique<state_connected>(); case event::timeout: return ++n < n_max ? nullptr : std::make_unique<state_idle>(); default: return nullptr; } } std::unique_ptr<s> state_connected::on_event(event e) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 18
  • 36. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 36/108 std::unique_ptr<s> state_idle::on_event(event e) { if(e == event::connect) return std::make_unique<state_connecting>(); return nullptr; } std::unique_ptr<s> state_connecting::on_event(event e) { switch(e) { case event::connected: return std::make_unique<state_connected>(); case event::timeout: return ++n < n_max ? nullptr : std::make_unique<state_idle>(); default: return nullptr; } } std::unique_ptr<s> state_connected::on_event(event e) { if(e == event::disconnect) return std::make_unique<state_idle>(); return nullptr; } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 18
  • 37. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 37/108 std::unique_ptr<s> state_idle::on_event(event e) { if(e == event::connect) return std::make_unique<state_connecting>(); return nullptr; } std::unique_ptr<s> state_connecting::on_event(event e) { switch(e) { case event::connected: return std::make_unique<state_connected>(); case event::timeout: return ++n < n_max ? nullptr : std::make_unique<state_idle>(); default: return nullptr; } } std::unique_ptr<s> state_connected::on_event(event e) { if(e == event::disconnect) return std::make_unique<state_idle>(); return nullptr; } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant The slow part 19
  • 38. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 38/108 • Fold expressions come handy ;-) template<typename Fsm, typename... Events> void dispatch(Fsm& fsm, Events... events) { (fsm.dispatch(events), ...); } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Testing transitions 20
  • 39. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 39/108 • Fold expressions come handy ;-) template<typename Fsm, typename... Events> void dispatch(Fsm& fsm, Events... events) { (fsm.dispatch(events), ...); } • Simple message flow connection_fsm fsm; dispatch(fsm, event::connect, event::timeout, event::connected, event::disconnect); ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Testing transitions 20
  • 40. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 40/108 • Open to new alternatives – new derived types may be added by clients at any point of time (long a er base class implementation is finished) ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 21
  • 41. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 41/108 • Open to new alternatives – new derived types may be added by clients at any point of time (long a er base class implementation is finished) • Closed to new operations – clients cannot add new operations to dynamic dispatch ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 21
  • 42. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 42/108 • Open to new alternatives – new derived types may be added by clients at any point of time (long a er base class implementation is finished) • Closed to new operations – clients cannot add new operations to dynamic dispatch • Multi-level – many levels of inheritance possible ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 21
  • 43. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 43/108 • Open to new alternatives – new derived types may be added by clients at any point of time (long a er base class implementation is finished) • Closed to new operations – clients cannot add new operations to dynamic dispatch • Multi-level – many levels of inheritance possible • Object Oriented – whole framework is based on objects ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Single dynamic dispatch 21
  • 44. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 44/108 Double dynamic dispatch CASE #2
  • 45. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 45/108 class event : noncopyable { public: virtual ~event() = default; }; class event_connect final : public event { std::string_view address_; public: explicit event_connect(std::string_view address): address_(address) {} std::string_view address() const { return address_; } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant What if we want our events to pass data? 23
  • 46. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 46/108 class event : noncopyable { public: virtual ~event() = default; }; class event_connect final : public event { std::string_view address_; public: explicit event_connect(std::string_view address): address_(address) {} std::string_view address() const { return address_; } }; std::unique_ptr<state> state_idle::on_event(const event& e) { if(auto ptr = dynamic_cast<const event_connect*>(&e)) { /* ... */ } else { /* ... */ } } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant What if we want our events to pass data? 23
  • 47. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 47/108 class event : noncopyable { public: virtual ~event() = default; }; class event_connect final : public event { std::string_view address_; public: explicit event_connect(std::string_view address): address_(address) {} std::string_view address() const { return address_; } }; std::unique_ptr<state> state_idle::on_event(const event& e) { if(auto ptr = dynamic_cast<const event_connect*>(&e)) { /* ... */ } else { /* ... */ } } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant What if we want our events to pass data? A really bad idea :-( 23
  • 48. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 48/108 Special form of multiple dispatch, and a mechanism that dispatches a function call to di erent concrete functions depending on the runtime types of two objects involved in the call -- Wikipedia ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dispatch (aka Visitor Pattern) 24
  • 49. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 49/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dispatch (aka Visitor Pattern) 25
  • 50. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 50/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; template<typename State, typename Event> class fsm { std::unique_ptr<State> state_; public: explicit fsm(std::unique_ptr<State> state) : state_(std::move(state)) {} void dispatch(const Event& e) { auto new_state = e.dispatch(*state_); if(new_state) state_ = std::move(new_state); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dispatch (aka Visitor Pattern) 25
  • 51. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 51/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; struct event_connect final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } // ... }; struct event_connected final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } }; struct event_disconnect final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } }; struct event_timeout final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dispatch (aka Visitor Pattern) 26
  • 52. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 52/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; class state : noncopyable { public: virtual ~state() = default; virtual std::unique_ptr<state> on_event(const event_connect&) { return nullptr; } virtual std::unique_ptr<state> on_event(const event_connected&) { return nullptr; } virtual std::unique_ptr<state> on_event(const event_disconnect&) { return nullptr; } virtual std::unique_ptr<state> on_event(const event_timeout&) { return nullptr; } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dispatch (aka Visitor Pattern) 27
  • 53. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 53/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; class state : noncopyable { public: virtual ~state() = default; virtual std::unique_ptr<state> on_event(const event_connect&) { return nullptr; } virtual std::unique_ptr<state> on_event(const event_connected&) { return nullptr; } virtual std::unique_ptr<state> on_event(const event_disconnect&) { return nullptr; } virtual std::unique_ptr<state> on_event(const event_timeout&) { return nullptr; } }; class state_idle final : public state { public: using state::on_event; std::unique_ptr<state> on_event(const event_connect& e) override { return std::make_unique<state_connecting>(std::string(e.address())); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dispatch (aka Visitor Pattern) 27
  • 54. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 54/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Class diagram 28
  • 55. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 55/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; struct event_connect final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } // ... }; struct event_connected final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } }; struct event_disconnect final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } }; struct event_timeout final : public event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*this); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Curiously Recurring Template Pattern (CRTP) 29
  • 56. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 56/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; template<typename Child> struct event_crtp : event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*static_cast<const Child*>(this)); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Curiously Recurring Template Pattern (CRTP) 30
  • 57. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 57/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; template<typename Child> struct event_crtp : event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*static_cast<const Child*>(this)); } }; struct event_connect final : public event_crtp<event_connect> { // ... }; struct event_connected final : public event_crtp<event_connected> {}; struct event_disconnect final : public event_crtp<event_disconnect> {}; struct event_timeout final : public event_crtp<event_timeout> {}; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Curiously Recurring Template Pattern (CRTP) 30
  • 58. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 58/108 template<typename State> struct event : private noncopyable { virtual ~event() = default; virtual std::unique_ptr<State> dispatch(State& s) const = 0; }; template<typename Child> struct event_crtp : event<state> { std::unique_ptr<state> dispatch(state& s) const override { return s.on_event(*static_cast<const Child*>(this)); } }; struct event_connect final : public event_crtp<event_connect> { explicit event_connect(std::string_view address): address_(address) {} std::string_view address() const { return address_; } private: std::string_view address_; }; struct event_connected final : public event_crtp<event_connected> {}; struct event_disconnect final : public event_crtp<event_disconnect> {}; struct event_timeout final : public event_crtp<event_timeout> {}; • Hey look ma, now all fits on one slide ;-) ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Curiously Recurring Template Pattern (CRTP) 31
  • 59. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 59/108 std::unique_ptr<state> state_idle::on_event(const event_connect& e) { } std::unique_ptr<state> state_connecting::on_event(const event_connected&) { } std::unique_ptr<state> state_connecting::on_event(const event_timeout&) { } std::unique_ptr<state> state_connected::on_event(const event_disconnect&) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 32
  • 60. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 60/108 std::unique_ptr<state> state_idle::on_event(const event_connect& e) { return std::make_unique<state_connecting>( std::string{e.address()}); } std::unique_ptr<state> state_connecting::on_event(const event_connected&) { } std::unique_ptr<state> state_connecting::on_event(const event_timeout&) { } std::unique_ptr<state> state_connected::on_event(const event_disconnect&) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 32
  • 61. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 61/108 std::unique_ptr<state> state_idle::on_event(const event_connect& e) { return std::make_unique<state_connecting>( std::string{e.address()}); } std::unique_ptr<state> state_connecting::on_event(const event_connected&) { return std::make_unique<state_connected>(); } std::unique_ptr<state> state_connecting::on_event(const event_timeout&) { } std::unique_ptr<state> state_connected::on_event(const event_disconnect&) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 32
  • 62. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 62/108 std::unique_ptr<state> state_idle::on_event(const event_connect& e) { return std::make_unique<state_connecting>( std::string{e.address()}); } std::unique_ptr<state> state_connecting::on_event(const event_connected&) { return std::make_unique<state_connected>(); } std::unique_ptr<state> state_connecting::on_event(const event_timeout&) { return ++n < n_max ? nullptr : std::make_unique<state_idle>(); } std::unique_ptr<state> state_connected::on_event(const event_disconnect&) { } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 32
  • 63. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 63/108 std::unique_ptr<state> state_idle::on_event(const event_connect& e) { return std::make_unique<state_connecting>( std::string{e.address()}); } std::unique_ptr<state> state_connecting::on_event(const event_connected&) { return std::make_unique<state_connected>(); } std::unique_ptr<state> state_connecting::on_event(const event_timeout&) { return ++n < n_max ? nullptr : std::make_unique<state_idle>(); } std::unique_ptr<state> state_connected::on_event(const event_disconnect&) { return std::make_unique<state_idle>(); } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 32
  • 64. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 64/108 std::unique_ptr<state> state_idle::on_event(const event_connect& e) { return std::make_unique<state_connecting>( std::string{e.address()}); } std::unique_ptr<state> state_connecting::on_event(const event_connected&) { return std::make_unique<state_connected>(); } std::unique_ptr<state> state_connecting::on_event(const event_timeout&) { return ++n < n_max ? nullptr : std::make_unique<state_idle>(); } std::unique_ptr<state> state_connected::on_event(const event_disconnect&) { return std::make_unique<state_idle>(); } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant The slow part 33
  • 65. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 65/108 template<typename Fsm, typename... Events> void dispatch(Fsm& fsm, const Events&... events) { (fsm.dispatch(*events), ...); } ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Testing transitions 34
  • 66. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 66/108 template<typename Fsm, typename... Events> void dispatch(Fsm& fsm, const Events&... events) { (fsm.dispatch(*events), ...); } dispatch(fsm, std::make_unique<event_connect>("train-it.eu"), std::make_unique<event_timeout>(), std::make_unique<event_connected>(), std::make_unique<event_disconnect>()); ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Testing transitions 34
  • 67. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 67/108 template<typename Fsm, typename... Events> void dispatch(Fsm& fsm, const Events&... events) { (fsm.dispatch(*events), ...); } dispatch(fsm, std::make_unique<event_connect>("train-it.eu"), std::make_unique<event_timeout>(), std::make_unique<event_connected>(), std::make_unique<event_disconnect>()); ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant The slow part 35
  • 68. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 68/108 • Open to new alternatives • Closed to new alternatives – one of class hierarchies fixed at design time and cannot be extended by clients • Closed to new operations – clients cannot add new operations to dynamic dispatch • Multi-level – many levels of inheritance possible • Object Oriented – whole framework is based on objects ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Double dynamic dispatch (aka Visitor Pattern) 36
  • 69. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 69/108 Variant + external transitions CASE #3
  • 70. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 70/108 struct event_connect { std::string_view address; }; struct event_connected {}; struct event_disconnect {}; struct event_timeout {}; using event = std::variant<event_connect, event_connected, event_disconnect, event_timeout>; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Events and states EVENTS 38
  • 71. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 71/108 struct event_connect { std::string_view address; }; struct event_connected {}; struct event_disconnect {}; struct event_timeout {}; using event = std::variant<event_connect, event_connected, event_disconnect, event_timeout>; struct state_idle {}; struct state_connecting { static constexpr int n_max = 3; int n = 0; std::string address; }; struct state_connected {}; using state = std::variant<state_idle, state_connecting, state_connected>; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Events and states EVENTS STATES 38
  • 72. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 72/108 struct transitions { optional<state> operator()(state_idle&, const event_connect& e) { } optional<state> operator()(state_connecting&, const event_connected&) { } optional<state> operator()(state_connecting& s, const event_timeout&) { } optional<state> operator()(state_connected&, const event_disconnect&) { } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 39
  • 73. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 73/108 struct transitions { optional<state> operator()(state_idle&, const event_connect& e) { return state_connecting{std::string(e.address)}; } optional<state> operator()(state_connecting&, const event_connected&) { } optional<state> operator()(state_connecting& s, const event_timeout&) { } optional<state> operator()(state_connected&, const event_disconnect&) { } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 39
  • 74. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 74/108 struct transitions { optional<state> operator()(state_idle&, const event_connect& e) { return state_connecting{std::string(e.address)}; } optional<state> operator()(state_connecting&, const event_connected&) { return state_connected{}; } optional<state> operator()(state_connecting& s, const event_timeout&) { } optional<state> operator()(state_connected&, const event_disconnect&) { } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 39
  • 75. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 75/108 struct transitions { optional<state> operator()(state_idle&, const event_connect& e) { return state_connecting{std::string(e.address)}; } optional<state> operator()(state_connecting&, const event_connected&) { return state_connected{}; } optional<state> operator()(state_connecting& s, const event_timeout&) { return ++s.n < state_connecting::n_max ? std::nullopt : optional<state>(state_idle{}); } optional<state> operator()(state_connected&, const event_disconnect&) { } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 39
  • 76. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 76/108 struct transitions { optional<state> operator()(state_idle&, const event_connect& e) { return state_connecting{std::string(e.address)}; } optional<state> operator()(state_connecting&, const event_connected&) { return state_connected{}; } optional<state> operator()(state_connecting& s, const event_timeout&) { return ++s.n < state_connecting::n_max ? std::nullopt : optional<state>(state_idle{}); } optional<state> operator()(state_connected&, const event_disconnect&) { return state_idle{}; } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 39
  • 77. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 77/108 struct transitions { optional<state> operator()(state_idle&, const event_connect& e) { return state_connecting{std::string(e.address)}; } optional<state> operator()(state_connecting&, const event_connected&) { return state_connected{}; } optional<state> operator()(state_connecting& s, const event_timeout&) { return ++s.n < state_connecting::n_max ? std::nullopt : optional<state>(state_idle{}); } optional<state> operator()(state_connected&, const event_disconnect&) { return state_idle{}; } template<typename State, typename Event> optional<state> operator()(State&, const Event&) const { return std::nullopt; } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions 39
  • 78. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 78/108 template<typename StateVariant, typename EventVariant, typename Transitions> class fsm { StateVariant state_; public: void dispatch(const EventVariant& event) { std::optional<StateVariant> new_state = std::visit(Transitions{}, state_, event); if(new_state) state_ = *std::move(new_state); } }; using connection_fsm = fsm<state, event, transitions>; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant FSM engine 40
  • 79. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 79/108 template<typename StateVariant, typename EventVariant, typename Transitions> class fsm { StateVariant state_; public: void dispatch(const EventVariant& event) { std::optional<StateVariant> new_state = std::visit(Transitions{}, state_, event); if(new_state) state_ = *std::move(new_state); } }; using connection_fsm = fsm<state, event, transitions>; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant FSM engine 41
  • 80. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 80/108 template<typename StateVariant, typename EventVariant, typename Transitions> class fsm { StateVariant state_; public: void dispatch(const EventVariant& event) { std::optional<StateVariant> new_state = std::visit(Transitions{}, state_, event); if(new_state) state_ = *std::move(new_state); } }; using connection_fsm = fsm<state, event, transitions>; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant FSM engine 42
  • 81. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 81/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Class diagram 43
  • 82. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 82/108 template<typename Fsm, typename... Events> void dispatch(Fsm& fsm, Events&&... events) { (fsm.dispatch(std::forward<Events>(events)), ...); } dispatch(fsm, event_connect{"train-it.eu"}, event_timeout{}, event_connected{}, event_disconnect{}); ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Testing transitions 44
  • 83. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 83/108 Variant + transitions in FSM CASE #4
  • 84. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 84/108 template<typename Derived, typename StateVariant, typename EventVariant> class fsm { StateVariant state_; public: void dispatch(const EventVariant& event) { auto new_state = std::visit( state_, event); if(new_state) state_ = *std::move(new_state); } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant FSM engine 46
  • 85. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 85/108 template<typename Derived, typename StateVariant, typename EventVariant> class fsm { StateVariant state_; public: void dispatch(const EventVariant& event) { Derived& child = static_cast<Derived&>(*this); auto new_state = std::visit( [&](auto& s, const auto& e) -> std::optional<StateVariant> { return child.on_event(s, e); }, state_, event); if(new_state) state_ = *std::move(new_state); } }; • CRTP again ;-) ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant FSM engine 46
  • 86. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 86/108 template<typename Derived, typename StateVariant> class fsm { StateVariant state_; public: template<typename Event> void dispatch(Event&& event) { Derived& child = static_cast<Derived&>(*this); auto new_state = std::visit( [&](auto& s) -> std::optional<StateVariant> { return child.on_event(s, std::forward<Event>(event)); }, state_); if(new_state) state_ = *std::move(new_state); } }; • Visitation on a StateVariant only ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant FSM engine: dispatch() as an overload set 47
  • 87. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 87/108 class connection_fsm : public fsm<connection_fsm, state> { public: auto on_event(state_idle&, const event_connect& e) { } auto on_event(state_connecting&, const event_connected&) { } auto on_event(state_connecting& s, const event_timeout&) { } auto on_event(state_connected&, const event_disconnect&) { } template<typename State, typename Event> auto on_event(State&, const Event&) { } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions de ned by the FSM itself 48
  • 88. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 88/108 class connection_fsm : public fsm<connection_fsm, state> { public: auto on_event(state_idle&, const event_connect& e) { return state_connecting{std::string(e.address)}; } auto on_event(state_connecting&, const event_connected&) { return state_connected{}; } auto on_event(state_connecting& s, const event_timeout&) { return ++s.n < state_connecting::n_max ? std::nullopt : std::optional<state>(state_idle{}); } auto on_event(state_connected&, const event_disconnect&) { return state_idle{}; } template<typename State, typename Event> auto on_event(State&, const Event&) { return std::nullopt; } }; ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Transitions de ned by the FSM itself 48
  • 89. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 89/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant Class diagram 49
  • 90. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 90/108 What about performance?
  • 91. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 91/108 CLOSED(Start) LISTEN/- CLOSE/- LISTEN SYN RECEIVED SYN SENT CONNECT/ (Step 1 of the 3-way-handshake)SYN SYN/SYN+ACK(Step 2 of the 3-way-handshake) unusual event client/receiver path server/sender path RST/- SYN/SYN+ACK (simultaneous open) SYN+ACK/ACK (Step 3 of the 3-way-handshake) Data exchange occurs ESTABLISHED FIN/ACK ACK/- CLOSE/- SEND/SYN CLOSE/FIN CLOSE/FIN CLOSING TIME WAIT CLOSED FIN WAIT 1 FIN WAIT 2 CLOSE WAIT LAST ACK CLOSE/FIN FIN/ACK FIN+ACK/ACK ACK/- FIN/ACK Timeout (Go back to start) Active CLOSE Passive CLOSE ACK/- ACK/- ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant TCP state diagram 51
  • 92. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 92/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant TCP FSM Performance 52
  • 93. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 93/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant TCP FSM Performance 52
  • 94. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 94/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant TCP FSM Performance 52
  • 95. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 95/108 Summary
  • 96. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 96/108 ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 97. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 97/108 • Open/Closed to new alternatives • Closed to new alternatives ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 98. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 98/108 • Open/Closed to new alternatives • Closed to new operations • Closed to new alternatives • Open to new operations ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 99. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 99/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • Closed to new alternatives • Open to new operations • Single level ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 100. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 100/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Closed to new alternatives • Open to new operations • Single level • Functional ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 101. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 101/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Pointer semantics • Closed to new alternatives • Open to new operations • Single level • Functional • Value semantics ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 102. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 102/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Pointer semantics • Design forced by the implementation details • Closed to new alternatives • Open to new operations • Single level • Functional • Value semantics • Many design choices possible ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 103. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 103/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Pointer semantics • Design forced by the implementation details • Forces dynamic memory allocations • Closed to new alternatives • Open to new operations • Single level • Functional • Value semantics • Many design choices possible • No dynamic memory allocations ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 104. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 104/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Pointer semantics • Design forced by the implementation details • Forces dynamic memory allocations • Strict interfaces • Closed to new alternatives • Open to new operations • Single level • Functional • Value semantics • Many design choices possible • No dynamic memory allocations • Duck typing ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 105. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 105/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Pointer semantics • Design forced by the implementation details • Forces dynamic memory allocations • Strict interfaces • Complex • Closed to new alternatives • Open to new operations • Single level • Functional • Value semantics • Many design choices possible • No dynamic memory allocations • Duck typing • Simple ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 106. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 106/108 • Open/Closed to new alternatives • Closed to new operations • Multi-level • OO • Pointer semantics • Design forced by the implementation details • Forces dynamic memory allocations • Strict interfaces • Complex • Slower • Closed to new alternatives • Open to new operations • Single level • Functional • Value semantics • Many design choices possible • No dynamic memory allocations • Duck typing • Simple • Faster ACCU 2019 | E ective replacement of dynamic polymorphism with std::variant std::variant<Types...> vs inheritance INHERITANCE VARIANT 54
  • 107. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 107/108
  • 108. 12.04.2019 Effective replacement of dynamic polymorphism with std::variant file:///C:/repos/cppTrainings/build/out/polymorphism_with_variant/polymorphism_with_variant.html#108 108/108