SlideShare a Scribd company logo
1 of 67
Download to read offline
Async. programming with ranges
Corehard Autumn 2018
dr Ivan Čukić
ivan@cukic.co core-dev @ KDE
http://cukic.co www.kde.org
Iterators Ranges Push Pipes Going postal
About me
KDE development
Talks and teaching
Author of ”Functional Programming in C++” (Manning)
Functional programming enthusiast, but not a purist
2
Iterators Ranges Push Pipes Going postal
Disclaimer
Make your code readable. Pretend the next person
who looks at your code is a psychopath and they
know where you live.
Philip Wadler
3
ITERATORS
Iterators Ranges Push Pipes Going postal
Iterators
At the core of generic programming in STL.
5
Iterators Ranges Push Pipes Going postal
Iterators
std::vector<std::string> identifiers;
std::copy_if(
std::cbegin(tokens),
std::cend(tokens),
std::back_inserter(identifiers),
is_valid_identifier);
6
Iterators Ranges Push Pipes Going postal
Iterators
std::vector<std::string> identifiers;
std::copy_if(
std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::back_inserter(identifiers),
is_valid_identifier);
7
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
8
Iterators Ranges Push Pipes Going postal
Example
template <typename It, typename Pred>
std::pair<It, It> move_selected(
It begin, It end, It destination,
Pred is_selected)
{
return {
std::stable_partition(begin, destination,
std::not_fn(is_selected)),
std::stable_partition(destination, end,
is_selected)
};
}
9
RANGES
Iterators Ranges Push Pipes Going postal
Problems with iterators
Example: Sum of squares
This should be separable into two subtasks:
squaring the values
summation
11
Iterators Ranges Push Pipes Going postal
Problems with iterators
std::vector<int> xs { ⋯ };
std::vector<int> squared(xs.size());
std::transform(std::cbegin(xs), std::cend(xs),
std::begin(squared),
[] (int x) { return x * x; });
return std::accumulate(std::cbegin(squared),
std::cend(squared),
0);
12
Iterators Ranges Push Pipes Going postal
Problems with iterators
std::vector<int> xs { ⋯ };
return std::transform_reduce(par,
std::cbegin(xs), std::cend(xs),
std::cbegin(xs),
0);
13
Iterators Ranges Push Pipes Going postal
Proxy iterators
template <typename Trafo, typename It>
class transform_proxy_iterator {
public:
auto operator*() const
{
return transformation(
*real_iterator);
}
private:
Trafo transformation;
It real_iterator;
};
14
Iterators Ranges Push Pipes Going postal
Ranges
[ iterator, sentinel )
Iterator:
*i – access the value
++i – move to the next element
Sentinel:
i == s – has iterator reached the end?
15
Iterators Ranges Push Pipes Going postal
Ranges
std::vector<int> xs { ⋯ };
accumulate(
transform(
xs,
[] (int x) { ⋯ }),
0);
16
Iterators Ranges Push Pipes Going postal
Ranges
std::vector<int> xs { ⋯ };
accumulate(
transform(
filter(
xs,
[] (int x) { ⋯ }),
[] (int x) { ⋯ }),
0);
17
Iterators Ranges Push Pipes Going postal
Ranges
std::vector<int> xs { ⋯ };
accumulate(
xs | filter([] (int x) { ⋯ })
| transform([] (int x) { ⋯ }),
0);
18
Iterators Ranges Push Pipes Going postal
Word frequency
1986: Donald Knuth was asked to implement a program for
the ”Programming pearls” column in the Communications
of ACM journal.
The task: Read a file of text, determine the n most
frequently used words, and print out a sorted list of those
words along with their frequencies.
19
Iterators Ranges Push Pipes Going postal
Word frequency
1986: Donald Knuth was asked to implement a program for
the ”Programming pearls” column in the Communications
of ACM journal.
The task: Read a file of text, determine the n most
frequently used words, and print out a sorted list of those
words along with their frequencies.
His solution written in Pascal was 10 pages long.
19
Iterators Ranges Push Pipes Going postal
Word frequency
Response by Doug McIlroy was a 6-line shell script that did
the same:
tr −cs A−Za−z ' n ' |
tr A−Z a−z |
sort |
uniq −c |
sort −rn |
sed ${1}q
20
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
21
Iterators Ranges Push Pipes Going postal
With ranges
const auto words =
// Range of words
istream_range<std::string>(std::cin)
// Cleaning the input
| view::transform(string_to_lower)
| view::transform(string_only_alnum)
| view::remove_if(&std::string::empty)
// Sort the result
| to_vector | action::sort;
22
Iterators Ranges Push Pipes Going postal
With ranges
const auto results =
words
// Group repeated words
| view::group_by(std::equal_to<>())
// Count how many repetitions we have
| view::transform([] (const auto &group) {
return std::make_pair(
distance(begin(group), end(group),
*begin(group));
})
// Sort by frequency
| to_vector | action::sort;
23
Iterators Ranges Push Pipes Going postal
With ranges
for (auto value:
results | view::reverse // descending
| view::take(n) // we need first n results
) {
std::cout << value.first << ” ”
<< value.second << std::endl;
}
24
PUSH
Iterators Ranges Push Pipes Going postal
Ranges
[ iterator, sentinel )
Iterator:
*i – access the value
++i – move to the next element
Sentinel:
i == s – has iterator reached the end
26
Iterators Ranges Push Pipes Going postal
Ranges
[ iterator, sentinel )
Iterator:
*i – access the value BLOCKING!
++i – move to the next element
Sentinel:
i == s – has iterator reached the end
26
Iterators Ranges Push Pipes Going postal
Push iterators
Input Iterator Output
27
Iterators Ranges Push Pipes Going postal
Push iterators
Each push iterator can:
Accept values
Emit values
No need for the accepted and emitted values to be 1-to-1.
28
Iterators Ranges Push Pipes Going postal
Push iterators
Sources – push iterators that only emit values
Sinks – push iterators that only accept values
Modifiers – push iterators that both accept and emit
values
29
Iterators Ranges Push Pipes Going postal
Continuation
template <typename Cont>
class continuator_base {
public:
void init() { ⋯ }
template <typename T>
void emit(T&& value) const
{
std::invoke(m_continuation, FWD(value));
}
void notify_ended() const { ⋯ }
protected:
Cont m_continuation;
};
30
Iterators Ranges Push Pipes Going postal
Invoke
std::invoke(function, arg1, arg2, ...)
For most cases (functions, function objects, lambdas)
equivalent to:
function(arg1, arg2, ...)
But it can also invoke class member functions:
arg1.function(arg2, ...)
31
Iterators Ranges Push Pipes Going postal
Source
template <typename Cont>
class values_node: public continuator_base<Cont>, non_copyable {
⋯
void init()
{
base::init();
for (auto&& value: m_values) {
base::emit(value);
}
m_values.clear();
base::notify_ended();
}
⋯
};
32
Iterators Ranges Push Pipes Going postal
Source
33
Iterators Ranges Push Pipes Going postal
Creating a source
As far as the rest of the system is concerned, this node
creates the messages.
34
Iterators Ranges Push Pipes Going postal
Creating a sink
35
Iterators Ranges Push Pipes Going postal
Creating a transformation
36
Iterators Ranges Push Pipes Going postal
Creating a transformation
template <typename Cont>
class transform_node: public continuator_base<Cont>, non_copyable {
public:
⋯
template <typename T>
void operator() (T&& value) const
{
base::emit(std::invoke(m_transformation, FWD(value)));
}
private:
Traf m_transformation;
};
37
Iterators Ranges Push Pipes Going postal
Filtering
template <typename Cont>
class filter_node: public continuator_base<Cont>, non_copyable {
public:
⋯
template <typename T>
void operator() (T&& value) const
{
if (std::invoke(m_predicate, value) {
base::emit(FWD(value)));
}
}
private:
Predicate m_predicate;
};
38
PIPES
Iterators Ranges Push Pipes Going postal
Connecting the components
auto pipeline = source | transform(⋯)
| filter(⋯)
| join
| transform(⋯)
⋯
40
Iterators Ranges Push Pipes Going postal
AST
When the pipeline AST is completed and evaluated, then we
get proper pipeline nodes.
41
Iterators Ranges Push Pipes Going postal
Associativity
auto my_transformation = filter(⋯)
| join;
auto pipeline = source | transform(⋯)
| my_transformation 
| transform(⋯)
⋯
42
Iterators Ranges Push Pipes Going postal
Different pipes
Composing two transformations
transform(⋯) | filter(⋯)
Connecting a source to the continuation
source | transform(⋯)
Ending the pipeline
filter(⋯) | sink
Closing the pipeline
source | sink
43
Iterators Ranges Push Pipes Going postal
Different pipes
struct source_node_tag {};
struct sink_node_tag {};
struct transformation_node_tag {};
template <typename T>
class values {
public:
using node_category = source_node_tag;
};
44
Iterators Ranges Push Pipes Going postal
Different pipes
struct source_node_tag {};
struct sink_node_tag {};
struct transformation_node_tag {};
template <typename T>
class filter {
public:
using node_category = transformation_node_tag;
};
45
Iterators Ranges Push Pipes Going postal
Concepts
template <typename Left, typename Right>
auto operator| (Left&& left, Right&& right)
{
return ⋯;
}
Problem: Defines operator| on all types
46
Iterators Ranges Push Pipes Going postal
Concepts
template < typename Node
, typename Category = detected_t<node_category, Node>
>
f_concept is_node()
{
if constexpr (!is_detected_v<node_category, Node>) {
return false;
} else if constexpr (std::is_same_v<void, Category>) {
return false;
} else {
return true;
}
}
Note: Proper concepts will come in C++20. This uses the
detection idiom to simulate concepts.
47
Iterators Ranges Push Pipes Going postal
Concepts
template < typename Left
, typename Right
, f_require(
is_node<Left> && is_node<Right>
)
>
auto operator| (Left&& left, Right&& right)
{
return ⋯;
}
48
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯ create a composite transformation
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯
} else {
⋯
}
49
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯ transformed source is also a source
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯
} else {
⋯
}
49
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯ transformation with a sink is a sink
} else {
⋯
}
49
Iterators Ranges Push Pipes Going postal
Concepts
if constexpr (!is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (is_source<Left> && !is_sink<Right>) {
⋯
} else if constexpr (!is_source<Left> && is_sink<Right>) {
⋯
} else {
⋯ the pipeline is complete, evaluate it
}
49
Iterators Ranges Push Pipes Going postal
Pipes
auto new_source = source | transform(⋯) | filter(⋯);
auto new_trafo = transform(⋯) | filter(⋯);
auto new_sink = filter(⋯) | sink;
auto pipeline = new_source | new_trafo | new_sink;
50
Iterators Ranges Push Pipes Going postal
Pipes
Easy implementation of reactive systems
Transparent handling of synchronous vs asynchronous
transformations
High-enough abstraction for more powerful idioms
51
GOING POSTAL
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
53
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
53
Iterators Ranges Push Pipes Going postal
Functional thinking – data transformation
53
Iterators Ranges Push Pipes Going postal
Distributed pipelines
auto pipeline =
system_cmd(”ping”s, ”localhost”s)
| transform(string_to_upper)
// Parse the ping output
| transform([] (std::string&& value) {
const auto pos = value.find_last_of('=');
return std::make_pair(std::move(value), pos);
})
// Extract the ping time from the output
| transform([] (std::pair<std::string, size_t>&& pair) {
auto [ value, pos ] = pair;
return pos == std::string::npos
? std::move(value)
: std::string(value.cbegin() + pos + 1, value.cend());
})
// Remove slow pings
| filter([] (const std::string& value) {
return value < ”0.145”s;
})
// Print out the ping info
| sink{cout};
54
Iterators Ranges Push Pipes Going postal
Distributed pipelines
auto pipeline =
system_cmd(”ping”s, ”localhost”s)
| transform(string_to_upper)
| voy_bridge(frontend_to_backend_1)
| transform([] (std::string&& value) {
const auto pos = value.find_last_of('=');
return std::make_pair(std::move(value), pos);
})
| transform([] (std::pair<std::string, size_t>&& pair) {
auto [ value, pos ] = pair;
return pos == std::string::npos
? std::move(value)
: std::string(value.cbegin() + pos + 1, value.cend());
})
| voy_bridge(backend_1_to_backend_2)
| filter([] (const std::string& value) {
return value < ”0.145”s;
})
| voy_bridge(backend_2_to_frontend)
| sink{cout};
55
Iterators Ranges Push Pipes Going postal
Live demo
56
Iterators Ranges Push Pipes Going postal
Answers? Questions! Questions? Answers!
Kudos (in chronological order):
Friends at KDE
Saša Malkov and Zoltán Porkoláb
спасибо Сергею и двум Антонам
MEAP – Manning Early Access Program
Functional Programming in C++
cukic.co/to/fp-in-cpp
57

More Related Content

What's hot (20)

String notes
String notesString notes
String notes
 
Acm aleppo cpc training introduction 1
Acm aleppo cpc training introduction 1Acm aleppo cpc training introduction 1
Acm aleppo cpc training introduction 1
 
Strings in c
Strings in cStrings in c
Strings in c
 
The string class
The string classThe string class
The string class
 
14 strings
14 strings14 strings
14 strings
 
Python data handling
Python data handlingPython data handling
Python data handling
 
Handling of character strings C programming
Handling of character strings C programmingHandling of character strings C programming
Handling of character strings C programming
 
Strings part2
Strings part2Strings part2
Strings part2
 
C Programming Unit-3
C Programming Unit-3C Programming Unit-3
C Programming Unit-3
 
Strings in c++
Strings in c++Strings in c++
Strings in c++
 
Strings
StringsStrings
Strings
 
String c
String cString c
String c
 
strings
stringsstrings
strings
 
COM1407: Type Casting, Command Line Arguments and Defining Constants
COM1407: Type Casting, Command Line Arguments and Defining Constants COM1407: Type Casting, Command Line Arguments and Defining Constants
COM1407: Type Casting, Command Line Arguments and Defining Constants
 
C programming - String
C programming - StringC programming - String
C programming - String
 
C string
C stringC string
C string
 
Strinng Classes in c++
Strinng Classes in c++Strinng Classes in c++
Strinng Classes in c++
 
C++ string
C++ stringC++ string
C++ string
 
05 c++-strings
05 c++-strings05 c++-strings
05 c++-strings
 
String in programming language in c or c++
 String in programming language  in c or c++  String in programming language  in c or c++
String in programming language in c or c++
 

Similar to C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić

Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Palak Sanghani
 
Type header file in c++ and its function
Type header file in c++ and its functionType header file in c++ and its function
Type header file in c++ and its functionFrankie Jones
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name ResolutionEelco Visser
 
The TclQuadcode Compiler
The TclQuadcode CompilerThe TclQuadcode Compiler
The TclQuadcode CompilerDonal Fellows
 
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)Ivan Čukić
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streamsjessitron
 
Reducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisReducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisSebastiano Panichella
 
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | PrometheusCreating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | PrometheusInfluxData
 
Automatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSELAutomatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSELJoel Falcou
 
Linq and lambda
Linq and lambdaLinq and lambda
Linq and lambdaJohn Walsh
 
C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8Christian Nagel
 
Visula C# Programming Lecture 6
Visula C# Programming Lecture 6Visula C# Programming Lecture 6
Visula C# Programming Lecture 6Abou Bakr Ashraf
 
Constraint Programming in Haskell
Constraint Programming in HaskellConstraint Programming in Haskell
Constraint Programming in HaskellDavid Overton
 

Similar to C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić (20)

Chapter 4 - Classes in Java
Chapter 4 - Classes in JavaChapter 4 - Classes in Java
Chapter 4 - Classes in Java
 
Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]Lec 8 03_sept [compatibility mode]
Lec 8 03_sept [compatibility mode]
 
Type header file in c++ and its function
Type header file in c++ and its functionType header file in c++ and its function
Type header file in c++ and its function
 
PYTHON
PYTHONPYTHON
PYTHON
 
Declare Your Language: Name Resolution
Declare Your Language: Name ResolutionDeclare Your Language: Name Resolution
Declare Your Language: Name Resolution
 
The TclQuadcode Compiler
The TclQuadcode CompilerThe TclQuadcode Compiler
The TclQuadcode Compiler
 
Csp scala wixmeetup2016
Csp scala wixmeetup2016Csp scala wixmeetup2016
Csp scala wixmeetup2016
 
8 - OOP - Syntax & Messages
8 - OOP - Syntax & Messages8 - OOP - Syntax & Messages
8 - OOP - Syntax & Messages
 
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)Reactive Qt - Ivan Čukić (Qt World Summit 2015)
Reactive Qt - Ivan Čukić (Qt World Summit 2015)
 
Charles Sharp: Java 8 Streams
Charles Sharp: Java 8 StreamsCharles Sharp: Java 8 Streams
Charles Sharp: Java 8 Streams
 
Reducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisReducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code Analysis
 
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | PrometheusCreating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
Creating the PromQL Transpiler for Flux by Julius Volz, Co-Founder | Prometheus
 
python1.ppt
python1.pptpython1.ppt
python1.ppt
 
Python ppt
Python pptPython ppt
Python ppt
 
Automatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSELAutomatic Task-based Code Generation for High Performance DSEL
Automatic Task-based Code Generation for High Performance DSEL
 
Intro toswift1
Intro toswift1Intro toswift1
Intro toswift1
 
Linq and lambda
Linq and lambdaLinq and lambda
Linq and lambda
 
C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8C# 7.x What's new and what's coming with C# 8
C# 7.x What's new and what's coming with C# 8
 
Visula C# Programming Lecture 6
Visula C# Programming Lecture 6Visula C# Programming Lecture 6
Visula C# Programming Lecture 6
 
Constraint Programming in Haskell
Constraint Programming in HaskellConstraint Programming in Haskell
Constraint Programming in Haskell
 

More from corehard_by

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...corehard_by
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...corehard_by
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотниковcorehard_by
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титовcorehard_by
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...corehard_by
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...corehard_by
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...corehard_by
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...corehard_by
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...corehard_by
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...corehard_by
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...corehard_by
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филоновcorehard_by
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakovacorehard_by
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...corehard_by
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019corehard_by
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019corehard_by
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019corehard_by
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019corehard_by
 

More from corehard_by (20)

C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
C++ CoreHard Autumn 2018. Создание пакетов для открытых библиотек через conan...
 
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
C++ CoreHard Autumn 2018. Что должен знать каждый C++ программист или Как про...
 
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений ОхотниковC++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
C++ CoreHard Autumn 2018. Actors vs CSP vs Tasks vs ... - Евгений Охотников
 
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр ТитовC++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
C++ CoreHard Autumn 2018. Знай свое "железо": иерархия памяти - Александр Титов
 
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
C++ CoreHard Autumn 2018. Ускорение сборки C++ проектов, способы и последстви...
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
C++ CoreHard Autumn 2018. Кодогенерация C++ кроссплатформенно. Продолжение - ...
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
C++ CoreHard Autumn 2018. Обработка списков на C++ в функциональном стиле - В...
 
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел ФилоновC++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
C++ Corehard Autumn 2018. Обучаем на Python, применяем на C++ - Павел Филонов
 
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia KazakovaC++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
C++ CoreHard Autumn 2018. Debug C++ Without Running - Anastasia Kazakova
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
C++ CoreHard Autumn 2018. Text Formatting For a Future Range-Based Standard L...
 
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
Исключительная модель памяти. Алексей Ткаченко ➠ CoreHard Autumn 2019
 
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019Как помочь и как помешать компилятору. Андрей Олейников ➠  CoreHard Autumn 2019
Как помочь и как помешать компилятору. Андрей Олейников ➠ CoreHard Autumn 2019
 
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019Автоматизируй это. Кирилл Тихонов ➠  CoreHard Autumn 2019
Автоматизируй это. Кирилл Тихонов ➠ CoreHard Autumn 2019
 
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019Статичный SQL в С++14. Евгений Захаров ➠  CoreHard Autumn 2019
Статичный SQL в С++14. Евгений Захаров ➠ CoreHard Autumn 2019
 

Recently uploaded

From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your QueriesExploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your QueriesSanjay Willie
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Recently uploaded (20)

From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your QueriesExploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
Exploring ChatGPT Prompt Hacks To Maximally Optimise Your Queries
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

C++ CoreHard Autumn 2018. Asynchronous programming with ranges - Ivan Čukić

  • 1. Async. programming with ranges Corehard Autumn 2018 dr Ivan Čukić ivan@cukic.co core-dev @ KDE http://cukic.co www.kde.org
  • 2. Iterators Ranges Push Pipes Going postal About me KDE development Talks and teaching Author of ”Functional Programming in C++” (Manning) Functional programming enthusiast, but not a purist 2
  • 3. Iterators Ranges Push Pipes Going postal Disclaimer Make your code readable. Pretend the next person who looks at your code is a psychopath and they know where you live. Philip Wadler 3
  • 5. Iterators Ranges Push Pipes Going postal Iterators At the core of generic programming in STL. 5
  • 6. Iterators Ranges Push Pipes Going postal Iterators std::vector<std::string> identifiers; std::copy_if( std::cbegin(tokens), std::cend(tokens), std::back_inserter(identifiers), is_valid_identifier); 6
  • 7. Iterators Ranges Push Pipes Going postal Iterators std::vector<std::string> identifiers; std::copy_if( std::istream_iterator<std::string>(std::cin), std::istream_iterator<std::string>(), std::back_inserter(identifiers), is_valid_identifier); 7
  • 8. Iterators Ranges Push Pipes Going postal Example 8
  • 9. Iterators Ranges Push Pipes Going postal Example 8
  • 10. Iterators Ranges Push Pipes Going postal Example 8
  • 11. Iterators Ranges Push Pipes Going postal Example 8
  • 12. Iterators Ranges Push Pipes Going postal Example template <typename It, typename Pred> std::pair<It, It> move_selected( It begin, It end, It destination, Pred is_selected) { return { std::stable_partition(begin, destination, std::not_fn(is_selected)), std::stable_partition(destination, end, is_selected) }; } 9
  • 14. Iterators Ranges Push Pipes Going postal Problems with iterators Example: Sum of squares This should be separable into two subtasks: squaring the values summation 11
  • 15. Iterators Ranges Push Pipes Going postal Problems with iterators std::vector<int> xs { ⋯ }; std::vector<int> squared(xs.size()); std::transform(std::cbegin(xs), std::cend(xs), std::begin(squared), [] (int x) { return x * x; }); return std::accumulate(std::cbegin(squared), std::cend(squared), 0); 12
  • 16. Iterators Ranges Push Pipes Going postal Problems with iterators std::vector<int> xs { ⋯ }; return std::transform_reduce(par, std::cbegin(xs), std::cend(xs), std::cbegin(xs), 0); 13
  • 17. Iterators Ranges Push Pipes Going postal Proxy iterators template <typename Trafo, typename It> class transform_proxy_iterator { public: auto operator*() const { return transformation( *real_iterator); } private: Trafo transformation; It real_iterator; }; 14
  • 18. Iterators Ranges Push Pipes Going postal Ranges [ iterator, sentinel ) Iterator: *i – access the value ++i – move to the next element Sentinel: i == s – has iterator reached the end? 15
  • 19. Iterators Ranges Push Pipes Going postal Ranges std::vector<int> xs { ⋯ }; accumulate( transform( xs, [] (int x) { ⋯ }), 0); 16
  • 20. Iterators Ranges Push Pipes Going postal Ranges std::vector<int> xs { ⋯ }; accumulate( transform( filter( xs, [] (int x) { ⋯ }), [] (int x) { ⋯ }), 0); 17
  • 21. Iterators Ranges Push Pipes Going postal Ranges std::vector<int> xs { ⋯ }; accumulate( xs | filter([] (int x) { ⋯ }) | transform([] (int x) { ⋯ }), 0); 18
  • 22. Iterators Ranges Push Pipes Going postal Word frequency 1986: Donald Knuth was asked to implement a program for the ”Programming pearls” column in the Communications of ACM journal. The task: Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies. 19
  • 23. Iterators Ranges Push Pipes Going postal Word frequency 1986: Donald Knuth was asked to implement a program for the ”Programming pearls” column in the Communications of ACM journal. The task: Read a file of text, determine the n most frequently used words, and print out a sorted list of those words along with their frequencies. His solution written in Pascal was 10 pages long. 19
  • 24. Iterators Ranges Push Pipes Going postal Word frequency Response by Doug McIlroy was a 6-line shell script that did the same: tr −cs A−Za−z ' n ' | tr A−Z a−z | sort | uniq −c | sort −rn | sed ${1}q 20
  • 25. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 21
  • 26. Iterators Ranges Push Pipes Going postal With ranges const auto words = // Range of words istream_range<std::string>(std::cin) // Cleaning the input | view::transform(string_to_lower) | view::transform(string_only_alnum) | view::remove_if(&std::string::empty) // Sort the result | to_vector | action::sort; 22
  • 27. Iterators Ranges Push Pipes Going postal With ranges const auto results = words // Group repeated words | view::group_by(std::equal_to<>()) // Count how many repetitions we have | view::transform([] (const auto &group) { return std::make_pair( distance(begin(group), end(group), *begin(group)); }) // Sort by frequency | to_vector | action::sort; 23
  • 28. Iterators Ranges Push Pipes Going postal With ranges for (auto value: results | view::reverse // descending | view::take(n) // we need first n results ) { std::cout << value.first << ” ” << value.second << std::endl; } 24
  • 29. PUSH
  • 30. Iterators Ranges Push Pipes Going postal Ranges [ iterator, sentinel ) Iterator: *i – access the value ++i – move to the next element Sentinel: i == s – has iterator reached the end 26
  • 31. Iterators Ranges Push Pipes Going postal Ranges [ iterator, sentinel ) Iterator: *i – access the value BLOCKING! ++i – move to the next element Sentinel: i == s – has iterator reached the end 26
  • 32. Iterators Ranges Push Pipes Going postal Push iterators Input Iterator Output 27
  • 33. Iterators Ranges Push Pipes Going postal Push iterators Each push iterator can: Accept values Emit values No need for the accepted and emitted values to be 1-to-1. 28
  • 34. Iterators Ranges Push Pipes Going postal Push iterators Sources – push iterators that only emit values Sinks – push iterators that only accept values Modifiers – push iterators that both accept and emit values 29
  • 35. Iterators Ranges Push Pipes Going postal Continuation template <typename Cont> class continuator_base { public: void init() { ⋯ } template <typename T> void emit(T&& value) const { std::invoke(m_continuation, FWD(value)); } void notify_ended() const { ⋯ } protected: Cont m_continuation; }; 30
  • 36. Iterators Ranges Push Pipes Going postal Invoke std::invoke(function, arg1, arg2, ...) For most cases (functions, function objects, lambdas) equivalent to: function(arg1, arg2, ...) But it can also invoke class member functions: arg1.function(arg2, ...) 31
  • 37. Iterators Ranges Push Pipes Going postal Source template <typename Cont> class values_node: public continuator_base<Cont>, non_copyable { ⋯ void init() { base::init(); for (auto&& value: m_values) { base::emit(value); } m_values.clear(); base::notify_ended(); } ⋯ }; 32
  • 38. Iterators Ranges Push Pipes Going postal Source 33
  • 39. Iterators Ranges Push Pipes Going postal Creating a source As far as the rest of the system is concerned, this node creates the messages. 34
  • 40. Iterators Ranges Push Pipes Going postal Creating a sink 35
  • 41. Iterators Ranges Push Pipes Going postal Creating a transformation 36
  • 42. Iterators Ranges Push Pipes Going postal Creating a transformation template <typename Cont> class transform_node: public continuator_base<Cont>, non_copyable { public: ⋯ template <typename T> void operator() (T&& value) const { base::emit(std::invoke(m_transformation, FWD(value))); } private: Traf m_transformation; }; 37
  • 43. Iterators Ranges Push Pipes Going postal Filtering template <typename Cont> class filter_node: public continuator_base<Cont>, non_copyable { public: ⋯ template <typename T> void operator() (T&& value) const { if (std::invoke(m_predicate, value) { base::emit(FWD(value))); } } private: Predicate m_predicate; }; 38
  • 44. PIPES
  • 45. Iterators Ranges Push Pipes Going postal Connecting the components auto pipeline = source | transform(⋯) | filter(⋯) | join | transform(⋯) ⋯ 40
  • 46. Iterators Ranges Push Pipes Going postal AST When the pipeline AST is completed and evaluated, then we get proper pipeline nodes. 41
  • 47. Iterators Ranges Push Pipes Going postal Associativity auto my_transformation = filter(⋯) | join; auto pipeline = source | transform(⋯) | my_transformation  | transform(⋯) ⋯ 42
  • 48. Iterators Ranges Push Pipes Going postal Different pipes Composing two transformations transform(⋯) | filter(⋯) Connecting a source to the continuation source | transform(⋯) Ending the pipeline filter(⋯) | sink Closing the pipeline source | sink 43
  • 49. Iterators Ranges Push Pipes Going postal Different pipes struct source_node_tag {}; struct sink_node_tag {}; struct transformation_node_tag {}; template <typename T> class values { public: using node_category = source_node_tag; }; 44
  • 50. Iterators Ranges Push Pipes Going postal Different pipes struct source_node_tag {}; struct sink_node_tag {}; struct transformation_node_tag {}; template <typename T> class filter { public: using node_category = transformation_node_tag; }; 45
  • 51. Iterators Ranges Push Pipes Going postal Concepts template <typename Left, typename Right> auto operator| (Left&& left, Right&& right) { return ⋯; } Problem: Defines operator| on all types 46
  • 52. Iterators Ranges Push Pipes Going postal Concepts template < typename Node , typename Category = detected_t<node_category, Node> > f_concept is_node() { if constexpr (!is_detected_v<node_category, Node>) { return false; } else if constexpr (std::is_same_v<void, Category>) { return false; } else { return true; } } Note: Proper concepts will come in C++20. This uses the detection idiom to simulate concepts. 47
  • 53. Iterators Ranges Push Pipes Going postal Concepts template < typename Left , typename Right , f_require( is_node<Left> && is_node<Right> ) > auto operator| (Left&& left, Right&& right) { return ⋯; } 48
  • 54. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ create a composite transformation } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ } else { ⋯ } 49
  • 55. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ transformed source is also a source } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ } else { ⋯ } 49
  • 56. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ transformation with a sink is a sink } else { ⋯ } 49
  • 57. Iterators Ranges Push Pipes Going postal Concepts if constexpr (!is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (is_source<Left> && !is_sink<Right>) { ⋯ } else if constexpr (!is_source<Left> && is_sink<Right>) { ⋯ } else { ⋯ the pipeline is complete, evaluate it } 49
  • 58. Iterators Ranges Push Pipes Going postal Pipes auto new_source = source | transform(⋯) | filter(⋯); auto new_trafo = transform(⋯) | filter(⋯); auto new_sink = filter(⋯) | sink; auto pipeline = new_source | new_trafo | new_sink; 50
  • 59. Iterators Ranges Push Pipes Going postal Pipes Easy implementation of reactive systems Transparent handling of synchronous vs asynchronous transformations High-enough abstraction for more powerful idioms 51
  • 61. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 53
  • 62. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 53
  • 63. Iterators Ranges Push Pipes Going postal Functional thinking – data transformation 53
  • 64. Iterators Ranges Push Pipes Going postal Distributed pipelines auto pipeline = system_cmd(”ping”s, ”localhost”s) | transform(string_to_upper) // Parse the ping output | transform([] (std::string&& value) { const auto pos = value.find_last_of('='); return std::make_pair(std::move(value), pos); }) // Extract the ping time from the output | transform([] (std::pair<std::string, size_t>&& pair) { auto [ value, pos ] = pair; return pos == std::string::npos ? std::move(value) : std::string(value.cbegin() + pos + 1, value.cend()); }) // Remove slow pings | filter([] (const std::string& value) { return value < ”0.145”s; }) // Print out the ping info | sink{cout}; 54
  • 65. Iterators Ranges Push Pipes Going postal Distributed pipelines auto pipeline = system_cmd(”ping”s, ”localhost”s) | transform(string_to_upper) | voy_bridge(frontend_to_backend_1) | transform([] (std::string&& value) { const auto pos = value.find_last_of('='); return std::make_pair(std::move(value), pos); }) | transform([] (std::pair<std::string, size_t>&& pair) { auto [ value, pos ] = pair; return pos == std::string::npos ? std::move(value) : std::string(value.cbegin() + pos + 1, value.cend()); }) | voy_bridge(backend_1_to_backend_2) | filter([] (const std::string& value) { return value < ”0.145”s; }) | voy_bridge(backend_2_to_frontend) | sink{cout}; 55
  • 66. Iterators Ranges Push Pipes Going postal Live demo 56
  • 67. Iterators Ranges Push Pipes Going postal Answers? Questions! Questions? Answers! Kudos (in chronological order): Friends at KDE Saša Malkov and Zoltán Porkoláb спасибо Сергею и двум Антонам MEAP – Manning Early Access Program Functional Programming in C++ cukic.co/to/fp-in-cpp 57