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 iterators
- from: constructs a range from an STL-like container that provides begin() and end() methods (representing the first and past-the-end elements). This is basically a wrapper on from_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 times
auto result = repeat("cpplinq", 10); // creates a range with 10 strings with the value "cpplinq" - empty: returns an empty range of a given type
auto 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 a std::vector<TValue> from a range, where TValue 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 a std::list<TValue> from a range, where TValue is the type of the elements of the range.
auto result = range(1, 10) >> to_list();
- to_map: creates a std::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 a cpplinq::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"}










no comment untill now