Click here to Skip to main content
Click here to Skip to main content

cpplinq: range generators and conversion operators

, 23 Nov 2012
Rate this:
Please Sign up or sign in to vote.
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 queri

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"}
    

License

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

About the Author

Marius Bancila
Software Developer (Senior) Visma Software
Romania Romania
Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for Visma, a Norwegian-based company. He is mainly focused on building desktop applications with VC++ and VC#. He keeps a blog at http://www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++ programmers.
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 5 PinmemberMember 999537726-Jul-13 7:13 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 23 Nov 2012
Article Copyright 2012 by Marius Bancila
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid