mirror of
https://github.com/dlang/phobos.git
synced 2025-05-02 08:00:48 +03:00
Merge pull request #544 from 9rnsr/fix7878
Issue 7878 - A problem with purity and general templated algorithms
This commit is contained in:
commit
8e37bf3d01
2 changed files with 11 additions and 105 deletions
|
@ -6977,7 +6977,8 @@ sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable,
|
|||
Range)(Range r)
|
||||
{
|
||||
alias binaryFun!(less) lessFun;
|
||||
static if (is(typeof(lessFun(r.front, r.front)) == bool))
|
||||
alias typeof(lessFun(r.front, r.front)) LessRet; // instantiate lessFun
|
||||
static if (is(LessRet == bool))
|
||||
{
|
||||
sortImpl!(lessFun, ss)(r);
|
||||
static if(is(typeof(text(r))))
|
||||
|
|
113
std/functional.d
113
std/functional.d
|
@ -40,57 +40,21 @@ template unaryFun(alias fun, bool byRef = false, string parmName = "a")
|
|||
{
|
||||
static if (is(typeof(fun) : string))
|
||||
{
|
||||
template Body(ElementType)
|
||||
{
|
||||
// enum testAsExpression = "{"~ElementType.stringof
|
||||
// ~" "~parmName~"; return ("~fun~");}()";
|
||||
enum testAsExpression = "{ ElementType "~parmName
|
||||
~"; return ("~fun~");}()";
|
||||
enum testAsStmts = "{"~ElementType.stringof
|
||||
~" "~parmName~"; "~fun~"}()";
|
||||
// pragma(msg, "Expr: "~testAsExpression);
|
||||
// pragma(msg, "Stmts: "~testAsStmts);
|
||||
static if (__traits(compiles, mixin(testAsExpression)))
|
||||
{
|
||||
enum string code = "return (" ~ fun ~ ");";
|
||||
alias typeof(mixin(testAsExpression)) ReturnType;
|
||||
}
|
||||
// else static if (__traits(compiles, mixin(testAsStmts)))
|
||||
// {
|
||||
// enum string code = fun;
|
||||
// alias typeof(mixin(testAsStmts)) ReturnType;
|
||||
// }
|
||||
else
|
||||
{
|
||||
// Credit for this idea goes to Don Clugston
|
||||
// static assert is a bit broken,
|
||||
// better to do it this way to provide a backtrace.
|
||||
// pragma(msg, "Bad unary function: " ~ fun ~ " for type "
|
||||
// ~ ElementType.stringof);
|
||||
static assert(false, "Bad unary function: " ~ fun ~
|
||||
" for type " ~ ElementType.stringof);
|
||||
}
|
||||
}
|
||||
|
||||
static if (byRef)
|
||||
{
|
||||
Body!(ElementType).ReturnType unaryFun(ElementType)(ref ElementType __a)
|
||||
auto unaryFun(ElementType)(ref ElementType __a)
|
||||
{
|
||||
mixin("alias __a "~parmName~";");
|
||||
mixin(Body!(ElementType).code);
|
||||
mixin("return (" ~ fun ~ ");");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Body!(ElementType).ReturnType unaryFun(ElementType)(ElementType __a)
|
||||
auto unaryFun(ElementType)(ElementType __a)
|
||||
{
|
||||
mixin("alias __a "~parmName~";");
|
||||
mixin(Body!(ElementType).code);
|
||||
mixin("return (" ~ fun ~ ");");
|
||||
}
|
||||
// string mixme = "Body!(ElementType).ReturnType"
|
||||
// " unaryFun(ElementType)(ElementType a)
|
||||
// { " ~ Body!(ElementType).code ~ " }";
|
||||
// mixin(mixme);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -134,76 +98,18 @@ template binaryFun(alias fun, string parm1Name = "a",
|
|||
{
|
||||
static if (is(typeof(fun) : string))
|
||||
{
|
||||
template Body(ElementType1, ElementType2)
|
||||
{
|
||||
enum testAsExpression = "{ ElementType1 "
|
||||
~parm1Name~"; ElementType2 "
|
||||
~parm2Name~"; return ("~fun~");}()";
|
||||
// enum testAsExpression = "{"~ElementType1.stringof
|
||||
// ~" "~parm1Name~"; "~ElementType2.stringof
|
||||
// ~" "~parm2Name~"; return ("~fun~");}()";
|
||||
// enum testAsStmts = "{"~ElementType1.stringof
|
||||
// ~" "~parm1Name~"; "~ElementType2.stringof
|
||||
// ~" "~parm2Name~"; "~fun~"}()";
|
||||
static if (__traits(compiles, mixin(testAsExpression)))
|
||||
{
|
||||
enum string code = "return (" ~ fun ~ ");";
|
||||
alias typeof(mixin(testAsExpression)) ReturnType;
|
||||
}
|
||||
// else static if (__traits(compiles, mixin(testAsStmts)))
|
||||
// {
|
||||
// enum string code = fun;
|
||||
// alias typeof(mixin(testAsStmts)) ReturnType;
|
||||
// }
|
||||
else
|
||||
{
|
||||
// Credit for this idea goes to Don Clugston
|
||||
enum string msg =
|
||||
"Bad binary function q{" ~ fun ~ "}."
|
||||
~" You need to use a valid D expression using symbols "
|
||||
~parm1Name~" of type "~ElementType1.stringof~" and "
|
||||
~parm2Name~" of type "~ElementType2.stringof~"."
|
||||
~(fun.length && fun[$ - 1] == ';'
|
||||
? " The trailing semicolon is _not_ needed."
|
||||
: "")
|
||||
~(fun.length && fun[$ - 1] == '}'
|
||||
? " The trailing bracket is mistaken."
|
||||
: "");
|
||||
static assert(false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
Body!(ElementType1, ElementType2).ReturnType
|
||||
binaryFun(ElementType1, ElementType2)
|
||||
auto binaryFun(ElementType1, ElementType2)
|
||||
(ElementType1 __a, ElementType2 __b)
|
||||
{
|
||||
mixin("alias __a "~parm1Name~";");
|
||||
mixin("alias __b "~parm2Name~";");
|
||||
mixin(Body!(ElementType1, ElementType2).code);
|
||||
mixin("return (" ~ fun ~ ");");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
alias fun binaryFun;
|
||||
}
|
||||
// static if (is(typeof(comp) : string))
|
||||
// {
|
||||
// // @@@BUG1816@@@: typeof(mixin(comp)) should work
|
||||
// typeof({
|
||||
// static ElementType1 a;
|
||||
// static ElementType2 b;
|
||||
// return mixin(comp);
|
||||
// }())
|
||||
// binaryFun(ElementType1, ElementType2)
|
||||
// (ElementType1 a, ElementType2 b)
|
||||
// {
|
||||
// return mixin(comp);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// alias comp binaryFun;
|
||||
// }
|
||||
}
|
||||
|
||||
unittest
|
||||
|
@ -239,15 +145,14 @@ unittest
|
|||
*/
|
||||
//alias binaryFun!(q{a == b}) equalTo;
|
||||
|
||||
/*
|
||||
/**
|
||||
Binary predicate that reverses the order of arguments, e.g., given
|
||||
$(D pred(a, b)), returns $(D pred(b, a)).
|
||||
*/
|
||||
template binaryReverseArgs(alias pred)
|
||||
{
|
||||
typeof({ ElementType1 a; ElementType2 b; return pred(b, a);}())
|
||||
binaryReverseArgs(ElementType1, ElementType2)(ElementType1 a,
|
||||
ElementType2 b)
|
||||
auto binaryReverseArgs(ElementType1, ElementType2)
|
||||
(ElementType1 a, ElementType2 b)
|
||||
{
|
||||
return pred(b, a);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue