Tech Blog

勉強したことをまとめます。

cpplinqサンプル集

はじめに

 ずいぶん昔にGooglebloggerに作ったcpplinqのサンプル集が、bloggerの仕様が変わって表示されなくなりました。こちらに転載します。

サンプル集

#include "cpplinq_samples.hpp"
#include <cpplinq.hpp>
#include <iostream>
#include <array>
#include <boost/range/algorithm.hpp>
#include <random>
#include <boost/format.hpp>

void sample_where()
{
    std::cout << "* cpplinq::where\n";
    auto vs = std::array<int, 5>{};
    // make an array of [1,2,3,4,5]
    std::iota(std::begin(vs), std::end(vs), 1);

    std::cout << " even: ";
    cpplinq::from(vs)
        >> cpplinq::where([](const auto& v){ return v % 2 == 0; })
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
    
    std::cout << " odd: ";
    cpplinq::from(vs)
        >> cpplinq::where([](const auto& v){ return v % 2 == 1; })
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_reference_wrapper()
{
    std::cout << "* std::reference_wrapper/cpplinq::ref\n";
    auto ls = std::list<int>(10);
    // make a list of [-4,-3,...]
    std::iota(std::begin(ls), std::end(ls), -4);
    
    std::cout << " 0: ";
    boost::for_each(ls, [](const auto& l){ std::cout << l << " "; });
    std::cout << std::endl;
    
    // Two expressions have the same meaning.
    auto vs = std::vector<std::reference_wrapper<int>>{
        std::begin(ls), std::end(ls)};
//    auto vs = cpplinq::from(ls) >> cpplinq::ref()
//        >> cpplinq::to_vector();
    
    std::shuffle(std::begin(vs), std::end(vs), std::mt19937{std::random_device{}()});
    
    std::cout << " 1: ";
    boost::for_each(vs, [](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
    
    boost::for_each(ls, [](auto& l){ l *= 2; });
    
    std::cout << " 2: ";
    cpplinq::from(ls)
        >> cpplinq::for_each([](const auto& l){ std::cout << l << " "; });
    std::cout << std::endl;
    
    std::cout << " 3: ";
    boost::for_each(vs, [](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_select()
{
    std::cout << "* cpplinq::select\n";
    auto ps = std::vector<std::pair<int, std::string>>{
        std::make_pair(1, "sabaton"),
        std::make_pair(2, "metallica"),
        std::make_pair(3, "slayer"),
    };
    
    std::cout << " 0: ";
    auto vs = cpplinq::from(ps)
        >> cpplinq::select([](const auto& p){ return p.second; })
        >> cpplinq::to_vector();
    boost::for_each(vs, [](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}
    
void sample_select_many()
{
    std::cout << "* cpplinq::select_many\n";
    auto vs = std::array<int, 3>{1, 2, 3};
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::select_many([](const auto& v){
            auto dst = std::vector<int>{};
            dst.reserve(3);
            dst.emplace_back(v);
            dst.emplace_back(10 * v);
            dst.emplace_back(100 * v);
            return cpplinq::from(dst);})
        >> cpplinq::for_each([](const auto& u){ std::cout << u << " "; });
    std::cout << std::endl;
}
    
void sample_select_many_flatten()
{
    std::cout << "* cpplinq::select_many(flatten)\n";
    auto vss = std::array<std::array<int, 3>, 3>{
        {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
    };
    std::cout << " 0: ";
    cpplinq::from(vss)
        >> cpplinq::select_many([](const auto& vs){
            return cpplinq::from(vs);})
        >> cpplinq::for_each([](const auto& u){ std::cout << u << " "; });
    std::cout << std::endl;
}

void sample_take()
{
    std::cout << "* cpplinq::take\n";
    auto vs = std::array<int, 100>{};
    std::iota(std::begin(vs), std::end(vs), 1);
    
    std::cout << " 0: ";
    cpplinq::from(vs) >> cpplinq::take(5)
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_orderby_descending()
{
    std::cout << "* cpplinq::orderby_descending\n";
    auto vs = std::array<std::pair<int, std::string>, 3>{{
        {std::make_pair(3, "tokyo" )},
        {std::make_pair(1, "osaka" )},
        {std::make_pair(2, "nagoya")},
    }};
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::orderby_descending([](const auto& v){ return v.first; })
        >> cpplinq::for_each([](const auto& u){
            std::cout << boost::format("(%1%, %2%) ") %u.first %u.second; });
    std::cout << std::endl;
}

void sample_orderby_ascending()
{
    std::cout << "* cpplinq::orderby_ascending\n";
    auto vs = std::array<std::pair<int, std::string>, 3>{{
        {std::make_pair(3, "tokyo" )},
        {std::make_pair(1, "osaka" )},
        {std::make_pair(2, "nagoya")},
    }};
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::orderby_ascending([](const auto& v){ return v.first; })
        >> cpplinq::for_each([](const auto& u){
            std::cout << boost::format("(%1%, %2%) ") %u.first %u.second; });
    std::cout << std::endl;
}

void sample_orderby_true()
{
    std::cout << "* cpplinq::orderby(true)\n";
    auto vs = std::array<std::pair<int, std::string>, 3>{{
        {std::make_pair(3, "tokyo" )},
        {std::make_pair(1, "osaka" )},
        {std::make_pair(2, "nagoya")},
    }};
    // The result is equal to that of orderby_ascending.
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::orderby([](const auto& v){ return v.first; }, true)
        >> cpplinq::for_each([](const auto& u){
            std::cout << boost::format("(%1%, %2%) ") %u.first %u.second; });
    std::cout << std::endl;
}

void sample_orderby_false()
{
    std::cout << "* cpplinq::orderby(false)\n";
    auto vs = std::array<std::pair<int, std::string>, 3>{{
        {std::make_pair(3, "tokyo" )},
        {std::make_pair(1, "osaka" )},
        {std::make_pair(2, "nagoya")},
    }};
    // The result is equal to that of orderby_descending.
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::orderby([](const auto& v){ return v.first; }, false)
        >> cpplinq::for_each([](const auto& u){
            std::cout << boost::format("(%1%, %2%) ") %u.first %u.second; });
    std::cout << std::endl;
}

void sample_thenby()
{
    std::cout << "* cpplinq::thenby\n";
    auto vs = std::array<std::pair<int, std::string>, 4>{{
        {std::make_pair(3, "tokyo" )},
        {std::make_pair(1, "osaka" )},
        {std::make_pair(2, "nagoya")},
        {std::make_pair(3, "tanaka")},
    }};
    // The result is equal to that of orderby_descending.
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::orderby([](const auto& v){ return v.first; },  false)
        >> cpplinq::for_each([](const auto& u){ std::cout << boost::format("(%1%, %2%) ") %u.first %u.second; });
    std::cout << std::endl;

    std::cout << " 1: ";
    cpplinq::from(vs)
        >> cpplinq::orderby([](const auto& v){ return v.first; },  false)
        >> cpplinq::thenby( [](const auto& v){ return v.second; }, true)
        >> cpplinq::for_each([](const auto& u){ std::cout << boost::format("(%1%, %2%) ") %u.first %u.second; });
    std::cout << std::endl;
}

void sample_take_while()
{
    std::cout << "* cpplinq::take_while\n";
    auto vs = std::array<int, 100>{};
    std::iota(std::begin(vs), std::end(vs), 1);
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::take_while([](const auto& v){ return v < 5; })
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_skip_while()
{
    std::cout << "* cpplinq::skip_while\n";
    auto vs = std::array<int, 10>{};
    std::iota(std::begin(vs), std::end(vs), 1);
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::skip_while([](const auto& v){ return v < 5; })
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_join()
{
    std::cout << "* cpplinq::join\n";

    struct vocal
    {
        int         id_;
        std::string name_;
    };
    
    struct band
    {
        int         id_;
        std::string name_;
    };
    
    auto bands = std::array<band, 4>
    {{
        {1, "Nightwish"},
        {2, "Amaranthe"},
        {3, "Epica"},
        {4, "Arch Enemy"},
        
    }};
    
    auto vocals = std::array<vocal, 3>
    {{
        {3, "Simone"},
        {1, "Floor"},
        {4, "Alissa"},
    }};
    
    std::cout << " 0: ";
    cpplinq::from(bands)
        >> cpplinq::join(
                cpplinq::from(vocals),
                [](const auto& band)  {return band.id_;},
                [](const auto& vocal) {return vocal.id_;},
                [](const auto& band, const auto& vocal) { return std::make_pair(band, vocal); })
        >> cpplinq::for_each([](const auto& p){
            std::cout << boost::format("(%1%, %2%) ") %p.first.name_ %p.second.name_; });
    std::cout << std::endl;

    std::cout << " 1: ";
    cpplinq::from(vocals)
        >> cpplinq::join(
                cpplinq::from(bands),
                [](const auto& vocal) {return vocal.id_;},
                [](const auto& band)  {return band.id_;},
                [](const auto& vocal, const auto& band) { return std::make_pair(vocal, band); })
        >> cpplinq::for_each([](const auto& p){
            std::cout << boost::format("(%1%, %2%) ") %p.first.name_ %p.second.name_; });
    std::cout << std::endl;

}

void sample_concat()
{
    std::cout << "* concat\n";
    auto vs = cpplinq::range(0, 5);
    auto us = cpplinq::range(5, 5);
    std::cout << " 0: ";
    vs >> cpplinq::concat(us) >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_reverse()
{
    std::cout << "* reverse\n";
    auto vs = cpplinq::range(0, 5);
    std::cout << " 0: ";
    vs >> cpplinq::reverse() >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;
}

void sample_distinct()
{
    std::cout << "* distinct\n";
    auto vs = std::array<int, 9>{5, 4, 3, 2, 1, 2, 3, 4, 5};
    std::cout << " 0: ";
    cpplinq::from(vs) >> cpplinq::distinct() >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;
}
    
void sample_union_with()
{
    std::cout << "* union_with\n";
    auto vs = std::array<int, 3>{5, 4, 3};
    auto us = std::array<int, 3>{3, 5, 1};
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::union_with(cpplinq::from(us))
        >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;

    std::cout << " 1: ";
    cpplinq::from(us)
        >> cpplinq::union_with(cpplinq::from(vs))
        >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;
}

void sample_intersect_with()
{
    std::cout << "* intersect_with\n";
    auto vs = std::array<int, 3>{5, 4, 3};
    auto us = std::array<int, 3>{3, 5, 1};
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::intersect_with(cpplinq::from(us))
        >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;

    std::cout << " 1: ";
    cpplinq::from(us)
        >> cpplinq::intersect_with(cpplinq::from(vs))
        >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;
}

void sample_except()
{
    std::cout << "* except\n";
    auto vs = std::array<int, 3>{5, 4, 3};
    auto us = std::array<int, 3>{3, 5, 1};
    
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::except(cpplinq::from(us))
        >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;

    std::cout << " 1: ";
    cpplinq::from(us)
        >> cpplinq::except(cpplinq::from(vs))
        >> cpplinq::for_each([](const auto& p){ std::cout << p << " "; });
    std::cout << std::endl;
}

void sample_to_vector()
{
    std::cout << "* to_vector\n";
    std::vector<int> vs = cpplinq::range(0, 3) >> cpplinq::to_vector();
    std::cout << " 0: ";
    boost::for_each(vs, [](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}
    
void sample_to_list()
{
    std::cout << "* to_list\n";
    std::list<int> vs = cpplinq::range(0, 3) >> cpplinq::to_list();
    std::cout << " 0: ";
    boost::for_each(vs, [](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_to_map()
{
    std::cout << "* to_map\n";
    auto vs = std::vector<std::pair<int, std::string>>{
        std::make_pair(1, "tarja"),
        std::make_pair(2, "annette"),
        std::make_pair(3, "floor"),
    };
    
    std::map<int, std::pair<int, std::string>> ms = cpplinq::from(vs)
        >> cpplinq::to_map([](const auto& v){ return v.first; });
    std::cout << " 0: ";
    boost::for_each(ms, [](const auto& p){
        std::cout << "(" << p.first << " " << p.second.second << ") ";
    });
    std::cout << std::endl;
}

void sample_to_lookup()
{
    std::cout << "* to_lookup\n";
    auto vs = std::vector<std::pair<int, std::string>>{
        std::make_pair(1, "fear factory"),
        std::make_pair(2, "soilwork"),
        std::make_pair(3, "arch enemy"),
        std::make_pair(3, "scar symmetry"),
    };
    
    auto ms = cpplinq::from(vs)
        >> cpplinq::to_lookup([](const auto& v){ return v.first; });
    std::cout << " 0: ";
    ms[3]
        >> cpplinq::select([](const auto& m){ return m.second; })
        >> cpplinq::for_each([](const auto& n){ std::cout << n << " "; });
    std::cout << std::endl;
}

void sample_sequence_equal()
{
    std::cout << "* sequence_equal\n";
    auto vs0 = std::vector<int>{1, 2, 3};
    auto vs1 = std::vector<int>{1, 2, 3};
    auto is_same = cpplinq::from(vs0) >> cpplinq::sequence_equal(cpplinq::from(vs1));
    std::cout << " 0: ";
    std::cout << std::boolalpha << is_same << std::endl;
    
    auto vs2 = std::vector<int>{3, 2, 1};
    is_same = cpplinq::from(vs0) >> cpplinq::sequence_equal(cpplinq::from(vs2));
    std::cout << " 1: ";
    std::cout << is_same << std::endl;
}
    
void sample_first()
{
    std::cout << "* first\n";
    auto vs = std::vector<int>{1, 2, 3};
    auto f = cpplinq::from(vs) >> cpplinq::first();
    std::cout << " 0: ";
    std::cout << f << std::endl;
    auto g = cpplinq::from(vs)
        >> cpplinq::first([](const auto& v){ return v % 2 == 0; });
    std::cout << " 1: ";
    std::cout << g << std::endl;
    try {
        auto h = cpplinq::from(vs)
            >> cpplinq::first([](const auto& v){ return v > 9; });
        std::cout << " 2: ";
        std::cout << h << std::endl;
    } catch (const std::exception& error) {
        std::cout << " 3: ";
        std::cout << error.what() << std::endl;
    }
}

void sample_first_or_default()
{
    std::cout << "* first_or_default\n";
    auto vs = std::vector<int>{1, 2, 3};
    auto f = cpplinq::from(vs) >> cpplinq::first_or_default();
    std::cout << " 0: ";
    std::cout << f << std::endl;
    auto g = cpplinq::from(vs)
        >> cpplinq::first_or_default([](const auto& v){ return v % 2 == 0; });
    std::cout << " 1: ";
    std::cout << g << std::endl;
    auto h = cpplinq::from(vs)
        >> cpplinq::first_or_default([](const auto& v){ return v > 9; });
    std::cout << " 2: ";
    std::cout << h << std::endl;
}

void sample_last_or_default()
{
    std::cout << "* last_or_default\n";
    auto vs = std::vector<int>{1, 2, 3, 4, 5};
    auto f = cpplinq::from(vs) >> cpplinq::last_or_default();
    std::cout << " 0: ";
    std::cout << f << std::endl;
    auto g = cpplinq::from(vs) >> cpplinq::last_or_default([](const auto& v){ return v % 2 == 0; });
    std::cout << " 1: ";
    std::cout << g << std::endl;
    auto h = cpplinq::from(vs) >> cpplinq::last_or_default([](const auto& v){ return v > 9; });
    std::cout << " 2: ";
    std::cout << h << std::endl;
}

void sample_element_at_or_default()
{
    std::cout << "* element_at_or_default\n";
    auto vs = std::vector<int>{1, 2, 3, 4, 5};
    auto f = cpplinq::from(vs) >> cpplinq::element_at_or_default(0);
    std::cout << " 0: ";
    std::cout << f << std::endl;
    auto g = cpplinq::from(vs) >> cpplinq::element_at_or_default(3);
    std::cout << " 1: ";
    std::cout << g << std::endl;
    auto h = cpplinq::from(vs) >> cpplinq::element_at_or_default(100);
    std::cout << " 2: ";
    std::cout << h << std::endl;
}
    
void sample_range()
{
    std::cout << "* range\n";
    auto start = 10;
    auto count = 3;
    std::cout << " 0: ";
    cpplinq::range(start, count)
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_repeat()
{
    std::cout << "* repeat\n";
    auto element = "tokyo";
    auto count = 3;
    std::cout << " 0: ";
    cpplinq::repeat(element, count)
        >> cpplinq::for_each([](const auto& v){ std::cout << v << " "; });
    std::cout << std::endl;
}

void sample_empty()
{
    std::cout << "* empty\n";
    auto is = cpplinq::empty<int>() >> cpplinq::to_vector();
    std::cout << " 0: ";
    std::cout << std::boolalpha << is.empty() << std::endl;
    
    auto ss = cpplinq::empty<std::string>() >> cpplinq::to_list();
    std::cout << " 1: ";
    std::cout << std::boolalpha << is.empty() << std::endl;
}

void sample_singleton()
{
    std::cout << "* singleton\n";
    std::cout << " 0: ";
    cpplinq::singleton(1)
        >> cpplinq::for_each([](const auto& v){ std::cout << v << std::endl; });
}

void sample_generate()
{
    std::cout << "* generate\n";
    auto mt = std::mt19937{std::random_device{}()};
    auto rnd = std::uniform_int_distribution<>{0, 10};
    std::cout << " 0: ";
    cpplinq::generate([&rnd, &mt](){
        auto value = rnd(mt);
        return (value != 0) ? cpplinq::to_opt(value) : cpplinq::to_opt<int>(); })
        >> cpplinq::for_each([](const auto& x){ std::cout << x << " "; });
    std::cout << std::endl;
}

void sample_any()
{
    std::cout << "* any\n";
    auto vs = std::array<int, 3>{1, 4, 8};
    std::cout << " 0: ";
    bool flag = cpplinq::from(vs)
        >> cpplinq::any([](const auto& v){ return v % 2 == 1; });
    std::cout << std::boolalpha << flag << std::endl;
}

void sample_all()
{
    std::cout << "* all\n";
    auto vs = std::array<int, 3>{2, 4, 8};
    std::cout << " 0: ";
    bool flag = cpplinq::from(vs)
        >> cpplinq::all([](const auto& v){ return v % 2 == 0; });
    std::cout << std::boolalpha << flag << std::endl;
    std::cout << " 1: ";
    flag = cpplinq::from(vs)
        >> cpplinq::all([](const auto& v){ return v % 2 == 1; });
    std::cout << std::boolalpha << flag << std::endl;
}

void sample_contains()
{
    std::cout << "* contains\n";
    auto vs = std::array<int, 3>{2, 4, 8};
    std::cout << " 0: ";
    bool flag = cpplinq::from(vs) >> cpplinq::contains(2);
    std::cout << std::boolalpha << flag << std::endl;

    struct info
    {
        int id_;
        std::string name_;
    };
    
    auto infos = std::vector<info>{
        info{3, "tokyo"},
        info{2, "osaka"},
        info{5, "nagoay"},
    };
    
    flag = cpplinq::from(infos)
        >> cpplinq::contains(infos[0], [](const auto& x, const auto& y){
            return x.id_ == y.id_;
        });
    std::cout << " 1: ";
    std::cout << flag << std::endl;
}

void sample_count()
{
    std::cout << "* count\n";
    auto vs = std::array<int, 5>{1, 2, 3, 4, 8};
    auto c = cpplinq::from(vs) >> cpplinq::count();
    std::cout << " 0: ";
    std::cout << c << std::endl;
    c = cpplinq::from(vs) >> cpplinq::count([](const auto& v){ return v % 2 == 0; });
    std::cout << " 1: ";
    std::cout << c << std::endl;
}

void sample_sum()
{
    std::cout << "* sum\n";
    auto vs = std::array<int, 5>{1, 2, 3, 4, 8};
    auto s = cpplinq::from(vs) >> cpplinq::sum();
    std::cout << " 0: ";
    std::cout << s << std::endl;
    s = cpplinq::from(vs) >> cpplinq::sum([](const auto& v){ return v * v; });
    std::cout << " 1: ";
    std::cout << s << std::endl;
}
    
void sample_min()
{
    std::cout << "* min\n";
    auto vs = std::array<int, 5>{1, 2, 3, 4, 8};
    auto m = cpplinq::from(vs) >> cpplinq::min();
    std::cout << " 0: ";
    std::cout << m << std::endl;
    m = cpplinq::from(vs) >> cpplinq::min([](const auto& v){ return 2 * v; });
    std::cout << " 1: ";
    std::cout << m << std::endl;
}

void sample_max()
{
    std::cout << "* max\n";
    auto vs = std::array<int, 5>{1, 2, 3, 4, 8};
    auto m = cpplinq::from(vs) >> cpplinq::max();
    std::cout << " 0: ";
    std::cout << m << std::endl;
    m = cpplinq::from(vs) >> cpplinq::max([](const auto& v){ return 2 * v; });
    std::cout << " 1: ";
    std::cout << m << std::endl;
}

void sample_avg()
{
    std::cout << "* avg\n";
    auto vs = std::array<double, 5>{1, 2, 3, 4, 8};
    auto m = cpplinq::from(vs) >> cpplinq::avg();
    std::cout << " 0: ";
    std::cout << m << std::endl;
    m = cpplinq::from(vs) >> cpplinq::avg([](const auto& v){ return 2 * v; });
    std::cout << " 1: ";
    std::cout << m << std::endl;
}

void sample_pairwise()
{
    std::cout << "* pairwise\n";
    auto vs = std::array<double, 5>{1, 2, 3, 4, 8};
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::pairwise()
        >> cpplinq::for_each(
            [](const auto& p){
                std::cout << boost::format("(%1%, %2%) ") %p.first %p.second;
            });
    std::cout << std::endl;
}

void sample_zip_with()
{
    std::cout << "* zip_with\n";
    auto vs = std::array<std::string, 3>{"nightwish", "amaranthe", "kamelot"};
    auto us = std::array<std::string, 5>{"finland", "sweden", "america", "japan", "canada"};
    std::cout << " 0: ";
    cpplinq::from(vs)
        >> cpplinq::zip_with(cpplinq::from(us))
        >> cpplinq::for_each(
            [](const auto& p){
                std::cout << boost::format("(%1%, %2%) ") %p.first %p.second;
            });
    std::cout << std::endl;
}