21#ifndef FORTRAN_COMMON_VISIT_H_
22#define FORTRAN_COMMON_VISIT_H_
25#include "flang/Common/api-attrs.h"
31template <std::size_t LOW, std::size_t HIGH,
typename RESULT,
typename VISITOR,
33RT_DEVICE_NOINLINE_HOST_INLINE RT_API_ATTRS RESULT Log2VisitHelper(
34 VISITOR &&visitor, std::size_t which, VARIANT &&...u) {
35 if constexpr (LOW + 7 >= HIGH) {
36 switch (which - LOW) {
37#define VISIT_CASE_N(N) \
39 if constexpr (LOW + N <= HIGH) { \
40 return visitor(std::get<(LOW + N)>(std::forward<VARIANT>(u))...); \
57 return visitor(std::get<LOW>(std::forward<VARIANT>(u))...);
59 static constexpr std::size_t mid{(HIGH + LOW) / 2};
61 return Log2VisitHelper<LOW, mid, RESULT>(
62 std::forward<VISITOR>(visitor), which, std::forward<VARIANT>(u)...);
64 return Log2VisitHelper<(mid + 1), HIGH, RESULT>(
65 std::forward<VISITOR>(visitor), which, std::forward<VARIANT>(u)...);
70template <
typename VISITOR,
typename... VARIANT>
71RT_DEVICE_NOINLINE_HOST_INLINE RT_API_ATTRS
auto
72visit(VISITOR &&visitor, VARIANT &&...u) ->
decltype(visitor(std::get<0>(
73 std::forward<VARIANT>(u))...)) {
74 using Result =
decltype(visitor(std::get<0>(std::forward<VARIANT>(u))...));
75 if constexpr (
sizeof...(u) == 1) {
76 static constexpr std::size_t high{
77 (std::variant_size_v<std::decay_t<
decltype(u)>> * ...) - 1};
78 return Log2VisitHelper<0, high, Result>(std::forward<VISITOR>(visitor),
79 u.index()..., std::forward<VARIANT>(u)...);
83 std::forward<VISITOR>(visitor), std::forward<VARIANT>(u)...);
92#if __GNUC__ < 9 && !defined(__clang__)
93#define FLANG_USE_STD_VISIT
96#ifdef FLANG_USE_STD_VISIT
99using Fortran::common::log2visit::visit;
Definition: bit-population-count.h:20