I am iterating over an argument sequence at compile-time, and I want to check if one of the arguments may be a span. If so, I will do span-things.
template<typename... Args, std::size_t... Indices>
inline auto SomeClass::resolve_args(std::index_sequence<Indices...>) const
{
std::tuple<std::decay_t<Args>...> retval;
size_t i = 0;
size_t f = 0;
([&] {
if constexpr (std::is_integral_v<Args>) {
std::get<Indices>(retval) = sysarg<Args>(i++);
}
else if constexpr (std::is_floating_point_v<Args>)
std::get<Indices>(retval) = sysarg<Args>(f++);
else if constexpr (std::is_same_v<Args, std::basic_string_view<char>>) {
std::get<Indices>(retval) = sysarg<Args>(i); i+= 2;
}
else if constexpr (is_stdstring<Args>::value)
std::get<Indices>(retval) = sysarg<Args>(i++);
else if constexpr (std::is_standard_layout_v<remove_cvref<Args>> && std::is_trivial_v<remove_cvref<Args>>)
std::get<Indices>(retval) = sysarg<Args>(i++);
else
static_assert(always_false<Args>, "Unknown type");
}(), ...);
return retval;
}
Somewhere in there I need to check if Args is a Span. Is that possible? My problem so far is that my attempts at an if constexpr branch makes other type-combinations fail. So, I am posting the whole function (with minor modifications). You can implement sysarg as a do-nothing function.
Ideally, the spans subtype would be trivial and standard_layout, but I can handle the details. I just need to figure out how to proceed!
#include <span>
#include <type_traits>
template <typename T>
struct is_span : std::false_type{};
template <typename T>
struct is_span<std::span<T>> : std::true_type{};
template <typename T>
constexpr bool is_span_v = is_span<T>::value;
int main() {
static_assert(is_span_v<std::span<int>>);
static_assert(!is_span_v<int>);
}
Edit:
The above only works for spans with dynamic extent. To make it work on all spans change the is_span
specialization to this:
template <typename T, std::size_t Extent>
struct is_span<std::span<T, Extent>> : std::true_type{};