www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Creating Tuple or AliasSeq

reply ANtlord <antlord92 gmail.com> writes:
Hello! I've got an issue related to making a Tuple or AliasSeq 
using income template arguments. I want to create template makes 
an array of objects from array of arrays have different sizes and 
different types of values.

I created temporary solution. It is a concatenation of strings 
that will be passed to mixin.

But I just want to reorder parameters and pass them to ObjectType 
using AliasSeq or Tuple. Does it possible?

import std.stdio;

template objectFactory(ObjectType, Args...)
{
	static string loopGen() {
		string code = (ObjectType[]).stringof ~ " res = []; ";
		foreach(i, _; Args)
		{
			enum level = to!string(i);
			code ~= "foreach(elem" ~ level ~ "; Args[" ~ level ~ "])";
		}

		code ~= "res ~= " ~ ObjectType.stringof ~ "(";

		foreach(i, _; Args)
		{
			enum level = to!string(i);
			code ~= "elem" ~ level;

			static if(i + 1 < Args.length)
			{
				code ~= ", ";
			}
		}
		code ~= ");";

		return code;
	}

	static ObjectType[] factory()
	in {
		static assert(Args.length > 0);
		foreach(argumentCases; Args)
			static assert(argumentCases.length > 0);
	}
	body
	{
		enum codeString = loopGen();
		mixin(codeString);
		return res;
	}

	alias objectFactory = factory;
}

Example:

struct Pair {
	int number;
	string name;
}

auto pairKit = objectFactory!(Pair, [1], ["qwe", "asd"]);
auto pairSet = pairKit();
assert(pairSet.length == 2);
writeln(pairSet[0]); // writes Pair(1, "qwe");
writeln(pairSet[1]); // writes Pair(1, "asd");

Thanks. Sorry if my english is not clear.
Apr 06 2017
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 04/06/2017 10:43 PM, ANtlord wrote:
 Hello! I've got an issue related to making a Tuple or AliasSeq using
 income template arguments. I want to create template makes an array of
 objects from array of arrays have different sizes and different types of
 values.
Here is a solution: auto objectFactory(ObjectType, Args...)(Args args) { import std.algorithm : cartesianProduct, map; import std.array : array; return cartesianProduct(args).map!(a => ObjectType(a.expand)).array; } struct Pair { int number; string name; } import std.stdio; void main() { auto pairKit = objectFactory!(Pair)([1, 2], ["qwe", "asd"]); auto pairSet = pairKit; writeln(pairSet); } Ali
Apr 07 2017
next sibling parent ANtlord <antlord92 gmail.com> writes:
On Friday, 7 April 2017 at 07:46:40 UTC, Ali Çehreli wrote:
 Here is a solution:

 auto objectFactory(ObjectType, Args...)(Args args) {
     import std.algorithm : cartesianProduct, map;
     import std.array : array;

     return cartesianProduct(args).map!(a => 
 ObjectType(a.expand)).array;
 }

 struct Pair {
     int number;
     string name;
 }

 import std.stdio;

 void main() {
     auto pairKit = objectFactory!(Pair)([1, 2], ["qwe", "asd"]);
     auto pairSet = pairKit;
     writeln(pairSet);
 }

 Ali
It's great! Thanks a lot!
Apr 07 2017
prev sibling parent reply ANtlord <antlord92 gmail.com> writes:
On Friday, 7 April 2017 at 07:46:40 UTC, Ali Çehreli wrote:
 Here is a solution:

 auto objectFactory(ObjectType, Args...)(Args args) {
     import std.algorithm : cartesianProduct, map;
     import std.array : array;

     return cartesianProduct(args).map!(a => 
 ObjectType(a.expand)).array;
 }

 struct Pair {
     int number;
     string name;
 }

 import std.stdio;

 void main() {
     auto pairKit = objectFactory!(Pair)([1, 2], ["qwe", "asd"]);
     auto pairSet = pairKit;
     writeln(pairSet);
 }

 Ali
I can't understand. Documentation of cartesianProduct points out about finite arrays. At least one of arrays must be a inifinte array. As far as I know finite arrays is `int[3]` and infinite is `int[]` (https://dlang.org/library/std/range/primitives/is_infinite.html). Am I right? If I am then I can't understand why DMD return error about finite ranges compiling following code. struct Hay { int a; disable this(this); disable this(); this(int a){ this.a = a; } } Hay[] params = [ Hay(1), Hay(23) ]; auto products = cartesianProduct(params, params); Error text:
 static assert  "cartesianProduct involving finite ranges must 
 have at least one finite forward range"
I noticed that removing disabling default constructors helps. Does that mean an array contains objects of a struct with disabled default constructor is finite?
Apr 07 2017
parent Graham Fawcett <fawcett uwindsor.ca> writes:
On Friday, 7 April 2017 at 10:26:24 UTC, ANtlord wrote:
 On Friday, 7 April 2017 at 07:46:40 UTC, Ali Çehreli wrote:
 [...]
I can't understand. Documentation of cartesianProduct points out about finite arrays. At least one of arrays must be a inifinte array. As far as I know finite arrays is `int[3]` and infinite is `int[]` (https://dlang.org/library/std/range/primitives/is_infinite.html). Am I right? If I am then I can't understand why DMD return error about finite ranges compiling following code. struct Hay { int a; disable this(this); disable this(); this(int a){ this.a = a; } } Hay[] params = [ Hay(1), Hay(23) ]; auto products = cartesianProduct(params, params); Error text:
 [...]
I noticed that removing disabling default constructors helps. Does that mean an array contains objects of a struct with disabled default constructor is finite?
No, int[] is a finite array. isInfinite is meant to test for ranges which are statically defined to *never* be empty, no matter how many times you consume them. See std.range.repeat(T) for an example of such a range.
Apr 07 2017