cpplinq: Range Generators and Conversion Operators





5.00/5 (1 vote)
In this post, I will discuss range generators and range conversion operators.
In my previous post, I introduced cpplinq, a C++ template library that provides .NET-like query operators for sequences of objects in C++11. In this second installment, I will discuss about two things: range generators and range conversion operators. These two sets of operators are ubiquitous in queries.
Range Generators
A range generator builds an object that represents the range on which query operators are applied. The library provides several such generators:
from_iterators
: constructs a range from a pair of iteratorsfrom
: constructs a range from an STL-like container that providesbegin()
andend()
methods (representing the first and past-the-end elements). This is basically a wrapper onfrom_iterators
operator.std::vector<int> numbers; numbers.push_back(1); numbers.push_back(2); numbers.push_back(3); numbers.push_back(4); numbers.push_back(5); auto result = from(numbers); result >> for_each([](int i) {std::cout << i << std::endl;});
This is similar to:
auto result = from_iterators(numbers.begin(), numbers.end());
from_array
: constructs a range from an array.int numbers[] = {1,2,3,4,5}; auto result = from_array(numbers); result >> for_each([](int i) {std::cout << i << std::endl;});
This is similar to:
auto result = from_iterators(arrnumbers, arrnumbers + 5);
In addition to the "from
" operators, the library also provides several .NET like range generators:
range
: generates a range of integral, consecutive numbers, starting with an initial seed and having a specified number of elements.auto result = range(10, 90); // creates a range of numbers in the interval [10, 100)
repeat
: generates a range by repeating a value a given number of timesauto result = repeat("cpplinq", 10); // creates a range with 10 strings with the value "cpplinq"
empty
: returns an empty range of a given typeauto result = empty<customer>(); // creates an empty range of customers
Range Conversion Operators
A conversion operator folds a range into a container that holds the values of the range. There are several such conversion operators that the library provides.
to_vector
: creates astd::vector<TValue>
from a range, whereTValue
is the type of the elements of the range.auto result = range(1, 10) >> to_vector(); std::list<int> numbers; auto result = from(numbers) >> to_vector(); // transforms a list into a vector
to_list
: creates astd::list<TValue>
from a range, whereTValue
is the type of the elements of the range.auto result = range(1, 10) >> to_list();
to_map
: creates astd::map<TKey, TValue>
from a range. It takes a predicate that selects the value to use as the key for each element of the range. It implements a one-to-one dictionary that maps keys to single values.// creates a map where key is the customer ID, and the value is the customer object auto result = from_array (customers) >> to_map ([](customer const & c){return c.id;});
to_lookup
: creates acpplinq::lookup<TKey, TElement>
from a sequence. It implements a one-to-many dictionary that maps keys to sequences of values.customer_address customer_addresses[] = { customer_address (2, 4, "Finland" ), customer_address (3, 4, "USA" ), customer_address (1, 1, "USA" ), }; auto lookup = from_array (customer_addresses) >> to_lookup ([] (customer_address const & ca){return ca.customer_id;}); auto countries = lookup[4] >> select([](customer_address const & ca) {return ca.country;}) >> to_vector(); // yields {"Finland", "USA"}