lvalueOf

Creates an lvalue or rvalue of type T to be used in conjunction with is(typeof(...)) or __traits(compiles, ...).

The idea is that some traits or other forms of conditional compilation need to verify that a particular piece of code compiles with an rvalue or an lvalue of a specific type, and these @property functions allow you to get an rvalue or lvalue of a specific type to use within an expression that is then tested to see whether it compiles.

They're @property functions so that using typeof on them gives the return type rather than the type of the function.

Note that these functions are not defined, so if they're actually used outside of type introspection, they'll result in linker errors. They're entirely for testing that a particular piece of code compiles with an rvalue or lvalue of the given type.

The __InoutWorkaroundStruct parameter is entirely to make it so that these work when the given type has the inout qualifier, since the language requires that a function that returns an inout type also have an inout type as a parameter. It should just be ignored.

@property ref
T
lvalueOf
(
T
)
(
inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init
)

Examples

static int foo(int);
static assert(is(typeof(foo(lvalueOf!int)) == int));
static assert(is(typeof(foo(rvalueOf!int)) == int));

static bool bar(ref int);
static assert(is(typeof(bar(lvalueOf!int)) == bool));
static assert(!is(typeof(bar(rvalueOf!int))));

static assert( is(typeof({ lvalueOf!int = 42; })));
static assert(!is(typeof({ rvalueOf!int = 42; })));

static struct S {}
static assert( is(typeof({ lvalueOf!S = S.init; })));
static assert(!is(typeof({ rvalueOf!S = S.init; })));

static struct NoAssign
{
    @disable void opAssign(ref NoAssign);
}
static assert(!is(typeof({ lvalueOf!NoAssign = NoAssign.init; })));
static assert(!is(typeof({ rvalueOf!NoAssign = NoAssign.init; })));

Meta