Reputation: 2843
I have a simple snipped below:
template<typename>
struct function_traits;
template<typename Rv, typename... Args>
struct function_traits<Rv(Args...)>
{
static constexpr const char _signature[] = {GetTypeChar<Rv>, '(', GetTypeChar<Args>()..., ')', '\0'};
}
where GetTypeChar returns character representing a type (i for integer, d for double et cetra).
This works really well for simple types, eg function_traits<int(float,double)>::_signature
returns i(f,d)
as expected.
Now Imagine I would have the ability to see whether it is an array or not by adding '[]' after the array, eg double[]
would result in d[]
.
I tried changing the signature to
static constexpr const char _signature[] = {GetTypeChar<Rv>(), '(', (std::is_array_v<Args> ? GetTypeChar<Args>(), '[', ']' : GetTypeChar<Args>())..., ')', '\0'};
but that seems to be completely ignored, and only things after :
are evaluated.
Is something like this possible?
Upvotes: 2
Views: 324
Reputation: 2843
Well, Initially I though I will be able to do this in a single array initialization, but the constexpr getter works well.
This is what I ended up with:
template<typename Tp>
constexpr void SetParamType(char*& dst)
{
if constexpr (std::is_pointer_v<Tp>)
{
*dst++ = '[';
}
*dst++ = GetTypeChar<Tp>();
}
[[nodiscard]]
constexpr auto signature() const
{
std::array<char, sizeof...(Args) * 2 + 4> out = {0};
char * ptr = out.data();
*ptr++ = GetTypeChar<return_type>();
*ptr++ = '(';
(SetParamType<Args>(ptr),...);
*ptr++ = ')';
*ptr++ = '\0';
return out;
}
Please note that it would be wise to calculate the size of an array to exactly match the required length (which would not be hard after all, but for sake of simplicity I'll leave it as it is for now)
Upvotes: 1