Mixins¶
Mixin is a special program element, which consists of mixin
keyword and an expression in ()
.
This expression should be a constexpr
array of char8
elements, which contains a text of a program fragment.
This text is compiled like any other source file text.
mixin
code fragment text may be generated during compilation via constexpr
calculations, including constexpr
functions.
This allows, for example, to create a code, which isn’t possible to create using macros or templates.
mixin usage contexts¶
mixin
may be used in namespaces:
mixin( "fn Foo() : i32 { return 52; }" ); // create a global function Foo
namespace Some
{
mixin( "fn Bar() : f32 { return 0.0f; }" ); // create function Some::Bar
}
It’s also possible to use mixin
in structs and classes:
struct S
{
// Create a couple of fields and a method declaration
mixin( "i32 x; f64 y; fn Foo(this) : u32;" );
}
fn Foo()
{
var S s{ .x= 67, .y= 0.124 };
s.Foo();
}
mixin
within blocks is possible too:
fn Foo() : i32
{
mixin( " return 123; " );
}
mixin
in type name:
type T= mixin(mixin_text);
auto mixin_text= "[ i32, 4 ]";
mixin
as expression:
fn Foo( i32 x, i32 y ) : i32
{
return mixin( "x + y" ) * 2;
}
mixins limitations¶
import
inside mixin
isn’t possible.
Macros declaration in mixin
isn’t possible.
But it’s allowed to use macros available in the file, where this mixin
is declared.
It’s allowed to declare a mixin
in another mixin
expansion result.
But expansion depth is limited and thus recursive mixin
expansions aren’t possible.
All mixins outside templates and all mixins inside single template class are expanded in two steps.
First all mixin
expressions are evaluated, than symbols from these mixins are added.
This makes impossible to use in expression of one mixin
symbols defined in expansion of another mixin
.