www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template recursion error on table struct

reply data pulverizer <data.pulverizer gmail.com> writes:
I am attempting to create a table struct with generic column 
types using templates. The subTable() member function subsets the 
table, however I am getting a template recursion error. I know 
where the problem is from, I don't know how to resolve it. I am 
modelling it after the matrix example in Ali Çehreli book: 
http://ddili.org/ders/d.en/templates_more.html

import std.stdio;

template ColumnTable(T...){
	struct ColumnTable{
	private:
		typeof(T) data;
		string[] names;
		struct Range{
			size_t begin;
			size_t end;
		}
         // This function is the source of the issue
	auto subTable(Range rowRange, Range columnRange)(){
		auto new_data = data[columnRange.begin .. columnRange.end];
		auto output = ColumnTable!(new_data)(new_data); // This is the 
problem
		string[] new_names = names[columnRange.begin .. 
columnRange.end];
		output.setNames(new_names);
		return output;
	}
	public:
		this(T...)(T args){
			data = args;
			foreach(i, arg; T){
				names ~= args[i].stringof;
			}
		}
		void setNames(string[] names){
			this.names = names;
		}
		void test(){
			writeln(subTable!(Range(0, 2), Range(0, 2))());
		}
	}
}


void main(){
	string[] names = ["tariq", "sharma", "peter", "rakel"];
	double[] salary = [44.5, 32.2, 40.1, 28.1];
	int[] age = [24, 20, 22, 25, 19];
	writeln(ColumnTable!(names, salary, age)(names, salary, age));
}
Mar 25 2016
next sibling parent data pulverizer <data.pulverizer gmail.com> writes:
p.s. I realise that the ColumnTable call is a little ponderous 
but I tidy it up in a convenience wrapper function:

auto CreateDataTable(Args...)(){
	string[] names;
	foreach(i, arg; Args){
		names ~= Args[i].stringof;
	}
	auto df = ColumnTable!(Args)(Args);
	df.setNames(names);
	return df;
}


// auto myTable = CreateDataTable!(names, salary, age)();
Mar 25 2016
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
WARNING: Do not try to compile this code. Your computer may be 
unresponsive for a while. :)

On 03/25/2016 02:54 PM, data pulverizer wrote:
 I am attempting to create a table struct with generic column types using
 templates.
However, the template arguments are not types; rather, aliases.
 template ColumnTable(T...){
      struct ColumnTable{
      private:
          typeof(T) data;
          string[] names;
          struct Range{
              size_t begin;
              size_t end;
          }
          // This function is the source of the issue
      auto subTable(Range rowRange, Range columnRange)(){
          auto new_data = data[columnRange.begin .. columnRange.end];
          auto output = ColumnTable!(new_data)(new_data); // This is the
 problem
new_data is a local variable. So, this instantiation of ColumnTable is with that symbol.
 void main(){
      string[] names = ["tariq", "sharma", "peter", "rakel"];
      double[] salary = [44.5, 32.2, 40.1, 28.1];
      int[] age = [24, 20, 22, 25, 19];
      writeln(ColumnTable!(names, salary, age)(names, salary, age));
 }
Likewise, that instantiation of ColumnTable is with the symbols 'names', 'salary', and 'age'. Is that what you want? Or do you want to instantiate with their types? Can you explain some more what you are trying to do. Ali
Mar 25 2016
next sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Saturday, 26 March 2016 at 06:28:42 UTC, Ali Çehreli wrote:
 WARNING: Do not try to compile this code. Your computer may be 
 unresponsive for a while. :)

 On 03/25/2016 02:54 PM, data pulverizer wrote:
 I am attempting to create a table struct with generic column
types using
 templates.
However, the template arguments are not types; rather, aliases.
 template ColumnTable(T...){
      struct ColumnTable{
      private:
          typeof(T) data;
          string[] names;
          struct Range{
              size_t begin;
              size_t end;
          }
          // This function is the source of the issue
      auto subTable(Range rowRange, Range columnRange)(){
          auto new_data = data[columnRange.begin ..
columnRange.end];
          auto output = ColumnTable!(new_data)(new_data); //
This is the
 problem
new_data is a local variable. So, this instantiation of ColumnTable is with that symbol.
 void main(){
      string[] names = ["tariq", "sharma", "peter", "rakel"];
      double[] salary = [44.5, 32.2, 40.1, 28.1];
      int[] age = [24, 20, 22, 25, 19];
      writeln(ColumnTable!(names, salary, age)(names, salary,
age));
 }
Likewise, that instantiation of ColumnTable is with the symbols 'names', 'salary', and 'age'. Is that what you want? Or do you want to instantiate with their types? Can you explain some more what you are trying to do. Ali
I am trying to build a table similar to R's dataframe but with unbounded data types. I am hoping that D's flexible template programming methods will allow table-like class or struct to be constructed with "naked" types i.e. unwrapped with variant. The ColumnTable object consists of vector columns that are bound together in a tuple - the data member and accessed in a similar way to your matrix example. The table will have column names and should be accessible by: table[0..4, "colname"] table[0..4, ["colname_1", "colname_2", "colname_3"]] table[0..$, 0..4] and should be able to be subsetted and inserted into by another table table_1[0..4, 3..4] = table_2 table_1[0..4, ["colname_1", "colname_2"]] = table_2 and columns could be added or overwritten table[0..$, 0] = someVector table.columnBind(someVector) column bind two table together ... auto new_table = ColumnTable(table_1, table_2) auto new_table = ColumnTable(table_1, someVector) row bind two table having the same column characteristics auto new_table = rbind(table_1, table_2) Then perhaps do something similar for row-based tables.
Mar 26 2016
prev sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Saturday, 26 March 2016 at 06:28:42 UTC, Ali Çehreli wrote:
 Likewise, that instantiation of ColumnTable is with the symbols 
 'names', 'salary', and 'age'. Is that what you want? Or do you 
 want to instantiate with their types? Can you explain some more 
 what you are trying to do.

 Ali
I guess am trying to instantiate the class using symbols that should pass a tuple right to the data member. Does that mean that I need to use a mixin template instead of a template?
Mar 26 2016
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
Please ignore my earlier response. :)

On 03/25/2016 02:54 PM, data pulverizer wrote:

 template ColumnTable(T...){
[...]
          auto output = ColumnTable!(new_data)(new_data); // This is the
 problem
You want to slice the template arguments there. The following removes the infinite recursion: auto output = ColumnTable!(T[columnRange.begin .. columnRange.end])(new_data); Ali
Mar 26 2016
parent data pulverizer <data.pulverizer gmail.com> writes:
On Saturday, 26 March 2016 at 09:47:10 UTC, Ali Çehreli wrote:
 Please ignore my earlier response. :)

 On 03/25/2016 02:54 PM, data pulverizer wrote:

 template ColumnTable(T...){
[...]
          auto output = ColumnTable!(new_data)(new_data); //
This is the
 problem
You want to slice the template arguments there. The following removes the infinite recursion: auto output = ColumnTable!(T[columnRange.begin .. columnRange.end])(new_data); Ali
Thanks a lot! The subTable() method includes a loop to subset the rows which I forgot to include originally ... auto subTable(Range rowRange, Range columnRange)(){ auto new_data = data[columnRange.begin .. columnRange.end]; foreach(i, col; new_data){ new_data[i] = col[rowRange.begin .. rowRange.end]; } auto output = ColumnTable!(T[columnRange.begin .. columnRange.end])(new_data); string[] new_names = names[columnRange.begin .. columnRange.end]; output.setNames(new_names); return output; }
Mar 26 2016