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.

Reply via email to