blob: 4c0836a96dc88f484d2f896abc38489e6ca74d4d [file] [log] [blame]
// RUNNABLE_PHOBOS_TEST
import std.math;
extern(C) int printf(const char*, ...);
string abc;
template Floating(T)
{
T[3] a;
T[3] b;
T[3] c;
T[] A()
{
printf("A\n");
abc ~= "A";
return a;
}
T[] B()
{
printf("B\n");
abc ~= "B";
return b;
}
T[] C()
{
printf("C\n");
abc ~= "C";
return c;
}
T D()
{
printf("D\n");
abc ~= "D";
return 4;
}
void testx()
{
a = [11, 22, 33];
b = [1, 2, 3];
c = [4, 5, 6];
abc = null;
A()[] = B()[] + C()[];
assert(abc == "ABC");
assert(a[0] == 5);
assert(a[1] == 7);
assert(a[2] == 9);
abc = null;
A()[] = B()[] + 4;
assert(abc == "AB");
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
abc = null;
A()[] = 4 + B()[];
assert(abc == "AB");
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
abc = null;
A()[] = D() + B()[];
assert(abc == "ADB");
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
a = [11, 22, 33];
abc = null;
A()[] += B()[];
assert(abc == "AB");
assert(a[0] == 12);
assert(a[1] == 24);
assert(a[2] == 36);
a = [11, 22, 33];
A()[] += 4;
assert(a[0] == 15);
assert(a[1] == 26);
assert(a[2] == 37);
a = [11, 22, 33];
A()[] -= 4;
assert(a[0] == 7);
assert(a[1] == 18);
assert(a[2] == 29);
a = [11, 22, 33];
A()[] *= 4;
assert(a[0] == 44);
assert(a[1] == 88);
assert(a[2] == 132);
a = [4, 8, 32];
A()[] /= 4;
assert(a[0] == 1);
assert(a[1] == 2);
assert(a[2] == 8);
a = [4, 8, 33];
A()[] %= 4;
assert(a[0] == 0);
assert(a[1] == 0);
assert(a[2] == 1);
a = [11, 22, 33];
abc = null;
A()[] += 4 + B()[];
assert(abc == "AB");
assert(a[0] == 16);
assert(a[1] == 28);
assert(a[2] == 40);
abc = null;
A()[] = B()[] - C()[];
assert(abc == "ABC");
printf("%Lg, %Lg, %Lg\n", cast(real)a[0], cast(real)a[1], cast(real)a[2]);
assert(a[0] == -3);
assert(a[1] == -3);
assert(a[2] == -3);
abc = null;
A()[] = -B()[] - C()[];
assert(abc == "ABC");
printf("%Lg, %Lg, %Lg\n", cast(real)a[0], cast(real)a[1], cast(real)a[2]);
assert(a[0] == -5);
assert(a[1] == -7);
assert(a[2] == -9);
abc = null;
A()[] = B()[] + C()[] * 4;
assert(abc == "ABC");
printf("%Lg, %Lg, %Lg\n", cast(real)a[0], cast(real)a[1], cast(real)a[2]);
assert(a[0] == 17);
assert(a[1] == 22);
assert(a[2] == 27);
abc = null;
A()[] = B()[] + C()[] * B()[];
assert(abc == "ABCB");
printf("%Lg, %Lg, %Lg\n", cast(real)a[0], cast(real)a[1], cast(real)a[2]);
assert(a[0] == 5);
assert(a[1] == 12);
assert(a[2] == 21);
abc = null;
A()[] = B()[] + C()[] / 2;
assert(abc == "ABC");
printf("%Lg, %Lg, %Lg\n", cast(real)a[0], cast(real)a[1], cast(real)a[2]);
assert(a[0] == 3);
assert(a[1] == 4.5);
assert(a[2] == 6);
abc = null;
A()[] = B()[] + C()[] % 2;
assert(abc == "ABC");
printf("%Lg, %Lg, %Lg\n", cast(real)a[0], cast(real)a[1], cast(real)a[2]);
assert(a[0] == 1);
assert(a[1] == 3);
assert(a[2] == 3);
}
}
mixin Floating!(float) Ffloat;
mixin Floating!(double) Fdouble;
mixin Floating!(real) Freal;
void test1()
{
Ffloat.testx();
Fdouble.testx();
Freal.testx();
}
/************************************************************************/
template Integral(T)
{
T[3] a;
T[3] b;
T[3] c;
T[] A()
{
printf("A\n");
abc ~= "A";
return a;
}
T[] B()
{
printf("B\n");
abc ~= "B";
return b;
}
T[] C()
{
printf("C\n");
abc ~= "C";
return c;
}
T D()
{
printf("D\n");
abc ~= "D";
return 4;
}
void testx()
{
a = [11, 22, 33];
b = [1, 2, 3];
c = [4, 5, 6];
abc = null;
A()[] = B()[] + C()[];
assert(abc == "ABC");
assert(a[0] == 5);
assert(a[1] == 7);
assert(a[2] == 9);
abc = null;
A()[] = B()[] + 4;
assert(abc == "AB");
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
abc = null;
A()[] = 4 + B()[];
assert(abc == "AB");
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
abc = null;
A()[] = D() + B()[];
assert(abc == "ADB");
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
a = [11, 22, 33];
abc = null;
A()[] += B()[];
assert(abc == "AB");
assert(a[0] == 12);
assert(a[1] == 24);
assert(a[2] == 36);
a = [11, 22, 33];
A()[] += 4;
assert(a[0] == 15);
assert(a[1] == 26);
assert(a[2] == 37);
a = [11, 22, 33];
A()[] -= 4;
assert(a[0] == 7);
assert(a[1] == 18);
assert(a[2] == 29);
a = [11, 22, 27];
A()[] *= 4;
assert(a[0] == 44);
assert(a[1] == 88);
assert(a[2] == 108);
a = [11, 22, 33];
A()[] /= 4;
assert(a[0] == 2);
assert(a[1] == 5);
assert(a[2] == 8);
a = [11, 22, 33];
A()[] %= 4;
assert(a[0] == 3);
assert(a[1] == 2);
assert(a[2] == 1);
a = [1, 2, 7];
A()[] &= 4;
assert(a[0] == 0);
assert(a[1] == 0);
assert(a[2] == 4);
a = [1, 2, 7];
A()[] |= 4;
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 7);
a = [1, 2, 7];
A()[] ^= 4;
assert(a[0] == 5);
assert(a[1] == 6);
assert(a[2] == 3);
a = [11, 22, 33];
abc = null;
A()[] += 4 + B()[];
assert(abc == "AB");
assert(a[0] == 16);
assert(a[1] == 28);
assert(a[2] == 40);
abc = null;
A()[] = B()[] - C()[];
assert(abc == "ABC");
printf("%lld, %lld, %lld\n", cast(long)a[0], cast(long)a[1], cast(long)a[2]);
assert(a[0] == -3);
assert(a[1] == -3);
assert(a[2] == -3);
abc = null;
A()[] = -B()[] - C()[];
assert(abc == "ABC");
printf("%lld, %lld, %lld\n", cast(long)a[0], cast(long)a[1], cast(long)a[2]);
assert(a[0] == -5);
assert(a[1] == -7);
assert(a[2] == -9);
abc = null;
A()[] = B()[] + C()[] * 4;
assert(abc == "ABC");
printf("%lld, %lld, %lld\n", cast(long)a[0], cast(long)a[1], cast(long)a[2]);
assert(a[0] == 17);
assert(a[1] == 22);
assert(a[2] == 27);
abc = null;
A()[] = B()[] + C()[] * B()[];
assert(abc == "ABCB");
printf("%lld, %lld, %lld\n", cast(long)a[0], cast(long)a[1], cast(long)a[2]);
assert(a[0] == 5);
assert(a[1] == 12);
assert(a[2] == 21);
abc = null;
A()[] = B()[] + C()[] / 2;
assert(abc == "ABC");
printf("%lld, %lld, %lld\n", cast(long)a[0], cast(long)a[1], cast(long)a[2]);
assert(a[0] == 3);
assert(a[1] == 4);
assert(a[2] == 6);
abc = null;
A()[] = B()[] + C()[] % 2;
assert(abc == "ABC");
printf("%lld, %lld, %lld\n", cast(long)a[0], cast(long)a[1], cast(long)a[2]);
assert(a[0] == 1);
assert(a[1] == 3);
assert(a[2] == 3);
abc = null;
A()[] = ~B()[];
assert(abc == "AB");
assert(a[0] == cast(T) ~1);
assert(a[1] == cast(T) ~2);
assert(a[2] == cast(T) ~3);
abc = null;
A()[] = B()[] & 2;
assert(abc == "AB");
assert(a[0] == 0);
assert(a[1] == 2);
assert(a[2] == 2);
abc = null;
A()[] = B()[] | 2;
assert(abc == "AB");
assert(a[0] == 3);
assert(a[1] == 2);
assert(a[2] == 3);
abc = null;
A()[] = B()[] ^ 2;
assert(abc == "AB");
assert(a[0] == 3);
assert(a[1] == 0);
assert(a[2] == 1);
}
}
/************************************************************************/
mixin Integral!(byte) Fbyte;
mixin Integral!(short) Fshort;
mixin Integral!(int) Fint;
mixin Integral!(long) Flong;
void test2()
{
Fbyte.testx();
Fshort.testx();
Fint.testx();
Flong.testx();
}
/************************************************************************/
void test3()
{
auto a = new double[10], b = a.dup, c = a.dup, d = a.dup;
a[] = -(b[] * (c[] + 4)) + 5 * d[] / 3.0;
}
/************************************************************************/
void test4()
{
int[] a, b;
if (a && b) {}
}
/***************************************************/
void test4662()
{
immutable double[] nums = [1.0, 2.0];
static assert(!is(typeof({ nums[] += nums[]; })));
static assert(!is(typeof({ nums[] -= nums[]; })));
static assert(!is(typeof({ nums[] /= nums[]; })));
static assert(!is(typeof({ nums[] += 4; })));
static assert(!is(typeof({ nums[] /= 7; })));
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=5284
void bug5284_1()
{
class C { int v; }
C [] mda;
immutable(C)[] ida;
static assert(!__traits(compiles, (mda[] = ida[])));
C [1] msa;
immutable(C)[1] isa;
static assert(!__traits(compiles, (msa[] = isa[])));
C m;
immutable(C) i;
static assert(!__traits(compiles, m = i));
}
void bug5284_2a()
{
struct S { int v; }
S [] mda;
immutable(S)[] ida;
mda[] = ida[];
S [1] msa;
immutable(S)[1] isa;
msa[] = isa[];
S m = S();
immutable(S) i = immutable(S)();
m = i;
}
void bug5284_2b()
{
struct S { int v; int[] arr; }
S [] mda;
immutable(S)[] ida;
static assert(!__traits(compiles, (mda[] = ida[])));
S [1] msa;
immutable(S)[1] isa;
static assert(!__traits(compiles, (msa[] = isa[])));
S m;
immutable(S) i;
static assert(!__traits(compiles, m = i));
}
void bug5284_3()
{
int [] ma;
immutable(int)[] ia;
ma[] = ia[];
int m;
immutable(int) i;
m = i;
}
void test5()
{
bug5284_1();
bug5284_2a();
bug5284_2b();
bug5284_3();
}
/************************************************************************/
void test6()
{
int[10] a = [1,2,3,4,5,6,7,8,9,10];
int[10] b;
b = a[] ^^ 2;
assert(b[0] == 1);
assert(b[1] == 4);
assert(b[2] == 9);
assert(b[3] == 16);
assert(b[4] == 25);
assert(b[5] == 36);
assert(b[6] == 49);
assert(b[7] == 64);
assert(b[8] == 81);
assert(b[9] == 100);
int[10] c = 3;
b = a[] ^^ c[];
assert(b[0] == 1);
assert(b[1] == 8);
assert(b[2] == 27);
assert(b[3] == 64);
assert(b[4] == 125);
assert(b[5] == 216);
assert(b[6] == 343);
assert(b[7] == 512);
assert(b[8] == 729);
assert(b[9] == 1000);
}
/************************************************************************/
void test8390() {
const int[] a = new int[5];
int[] b = new int[5];
b[] += a[];
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=8651
void test8651()
{
void test(T)() @safe pure nothrow
{
T[3] a = [11, 22, 33];
T[3] b = [1, 2, 3];
T[3] c = [4, 5, 6];
T d = 4;
// Arithmetic array ops
{
a[] = b[] + c[];
a[] = b[] + 4;
a[] = 4 + b[];
a[] = d + b[];
a[] += b[];
a[] += 4;
a[] -= 4;
a[] *= 4;
a[] /= 4;
a[] %= 4;
a[] += 4 + b[];
a[] = b[] - c[];
a[] = -b[] - c[];
a[] = b[] + c[] * 4;
a[] = b[] + c[] * b[];
a[] = b[] + c[] / 2;
a[] = b[] + c[] % 2;
}
// Bitwise array ops
static if (is(typeof(T.init & T.init)))
{
a[] &= 4;
a[] |= 4;
a[] ^= 4;
a[] = ~b[];
a[] = b[] & 2;
a[] = b[] | 2;
a[] = b[] ^ 2;
}
}
test!float();
test!double();
test!real();
test!byte();
test!short();
test!int();
test!long();
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=9656
void test9656()
{
static class C {}
static struct S
{
immutable int[] narr1;
immutable int[] narr2;
immutable C[] carr1;
immutable C[] carr2;
this(int n) {
narr1 = new int[](3); // OK, expected
narr2 = [1,2,3].dup; // NG -> OK
carr1 = [new C].dup; // NG -> OK
C c = new C;
static assert(!__traits(compiles, carr2 = [c]));
}
}
{
int[] ma = [1,2,3];
immutable ia = ma.idup;
}
{
static struct V { int val; }
V[] ma = [V(1), V(2)];
immutable ia = ma.idup;
}
{
static struct R { int* ptr; }
R[] ma = [R(new int), R(null)];
static assert(!__traits(compiles, { immutable ia = rarr.dup; }));
}
{
C[] ma = [new C(), new C()];
static assert(!__traits(compiles, { immutable ia = carr.dup; }));
}
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=10282
void test10282()
{
int[3] a1 = [1, 3, 6];
int[3] a2 = [1, 3, 6] * 3; // OK
const int[3] a3 = a1[] * 3; // OK <- Error
const int[3] a4 = [1, 3, 6] * 3; // OK <- Error
immutable int[3] a5 = [1, 3, 6] * 3; // OK <- Error
assert(a1[0] == 1 && a1[1] == 3 && a1[2] == 6);
assert(a2[0] == 3 && a2[1] == 9 && a2[2] == 18);
assert(a3[0] == 3 && a3[1] == 9 && a3[2] == 18);
assert(a4[0] == 3 && a4[1] == 9 && a4[2] == 18);
assert(a5[0] == 3 && a5[1] == 9 && a5[2] == 18);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=10433
void test10433()
{
void foo(T)(in int[] v1, in T v2)
{
int[2] r;
r[] = v1[] + v2[];
}
immutable int[] v = [10, 20];
foo(v, v);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=10684
void test10684a()
{
int[] a = [0, 0];
a[] += [10, 20][];
}
void test10684b()
{
int[] a = [1, 2, 3];
int[] b = [4, 5, 6];
// Allow array literal as the operand of array oeration
a[] += [1, 2, 3];
assert(a == [2, 4, 6]);
a[] *= b[] + [1, 1, 1];
assert(a == [2*(4+1), 4*(5+1), 6*(6+1)]);
a[] = [9, 8, 7] - [1, 2, 3];
assert(a == [8, 6, 4]);
a[] = [2, 4, 6] / 2;
assert(a == [1,2,3]);
// Disallow: [1,2,3] is not an lvalue
static assert(!__traits(compiles, { [1,2,3] = a[] * 2; }));
static assert(!__traits(compiles, { [1,2,3] += a[] * b[]; }));
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=11376
template TL11376(T...)
{
alias TL11376 = T;
}
auto sumArrs11376(T0, T1)(T0[] a, T1[] b)
{
a[] += b[]; //no ICE without this line
return a;
}
static assert(!__traits(compiles, sumArrs11376(TL11376!(string[], string).init)));
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=11525
void test11525()
{
static struct Complex(T)
{
T re, im;
ref opOpAssign(string op : "*")(Complex z)
{
auto temp = re*z.re - im*z.im;
im = im*z.re + re*z.im;
re = temp;
return this;
}
}
auto a = [Complex!double(2, 2)];
assert(a.length == 1 && a[0].re == 2 && a[0].im == 2);
a[] *= a[];
assert(a.length == 1 && a[0].re == 0 && a[0].im == 8);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=12250
void f12250(inout int[] p, inout int[] q, int[] r)
{
r[] = p[] + q[];
assert(r == [5,7,9]);
r[] -= p[] - q[];
assert(r == [8,10,12]);
}
void test12250()
{
immutable int[3] x = [1,2,3], y = [4,5,6];
int[3] z;
f12250(x[], y[], z[]);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=12179
void test12179()
{
void foo(int[]) {}
int[1] a;
foo(a[] = a[]);
foo(a[] += a[]);
foo(a[] -= a[]);
foo(a[] *= a[]);
foo(a[] /= a[]);
foo(a[] %= a[]);
foo(a[] ^= a[]);
foo(a[] &= a[]);
foo(a[] |= a[]);
foo(a[] ^^= a[]);
// from https://issues.dlang.org/show_bug.cgi?id=11992
int[] arr1;
int[][] arr2;
arr1 ~= (a[] = [1] + a[]); // OK
arr2 ~= (a[] = [1] + a[]); // OK
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=12780
void test12780()
{
int ival = 2;
int[] iarr = [1, 2, 3];
double dval = 2.0;
double[] darr = [4, 5, 6];
double[] oarr = [0, 0, 0];
// multiply array operations
oarr[] = dval * iarr[];
assert(oarr == [dval * iarr[0],
dval * iarr[1],
dval * iarr[2]]);
oarr[] = iarr[] / dval;
assert(oarr == [iarr[0] / dval,
iarr[1] / dval,
iarr[2] / dval]);
oarr[] = dval * (ival + iarr[]);
assert(oarr == [dval * (ival + iarr[0]),
dval * (ival + iarr[1]),
dval * (ival + iarr[2])]);
oarr[] = (iarr[] & ival) / dval;
assert(oarr == [(iarr[0] & ival) / dval,
(iarr[1] & ival) / dval,
(iarr[2] & ival) / dval]);
oarr[] = darr[] + iarr[];
assert(oarr == [darr[0] + iarr[0],
darr[1] + iarr[1],
darr[2] + iarr[2]]);
oarr[] = iarr[] - darr[];
assert(oarr == [iarr[0] - darr[0],
iarr[1] - darr[1],
iarr[2] - darr[2]]);
oarr[] = darr[] * (ival & iarr[]);
assert(oarr == [darr[0] * (ival & iarr[0]),
darr[1] * (ival & iarr[1]),
darr[2] * (ival & iarr[2])]);
oarr[] = (iarr[] ^ ival) / darr[];
assert(oarr == [(iarr[0] ^ ival) / darr[0],
(iarr[1] ^ ival) / darr[1],
(iarr[2] ^ ival) / darr[2]]);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=13497
void test13497()
{
int[1] a = [2], b = [3];
int[1] c1 = a[] * b[];
int[1] c2 = (a[] * b[])[];
assert(c1 == [6]);
assert(c2 == [6]);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=14649
void test14649()
{
char[] a = "abc".dup;
char[] b = [char(1), char(2), char(3)];
string x = "abc";
string y = [char(1), char(2), char(3)];
char[] r = new char[](3);
r[] = a[] + b[];
assert(r == "bdf");
r[] = x[] + y[];
assert(r == "bdf");
r[] = "hel"[] + "lo."[];
assert(r == [('h'+'l'), ('e'+'o'), ('l'+'.')]);
enum s = "abc";
r[] = s[0..3] + "def"[0..3];
assert(r == [('a'+'d'), ('b'+'e'), ('c'+'f')]);
}
/************************************************************************/
// https://issues.dlang.org/show_bug.cgi?id=14851
void test14851()
{
int[8] a, b, c;
c = a[] | b[]; // OK <- NG from 2.068.0-b2
c = a[] ^ b[]; // OK <- NG from 2.068.0-b2
c[] = a[] | b[]; // OK
c[] = a[] ^ b[]; // OK
}
/************************************************************************/
int main()
{
version(X86)
{
test1();
test2();
}
else version(X86_64)
{
test1();
test2();
}
else
{
//pragma(msg, "Test skipped because arrayop evaluation order is ill-defined.");
}
test3();
test4();
test5();
test6();
test8390();
test8651();
test9656();
test10282();
test10433();
test10684a();
test10684b();
test11525();
test12250();
test12780();
test13497();
test14649();
test14851();
printf("Success\n");
return 0;
}
version (none)
{
extern (C) T[] _arraySliceSliceAddSliceAssignd(T[] a, T[] c, T[] b)
{
foreach (i; 0 .. a.length)
a[i] = b[i] + c[i];
return a;
}
}