mirror of
https://github.com/dlang/phobos.git
synced 2025-05-02 08:00:48 +03:00
Move 'forward' to std.functional.
This commit is contained in:
parent
e8ce21d16a
commit
a43e8d22cd
2 changed files with 99 additions and 109 deletions
|
@ -183,115 +183,6 @@ public import std.algorithm.setops;
|
||||||
public import std.algorithm.searching;
|
public import std.algorithm.searching;
|
||||||
public import std.algorithm.sorting;
|
public import std.algorithm.sorting;
|
||||||
|
|
||||||
// FIXME
|
|
||||||
import std.functional; // : unaryFun, binaryFun;
|
|
||||||
import std.range.primitives;
|
|
||||||
// FIXME
|
|
||||||
import std.range; // : SortedRange;
|
|
||||||
import std.traits;
|
|
||||||
// FIXME
|
|
||||||
import std.typecons; // : tuple, Tuple;
|
|
||||||
// FIXME
|
|
||||||
import std.typetuple; // : TypeTuple, staticMap, allSatisfy, anySatisfy;
|
|
||||||
|
|
||||||
version(unittest) debug(std_algorithm) import std.stdio;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Forwards function arguments with saving ref-ness.
|
|
||||||
*/
|
|
||||||
template forward(args...)
|
|
||||||
{
|
|
||||||
import std.typetuple;
|
|
||||||
|
|
||||||
static if (args.length)
|
|
||||||
{
|
|
||||||
alias arg = args[0];
|
|
||||||
static if (__traits(isRef, arg))
|
|
||||||
alias fwd = arg;
|
|
||||||
else
|
|
||||||
@property fwd()(){ return move(arg); }
|
|
||||||
alias forward = TypeTuple!(fwd, forward!(args[1..$]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
alias forward = TypeTuple!();
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@safe unittest
|
|
||||||
{
|
|
||||||
class C
|
|
||||||
{
|
|
||||||
static int foo(int n) { return 1; }
|
|
||||||
static int foo(ref int n) { return 2; }
|
|
||||||
}
|
|
||||||
int bar()(auto ref int x) { return C.foo(forward!x); }
|
|
||||||
|
|
||||||
assert(bar(1) == 1);
|
|
||||||
int i;
|
|
||||||
assert(bar(i) == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
@safe unittest
|
|
||||||
{
|
|
||||||
void foo(int n, ref string s) { s = null; foreach (i; 0..n) s ~= "Hello"; }
|
|
||||||
|
|
||||||
// forwards all arguments which are bound to parameter tuple
|
|
||||||
void bar(Args...)(auto ref Args args) { return foo(forward!args); }
|
|
||||||
|
|
||||||
// forwards all arguments with swapping order
|
|
||||||
void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
|
|
||||||
|
|
||||||
string s;
|
|
||||||
bar(1, s);
|
|
||||||
assert(s == "Hello");
|
|
||||||
baz(s, 2);
|
|
||||||
assert(s == "HelloHello");
|
|
||||||
}
|
|
||||||
|
|
||||||
@safe unittest
|
|
||||||
{
|
|
||||||
auto foo(TL...)(auto ref TL args)
|
|
||||||
{
|
|
||||||
string result = "";
|
|
||||||
foreach (i, _; args)
|
|
||||||
{
|
|
||||||
//pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
|
|
||||||
result ~= __traits(isRef, args[i]) ? "L" : "R";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
string bar(TL...)(auto ref TL args)
|
|
||||||
{
|
|
||||||
return foo(forward!args);
|
|
||||||
}
|
|
||||||
string baz(TL...)(auto ref TL args)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct S {}
|
|
||||||
S makeS(){ return S(); }
|
|
||||||
int n;
|
|
||||||
string s;
|
|
||||||
assert(bar(S(), makeS(), n, s) == "RRLL");
|
|
||||||
assert(baz(S(), makeS(), n, s) == "LLRRRL");
|
|
||||||
}
|
|
||||||
|
|
||||||
@safe unittest
|
|
||||||
{
|
|
||||||
ref int foo(return ref int a) { return a; }
|
|
||||||
ref int bar(Args)(auto ref Args args)
|
|
||||||
{
|
|
||||||
return foo(forward!args);
|
|
||||||
}
|
|
||||||
static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
|
|
||||||
int value = 3;
|
|
||||||
auto x2 = bar(value); // case of OK
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Specifies whether the output of certain algorithm is desired in sorted
|
Specifies whether the output of certain algorithm is desired in sorted
|
||||||
format.
|
format.
|
||||||
|
|
|
@ -1359,3 +1359,102 @@ unittest {
|
||||||
static assert(! is(typeof(dg_xtrnC) == typeof(dg_xtrnD)));
|
static assert(! is(typeof(dg_xtrnC) == typeof(dg_xtrnD)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Forwards function arguments with saving ref-ness.
|
||||||
|
*/
|
||||||
|
template forward(args...)
|
||||||
|
{
|
||||||
|
import std.typetuple;
|
||||||
|
|
||||||
|
static if (args.length)
|
||||||
|
{
|
||||||
|
import std.algorithm.mutation : move;
|
||||||
|
|
||||||
|
alias arg = args[0];
|
||||||
|
static if (__traits(isRef, arg))
|
||||||
|
alias fwd = arg;
|
||||||
|
else
|
||||||
|
@property fwd()(){ return move(arg); }
|
||||||
|
alias forward = TypeTuple!(fwd, forward!(args[1..$]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
alias forward = TypeTuple!();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
class C
|
||||||
|
{
|
||||||
|
static int foo(int n) { return 1; }
|
||||||
|
static int foo(ref int n) { return 2; }
|
||||||
|
}
|
||||||
|
int bar()(auto ref int x) { return C.foo(forward!x); }
|
||||||
|
|
||||||
|
assert(bar(1) == 1);
|
||||||
|
int i;
|
||||||
|
assert(bar(i) == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
void foo(int n, ref string s) { s = null; foreach (i; 0..n) s ~= "Hello"; }
|
||||||
|
|
||||||
|
// forwards all arguments which are bound to parameter tuple
|
||||||
|
void bar(Args...)(auto ref Args args) { return foo(forward!args); }
|
||||||
|
|
||||||
|
// forwards all arguments with swapping order
|
||||||
|
void baz(Args...)(auto ref Args args) { return foo(forward!args[$/2..$], forward!args[0..$/2]); }
|
||||||
|
|
||||||
|
string s;
|
||||||
|
bar(1, s);
|
||||||
|
assert(s == "Hello");
|
||||||
|
baz(s, 2);
|
||||||
|
assert(s == "HelloHello");
|
||||||
|
}
|
||||||
|
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
auto foo(TL...)(auto ref TL args)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
foreach (i, _; args)
|
||||||
|
{
|
||||||
|
//pragma(msg, "[",i,"] ", __traits(isRef, args[i]) ? "L" : "R");
|
||||||
|
result ~= __traits(isRef, args[i]) ? "L" : "R";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string bar(TL...)(auto ref TL args)
|
||||||
|
{
|
||||||
|
return foo(forward!args);
|
||||||
|
}
|
||||||
|
string baz(TL...)(auto ref TL args)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
return foo(forward!args[3], forward!args[2], 1, forward!args[1], forward!args[0], x);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {}
|
||||||
|
S makeS(){ return S(); }
|
||||||
|
int n;
|
||||||
|
string s;
|
||||||
|
assert(bar(S(), makeS(), n, s) == "RRLL");
|
||||||
|
assert(baz(S(), makeS(), n, s) == "LLRRRL");
|
||||||
|
}
|
||||||
|
|
||||||
|
@safe unittest
|
||||||
|
{
|
||||||
|
ref int foo(return ref int a) { return a; }
|
||||||
|
ref int bar(Args)(auto ref Args args)
|
||||||
|
{
|
||||||
|
return foo(forward!args);
|
||||||
|
}
|
||||||
|
static assert(!__traits(compiles, { auto x1 = bar(3); })); // case of NG
|
||||||
|
int value = 3;
|
||||||
|
auto x2 = bar(value); // case of OK
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue