// // projection_tuple.h // iterator // // Created by Sam Jaffe on 9/23/25. // Copyright © 2025 Sam Jaffe. All rights reserved. // #pragma once #include #include #include #include #include namespace iterator::detail { template class Projections { private: std::tuple fns_; public: Projections(Projs... fns) : fns_(fns...) {} Projections(std::tuple const & fns) : fns_(fns) {} template decltype(auto) operator()(T && arg, std::integral_constant = {}) const { if constexpr (I >= sizeof...(Projs)) { return std::forward(arg); } else if constexpr (Assoc>) { return std::tie(arg.first, std::invoke(std::get(fns_), std::forward(arg).second)); } else { return std::invoke(std::get(fns_), std::forward(arg)); } } }; template struct ProjectionExpander { using type = std::tuple<>; }; template requires(I < sizeof...(Projs)) struct ProjectionExpander, I> { using Fn = std::tuple_element_t>; template static decltype(auto) get(T && ref) { if constexpr (Assoc>) { return std::forward(ref).second; } else { return std::forward(ref); } } static std::iter_reference_t _ref; using value_type = decltype(get(_ref)); using result_type = std::invoke_result_t; using type = tuple_cat_t< std::tuple, Fn, CaptureFn>>, typename ProjectionExpander, Projections, I + 1>::type>; }; }