#pragma once #include "integral_constant.hpp" #include "Sequence.hpp" struct forwarder { template __host__ __device__ constexpr T&& operator()(T&& x) const { return static_cast(x); } }; struct swallow { template __host__ __device__ constexpr swallow(Ts&&... ts) { } }; // Emulate if constexpr template struct static_if { }; template <> struct static_if { using Type = static_if; template __host__ __device__ constexpr auto operator()(F f) const { // This is a trick for compiler: // Pass forwarder to lambda "f" as "auto" argument, and maks sure "f" will use it, // this will make "f" a generic lambda, so that "f" won't be compiled until being // instantiated here f(forwarder{}); return Type{}; } template __host__ __device__ static constexpr auto Else(F) { return Type{}; } }; template <> struct static_if { using Type = static_if; template __host__ __device__ constexpr auto operator()(F) const { return Type{}; } template __host__ __device__ static constexpr auto Else(F f) { // This is a trick for compiler: // Pass forwarder to lambda "f" as "auto" argument, and maks sure "f" will use it, // this will make "f" a generic lambda, so that "f" won't be compiled until being // instantiated here f(forwarder{}); return Type{}; } };