Advanced usages of CppLinq

One of the major reasons for building CppLinq is to allow developers writing their own range operators or range aggregators. While this is easy and straightforward in C# the lack of yield return and extension methods make it more of a challenge in C++ but since
CppLinq is based around operator>> it is possible.

Building a range aggregator

The purpose of range aggregators is to aggregate a range into a sum, vector, map or something else. In the functional world it would be known as fold.

Building a range operator

The purpose of range operator is to transmute a range into another range; ie the select range operator can transmute a range of ints into a range of strings, the where range operator can be used to transmute a range of ints to a range of ints containing only
even numbers. It turns out that a range operator is a range aggregator with the added requirements that the build method of the builder class returns a new range.

Has member type called value_type which is the type of value in the range

Has member type called return_type which is value_type const & or
value_type

Has an enum member returns_reference which is either 0 or 1 depending if
return_type is reference or not

Has a member method called front which returns the current value as a return_type

If called on a range where next has not be been called or the previous next returned false the behavior is undefined

front () previously was required to return a value type, this has been relaxed to allow references as well (if its correct to do so)

Has a member method called next which moves the range to the next value if available (returns
true) or returns false if no value is available

If called on a range where the previous next returned false next should do nothing and return false

A range where next never has been should be seen as "pointing" to no-value (as opposed to
begin () which "points" to the first value in a collection)

Has a member method called operator>> that accepts a range builder and returns the new range

This is the operator that chains the range expressions together

Note: There is no method to reset to range to the first position again. Once it's traversed the race is over. The rationale for that is that I like to support range sources that doesn't support resets. In practice for in-memory collections resets
are possible but as long as the range source supports normal copy-semantics resets are achievable using that.

Building a range source

The purpose of range sources is to take a concept of a collection of any kind such arrays, STL containers or generated collections and express it as cpplinq range in order to make it composable with cpplinq range operators and range aggregators.

A range source consists of two parts:

A range class which does the work

A helper method to help contruct an instance of the range class

The range class has the same implicit contract as above.

Let's look at the from_range in CppLinq ({from_range"} takes two iterators and make a range source from them):

Finally the helper method from needs to be provided, this helper method takes a STL container and creates range source.
from_range is also used to iterate over classic C arrays using the helper method
from_array.