/usr/lib/gcc/x86_64-linux-gnu/5/include/d/core/internal/traits.d is in libphobos-5-dev 5.5.0-12ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | /**
* Contains traits for runtime internal usage.
*
* Copyright: Copyright Digital Mars 2014 -.
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
* Authors: Martin Nowak
* Source: $(DRUNTIMESRC core/internal/_traits.d)
*/
module core.internal.traits;
/// taken from std.typetuple.TypeTuple
template TypeTuple(TList...)
{
alias TypeTuple = TList;
}
T trustedCast(T, U)(auto ref U u) @trusted pure nothrow
{
return cast(T)u;
}
template Unconst(T)
{
static if (is(T U == immutable U)) alias Unconst = U;
else static if (is(T U == inout const U)) alias Unconst = U;
else static if (is(T U == inout U)) alias Unconst = U;
else static if (is(T U == const U)) alias Unconst = U;
else alias Unconst = T;
}
/// taken from std.traits.Unqual
template Unqual(T)
{
version (none) // Error: recursive alias declaration @@@BUG1308@@@
{
static if (is(T U == const U)) alias Unqual = Unqual!U;
else static if (is(T U == immutable U)) alias Unqual = Unqual!U;
else static if (is(T U == inout U)) alias Unqual = Unqual!U;
else static if (is(T U == shared U)) alias Unqual = Unqual!U;
else alias Unqual = T;
}
else // workaround
{
static if (is(T U == immutable U)) alias Unqual = U;
else static if (is(T U == shared inout const U)) alias Unqual = U;
else static if (is(T U == shared inout U)) alias Unqual = U;
else static if (is(T U == shared const U)) alias Unqual = U;
else static if (is(T U == shared U)) alias Unqual = U;
else static if (is(T U == inout const U)) alias Unqual = U;
else static if (is(T U == inout U)) alias Unqual = U;
else static if (is(T U == const U)) alias Unqual = U;
else alias Unqual = T;
}
}
// Substitute all `inout` qualifiers that appears in T to `const`
template substInout(T)
{
static if (is(T == immutable))
{
alias substInout = T;
}
else static if (is(T : shared const U, U) || is(T : const U, U))
{
// U is top-unqualified
mixin("alias substInout = "
~ (is(T == shared) ? "shared " : "")
~ (is(T == const) || is(T == inout) ? "const " : "") // substitute inout to const
~ "substInoutForm!U;");
}
else
static assert(0);
}
private template substInoutForm(T)
{
static if (is(T == struct) || is(T == class) || is(T == union) || is(T == interface))
{
alias substInoutForm = T; // prevent matching to the form of alias-this-ed type
}
else static if (is(T : V[K], K, V)) alias substInoutForm = substInout!V[substInout!K];
else static if (is(T : U[n], U, size_t n)) alias substInoutForm = substInout!U[n];
else static if (is(T : U[], U)) alias substInoutForm = substInout!U[];
else static if (is(T : U*, U)) alias substInoutForm = substInout!U*;
else alias substInoutForm = T;
}
/// used to declare an extern(D) function that is defined in a different module
template externDFunc(string fqn, T:FT*, FT) if(is(FT == function))
{
static if (is(FT RT == return) && is(FT Args == function))
{
import core.demangle : mangleFunc;
enum decl = {
string s = "extern(D) RT externDFunc(Args)";
foreach (attr; __traits(getFunctionAttributes, FT))
s ~= " " ~ attr;
return s ~ ";";
}();
pragma(mangle, mangleFunc!T(fqn)) mixin(decl);
}
else
static assert(0);
}
template staticIota(int beg, int end)
{
static if (beg + 1 >= end)
{
static if (beg >= end)
{
alias staticIota = TypeTuple!();
}
else
{
alias staticIota = TypeTuple!(+beg);
}
}
else
{
enum mid = beg + (end - beg) / 2;
alias staticIota = TypeTuple!(staticIota!(beg, mid), staticIota!(mid, end));
}
}
template dtorIsNothrow(T)
{
enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);
}
template anySatisfy(alias F, T...)
{
static if (T.length == 0)
{
enum anySatisfy = false;
}
else static if (T.length == 1)
{
enum anySatisfy = F!(T[0]);
}
else
{
enum anySatisfy =
anySatisfy!(F, T[ 0 .. $/2]) ||
anySatisfy!(F, T[$/2 .. $ ]);
}
}
// Somehow fails for non-static nested structs without support for aliases
template hasElaborateDestructor(T...)
{
static if (is(T[0]))
alias S = T[0];
else
alias S = typeof(T[0]);
static if (is(S : E[n], E, size_t n) && S.length)
{
enum bool hasElaborateDestructor = hasElaborateDestructor!E;
}
else static if (is(S == struct))
{
enum hasElaborateDestructor = __traits(hasMember, S, "__dtor")
|| anySatisfy!(.hasElaborateDestructor, S.tupleof);
}
else
enum bool hasElaborateDestructor = false;
}
// Somehow fails for non-static nested structs without support for aliases
template hasElaborateCopyConstructor(T...)
{
static if (is(T[0]))
alias S = T[0];
else
alias S = typeof(T[0]);
static if (is(S : E[n], E, size_t n) && S.length)
{
enum bool hasElaborateCopyConstructor = hasElaborateCopyConstructor!E;
}
else static if (is(S == struct))
{
enum hasElaborateCopyConstructor = __traits(hasMember, S, "__postblit")
|| anySatisfy!(.hasElaborateCopyConstructor, S.tupleof);
}
else
enum bool hasElaborateCopyConstructor = false;
}
|