How it works...

C++ Ranges is a welcome addition to C++20 as it provides a simple means for working with any list of objects or values. To best explain how this works, let's look at the following example (note that, in these recipes, we will use Ranges v3 while we wait for GCC to support Ranges as v3 was the implementation adopted by C++20):

#include <iostream>
#include <range/v3/algorithm/count.hpp>

int main(void)
{
auto list = {4, 8, 15, 16, 23, 42};
std::cout << ranges::count(list, 42) << ' ';
}

As shown in the preceding code snippet, we have created a list of integers (in this specific case, we have created a simple initializer list). We then use the ranges::count() function to count the total number of times the value 42 shows up in the list, resulting in the following output:

Ranges can also be used for searching:

#include <iostream>
#include <range/v3/algorithm/find.hpp>

int main(void)
{
auto list = {4, 8, 15, 16, 23, 42};
if (auto i = ranges::find(list, 42); i != ranges::end(list)) {
std::cout << *i << ' ';
}
}

As shown in the preceding example, we have created the same initializer list of integers and we use ranges to return an iterator. This iterator can be used to traverse the list or get the located value. Initializer lists already support iterators, and one thing that Ranges does is extend this functionality to other types, including simple C-style arrays:

#include <iostream>
#include <range/v3/algorithm/find.hpp>

int main(void)
{
int list[] = {4, 8, 15, 16, 23, 42};
if (auto i = ranges::find(list, 42); i != ranges::end(list)) {
std::cout << *i << ' ';
}
}

The preceding example uses a C-style array instead of an initializer list and, as shown, Ranges provides an iterator to work with, in the C-style array, something currently not possible.

Ranges also provides some convenience algorithms. For example, consider the following code:

#include <iostream>
#include <range/v3/algorithm/for_each.hpp>

int main(void)
{
auto list = {4, 8, 15, 16, 23, 42};

ranges::for_each(list, [](const int &val){
std::cout << val << ' ';
});

std::cout << ' ';
}

In the preceding example, we have created a list of integers. We then loop over the entire range of integers and execute a lambda on this list. Although this could be done using traditional loops, such as the range-based loops added in C++11, for_each could simplify your logic (depending on your use case).

Ranges also provides the ability to transform one list into another. Consider the following example:

#include <iostream>
#include <range/v3/view/transform.hpp>

class my_type
{
int m_i;

public:
my_type(int i) :
m_i{i}
{ }

auto get() const
{
return m_i;
}
};

We will start this example by creating our own type. As shown in the preceding code snippet, we have a new type called my_type that is constructed with an integer and returns the integer using the get() function. We can then extend our previous examples to transform our list of integers into a list of our custom types, as follows:

int main(void)
{
using namespace ranges::views;

auto list1 = {4, 8, 15, 16, 23, 42};
auto list2 = list1 | transform([](int val){
return my_type(val);
});

for(const auto &elem : list2) {
std::cout << elem.get() << ' ';
}

std::cout << ' ';
}

As shown in the preceding example, we create our initial list of integers and then convert this list into a second list of our custom types using the ranges::views::transform function. We can then iterate over this new list using a traditional range-based for loop.

Finally, Ranges also provides some actions that let you actually modify an existing range. For example, consider the following code:

#include <vector>
#include <iostream>
#include <range/v3/action/sort.hpp>

int main(void)
{
using namespace ranges;

std::vector<int> list = {4, 42, 15, 8, 23, 16};
list |= actions::sort;

for(const auto &elem : list) {
std::cout << elem << ' ';
}

std::cout << ' ';
}

In the preceding example, we use the actions::sort function to sort our list of vectors, resulting in the following output:

As shown in the preceding example, C++20 Ranges provides us with a simple means to sort std::vector using the pipe operator instead of having to use std::sort, explicitly defining our begin and end iterators.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset