/* Copyright 2019 Rene Rivera * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt) */ #ifndef B2_MP_H #define B2_MP_H namespace b2 { namespace mp { // Simulate C++14 (make_)index_sequence.. template struct index_sequence { using type = index_sequence; }; template struct merge_index_sequence; template struct merge_index_sequence< index_sequence, index_sequence> : index_sequence { }; template struct make_index_sequence : merge_index_sequence< typename make_index_sequence::type, typename make_index_sequence::type> { }; template <> struct make_index_sequence<0> : index_sequence<> { }; template <> struct make_index_sequence<1> : index_sequence<0> { }; // Shallow, simulated, invoke.. template Return invoke(Call &&call, ArgsTuple &&args, index_sequence) { using std::get; return call(get(args)...); } // Simulate C++ 20 remove_cvref.. template struct remove_cvref { using type = typename std::remove_cv< typename std::remove_reference::type>::type; }; // Fusion style for_each.. template void for_each_arg(Call &&call, Args &&... args) { using x = int[]; (void)x{0, ((void)call(std::forward(args)), 0)...}; } template void for_each(Tuple &&tuple, Call &&call, index_sequence) { using std::get; for_each_arg( std::forward(call), get(std::forward(tuple))...); } template void for_each(Tuple &&tuple, Call &&call) { using std::get; for_each( std::forward(tuple), std::forward(call), make_index_sequence::value>{}); } } // namespace mp } // namespace b2 #endif