OvenでPythonで言うところのenumerate関数を作る。(何番煎じ?)
enumerate.hpp
#ifndef HWM_ENUMERATE_HPP_ #define HWM_ENUMERATE_HPP_ #include <boost/tuple/tuple.hpp> #include <pstade/pass_by.hpp> #include <pstade/result_of.hpp> #include <pstade/oven/any_range.hpp> #include <pstade/oven/counting.hpp> #include <pstade/oven/distance.hpp> #include <pstade/oven/pack.hpp> #include <pstade/oven/range_value.hpp> #include <pstade/oven/range_traversal.hpp> #include <pstade/oven/zipped.hpp> #include <pstade/oven/zipped_with.hpp> namespace hwm { namespace enumerate_detail { using namespace pstade; using namespace pstade::oven; struct little { template< class Myself, class Range, class BinaryFun = void> struct apply { typedef typename range_value<Range>::type org_value_t; typedef typename range_traversal<Range>::type org_traversal_t; typedef typename pass_by_value<BinaryFun>::type fun_t; typedef typename any_range< typename result_of<fun_t const(unsigned int, org_value_t)>::type, org_traversal_t > const range_t; typedef range_t type; }; template< class Result, class Range, class BinaryFun > Result call(Range &r, BinaryFun &f) const { return pack(counting((unsigned int)0, (unsigned int)(r|distance)), r)|zipped_with(f); } template< class Myself, class Range > struct apply<Myself, Range> { typedef typename range_value<Range>::type org_value_t; typedef typename range_traversal<Range>::type org_traversal_t; typedef typename any_range< boost::tuples::tuple<unsigned int, org_value_t>, org_traversal_t > const range_t; typedef range_t type; }; template<class Result, class Range> Result call(Range &r) const { return pack(counting((unsigned int)0, (unsigned int)(r|distance)), r)|zipped; } }; } //namespace enumerate_detail PSTADE_OVEN_LITTLE_TO_ADAPTOR(enumerate, (enumerate_detail::little)) } //namespace hwm #endif //HWM_ENUMERATE_HPP_
test.cpp
#include <iostream> #include <vector> #include <boost/tuple/tuple_io.hpp> #include <pstade/oven/foreach.hpp> #include <pstade/oven/io.hpp> #include "enumerate.hpp" struct pack_ { pack_(int i, int j) : i_(i) , j_(j) {} pack_() {} int i_; int j_; }; namespace std { ostream& operator<<(ostream& ost, ::pack_ const &p) { return ost << '(' << p.i_ << ',' << p.j_ << ')'; } } struct make_pack_ { typedef pack_ result_type; result_type operator()(int i, int j) const { return pack_(i, j); } }; int plus_(int i, int j) { return i + j; } int main() { using namespace pstade::oven; int v[] = {5, 6, 7, 8, 9}; PSTADE_OVEN_FOREACH(elem, v|hwm::enumerate) { std::cout << elem << std::endl; } PSTADE_OVEN_FOREACH(elem, v|hwm::enumerate(&::plus_)) { std::cout << elem << std::endl; } PSTADE_OVEN_FOREACH(elem, v|hwm::enumerate(make_pack_())) { std::cout << elem << std::endl; } }
さて、この実装ではインデックス(に使ってるcounting_range)かなんかの型の違いで警告が出てしまいまする・・・どう回避したものか・・・
ところで携帯からの投稿なのでうまくいくかどうか