digitalmars.D.learn - Getting the size of a type tuple
- David Zhang (16/16) Sep 21 2017 Given the function F, where: F(Args...)(Args args) { ... }
- ag0aep6g (30/48) Sep 21 2017 I don't have a one-liner, but here are some other solutions that might
- David Zhang (3/10) Sep 21 2017 I think the recursive one looks best, but I agree. None of them
- H. S. Teoh (12/20) Sep 21 2017 I'd just do:
- ag0aep6g (2/22) Sep 21 2017 Yup. That's better.
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? Thanks
Sep 21 2017
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; } (); ----
Sep 21 2017
On Thursday, 21 September 2017 at 19:49:14 UTC, ag0aep6g wrote: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: <snip> 2) Using the std library: <snip> 3) Declaring a packed struct in a function literal that gets immediately called: <snip>I think the recursive one looks best, but I agree. None of them look particularly good.
Sep 21 2017
On Thu, Sep 21, 2017 at 09:49:14PM +0200, ag0aep6g via Digitalmars-d-learn wrote: [...]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; } (); ----I'd just do: template sizeofStruct(Types...) { struct S { align(1) Types fields; } enum sizeofStruct = S.sizeof; } Skip the CTFE implied by the function literal, the compiler already knows the size very well. T -- What are you when you run out of Monet? Baroque.
Sep 21 2017
On 09/21/2017 09:59 PM, H. S. Teoh wrote:On Thu, Sep 21, 2017 at 09:49:14PM +0200, ag0aep6g via Digitalmars-d-learn wrote: [...]Yup. That's better.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; } (); ----I'd just do: template sizeofStruct(Types...) { struct S { align(1) Types fields; } enum sizeofStruct = S.sizeof; } Skip the CTFE implied by the function literal, the compiler already knows the size very well.
Sep 21 2017