OvenToBoostのexperimentalに少し前から入っていたadjacent_zipped Rangeアダプタを、コードを整理し、ドキュメントを書いて本流に移動しました。
このRangeアダプタは、元となったRangeを、隣接要素のタプルのRangeに変換します。
#include <iostream> #include <vector> #include <boost/range/adaptor/adjacent_zipped.hpp> #include <boost/range/algorithm/for_each.hpp> #include <boost/tuple/tuple_io.hpp> void print(const boost::tuple<int, int>& t) { std::cout << t << std::endl; } int main() { const std::vector<int> v = {1, 2, 3, 4, 5}; boost::for_each(v | boost::adaptors::adjacent_zipped, print); }
(1 2) (2 3) (3 4) (4 5)
これは内部的には、[begin(r), prior(end(r)))とr | dropped(1)をzipしたものです(0要素でも扱えるようにしてあります)。
boost::zip_iteratorには異なる長さのRangeを渡せないので、prior()が必要になっています。それによってRangeの要件がForwardRangeではなくBidirectionalRangeになっています。
要素がタプルのままだと使いにくいので、fused_for_each()でタプルを展開するといいでしょう。
#include <iostream> #include <vector> #include <boost/range/adaptor/adjacent_zipped.hpp> #include <boost/range/algorithm_ext/fused_for_each.hpp> #include <boost/fusion/include/boost_tuple.hpp> void print(int first, int second) { std::cout << '(' << first << ' ' << second << ')' << std::endl; } int main() { const std::vector<int> v = {1, 2, 3, 4, 5}; boost::fused_for_each(v | boost::adaptors::adjacent_zipped, print); }
(1 2) (2 3) (3 4) (4 5)