2つの range の全ての組み合わせが欲しい


[お題]
2つの range の全ての組み合わせが欲しい。

#include <iostream>

#include <pstade/oven/matrix.hpp>
#include <pstade/oven/concatenated.hpp>
#include <pstade/oven/cycled.hpp>
#include <pstade/oven/distance.hpp>
#include <pstade/oven/zipped.hpp>
#include <pstade/oven/any_range.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

#include <pstade/oven/counting.hpp>
#include <pstade/oven/copied.hpp>
#include <pstade/oven/io.hpp>

#include <boost/tuple/tuple_io.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/array.hpp>


template<
    typename T1,
    typename T2
>
pstade::oven::any_range<
    boost::tuple<
        typename boost::range_value<T1>::type,
        typename boost::range_value<T2>::type
    >,
    boost::forward_traversal_tag
>
combination(const T1& range1, T2& range2){
    namespace oven = pstade::oven;
    namespace lambda = boost::lambda;
    
    return boost::make_tuple(
        range1|oven::rows(range1|oven::distance, 1)
              |oven::transformed(
                lambda::bind(oven::make_cycled, lambda::_1, range2|oven::distance
              ))
              |oven::concatenated,
        range2|oven::cycled(range1|oven::distance)
    )|oven::zipped;
}

int
main(){
    namespace oven = pstade::oven;

    int  array1[] = {0, 1, 2};
    char array2[] = {'a', 'b'};
    std::cout << (array1|oven::identities) << std::endl;
    std::cout << (array2|oven::identities) << std::endl;
    
    std::cout << combination(array1, array2) << std::endl;

    return 0;
}


[出力]

{0,1,2}
{a,b}
{(0 a),(0 b),(1 a),(1 b),(2 a),(2 b)}


combination は、2つの range を受け取り、全ての組み合わせを boost::tuple の range として返しています。
まぁやっていることは、

boost::make_tuple({0,0,1,1,2,2}, {a,b,a,b,a,b})|oven::zipped;

こんな感じですね。


アダプタで実装するなら boost::tuple で渡したほうがいいかも知れない。
めんどくさいからやらなかったけど。

boost::make_tuple(array1, array2)|combination;  // combination の過去形?


[pstade]
ver 1.04.3