Thread overview
Get the type that a mixin is mixing into
Mar 17, 2014
Mike
Mar 17, 2014
John Colvin
Mar 17, 2014
anonymous
March 17, 2014
Hello,

Consider the following silly, but illustrative example:
***********************************************
mixin template HasValue(ContainingType)
{
    uint value = ContainingType.outerValue;
}

struct MyStruct
{
    uint outerValue;

    mixin HasValue!(typeof(this));
}
***********************************************


Now what if I wanted to use that mixin in a module:
***********************************************
module myModule;

uint outerValue;

mixin HasValue!(typeof({what?});   //how do I refer to the module type
                                     there is no 'this' for modules
************************************************

Basic question:  How can I have my mixin refer to the type it's mixing into, and have it work regardless of whether it's mixing into a module or a class/struct?

Thanks for the help,
Mike
March 17, 2014
On Monday, 17 March 2014 at 13:04:36 UTC, Mike wrote:
> Hello,
>
> Consider the following silly, but illustrative example:
> ***********************************************
> mixin template HasValue(ContainingType)
> {
>     uint value = ContainingType.outerValue;
> }
>
> struct MyStruct
> {
>     uint outerValue;
>
>     mixin HasValue!(typeof(this));
> }
> ***********************************************
>
>
> Now what if I wanted to use that mixin in a module:
> ***********************************************
> module myModule;
>
> uint outerValue;
>
> mixin HasValue!(typeof({what?});   //how do I refer to the module type
>                                      there is no 'this' for modules
> ************************************************
>
> Basic question:  How can I have my mixin refer to the type it's mixing into, and have it work regardless of whether it's mixing into a module or a class/struct?
>
> Thanks for the help,
> Mike

That doesn't work in either case: you can't initialise a member of a mixin template with a runtime value.

To refer to the module name, just use the name of the module. Here's something that does work, to demonstrate that:

module myModule;

mixin template HasValue(alias ContainingType)
{
    alias value = ContainingType.outerValue;
}

struct foo
{
    uint outerValue;

    mixin HasValue!(typeof(this));
}

uint outerValue;

mixin HasValue!(myModule);
March 17, 2014
On Monday, 17 March 2014 at 13:04:36 UTC, Mike wrote:
> Consider the following silly, but illustrative example:
> ***********************************************
> mixin template HasValue(ContainingType)
> {
>     uint value = ContainingType.outerValue;
> }
>
> struct MyStruct
> {
>     uint outerValue;
>
>     mixin HasValue!(typeof(this));
> }
> ***********************************************
>
>
> Now what if I wanted to use that mixin in a module:
> ***********************************************
> module myModule;
>
> uint outerValue;
>
> mixin HasValue!(typeof({what?});   //how do I refer to the module type
>                                      there is no 'this' for modules
> ************************************************
>
> Basic question:  How can I have my mixin refer to the type it's mixing into, and have it work regardless of whether it's mixing into a module or a class/struct?

Modules aren't types.

Templates can have different kinds of parameters[1]:
* Type parameters take types. That means, modules are out.
* Alias parameters take symbols, e.g. user defined types (e.g.
MyStruct) and modules (e.g. myModule), but not built-in types
(e.g. int).
* Tuple parameters take any amount of anything the other
parameter variants accept.
* Value parameters and this parameters are not of interest here.

So, when you need to accept built-in types, you have to go with a
tuple parameter. Otherwise, an alias parameter works, too.

With a tuple parameter:
---
mixin template HasValue(context ...) if(context.length == 1)
{
     uint value = context[0].outerValue;
}
---

The alias parameter version is a bit simpler:
---
mixin template HasValue(alias context)
{
     uint value = context.outerValue;
}
---

[1] http://dlang.org/template#TemplateParameter