Thread overview
How to structure templated classes
May 09, 2012
Christian Köstlin
May 09, 2012
Jacob Carlborg
May 10, 2012
Christian Köstlin
May 10, 2012
Jacob Carlborg
May 10, 2012
Christian Köstlin
May 10, 2012
Jacob Carlborg
May 10, 2012
Christian Köstlin
May 09, 2012
I have a templated class that has many (static) inner classes which also use the template parameter. e.g.
import std.stdio;

class Test(T) {
  static class Inner1 : Test {
	T h;
  }
  static class Inner2 : Test {
	T h;
  }
}

unittest {
  alias Test!(string) StringTest;
  alias Test!(int) IntTest;

  auto t1 = new StringTest.Inner1();
  auto t2 = new StringTest.Inner1();
  auto t3 = new IntTest.Inner2();
  auto t4 = new IntTest.Inner2();
}

int main(string[] args) {
  return 0;
}

in my real case there are a lot more inner classes (which acutally implement the interface defined by the surrounding class).

this is very convenient, because i can create all of the inner classes for one type just with an alias. thats what templates are for.

the problem is, i want to pull out the inner classes so that my module gets smaller, but then i have to make several aliases to get the desired template instances e.g. i would create a module:
class Innert1(T) : Test!(T) {
  T h;
}

and an alias for that like: alias Innert1!(string) StringInner1;

that is very repetitive when i have many of those inner classes.

So the question now is. Is there a way to split the big module in several smaller ones, and at the same time keep the possibility to let the "template magic" do its work?

thanks in advance

christian
May 09, 2012
On 2012-05-09 22:21, Christian Köstlin wrote:
> I have a templated class that has many (static) inner classes which also
> use the template parameter. e.g.
> import std.stdio;
>
> class Test(T) {
> static class Inner1 : Test {
> T h;
> }
> static class Inner2 : Test {
> T h;
> }
> }
>
> unittest {
> alias Test!(string) StringTest;
> alias Test!(int) IntTest;
>
> auto t1 = new StringTest.Inner1();
> auto t2 = new StringTest.Inner1();
> auto t3 = new IntTest.Inner2();
> auto t4 = new IntTest.Inner2();
> }
>
> int main(string[] args) {
> return 0;
> }
>
> in my real case there are a lot more inner classes (which acutally
> implement the interface defined by the surrounding class).
>
> this is very convenient, because i can create all of the inner classes
> for one type just with an alias. thats what templates are for.
>
> the problem is, i want to pull out the inner classes so that my module
> gets smaller, but then i have to make several aliases to get the desired
> template instances e.g. i would create a module:
> class Innert1(T) : Test!(T) {
> T h;
> }
>
> and an alias for that like: alias Innert1!(string) StringInner1;
>
> that is very repetitive when i have many of those inner classes.
>
> So the question now is. Is there a way to split the big module in
> several smaller ones, and at the same time keep the possibility to let
> the "template magic" do its work?
>
> thanks in advance
>
> christian

Perhaps you can use template mixins (untested).

class Test (T)
{
    mixin InnerClasses!(T);
}

template InnerClasses (T)
{
    static class Inner1 : Test!(T) {}
    // ... and so on
}



-- 
/Jacob Carlborg
May 10, 2012
On 05/09/2012 10:48 PM, Jacob Carlborg wrote:
> Perhaps you can use template mixins (untested).
>
> class Test (T)
> {
> mixin InnerClasses!(T);
> }
>
> template InnerClasses (T)
> {
> static class Inner1 : Test!(T) {}
> // ... and so on
> }

thank for your answer,

yes .. that could possibly work, but would still force me to add all the mixins to the main class. in addition to that i could not longer use the mixin-classes standalone (i would have to mixin them into the place i want to use them).

i think i have to rework my code ...

regards

christian
May 10, 2012
On 2012-05-10 13:41, Christian Köstlin wrote:

> thank for your answer,
>
> yes .. that could possibly work, but would still force me to add all the
> mixins to the main class. in addition to that i could not longer use the
> mixin-classes standalone (i would have to mixin them into the place i
> want to use them).
>
> i think i have to rework my code ...
>
> regards
>
> christian

You don't need to mix in the classes. You can access them by:

InnerClasses!(T).Inner1

-- 
/Jacob Carlborg
May 10, 2012
On 05/10/2012 02:13 PM, Jacob Carlborg wrote:
> On 2012-05-10 13:41, Christian Köstlin wrote:
>
>> thank for your answer,
>>
>> yes .. that could possibly work, but would still force me to add all the
>> mixins to the main class. in addition to that i could not longer use the
>> mixin-classes standalone (i would have to mixin them into the place i
>> want to use them).
>>
>> i think i have to rework my code ...
>>
>> regards
>>
>> christian
>
> You don't need to mix in the classes. You can access them by:
>
> InnerClasses!(T).Inner1
>
ok .. sure you can use them by the way of InnerClasses, but you cannot use them directly anymore, which was one motivation to extract them from InnerClasses.

Thanks

May 10, 2012
On 2012-05-10 17:39, Christian Köstlin wrote:

> ok .. sure you can use them by the way of InnerClasses, but you cannot
> use them directly anymore, which was one motivation to extract them from
> InnerClasses.

Ah, I missed that. But one mixin isn't that bad? Or do you want to place them in several templates.

-- 
/Jacob Carlborg
May 10, 2012
On 05/10/2012 06:47 PM, Jacob Carlborg wrote:
> On 2012-05-10 17:39, Christian Köstlin wrote:
>
>> ok .. sure you can use them by the way of InnerClasses, but you cannot
>> use them directly anymore, which was one motivation to extract them from
>> InnerClasses.
>
> Ah, I missed that. But one mixin isn't that bad? Or do you want to place
> them in several templates.
yeah you are right ... actually i am not sure what i really want.
when i extracted the classes into seperate modules i liked it really, but then i updated old code that used these classes and one of the files used the alias trick to get all of the inner classes (a usecase which i had forgotten). i was able to work around this problem, but this made me reconsider the last refactoring :)

thank again for your solution!

christian