Sprout.Tuple で transform_view
Sprout 側で処理できるようにゴニョゴニョと拡張してみました。
[ソース]
#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION #include <functional> #include <sprout/tuple.hpp> #include <sprout/string.hpp> template<typename Tuple, typename F> struct transform_view_tuple{ Tuple tuple; F func; }; namespace sprout{ namespace tuples{ template<std::size_t I, typename Tuple, typename F> struct tuple_element<I, transform_view_tuple<Tuple, F>> : std::result_of<F(typename tuple_element<I, Tuple>::type)> {}; template<typename Tuple, typename F> struct tuple_size<transform_view_tuple<Tuple, F>> : tuple_size<Tuple>{}; template<typename Tuple, typename F> struct tuple_size<transform_view_tuple<Tuple, F> const> : tuple_size<Tuple>{}; template<typename Tuple, typename F> struct rebind_types<transform_view_tuple<Tuple, F>> : rebind_types<Tuple> {}; template<std::size_t I, typename Tuple, typename F> SPROUT_CONSTEXPR auto get(transform_view_tuple<Tuple, F> const& tuple) SPROUT_NOEXCEPT ->decltype(tuple.func(sprout::get<I>(tuple.tuple))) { return tuple.func(sprout::get<I>(tuple.tuple)); } } // namespace tuples } // namespace sprout template<typename Tuple, typename F> SPROUT_CONSTEXPR transform_view_tuple<Tuple, F> transform_view(Tuple const& tuple, F func){ return { tuple, func }; } #include <iostream> #include <sprout/tuple/algorithm/copy.hpp> struct twice{ template<typename T> constexpr auto operator ()(T&& t) ->decltype(t + t){ return t + t; } }; int main(){ constexpr auto t = sprout::make_tuple(1, 1.25f, sprout::to_string("homu")); constexpr auto result = transform_view(t, twice()); constexpr auto result_check(sprout::make_tuple(2, 2.5f, sprout::to_string("homuhomu"))); static_assert( sprout::tuples::copy(decltype(result_check){}, result) == result_check, ""); return 0; }
やっていることは要素のアクセス時に変換関数を噛ませているだけですね。
operator はそのままだと使用できないので、Sprout.Tuple に変換してから比較しています。
constexpr Boost.Fusion が欲しくなる。