On 09/21/2017 08:44 PM, David Zhang wrote:
Given the function F, where: F(Args...)(Args args) { ... }

How can I statically determine the size of the argument list in bytes?

Preferably, I would like a one-liner. However, std.algorithm doesn't seem to support tuples, or `Args.each!(T => T.sizeof).sum` would work.

For the moment, I've settled on using a helper function:

size_t size(Args...)()
{
     size_t size;
     foreach(Arg; Args)
         size += Arg.sizeof;
     return size;
}

But it's a bit clunky. Is there a more idiomatic way to do this?

I don't have a one-liner, but here are some other solutions that might be interesting. None of them is particularly pretty, though.

1) Recursive template:
----
template size_recur(Types ...)
{
    static if (Types.length == 0) enum size_recur = 0;
    else enum size_recur = Types[0].sizeof + size_recur!(Types[1 .. $]);
}
----

2) Using the std library:
----
template size_std(Types ...)
{
    import std.algorithm: sum;
    import std.range: only;
    import std.meta: staticMap;
    enum sizeOf(T) = T.sizeof;
    enum size_std = staticMap!(sizeOf, Types).only.sum;
}
----

3) Declaring a packed struct in a function literal that gets immediately called:
----
enum size_so_very_clever(Types ...) = () {
    struct S { align(1) Types fields; }
    return S.sizeof;
} ();
----

Reply via email to