|
| 1 | +\subsection[range]{Ranges} |
| 2 | + |
| 3 | +\begin{frame}[fragile] |
| 4 | + \frametitlecpp[20]{Ranges} |
| 5 | + \begin{block}{The range concept} |
| 6 | + \begin{itemize} |
| 7 | + \item A range is a group of items that you can iterate over |
| 8 | + \item It must provide iterators to its beginning and end, obtainable via \mintinline{cpp}{std::range::begin} and \mintinline{cpp}{std::range::end} |
| 9 | + \item Range concepts are located in \mintinline{cpp}{std::ranges} namespace |
| 10 | + \item All STL containers are ranges |
| 11 | + \end{itemize} |
| 12 | + \end{block} |
| 13 | + \begin{exampleblock}{Variations on ranges} |
| 14 | + There are actually different type of ranges |
| 15 | + \begin{itemize} |
| 16 | + \item \mintinline{cpp}{input_range}, \mintinline{cpp}{output_range}, \mintinline{cpp}{forward_range}, \mintinline{cpp}{bidirectional_range}, \mintinline{cpp}{random_access_range}, \mintinline{cpp}{contiguous_range} |
| 17 | + \item corresponding to the different iterator categories |
| 18 | + \end{itemize} |
| 19 | + \end{exampleblock} |
| 20 | +\end{frame} |
| 21 | + |
| 22 | +\begin{frame}[fragile] |
| 23 | + \frametitlecpp[20]{Views} |
| 24 | + \begin{block}{The view concept} |
| 25 | + \begin{itemize} |
| 26 | + \item A \mintinline{cpp}{view} is a non-owning object built from a range or another view after applying some range adaptor(s) |
| 27 | + \item The time complexity to copy, move, assign is constant |
| 28 | + \item Range adaptors can be applied/changed with \mintinline{cpp}{|} and are lazy |
| 29 | + \item They live in the \mintinline{cpp}{std::views} namespace |
| 30 | + \item They introduce easy functional programming to the STL |
| 31 | + \end{itemize} |
| 32 | + \end{block} |
| 33 | + \begin{exampleblock}{Example} |
| 34 | + { \scriptsize |
| 35 | + \begin{cppcode*}{gobble=4} |
| 36 | + auto const numbers = std::views::iota(0, 6); |
| 37 | + auto even = [](int i) { return 0 == i % 2; }; |
| 38 | + auto square = [](int i) { return i * i; }; |
| 39 | + auto results = numbers | std::views::filter(even) |
| 40 | + | std::views::transform(square); |
| 41 | + for (auto a : results) { ... } // 0, 4, 16 |
| 42 | + \end{cppcode*} |
| 43 | + } |
| 44 | + \end{exampleblock} |
| 45 | +\end{frame} |
| 46 | + |
| 47 | +\begin{frame}[fragile] |
| 48 | + \frametitlecpp[20]{Many range adaptors are provided by the STL} |
| 49 | + \begin{block}{Useful subset} |
| 50 | + \begin{description}[keys/values] |
| 51 | + \item[all] a view on all elements |
| 52 | + \item[filter] applies a filter |
| 53 | + \item[transform] applies a transformation |
| 54 | + \item[take] takes only first n elements |
| 55 | + \item[drop] skips first n elements |
| 56 | + \item[join/split] joins ranges or splits into subranges |
| 57 | + \item[reverse] reverses view order |
| 58 | + \item[elements] for tuple views, extract nth elements of each tuple |
| 59 | + \item[keys/values] for pair like views, takes 1st/2nd element of each pair |
| 60 | + \end{description} |
| 61 | + \end{block} |
| 62 | + Remember you can combine them via (\mintinline{cpp}{|}) |
| 63 | +\end{frame} |
| 64 | + |
| 65 | +\begin{frame}[fragile] |
| 66 | + \frametitlecpp[23]{Back to lazyness} |
| 67 | + \begin{exampleblock}{\texttt{view}s are lazy} |
| 68 | + \begin{itemize} |
| 69 | + \item Computation is only trigerred when iterating |
| 70 | + \item And can be stopped by e.g. \mintinline{cpp}{take} |
| 71 | + \item Here the mininal number of iteration is performed |
| 72 | + \end{itemize} |
| 73 | + { \scriptsize |
| 74 | + \begin{cppcode*}{gobble=2} |
| 75 | + // print first 20 prime numbers above 1000000 |
| 76 | + for (int i: std::views::iota(1000000) | std::views::filter(odd) |
| 77 | + | std::views::filter(isPrime) |
| 78 | + | std::views::take(20)) { |
| 79 | + std::cout << i << " "; |
| 80 | + } |
| 81 | + \end{cppcode*} |
| 82 | + } |
| 83 | + \end{exampleblock} |
| 84 | +\end{frame} |
0 commit comments