On Saturday, 19 August 2017 at 19:15:25 UTC, bitwise wrote:
On Saturday, 19 August 2017 at 18:22:58 UTC, Guillaume Boucher
wrote:
On Thursday, 17 August 2017 at 16:32:20 UTC, bitwise wrote:
In a high-performance context though, the performance hit may
be unacceptable.
Well in those super rare situations, there's always the
workaround with mixins:
Those situations are not rare.
mixin template funcWithAttr(string decl, string attributes,
string code) {
pragma(msg, "<<<" ~ code ~ ">>>");
mixin(decl ~ attributes ~ "{" ~ code ~" }");
}
struct Container(T, bool safetyOn = true)
{
static if(safe)
RefCounted!(T[]) data;
else
T[] data;
mixin funcWithAttr!("auto opSlice()", safetyOn ? "@safe" :
"", q{
return Range(data, 0, data.length);
});
}
Really?
With DIP 1012 you should be able to go
struct Container(T, bool safetyOn = true)
{
static if(safe)
RefCounted!(T[]) data;
else
T[] data;
auto opSlice() @safeIf!safetyOn {
return Range(data, 0, data.length);
}
}
template safeIf(bool cond)
{
static if (cond) alias safeIf = AliasSeq!(safe);
else alias safeIf = AliasSeq!();
}
or even just
struct Container(T, FunctionSafety safetyOn = safe)
{
static if(safe)
RefCounted!(T[]) data;
else
T[] data;
auto opSlice() @safetyOn {
return Range(data, 0, data.length);
}
}
Container!int foo; // Container!(int, safe)
Container!(int, system) bar;
The only downside is that the second form leaves itself open to
Container!(int, trusted) quux;
which is probably undesirable.