Variables should have the ability to be @nogc
Marco Leise via Digitalmars-d
digitalmars-d at puremagic.com
Tue May 31 12:04:39 PDT 2016
Am Tue, 31 May 2016 15:53:44 +0000
schrieb Basile B. <b2.temp at gmx.com>:
> This solution seems smarter than using the existing '@nogc'
> attribute. Plus one also for the fact that nothing has to be done
> in DMD.
I just constrained myself to what can be done in user code
from the start. :)
> Did you encounter the issue with protected and private members ?
>
> For me when i've tested the template i've directly got some
> warnings. DMD interprets my 'getMember' calls as a deprecated
> abuse of bug 314 but in dmd 2.069 I would get true errors.
Actually it is in a large half-ported code base from C++ and I
haven't ever had a running executable, nor did I test it with
recent dmd versions. My idea was to mostly have @nogc code,
but allow it for a transition time or places where GC use
does not have an impact. Here is the code, free to use for
all purposes.
enum GcScan { no, yes, automatic }
enum noScan = GcScan.no;
template gcScanOf(T)
{
import std.typetuple;
static if (is(T == struct) || is(T == union))
{
enum isGcScan(alias uda) = is(typeof(uda) == GcScan);
GcScan findGcScan(List...)()
{
auto result = GcScan.automatic;
foreach (attr; List) if (is(typeof(attr) == GcScan))
result = attr;
return result;
}
enum gcScanOf()
{
auto result = GcScan.no;
foreach (i; Iota!(T.tupleof.length))
{
enum memberGcScan = findMatchingUda!(T.tupleof[i], isGcScan, true);
static if (memberGcScan.length == 0)
enum eval = gcScanOf!(typeof(T.tupleof[i]));
else
enum eval = evalGcScan!(memberGcScan, typeof(T.tupleof[i]));
static if (eval)
{
result = eval;
break;
}
}
return result;
}
}
else
{
static if (isStaticArray!T && is(T : E[N], E, size_t N))
enum gcScanOf = is(E == void) ? GcScan.yes : gcScanOf!E;
else
enum gcScanOf = hasIndirections!T ? GcScan.yes : GcScan.no;
}
}
enum evalGcScan(GcScan gc, T) = (gc == GcScan.automatic) ? gcScanOf!T : gc;
template findMatchingUda(alias symbol, alias func, bool optional = false, bool multiple = false)
{
import std.typetuple;
enum symbolName = __traits(identifier, symbol);
enum funcName = __traits(identifier, func);
template Filter(List...)
{
static if (List.length == 0)
alias Filter = TypeTuple!();
else static if (__traits(compiles, func!(List[0])) && func!(List[0]))
alias Filter = TypeTuple!(List[0], Filter!(List[1 .. $]));
else
alias Filter = Filter!(List[1 .. $]);
}
alias filtered = Filter!(__traits(getAttributes, symbol));
static assert(filtered.length <= 1 || multiple,
symbolName ~ " may only have one UDA matching " ~ funcName ~ ".");
static assert(filtered.length >= 1 || optional,
symbolName ~ " requires a UDA matching " ~ funcName ~ ".");
static if (multiple || optional)
alias findMatchingUda = filtered;
else static if (filtered.length == 1)
alias findMatchingUda = filtered[0];
}
--
Marco
More information about the Digitalmars-d
mailing list