Click here to Skip to main content
15,867,704 members
Articles / Programming Languages / C++

cpplinq: Range Generators and Conversion Operators

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
23 Nov 2012CPOL2 min read 8.4K   2   1
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 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.
    C++
    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:

    C++
    auto result = from_iterators(numbers.begin(), numbers.end());
  • from_array: constructs a range from an array.
    C++
    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:

    C++
    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.
    C++
    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
    C++
    auto result = repeat("cpplinq", 10); // creates a range with 10 strings with the value "cpplinq"
  • empty: returns an empty range of a given type
    C++
    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.
    C++
    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.
    C++
    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.
    C++
    // 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.
    C++
    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"}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Visma Software
Romania Romania
Marius Bancila is the author of Modern C++ Programming Cookbook and The Modern C++ Challenge. He has been a Microsoft MVP since 2006, initially for VC++ and nowadays for Development technologies. He works as a system architect for Visma, a Norwegian-based company. He works with various technologies, both managed and unmanaged, for desktop, cloud, and mobile, mainly developing with VC++ and VC#. He keeps a blog at http://www.mariusbancila.ro/blog, focused on Windows programming. You can follow Marius on Twitter at @mariusbancila.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Member 999537726-Jul-13 7:13
Member 999537726-Jul-13 7:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.