Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
josuttis_nm_c20_the_complete_guide.pdf
Скачиваний:
48
Добавлен:
27.03.2023
Размер:
5.85 Mб
Скачать

192

Chapter 7: Utilities for Ranges and Views

7.6Range Algorithms

With the support to pass ranges as one argument and be able to process sentinels (end iterators) with a different type, new ways of calling algorithms are now available in C++20.

However, they come with some restrictions and not all algorithms support passing ranges as a whole yet.

7.6.1 Benefits and Restrictions for Range Algorithms

For some algorithms, there are no range versions that allow programmers to pass ranges as a single argument yet:

Range algorithms do not support parallel execution (introduced with C++17). There are no APIs that take range parameters as single objects and an execution policy.

There are no numeric algorithms for single-object ranges yet. To call algorithms like std::accumulate(), you still have to pass both the begin and the end of the range. C++23 will probably provide numeric range algorithms.

If there is range support for algorithms, they use concepts to find possible errors at compile time:

Concepts for iterators and ranges ensure that you pass valid iterators and ranges.

Concepts for callables ensure that you pass valid helper functions.

In addition, return types may differ because:

They support and might return iterators of different types, for which special return types are defined. These types are listed in table New return types for range algorithms.

They might return borrowed iterators, signaling that the iterator is no valid iterator because a temporary range (rvalue) was passed.

Type

Meaning

Members

std::ranges::in_in_result

For the positions of two input ranges

in1, in2

std::ranges::in_out_result

For one position of an input range and

in, out

 

one position of an output range

 

std::ranges::in_in_out_result

For the positions of two input ranges

in1, in2, out

 

and one position of an output range

 

std::ranges::in_out_out_result

For one position of an input range and

in, out1, out2

 

the position of two output ranges

 

std::ranges::in_fun_result

For one position of an input range and

in, out

 

a function

 

std::ranges::min_max_result

For one maximum and one minimum

min, max

 

position/value

 

std::ranges::in_found_result

For one position of an input range and

in, found

 

a Boolean value

 

Table 7.11. New return types for range algorithms

7.6 Range Algorithms

193

The following program demonstrates how to use these return types:

ranges/results.cpp

#include <iostream> #include <string_view> #include <vector> #include <algorithm>

void print(std::string_view msg, auto beg, auto end)

{

std::cout << msg;

for(auto pos = beg; pos != end; ++pos) { std::cout << ' ' << *pos;

}

std::cout << '\n';

}

int main()

{

std::vector inColl{1, 2, 3, 4, 5, 6, 7}; std::vector outColl{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

auto result = std::ranges::transform(inColl, outColl.begin(), [] (auto val) {

return val*val; });

print("processed in:",

inColl.begin(), result.in);

print("rest of in: ",

result.in, inColl.end());

print("written out: ",

outColl.begin(), result.out);

print("rest of out: ",

result.out, outColl.end());

 

 

}

 

 

The program has the following output:

processed in: 1 2 3 4 5 6 7 rest of in:

written out: 1 4 9 16 25 36 49 rest of out: 8 9 10

7.6.2Algorithm Overview

The situation of all algorithms becomes more and more complex. Some of them can be used in parallel, some not. Some of them are supported by the ranges library, some not. This section gives an overview of which algorithms are available in which form (without going into detail about what each algorithm does).

194

Chapter 7: Utilities for Ranges and Views

The last three columns have the following meaning:

Ranges signals whether the algorithm is supported by the range library

_result signals whether and which _result types are used (e.g., in_out stands for in_out_result)

Borrowed signals whether the algorithm returns borrowed iterators

Table Non-modifying algorithms lists the available non-modifying standard algorithms of C++20.

Name

Since

Parallel

Ranges

_result

Borrowed

for_each()

C++98

yes

yes

in_fun

yes

for_each_n()

C++17

yes

yes

in_fun

 

count()

C++98

yes

yes

 

 

count_if()

C++98

yes

yes

 

 

min_element()

C++98

yes

yes

yes

 

max_element()

C++98

yes

yes

yes

 

minmax_element()

C++11

yes

yes

min_max

yes

min()

C++20

no

yes (only)

 

 

max()

C++20

no

yes (only)

 

 

minmax()

C++20

no

yes (only)

min_max

 

find()

C++98

yes

yes

 

yes

find_if()

C++98

yes

yes

 

yes

find_if_not()

C++11

yes

yes

 

yes

search()

C++98

yes

yes

 

yes

search_n()

C++98

yes

yes

 

yes

find_end()

C++98

yes

yes

 

yes

find_first_of()

C++98

yes

yes

 

yes

adjacent_find()

C++98

yes

yes

 

yes

equal()

C++98

yes

yes

 

 

is_permutation()

C++11

no

yes

 

 

mismatch()

C++98

yes

yes

in_in

yes

lexicographical_compare()

C++98

yes

yes

 

 

lexicographical_compare_three_way()

C++20

no

no

 

 

is_sorted()

C++11

yes

yes

 

 

is_sorted_until()

C++11

yes

yes

 

yes

is_partitioned()

C++11

yes

yes

 

 

partition_point()

C++11

no

yes

 

 

is_heap()

C++11

yes

yes

 

 

is_heap_until()

C++11

yes

yes

 

yes

all_of()

C++11

yes

yes

 

 

any_of()

C++11

yes

yes

 

 

none_of()

C++11

yes

yes

 

 

Table 7.12. Non-modifying algorithms

7.6 Range Algorithms

195

Note that the algorithms std::ranges::min(), std::ranges::max(), and std::ranges::minmax() have only counterparts in std that take two values or a std::initializer_list<>.

Table Modifying algorithms lists the available modifying standard algorithms in C++20.

Name

Since

Parallel

Ranges

_result

Borrowed

for_each()

C++98

yes

yes

in_fun

yes

for_each_n()

C++17

yes

yes

in_fun

 

copy()

C++98

yes

yes

in_out

yes

copy_if()

C++98

yes

yes

in_out

 

copy_n()

C++11

yes

yes

in_out

yes

copy_backward()

C++11

no

yes

in_out

yes

move()

C++11

yes

yes

in_out

yes

move_backward()

C++11

no

yes

in_out

yes

transform() for one range

C++98

yes

yes

in_out

yes

transform() for two ranges

C++98

yes

yes

in_in_out

yes

merge()

C++98

yes

yes

 

 

swap_ranges()

C++98

yes

yes

in_in

yes

fill()

C++98

yes

yes

 

yes

fill_n()

C++98

yes

yes

 

 

generate()

C++98

yes

yes

 

yes

generate_n()

C++98

yes

yes

 

 

iota()

C++11

no

no

 

 

replace()

C++98

yes

yes

 

yes

replace_if()

C++98

yes

yes

 

yes

replace_copy()

C++98

yes

yes

in_out

yes

replace_copy_if()

C++98

yes

yes

in_out

yes

Table 7.13. Modifying algorithms

Table Removing algorithms lists the available “removing” standard algorithms in C++20. Note that algorithms never really remove elements. This still applies when they take whole ranges as single arguments. They change the order so that the elements not removed are packed to the front and return the new end.

Name

Since

Parallel

Ranges

_result

Borrowed

remove()

C++98

yes

yes

 

yes

remove_if()

C++98

yes

yes

 

yes

remove_copy()

C++98

yes

yes

in_out

yes

remove_copy_if()

C++98

yes

yes

in_out

yes

unique()

C++98

yes

yes

 

yes

unique_copy()

C++98

yes

yes

in_out

yes

Table 7.14. Removing algorithms

196

 

 

 

Chapter 7: Utilities for Ranges and Views

Table Mutating algorithms lists the available mutating standard algorithms in C++20.

 

 

 

 

 

 

 

 

 

Name

Since

Parallel

Ranges

_result

Borrowed

 

reverse()

C++98

yes

yes

 

yes

 

 

reverse_copy()

C++98

yes

yes

in_out

yes

 

rotate()

C++98

yes

yes

 

yes

 

rotate_copy()

C++98

yes

yes

in_out

yes

 

shift_left()

C++20

yes

no

 

 

 

 

shift_right()

C++20

yes

no

 

 

 

 

sample()

C++17

no

yes

 

 

 

 

next_permutation()

C++98

no

yes

in_found

yes

 

prev_permutation()

C++98

no

yes

in_found

yes

 

shuffle()

C++11

no

yes

 

yes

 

random_shuffle()

C++98

no

no

 

 

 

 

partition()

C++98

yes

yes

 

 

 

 

stable_partition()

C++98

yes

yes

 

 

 

 

partition_copy()

C++11

yes

yes

 

 

 

Table 7.15. Mutating algorithms

Table Sorting algorithms lists the available sorting standard algorithms in C++20.

Name

Since

Parallel

Ranges

_result

Borrowed

sort()

C++98

yes

yes

 

yes

stable_sort()

C++98

yes

yes

 

yes

partial_sort()

C++98

yes

yes

 

yes

partial_sort_copy()

C++98

yes

yes

in_out

yes

nth_element()

C++98

yes

yes

 

yes

partition()

C++98

yes

yes

 

yes

stable_partition()

C++98

yes

yes

 

yes

partition_copy()

C++11

yes

yes

in_out_out

yes

make_heap()

C++98

no

yes

 

yes

push_heap()

C++98

no

yes

 

yes

pop_heap()

C++98

no

yes

 

yes

sort_heap()

C++98

no

yes

 

yes

Table 7.16. Sorting algorithms

7.6 Range Algorithms

197

Table Algorithms for sorted ranges lists the available standard algorithms for sorted ranges in C++20.

Name

Since

Parallel

Ranges

_result

Borrowed

binary_search()

C++98

no

yes

 

 

includes()

C++98

yes

yes

 

 

lower_bound()

C++98

no

yes

 

yes

upper_bound()

C++98

no

yes

 

yes

equal_range()

C++98

no

yes

 

yes

merge()

C++98

yes

yes

in_in_out

yes

inplace_merge()

C++98

yes

yes

 

yes

set_union()

C++98

yes

yes

in_in_out

yes

set_intersection()

C++98

yes

yes

in_in_out

yes

set_difference()

C++98

yes

yes

in_out

yes

set_symmetric_difference()

C++98

yes

yes

in_in_out

yes

partition_point()

C++11

no

yes

 

yes

 

 

 

 

 

 

Table 7.17. Algorithms for sorted ranges

Table Numeric algorithms lists the available numeric standard algorithms in C++20.

Name

Since

Parallel

Ranges _result Borrowed

accumulate()

C++98

no

no

reduce()

C++17

yes

no

transform_reduce()

C++17

yes

no

inner_product()

C++98

no

no

adjacent_difference()

C++98

no

no

partial_sum()

C++98

no

no

inclusive_scan()

C++17

yes

no

exclusive_scan()

C++17

yes

no

transform_inclusive_scan()

C++17

yes

no

transform_exclusive_scan()

C++17

yes

no

iota()

C++11

no

no

 

 

 

 

Table 7.18. Numeric algorithms

198

This page is intentionally left blank