Full closures for D
Walter Bright
newshound1 at digitalmars.com
Fri Nov 2 14:03:59 PDT 2007
D 2.007 brings full closures to D. I was tired of D being denigrated for
not having "real" closures.
Here are some test cases for it, so you can see what it does:
-------------------------------------------
struct S { int a,b,c,d; }
alias int delegate() dg_t;
alias int delegate(int) dg1_t;
void fill()
{
int[100] x;
}
/************************************/
dg_t foo()
{
int x = 7;
int bar()
{
return x + 3;
}
return &bar;
}
void test1()
{
dg_t dg = foo();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo2()
{
dg_t abc()
{
int x = 7;
int bar()
{
return x + 3;
}
return &bar;
}
return abc();
}
void test2()
{
dg_t dg = foo2();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo3()
{
dg_t abc(int x)
{
int bar()
{
return x + 3;
}
return &bar;
}
return abc(7);
}
void test3()
{
dg_t dg = foo3();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo4()
{ S s;
s = S(4,5,6,7);
dg_t abc(S t)
{
int bar()
{
return t.d + 3;
}
return &bar;
}
return abc(s);
}
void test4()
{
dg_t dg = foo4();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
void test5()
{ int x = 7;
dg_t abc(ref int y)
{
int bar()
{ y += 4;
return y + 3;
}
return &bar;
}
dg_t dg = abc(x);
fill();
assert(x == 7);
auto i = dg();
assert(x == 11);
assert(i == 14);
x = 8;
i = dg();
assert(x == 12);
assert(i == 15);
}
/************************************/
void test6()
{ int x = 7;
dg_t abc(out int y)
{
int bar()
{ y += 4;
return y + 3;
}
return &bar;
}
dg_t dg = abc(x);
fill();
assert(x == 0);
auto i = dg();
assert(x == 4);
assert(i == 7);
x = 8;
i = dg();
assert(x == 12);
assert(i == 15);
}
/************************************/
void test7()
{ int[3] a = [10,11,12];
dg_t abc(int[3] y)
{
int bar()
{ y[2] += 4;
return y[2] + 3;
}
return &bar;
}
dg_t dg = abc(a);
fill();
assert(a[2] == 12);
auto i = dg();
assert(a[2] == 16);
assert(i == 19);
}
/************************************/
void test8()
{ S s = S(7,8,9,10);
dg_t abc(ref S t)
{
int bar()
{ t.d += 4;
return t.c + 3;
}
return &bar;
}
dg_t dg = abc(s);
fill();
assert(s.d == 10);
auto i = dg();
assert(s.d == 14);
assert(i == 12);
}
/************************************/
S foo9(out dg_t dg)
{ S s1 = S(7,8,9,10);
dg_t abc()
{
int bar()
{ s1.d += 4;
return s1.c + 3;
}
return &bar;
}
dg = abc();
return s1;
}
void test9()
{ dg_t dg;
S s = foo9(dg);
fill();
assert(s.a == 7);
assert(s.b == 8);
assert(s.c == 9);
assert(s.d == 10);
auto i = dg();
assert(s.d == 10);
assert(i == 12);
}
/************************************/
dg_t foo10()
{
dg_t abc()
{
int x = 7;
int bar()
{
int def()
{
return x + 3;
}
return def();
}
return &bar;
}
return abc();
}
void test10()
{
dg_t dg = foo10();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo11()
{
int x = 7;
class T
{
int bar()
{
return x + 3;
}
}
T t = new T;
return &t.bar;
}
void test11()
{
dg_t dg = foo11();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo12()
{
int x = 7;
class T
{
int bar()
{
return x + 3;
}
int xyz()
{
return bar();
}
}
T t = new T;
return &t.xyz;
}
void test12()
{
dg_t dg = foo12();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo13()
{
int x = 7;
class T
{
int xyz()
{
int bar()
{
return x + 3;
}
return bar();
}
}
T t = new T;
return &t.xyz;
}
void test13()
{
dg_t dg = foo13();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo14()
{
class T
{
int xyz()
{ int x = 7;
int bar()
{
return x + 3;
}
return bar();
}
}
T t = new T;
return &t.xyz;
}
void test14()
{
dg_t dg = foo14();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo15()
{
class T
{ int x = 7;
int xyz()
{
int bar()
{
return x + 3;
}
return bar();
}
}
T t = new T;
return &t.xyz;
}
void test15()
{
dg_t dg = foo15();
fill();
printf("bar = %d\n", dg());
assert(dg() == 10);
}
/************************************/
dg_t foo16()
{ int a = 5;
class T
{ int x = 7;
int xyz()
{ int y = 8;
int bar()
{
return a + x + y + 3;
}
return bar();
}
}
T t = new T;
return &t.xyz;
}
void test16()
{
dg_t dg = foo16();
fill();
printf("bar = %d\n", dg());
assert(dg() == 23);
}
/************************************/
dg_t foo17()
{ int a = 5;
class T
{ int x = 7;
dg_t xyz()
{ int y = 8;
int bar()
{
return a + x + y + 3;
}
return &bar;
}
}
T t = new T;
return t.xyz();
}
void test17()
{
dg_t dg = foo17();
fill();
printf("bar = %d\n", dg());
assert(dg() == 23);
}
/************************************/
dg_t dg18;
void bar18()
{ int a = 7;
int foo() { return a + 3; }
dg18 = &foo;
int i = dg18();
assert(i == 10);
}
void test18()
{
bar18();
fill();
int i = dg18();
assert(i == 10);
}
/************************************/
void abc19(void delegate() dg)
{
dg();
dg();
dg();
}
struct S19
{
static S19 call(int v)
{
S19 result;
result.v = v;
void nest()
{
result.v += 1;
}
abc19(&nest);
return result;
}
int a;
int v;
int x,y,z;
}
int foo19()
{
auto s = S19.call(5);
return s.v;
}
void test19()
{
int i = foo19();
printf("%d\n", i);
assert(i == 8);
}
/************************************/
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
test10();
test11();
test12();
test13();
test14();
test15();
test16();
test17();
test18();
test19();
printf("Success\n");
return 0;
}
More information about the Digitalmars-d
mailing list