(root)/
gcc-13.2.0/
gcc/
testsuite/
gdc.test/
runnable/
arrayop.d
// 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;
}
}