Skip to content

Commit 92b757a

Browse files
Add Option and Result types
1 parent 689d236 commit 92b757a

File tree

7 files changed

+398
-36
lines changed

7 files changed

+398
-36
lines changed

source/numem/core/exception.d

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,24 @@ auto assumePure(T, Args...)(T expr, auto ref Args args) pure if (isSomeFunction!
8383
return (cast(ft)expr)(args);
8484
}
8585

86+
/**
87+
Assumes that the provided function is @nogc, nothrow and pure.
88+
89+
Params:
90+
expr = The expression to execute.
91+
args = Arguments to pass to the function.
92+
*/
93+
auto assumeNoThrowNoGCPure(T, Args...)(T expr, auto ref Args args) pure if (isSomeFunction!T) {
94+
static if (is(T Fptr : Fptr*) && is(Fptr == function))
95+
alias ft = @nogc nothrow pure ReturnType!T function(Parameters!T);
96+
else static if (is(T Fdlg == delegate))
97+
alias ft = @nogc nothrow pure ReturnType!T delegate(Parameters!T);
98+
else
99+
static assert(0);
100+
101+
return (cast(ft)expr)(args);
102+
}
103+
86104
/**
87105
An exception which can be thrown from numem
88106
*/
@@ -107,6 +125,13 @@ public:
107125
super(cast(string)msg.nu_dup(), nextInChain, file, line);
108126
}
109127

128+
/**
129+
Helper that creates a new exception.
130+
*/
131+
static NuException create(const(char)[] msg, Throwable nextInChain = null, string file = __FILE__, size_t line = __LINE__) {
132+
return nogc_new!NuException(msg, nextInChain, file, line);
133+
}
134+
110135
/**
111136
Returns the error message
112137
*/

source/numem/core/lifetime.d

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -103,39 +103,41 @@ void destruct(T, bool reInit=true)(ref T obj_) @nogc {
103103
} else {
104104
static if (isHeapAllocated!T) {
105105
if (obj_ !is null) {
106-
static if (__traits(getLinkage, RealT) == "D") {
107-
auto cInfo = cast(ClassInfo)typeid(obj_);
108-
if (cInfo) {
109-
auto c = cInfo;
110-
111-
// Call destructors in order of most specific
112-
// to least-specific
113-
do {
114-
if (c.destructor)
115-
(cast(fp_t)c.destructor)(cast(Object)obj_);
116-
} while((c = c.base) !is null);
117-
118-
} else {
106+
static if (hasAnyDestructor!RealT) {
107+
static if (__traits(getLinkage, RealT) == "D") {
108+
auto cInfo = cast(ClassInfo)typeid(obj_);
109+
if (cInfo) {
110+
auto c = cInfo;
111+
112+
// Call destructors in order of most specific
113+
// to least-specific
114+
do {
115+
if (c.destructor)
116+
(cast(fp_t)c.destructor)(cast(Object)obj_);
117+
} while((c = c.base) !is null);
118+
119+
} else {
119120

120-
// Item is a struct, we can destruct it directly.
121-
static if (__traits(hasMember, RealT, "__xdtor")) {
122-
assumeNoGC(&obj_.__xdtor);
123-
} else static if (__traits(hasMember, RealT, "__dtor")) {
124-
assumeNoGC(&obj_.__dtor);
121+
// Item is a struct, we can destruct it directly.
122+
static if (__traits(hasMember, RealT, "__xdtor")) {
123+
assumeNoGC(&obj_.__xdtor);
124+
} else static if (__traits(hasMember, RealT, "__dtor")) {
125+
assumeNoGC(&obj_.__dtor);
126+
}
125127
}
126-
}
127-
} else static if (__traits(getLinkage, Unref!T) == "C++") {
128+
} else static if (__traits(getLinkage, RealT) == "C++") {
128129

129-
// C++ and Objective-C types may have D destructors declared
130-
// with extern(D), in that case, just call those.
130+
// C++ and Objective-C types may have D destructors declared
131+
// with extern(D), in that case, just call those.
131132

132-
static if (__traits(hasMember, RealT, "__xdtor")) {
133+
static if (__traits(hasMember, RealT, "__xdtor")) {
134+
assumeNoGC(&xdtor!T, obj_);
135+
}
136+
} else static if (__traits(hasMember, RealT, "__xdtor")) {
137+
138+
// Item is liekly a struct, we can destruct it directly.
133139
assumeNoGC(&xdtor!T, obj_);
134140
}
135-
} else static if (__traits(hasMember, RealT, "__xdtor")) {
136-
137-
// Item is liekly a struct, we can destruct it directly.
138-
assumeNoGC(&xdtor!T, obj_);
139141
}
140142
}
141143
} else {

source/numem/core/meta.d

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ alias AliasSeq(AliasList...) = AliasList;
2727
*/
2828
template allSatisfy(alias F, T...) {
2929
static foreach(U; T) {
30-
static if (!is(typeof(allSatisfy) == bool) && is(typeof(F!U)) && !F!(U))
30+
static if (!is(typeof(allSatisfy) == bool) && isValidTemplate!(F, U) && !F!(U))
3131
enum allSatisfy = false;
3232
}
3333

@@ -41,14 +41,19 @@ template allSatisfy(alias F, T...) {
4141
*/
4242
template anySatisfy(alias F, T...) {
4343
static foreach(U; T) {
44-
static if (!is(typeof(anySatisfy) == bool) && is(typeof(F!U)) && F!U)
44+
static if (!is(typeof(anySatisfy) == bool) && isValidTemplate!(F, U) && F!U)
4545
enum anySatisfy = true;
4646
}
4747

4848
static if (!is(typeof(anySatisfy) == bool))
4949
enum anySatisfy = false;
5050
}
5151

52+
/**
53+
Gets whether template invocation $(D F) is valid.
54+
*/
55+
enum isValidTemplate(alias F, Args...) = is(typeof(F!Args)) || is(F!Args);
56+
5257
/**
5358
Returns a sequence of F!(T[0]), F!(T[1]), ..., F!(T[$-1])
5459
*/

source/numem/core/traits.d

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ template Ref(T) {
103103
}
104104

105105
/**
106-
Gets the reference type version of type $(D T).
106+
Gets the value type version of type $(D T).
107107
*/
108108
template Unref(T) {
109109
static if (!isClasslike!T && isHeapAllocated!T)
@@ -179,6 +179,11 @@ enum isClasslike(T) =
179179
enum isStructLike(T) =
180180
is(T == struct) || is(T == union);
181181

182+
/**
183+
Gets whether $(D T) is a type.
184+
*/
185+
enum isType(T) = !is(typeof(T)) || is(T == void);
186+
182187
/**
183188
Gets whether the provided type is a scalar type.
184189
*/
@@ -397,7 +402,7 @@ enum rcReleaseNames = AliasSeq!("release", "Release");
397402
*/
398403
template hasRCReleaseFunction(T) {
399404
static if (isCOMClass!T || isValidObjectiveC!T) {
400-
enum hasRCRetainFunction = true;
405+
enum hasRCReleaseFunction = true;
401406
} else {
402407
enum hasRCFunc(string name) = __traits(hasMember, T, name) && is(typeof((ref T obj) { __traits(getMember, obj, name)(); }));
403408
enum hasRCReleaseFunction = anySatisfy!(hasRCFunc, rcReleaseNames);
@@ -493,14 +498,34 @@ template hasElaborateCopyConstructor(T) {
493498
*/
494499
template hasElaborateDestructor(T) {
495500
static if (isObjectiveC!T)
496-
enum hasElaborateDestructor = false;
501+
enum bool hasElaborateDestructor = false;
497502
else static if (__traits(isStaticArray, T))
498503
enum bool hasElaborateDestructor = T.sizeof && hasElaborateDestructor!(BaseElemOf!T);
499504
else static if (isAggregateType!T)
500-
enum hasElaborateDestructor = __traits(hasMember, T, "__dtor") ||
505+
enum bool hasElaborateDestructor = __traits(hasMember, T, "__dtor") ||
501506
anySatisfy!(.hasElaborateDestructor, Fields!T);
502507
else
503-
enum hasElaborateDestructor = false;
508+
enum bool hasElaborateDestructor = false;
509+
}
510+
511+
/**
512+
Gets whether type $(D T) has any destructor semantics, whether explicit
513+
or implicit.
514+
*/
515+
template hasAnyDestructor(T) {
516+
static if (isObjectiveC!T)
517+
enum bool hasAnyDestructor = false;
518+
else static if (__traits(isStaticArray, T))
519+
enum bool hasAnyDestructor = T.sizeof && hasAnyDestructor!(BaseElemOf!T);
520+
else static if (isAggregateType!T)
521+
enum bool hasAnyDestructor =
522+
is(T == class) || // Classes have implicit destructors
523+
is(T == interface) || // Interfaces have implicit destructors
524+
__traits(hasMember, T, "__xdtor") ||
525+
__traits(hasMember, T, "__dtor") ||
526+
anySatisfy!(.hasAnyDestructor, Fields!T);
527+
else
528+
enum bool hasAnyDestructor = false;
504529
}
505530

506531
/**

source/numem/lifetime.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ void nogc_delete(T, bool doFree=true)(T[] objects) @trusted {
270270
*/
271271
bool nogc_trydelete(T, bool doFree=true)(ref T obj_) @trusted nothrow {
272272
try {
273-
nogc_delete(obj_);
273+
nogc_delete!(T, doFree)(obj_);
274274
return true;
275275

276276
} catch (Exception ex) {
@@ -300,7 +300,7 @@ bool nogc_trydelete(T, bool doFree=true)(NuHeap heap, ref T obj_) @trusted nothr
300300
static if (isHeapAllocated!T) {
301301
try {
302302

303-
nogc_delete(heap, obj_);
303+
nogc_delete!(T, doFree)(heap, obj_);
304304
return true;
305305
} catch (Exception ex) {
306306

0 commit comments

Comments
 (0)