Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions std/functional.d
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ Distributed under the Boost Software License, Version 1.0.
*/
module std.functional;

import std.meta, std.traits;
import std.meta; // AliasSeq, Reverse
import std.traits; // isCallable, Parameters
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AliasSeq is only called from one unittest block and Parameters from four templates, but if I make these two symbols into local selective imports and have only the two remaining symbols selectively imported at module scope, I started getting template instantiation errors. Not sure what's going on, so just moved those two up here.



private template needOpCallAlias(alias fun)
Expand All @@ -82,8 +83,6 @@ private template needOpCallAlias(alias fun)
*/
static if (is(typeof(fun.opCall) == function))
{
import std.traits : Parameters;

enum needOpCallAlias = !is(typeof(fun)) && __traits(compiles, () {
return fun(Parameters!fun.init);
});
Expand Down Expand Up @@ -305,7 +304,6 @@ private uint _ctfeSkipName(ref string op, string name)
private uint _ctfeMatchUnary(string fun, string name)
{
if (!__ctfe) assert(false);
import std.stdio;
fun._ctfeSkipOp();
for (;;)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unused import was causing a shared ctor cycle after changing the imports in std.range.

{
Expand Down Expand Up @@ -421,15 +419,18 @@ unittest
template safeOp(string S)
if (S=="<"||S==">"||S=="<="||S==">="||S=="=="||S=="!=")
{
import std.traits : isIntegral;
private bool unsafeOp(ElementType1, ElementType2)(ElementType1 a, ElementType2 b) pure
if (isIntegral!ElementType1 && isIntegral!ElementType2)
{
import std.traits : CommonType;
alias T = CommonType!(ElementType1, ElementType2);
return mixin("cast(T)a "~S~" cast(T)b");
}

bool safeOp(T0, T1)(auto ref T0 a, auto ref T1 b)
{
import std.traits : mostNegative;
static if (isIntegral!T0 && isIntegral!T1 &&
(mostNegative!T0 < 0) != (mostNegative!T1 < 0))
{
Expand Down Expand Up @@ -461,7 +462,7 @@ template safeOp(string S)

unittest //check user defined types
{
import std.algorithm : equal;
import std.algorithm.comparison : equal;
struct Foo
{
int a;
Expand Down Expand Up @@ -630,8 +631,8 @@ template not(alias pred)
///
unittest
{
import std.algorithm.searching : find;
import std.functional;
import std.algorithm : find;
import std.uni : isWhite;
string a = " Hello, world!";
assert(find!(not!isWhite)(a) == "Hello, world!");
Expand All @@ -656,6 +657,7 @@ template partial(alias fun, alias arg)
{
static if (is(typeof(fun) == delegate) || is(typeof(fun) == function))
{
import std.traits : ReturnType;
ReturnType!fun partial(Parameters!fun[1..$] args2)
{
return fun(arg, args2);
Expand Down Expand Up @@ -823,7 +825,7 @@ template adjoin(F...) if (F.length > 1)
///
unittest
{
import std.functional, std.typecons;
import std.functional, std.typecons : Tuple;
static bool f1(int a) { return a != 0; }
static int f2(int a) { return a / 2; }
auto x = adjoin!(f1, f2)(5);
Expand All @@ -833,7 +835,7 @@ unittest

unittest
{
import std.typecons;
import std.typecons : Tuple;
static bool F1(int a) { return a != 0; }
auto x1 = adjoin!(F1)(5);
static int F2(int a) { return a / 2; }
Expand Down Expand Up @@ -910,7 +912,8 @@ template compose(fun...)
///
unittest
{
import std.algorithm : equal, map;
import std.algorithm.comparison : equal;
import std.algorithm.iteration : map;
import std.array : split;
import std.conv : to;

Expand Down Expand Up @@ -982,6 +985,7 @@ is useful to memoize an impure function, too.
*/
template memoize(alias fun)
{
import std.traits : ReturnType;
// alias Args = Parameters!fun; // Bugzilla 13580

ReturnType!fun memoize(Parameters!fun args)
Expand All @@ -1000,17 +1004,19 @@ template memoize(alias fun)
/// ditto
template memoize(alias fun, uint maxSize)
{
import std.traits : ReturnType;
// alias Args = Parameters!fun; // Bugzilla 13580
ReturnType!fun memoize(Parameters!fun args)
{
import std.traits : hasIndirections;
import std.typecons : tuple;
static struct Value { Parameters!fun args; ReturnType!fun res; }
static Value[] memo;
static size_t[] initialized;

if (!memo.length)
{
import core.memory;
import core.memory : GC;

enum attr = GC.BlkAttr.NO_INTERIOR | (hasIndirections!Value ? 0 : GC.BlkAttr.NO_SCAN);
memo = (cast(Value*)GC.malloc(Value.sizeof * maxSize, attr))[0 .. maxSize];
Expand Down Expand Up @@ -1108,7 +1114,7 @@ unittest

unittest
{
import core.math;
import core.math : sqrt;
alias msqrt = memoize!(function double(double x) { return sqrt(x); });
auto y = msqrt(2.0);
assert(y == msqrt(2.0));
Expand Down Expand Up @@ -1154,7 +1160,7 @@ unittest

private struct DelegateFaker(F)
{
import std.typecons;
import std.typecons : FuncInfo, MemberFunctionGenerator;

// for @safe
static F castToF(THIS)(THIS x) @trusted
Expand Down Expand Up @@ -1203,7 +1209,7 @@ private struct DelegateFaker(F)
alias FuncInfo_doIt = FuncInfo!(F);

// Generate the member function doIt().
mixin( std.typecons.MemberFunctionGenerator!(GeneratingPolicy!())
mixin( MemberFunctionGenerator!(GeneratingPolicy!())
.generateFunction!("FuncInfo_doIt", "doIt", F) );
}

Expand Down Expand Up @@ -1371,8 +1377,6 @@ Forwards function arguments with saving ref-ness.
*/
template forward(args...)
{
import std.meta;

static if (args.length)
{
import std.algorithm.mutation : move;
Expand Down
Loading