Compensate for broken isFunction in Phobos by rolling own implementation (Fixes #32)

This commit is contained in:
Mike Bierlee 2021-05-01 20:22:27 +03:00
parent edfa5cdffb
commit 6ab7795463
4 changed files with 69 additions and 37 deletions

View file

@ -0,0 +1,44 @@
/**
* Tweaks to Phobos's standard templates.
*
* Implementations copied and adapted from std.traits;
*
* Authors: $(HTTP erdani.org, Andrei Alexandrescu),
* Jonathan M Davis,
* $(HTTP digitalmars.com, Walter Bright),
* Tomasz Stachowiak ($(D isExpressions)),
* $(HTTP erdani.org, Andrei Alexandrescu),
* Shin Fujishiro,
* $(HTTP octarineparrot.com, Robert Clipsham),
* $(HTTP klickverbot.at, David Nadlinger),
* Kenji Hara,
* Shoichi Kato,
* Mike Bierlee (m.bierlee@lostmoment.com)
* Copyright: Copyright Digital Mars 2005 - 2009., Copyright Andrei Alexandrescu 2008-, Jonathan M Davis 2011-., 2014-2021 Mike Bierlee
* License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0)
*/
module poodinis.altphobos;
template isFunction(X...)
{
static if (X.length == 1)
{
static if (is(typeof(&X[0]) U : U*) && is(U == function) || is(typeof(&X[0]) U == delegate))
{
// x is a (nested) function symbol.
enum isFunction = true;
}
else static if (is(X[0] T))
{
// x is a type. Take the type of it and examine.
enum isFunction = is(T == function);
}
else
enum isFunction = false;
}
else
{
enum isFunction = false;
}
}

View file

@ -21,14 +21,17 @@ import poodinis.container;
import poodinis.registration; import poodinis.registration;
import poodinis.factory; import poodinis.factory;
import poodinis.valueinjection; import poodinis.valueinjection;
import poodinis.polyfill; import poodinis.altphobos : isFunction;
import poodinis.imports; import poodinis.imports;
import std.exception; import std.exception : enforce;
import std.stdio; import std.string : format;
import std.string; import std.traits : BaseClassesTuple, FieldNameTuple, fullyQualifiedName, hasUDA, isDynamicArray;
import std.traits; import std.range : ElementType;
import std.range;
debug {
import std.stdio : writeln;
}
private struct UseMemberType {} private struct UseMemberType {}
@ -92,7 +95,9 @@ struct OptionalDependency {}
struct AssignNewInstance {} struct AssignNewInstance {}
private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAddress) { private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAddress) {
debug {
writeln(format("DEBUG: Autowiring members of [%s@%s]", instanceType, instanceAddress)); writeln(format("DEBUG: Autowiring members of [%s@%s]", instanceType, instanceAddress));
}
} }
/** /**
@ -121,11 +126,15 @@ public void autowire(Type)(shared(DependencyContainer) container, Type instance)
} }
private void printDebugAutowiringCandidate(TypeInfo candidateInstanceType, void* candidateInstanceAddress, TypeInfo instanceType, void* instanceAddress, string member) { private void printDebugAutowiringCandidate(TypeInfo candidateInstanceType, void* candidateInstanceAddress, TypeInfo instanceType, void* instanceAddress, string member) {
debug {
writeln(format("DEBUG: Autowired instance [%s@%s] to [%s@%s].%s", candidateInstanceType, candidateInstanceAddress, instanceType, instanceAddress, member)); writeln(format("DEBUG: Autowired instance [%s@%s] to [%s@%s].%s", candidateInstanceType, candidateInstanceAddress, instanceType, instanceAddress, member));
}
} }
private void printDebugAutowiringArray(TypeInfo superTypeInfo, TypeInfo instanceType, void* instanceAddress, string member) { private void printDebugAutowiringArray(TypeInfo superTypeInfo, TypeInfo instanceType, void* instanceAddress, string member) {
debug {
writeln(format("DEBUG: Autowired all registered instances of super type %s to [%s@%s].%s", superTypeInfo, instanceType, instanceAddress, member)); writeln(format("DEBUG: Autowired all registered instances of super type %s to [%s@%s].%s", superTypeInfo, instanceType, instanceAddress, member));
}
} }
private void autowireMember(string member, size_t memberIndex, Type)(shared(DependencyContainer) container, Type instance) { private void autowireMember(string member, size_t memberIndex, Type)(shared(DependencyContainer) container, Type instance) {
@ -227,7 +236,9 @@ private void injectValue(string member, size_t memberIndex, string key, bool man
} }
private void printDebugValueInjection(TypeInfo instanceType, void* instanceAddress, string member, TypeInfo valueType, string key) { private void printDebugValueInjection(TypeInfo instanceType, void* instanceAddress, string member, TypeInfo valueType, string key) {
debug {
writeln(format("DEBUG: Injected value with key '%s' of type %s into [%s@%s].%s", key, valueType, instanceType, instanceAddress, member)); writeln(format("DEBUG: Injected value with key '%s' of type %s into [%s@%s].%s", key, valueType, instanceType, instanceAddress, member));
}
} }
/** /**

View file

@ -18,13 +18,12 @@ import poodinis.autowire;
import poodinis.context; import poodinis.context;
import poodinis.factory; import poodinis.factory;
import poodinis.valueinjection; import poodinis.valueinjection;
import poodinis.polyfill; import poodinis.altphobos : isFunction;
import poodinis.imports; import poodinis.imports;
import std.string; import std.string : format;
import std.algorithm; import std.algorithm: canFind;
import std.concurrency; import std.traits : fullyQualifiedName, hasUDA, BaseTypeTuple;
import std.traits;
import std.meta : AliasSeq; import std.meta : AliasSeq;
debug { debug {

View file

@ -42,25 +42,3 @@ static if (!__traits(compiles, basicExceptionCtors)) {
} }
} }
} }
static if (!__traits(compiles, isFunction)) {
template isFunction(X...)
{
static if (X.length > 1) {
enum isFunction = false;
} else
static if (is(typeof(&X[0]) U : U*) && is(U == function) ||
is(typeof(&X[0]) U == delegate))
{
// x is a (nested) function symbol.
enum isFunction = true;
}
else static if (is(X[0] T))
{
// x is a type. Take the type of it and examine.
enum isFunction = is(T == function);
}
else
enum isFunction = false;
}
}