Vittorio Romeo - Higher Order Functions and Function Ref
Vittorio Romeo - Higher Order Functions and Function Ref
function_ref
Higher-order functions
What they are
Use cases and implementation techniques
function_ref
Motivation
Specification and usage examples
Implementation
Benchmarks
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
introduction 10
disclaimer
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
introduction 11
assumptions
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
12
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 13
definition
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 14
basic examples
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 15
basic examples
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 16
in the Standard
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 17
in the Standard
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 18
in the Standard
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 19
in the Standard
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 20
in the Standard
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 21
in the Standard
#include <csignal>
int main()
{
std signal(SIGINT, [](int signal_num)
{
std cout "signal: " signal_num '\n';
});
}
(on godbolt.org)
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 22
in the Standard
std set_terminate
std visit , std apply , std invoke
std bind , std bind_front (C++20)
<numeric> and <algorithm>
...
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 23
in the Standard
"Erase-remove idiom":
Moves kept elements to the beginning of the range
Relative order of elements is preserved
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 24
in the Standard
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 25
use cases
Avoiding repetition
Inversion of control flow
Asynchronicity
Compile-time metaprogramming
...
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 26
use cases - avoiding repetition
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 27
use cases - avoiding repetition
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 29
use cases - avoiding repetition
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 30
use cases - inversion of control flow
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 31
use cases - inversion of control flow
struct physics_component
{
vec2f _pos, _vel, _acc;
};
std vector<physics_component> components{ };
std for_each(std execution par_unseq,
components.begin(),
components.end(),
[](auto& c)
{
c._vel += c._acc;
c._pos += c._vel;
});
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 32
use cases - inversion of control flow
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 33
use cases - inversion of control flow
Initial version
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 34
use cases - inversion of control flow
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 35
use cases - inversion of control flow
Create an abstraction
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 36
use cases - inversion of control flow
Redefine print
for_separated is reusable
It provides the control flow
The user provides the actions
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 37
use cases - inversion of control flow
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 38
use cases - inversion of control flow
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 39
use cases - asynchronicity
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 40
use cases - asynchronicity
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 41
use cases - metaprogramming fun!
0: i
1: f
2: c
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 42
vs other abstractions
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 43
vs RAII guards
class foo { };
synchronized<foo> s_foo;
some way to access contents of `s_foo` in a thread safe manner
i. RAII guards
ii. Higher-order functions
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 44
vs RAII guards
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 45
vs RAII guards
public:
auto access()
{
struct access_guard
{
std lock_guard<std mutex> _guard;
T* operator ();
constructors, etc
};
return access_guard{*this};
}
};
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 46
vs RAII guards
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 47
vs RAII guards
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 48
vs RAII guards
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 49
vs iterators
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 50
vs iterators
From Boost.Iterator
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 51
vs iterators
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
higher order functions 52
recap
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
53
function_ref
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 54
motivation
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 55
motivation
Pointers to functions
int operation(int( f)(int, int))
{
return f(1, 2);
}
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 56
motivation
Template parameters
template <typename T>
auto operation(F f) decltype(std forward<F>(f)(1, 2))
{
return std forward<F>(f)(1, 2);
}
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 57
motivation
std function
int operation(const std function<int(int, int)>& f)
{
return f(1, 2);
}
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 58
motivation
function_ref
int operation(function_ref<int(int, int)> f)
{
return f(1, 2);
}
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 59
in a nutshell
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 60
practical comparsions
Easier to write/read/teach
Usable in polymorphic hierarchies
Better compilation times
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 61
synopsis
class replay_map
{
std unordered_map<command_id, ref_counted<command _items;
std unordered_map<queue_id, std deque<command_id _queues;
void iterate(const queue_id& id,
const function_ref<void(const Value&)> f) const
{
const auto queueIt = _queues.find(qk);
if(queueIt std end(_queues)) { return; }
const auto& q = queueIt second;
for(auto it = q.rbegin(); it q.rend(); it)
{
f(d_items.at( it).d_value);
}
}
};
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 63
use case examples
struct packet_cache
{
using replay_cb = function_ref<void(const VALUE&)>;
using consume_cb = function_ref<void(VALUE )>;
virtual void replay(replay_cb cb) const = 0;
virtual void consume(consume_cb cb) = 0;
virtual ~packet_cache() { }
};
...
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 64
use case examples
using status_change_cb =
function_ref<void(const node_id&, const node_state_transition&)>;
void node_monitor sweep(const status_change_cb& cb,
const timestamp& ts)
{
for(auto it = std begin(_data); it std end(_data);)
{
if ( (it second._state node_state down)
(ts - v._last_heartbeat 10s))
{
cb(it first, transition_to(v, node_state Down));
it = _data.erase(it);
}
else { it; }
}
}
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 66
implementation
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 67
implementation
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 68
implementation
private:
void* _ptr;
Return (*_erased_fn)(void*, Args );
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 69
implementation
private:
void* _ptr;
Return (*_erased_fn)(void*, Args );
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 70
implementation
public:
template <typename F, some constraints >
function_ref(F f) noexcept : _ptr{(void*) &f}
{
_erased_fn = [](void* ptr, Args xs) Return {
return (*reinterpret_cast<F (ptr))(
std forward<Args>(xs) );
};
}
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 72
pitfalls
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 73
benchmarks - methodology
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 74
benchmarks - methodology
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 75
benchmarks - methodology
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 76
benchmarks - methodology
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 77
benchmarks - results (0/2)
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 78
benchmarks - results (1/2)
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 79
benchmarks - results (2/2)
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
function_ref 80
benchmarks - conclusions
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
conclusion 81
recap - higher order functions
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
conclusion 82
recap - function_ref
P0792
github:TartanLlama/function_ref
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
Thanks!
https://vittorioromeo.info
[email protected]
[email protected]
@supahvee1234
https://github.com/SuperV1234/cpponsea2019
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
Extras
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.
"compile-time iteration with C++20 lambdas"
"P0573R2: Abbreviated Lambdas for Fun and Profit" (by Barry Revzin & Tomasz Kamiński)
vittorioromeo.info | [email protected] | [email protected] | @supahvee1234 | (C) 2019 Bloomberg Finance L.P. All rights reserved.