www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Heterogeneous Variadic Arguments with Other Arguments

reply harakim <harakim gmail.com> writes:
I wanted to do this:
package int serialize(byte[] destination, int offset, T...)(T 
values)
{	
	static foreach (i, value; values)
	{
		*cast(T[i] *)(destination.ptr + offset) = value;
		offset += typeid(T[i]).tsize();
	}
	
	return offset;
}

But I got this error:
main.d(8): Error: template main.serialize cannot deduce function 
from argument types !()(byte[], int, byte, int), candidates are:
main.d(20):        main.serialize(byte[] destination, int offset, 
T...)(T values)

Eventually, I assumed that you couldn't do heterogeneous 
arguments with other arguments first.

I was able to do this and it works:
package int serialize(T...)(T values)
{
	static assert(values.length >= 2);

	auto ptr = (cast(byte[])values[0]).ptr;
	
	int offset = cast(int)values[1];

	static foreach (i, value; values)
	{
		static if (i > 1)
		{
			*cast(T[i] *)(ptr + offset) = value;
			offset += typeid(T[i]).tsize();
		}
	}
	
	return offset;
}

That is obviously a lot uglier. Can you have a function with 
non-variadic arguments followed by heterogeneous variadic 
arguments?
Jul 13 2019
parent reply evilrat <evilrat666 gmail.com> writes:
On Sunday, 14 July 2019 at 03:51:14 UTC, harakim wrote:
 I wanted to do this:
 package int serialize(byte[] destination, int offset, T...)(T 
 values)
 ....
Can't really tell what's going on without call site and what do you exactly mean by "heterogeneous arguments with other arguments", but this thing is syntax error. You declared a template here, and template parameters (compile-time parameters) must come first. int serialize(T...)(byte[] destination, int offset, T values) This is the case if you wanted to pass that buffer at runtime, not sure if you can do this with CT parameters, though it shouldn't prevent you from forcing CTFE evaluation by assigning result to another CT parameter or enum. But if by "other arguments" you mean passing different types there is untyped variadics with a bit different behavior(see [1]) [1] https://dlang.org/spec/function.html#d_style_variadic_functions
Jul 13 2019
parent harakim <harakim gmail.com> writes:
On Sunday, 14 July 2019 at 06:05:13 UTC, evilrat wrote:
 On Sunday, 14 July 2019 at 03:51:14 UTC, harakim wrote:
 I wanted to do this:
 package int serialize(byte[] destination, int offset, T...)(T 
 values)
 ....
Can't really tell what's going on without call site and what do you exactly mean by "heterogeneous arguments with other arguments", but this thing is syntax error. You declared a template here, and template parameters (compile-time parameters) must come first. int serialize(T...)(byte[] destination, int offset, T values) This is the case if you wanted to pass that buffer at runtime, not sure if you can do this with CT parameters, though it shouldn't prevent you from forcing CTFE evaluation by assigning result to another CT parameter or enum. But if by "other arguments" you mean passing different types there is untyped variadics with a bit different behavior(see [1]) [1] https://dlang.org/spec/function.html#d_style_variadic_functions
Thanks. That answered my question. I was hoping to do this: int serialize(T...)(byte[] destination, int offset, T values) And now I understand a lot more about variadic functions and type arguments.
Jul 13 2019