Access tuple by runtime index (C++20)
January 15, 2023 ยท View on GitHub
#include
template <int Low, int High, int Mid = (Low + High) / 2> inline constexpr auto _visit_at = nullptr;
template <int Low, int High, int Mid> requires(Low > High) inline constexpr auto _visit_at<Low, High, Mid> = [](int, auto&&...) { throw std::out_of_range("visit_at"); };
template
template <int Low, int High, int Mid>
requires(Low < High)
inline constexpr auto _visit_at<Low, High, Mid> =
[]<class... T>(int n, T&&... t) -> decltype(auto) {
{
if (n < Mid)
return _visit_at<Low, Mid - 1>(n, std::forward
template <typename Tuple, typename F>
constexpr decltype(auto) visit_at(int n, F&& f, Tuple&& tp) {
return _visit_at<0, int(std::tuple_size_v<std::decay_t
#include
int main() { auto tp = std::make_tuple("moew", 'a', 42); auto f = [](auto&& v) { std::cout << v << ", "; }; auto f2 = [](auto&& v) -> decltype(auto) { return std::cout << v; };
visit_at(1, f, tp);
visit_at(0, f, tp);
visit_at(2, f2, tp) << std::endl;
// visit_at(4, f, tp); // throws out_of_range
auto tp2 = std::make_tuple(std::make_unique<int>(3));
std::unique_ptr<int> p;
visit_at(
0, [&](auto&& v) { p = std::move(v); }, std::move(tp2));
assert(p);
try {
visit_at(
0, [p(std::move(p))](auto&& v) {}, std::make_tuple());
assert(0);
} catch (std::out_of_range&) {
}
}