25: Compile‐time Conditionals - royal-lang/rl GitHub Wiki
There are two types of compile-time conditionals in Royal. The version statement and actual conditional statements like static if and static switch.
Static statements does not create a scope which is why they are useful in the creation of fields etc.
Version
The version statement is used to declare scopes only available during specific versions etc.
Versions can be set from the project file, package files, using an assignment for a version statement and also through a compiler flag.
version (FLAG)
{
// Compiled with: version (FLAG)
}
else
{
// Not compiled with: version (FLAG)
}
version (!FLAG)
{
// Not compiled with: version (FLAG)
}
else
{
// Compiled with: version (FLAG)
}
Example:
version (Windows)
{
alias myFun = SomeWindowsFunctionOnlyAvailableOnWindows;
}
else
{
alias myFun = someFunctionNotAvailableOnWindows;
}
myFun(); // Depending on the platform this will call either "SomeWindowsFunctionOnlyAvailableOnWindows" or "someFunctionNotAvailableOnWindows"
Static If
A static if is the same as an actual if statement. The only difference is that it can be declared in any scope and will be evaluated at compile-time.
static if (EXPRESSION)
{
}
static else if (EXPRESSION)
{
}
static else
{
}
Example:
struct BitInteger(size_t bits)
{
static if (bits == 8)
{
var byte value;
}
static else if (bits == 16)
{
var ushort value;
}
static else if (bits == 32)
{
var uint value;
}
static else if (bits == 64)
{
var ulong value;
}
static else if (bits == 128)
{
var ucent value;
}
static else
{
static assert(0, "Invalid bits");
}
}
var BitInteger(16) integer;
writeln(integer.value.typeof); // Prints: ushort
Static Switch
A static switch is similar to static if in that its mechanics are the same but instead of being based on the condition of a boolean expression it's based on a compile-time available value.
A static switch supports the same functionality as an actual switch statement except for return, break and goto since it just ends when the case scope ends.
static switch (VALUE) // Or just: switch VALUE
{
static case MATCHING_VALUE
{
}
static case MATCHING_VALUE1,MATCHING_VALUE2
{
}
static case MATCHING_VALUE_RANGE_1 .. MATCHING_VALUE_RANGE_2
{
}
static default
{
}
static final
{
}
}
Example:
struct BitInteger(size_t bits)
{
static switch (bits)
{
static case 8
{
var byte value;
}
static case 16
{
var ushort value;
}
static case 32
{
var uint value;
}
static case 64
{
var ulong value;
}
static case 128
{
var ucent value;
}
static default
{
static assert(0, "Invalid bits");
}
}
}
var BitInteger(16) integer;
writeln(integer.value.typeof); // Prints: ushort