Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 286479b

Browse files
authored
Merge pull request #2412 from thewilsonator/traits
Add some traits merged-on-behalf-of: Nicholas Wilson <[email protected]>
2 parents c9c8df7 + 27ade86 commit 286479b

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

src/core/internal/traits.d

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ template TypeTuple(TList...)
1414
alias TypeTuple = TList;
1515
}
1616

17+
template FieldTypeTuple(T)
18+
{
19+
static if (is(T == struct) || is(T == union))
20+
alias FieldTypeTuple = typeof(T.tupleof[0 .. $ - __traits(isNested, T)]);
21+
else static if (is(T == class))
22+
alias FieldTypeTuple = typeof(T.tupleof);
23+
else
24+
{
25+
alias FieldTypeTuple = TypeTuple!T;
26+
}
27+
}
28+
1729
T trustedCast(T, U)(auto ref U u) @trusted pure nothrow
1830
{
1931
return cast(T)u;
@@ -123,6 +135,34 @@ template staticIota(int beg, int end)
123135
}
124136
}
125137

138+
private struct __InoutWorkaroundStruct {}
139+
@property T rvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
140+
@property ref T lvalueOf(T)(inout __InoutWorkaroundStruct = __InoutWorkaroundStruct.init);
141+
142+
// taken from std.traits.isAssignable
143+
template isAssignable(Lhs, Rhs = Lhs)
144+
{
145+
enum isAssignable = __traits(compiles, lvalueOf!Lhs = rvalueOf!Rhs) && __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs);
146+
}
147+
148+
// taken from std.traits.isInnerClass
149+
template isInnerClass(T) if (is(T == class))
150+
{
151+
static if (is(typeof(T.outer)))
152+
{
153+
template hasOuterMember(T...)
154+
{
155+
static if (T.length == 0)
156+
enum hasOuterMember = false;
157+
else
158+
enum hasOuterMember = T[0] == "outer" || hasOuterMember!(T[1 .. $]);
159+
}
160+
enum isInnerClass = __traits(isSame, typeof(T.outer), __traits(parent, T)) && !hasOuterMember!(__traits(allMembers, T));
161+
}
162+
else
163+
enum isInnerClass = false;
164+
}
165+
126166
template dtorIsNothrow(T)
127167
{
128168
enum dtorIsNothrow = is(typeof(function{T t=void;}) : void function() nothrow);
@@ -162,6 +202,23 @@ template anySatisfy(alias F, T...)
162202
}
163203
}
164204

205+
// simplified from std.traits.maxAlignment
206+
private template maxAlignment(U...)
207+
{
208+
static if (U.length == 0)
209+
static assert(0);
210+
else static if (U.length == 1)
211+
enum maxAlignment = U[0].alignof;
212+
else static if (U.length == 2)
213+
enum maxAlignment = U[0].alignof > U[1].alignof ? U[0].alignof : U[1].alignof;
214+
else
215+
{
216+
enum a = maxAlignment!(U[0 .. ($+1)/2]);
217+
enum b = maxAlignment!(U[($+1)/2 .. $]);
218+
enum maxAlignment = a > b ? a : b;
219+
}
220+
}
221+
165222
// std.traits.Fields
166223
private template Fields(T)
167224
{
@@ -208,6 +265,24 @@ template hasElaborateCopyConstructor(S)
208265
}
209266
}
210267

268+
template hasElaborateAssign(S)
269+
{
270+
static if (__traits(isStaticArray, S) && S.length)
271+
{
272+
enum bool hasElaborateAssign = hasElaborateAssign!(typeof(S.init[0]));
273+
}
274+
else static if (is(S == struct))
275+
{
276+
enum hasElaborateAssign = is(typeof(S.init.opAssign(rvalueOf!S))) ||
277+
is(typeof(S.init.opAssign(lvalueOf!S))) ||
278+
anySatisfy!(.hasElaborateAssign, FieldTypeTuple!S);
279+
}
280+
else
281+
{
282+
enum bool hasElaborateAssign = false;
283+
}
284+
}
285+
211286
// std.meta.Filter
212287
template Filter(alias pred, TList...)
213288
{

0 commit comments

Comments
 (0)