/*
$ tks join.tks
ia ia_1+ia_2: [1, 2, 3, 4, 5, 6]
ia va_1+ia_2: [1, 2, 3, 4, 5, 6]
ia ia_1+va_2: [1, 2, 3, 4, 0, 6]
ia ia_1+null: [1, 2, 3]
ia null+ia_2: [4, 5, 6]
ia null+null: []
ia ia_1+ia_2: [1, 2, 3, 4, 5, 6]

fa fa_1+fa_2: [1.1, 2.2, 3.3, 4.4, 5.5, 6.6]
fa va_1+fa_2: [1.11, 2.22, 3.33, 4.4, 5.5, 6.6]
fa fa_1+va_2: [1.1, 2.2, 3.3, 4.44, 0, 6.66]
fa fa_1+null: [1.1, 2.2, 3.3]
fa null+fa_2: [4.4, 5.5, 6.6]
fa null+null: []
fa fa_1+fa_2: [1.1, 2.2, 3.3, 4.4, 5.5, 6.6]

sa sa_1+sa_2: ["Hello", ", ", "world.", "One", "Two", "Three"]
sa va_1+sa_2: ["1.11", "2.22", "3.33", "One", "Two", "Three"]
sa sa_1+va_2: ["Hello", ", ", "world.", "4.44", "[5]", "6.66"]
sa sa_1+null: ["Hello", ", ", "world."]
sa null+sa_2: ["One", "Two", "Three"]
sa null+null: []
sa +: ["one", "two", "three", "four", "five", "six"]
sa sa_1+sa_2: ["Hello", ", ", "world.", "One", "Two", "Three"]

pa joinCC(pa_1, pa_2)=<PointerArray#0x01BFC8E0(["Hello", "World", <null>, [-1, -2, -3], #[a=42], {-4, -5, -6}])> getDeref(0)=<String@0x01BFD1E8("Hello")>
pa joinRR(pa_1, pa_2)=<PointerArray#0x01BFC8E0(["Hello", "World", <null>, [-1, -2, -3], #[a=42], {-4, -5, -6}])> getDeref(0)=<String#0x01BFDAA8("Hello")>
pa joinRR(pa, pa_2)=<PointerArray#0x01BFC8E0(["Hello", "World", <null>, [-1, -2, -3], #[a=42], {-4, -5, -6}])> getDeref(1)=<String@0x01BFD1C0("World")>
pa pa_1+pa_2: ["Hello", "World", <null>, [-1, -2, -3], #[a=42], {-4, -5, -6}]

va joinCC(va_1, va_2)=<ValueArray#0x01BFC8C0([1.11, "2.22", 3.33, 4.44, [5], 6.66])> getDeref(0)=<Float@0x01A78B10(1.11)>
va joinRR(va_1, va_2)=<ValueArray#0x01BFC8C0([1.11, "2.22", 3.33, 4.44, [5], 6.66])> getDeref(0)=<Float#0x01A78B40(1.11)>
va joinRR(va, va_2)=<ValueArray#0x01BFC8C0([1.11, "2.22", 3.33, 4.44, [5], 6.66])> getDeref(1)=<String@0x01BFD1C0("2.22")>
va va_1+va_2: [1.11, "2.22", 3.33, 4.44, [5], 6.66]
*/


IntArray     ia;
FloatArray   fa;
PointerArray pa;
ValueArray   va;
StringArray  sa;

IntArray     ia_1 = [1, 2, 3];
IntArray     ia_2 = [4, 5, 6];
FloatArray   fa_1 = [1.1, 2.2, 3.3];
FloatArray   fa_2 = [4.4, 5.5, 6.6];
ValueArray   va_1 = [Object(1.11), "2.22", 3.33f];
ValueArray   va_2 = [Object(4.44), new [5], 6.66f];
PointerArray pa_1 = ["Hello", String("World"), null];
PointerArray pa_2 = [[-1,-2,-3], #["a"=42], new {-4, -5, -6}];
StringArray  sa_1 = ["Hello", ", ", "world."];
StringArray  sa_2 = ["One", "Two", "Three"];


function TestJoinIntArray() {
   ia.free();
   ia.join(ia_1, ia_2);
   trace "ia ia_1+ia_2: "+ia;

   ia.free();
   ia.join(va_1, ia_2);
   trace "ia va_1+ia_2: "+ia;

   ia.free();
   ia.join(ia_1, va_2);
   trace "ia ia_1+va_2: "+ia;

   ia.free();
   ia.join(ia_1, null);
   trace "ia ia_1+null: "+ia;

   ia.free();
   ia.join(null, ia_2);
   trace "ia null+ia_2: "+ia;

   ia = [7, 8, 9];
   ia.join(null, null);
   trace "ia null+null: "+ia;

   ia = ia_1 + ia_2;
   trace "ia ia_1+ia_2: "+ia;
}


function TestJoinFloatArray() {
   fa.free();
   fa.join(fa_1, fa_2);
   trace "fa fa_1+fa_2: "+fa;

   fa.free();
   fa.join(va_1, fa_2);
   trace "fa va_1+fa_2: "+fa;

   fa.free();
   fa.join(fa_1, va_2);
   trace "fa fa_1+va_2: "+fa;

   fa.free();
   fa.join(fa_1, null);
   trace "fa fa_1+null: "+fa;

   fa.free();
   fa.join(null, fa_2);
   trace "fa null+fa_2: "+fa;

   fa = [7, 8, 9];
   fa.join(null, null);
   trace "fa null+null: "+fa;

   fa = fa_1 + fa_2;
   trace "fa fa_1+fa_2: "+fa;
}


function TestJoinStringArray() {
   sa.free();
   sa.join(sa_1, sa_2);
   trace "sa sa_1+sa_2: "+sa;

   sa.free();
   sa.join(va_1, sa_2);
   trace "sa va_1+sa_2: "+sa;

   sa.free();
   sa.join(sa_1, va_2);
   trace "sa sa_1+va_2: "+sa;

   sa.free();
   sa.join(sa_1, null);
   trace "sa sa_1+null: "+sa;

   sa.free();
   sa.join(null, sa_2);
   trace "sa null+sa_2: "+sa;

   sa = [7, 8, 9];
   sa.join(null, null);
   trace "sa null+null: "+sa;

   sa = ["one", "two", "three"] + ["four", "five", "six"];
   trace "sa +: "+sa;

   sa = sa_1 + sa_2;
   trace "sa sa_1+sa_2: "+sa;
}


function TestJoinPointerArray() {
   pa.free();
   pa.joinCC(pa_1, pa_2);
   trace "pa joinCC(pa_1, pa_2)="+#(pa)+" getDeref(0)="+#(pa.getDeref(0));

   pa.free();
   pa.joinRR(pa_1, pa_2);
   trace "pa joinRR(pa_1, pa_2)="+#(pa)+" getDeref(0)="+#(pa.getDeref(0));

   pa.free();
   pa.joinCC(pa_1, null); // copy all elements of pa_a1 by value
   pa.joinRR(pa, pa_2);   // copy elements of pa_2 by reference, keep ownership of own elements
   trace "pa joinRR(pa, pa_2)="+#(pa)+" getDeref(1)="+#(pa.getDeref(1));

   // (note) do NOT use simple assign (=) in this case since the temporary object result of (pa_1 + pa_2) will
   //         be deleted after assignment to "pa" !
   PointerArray paAdd <= pa_1 + pa_2;
   trace "pa pa_1+pa_2: "+paAdd;
}


function TestJoinValueArray() {
   va.free();
   va.joinCC(va_1, va_2);
   trace "va joinCC(va_1, va_2)="+#(va)+" getDeref(0)="+#(va.getDeref(0));

   va.free();
   va.joinRR(va_1, va_2);
   trace "va joinRR(va_1, va_2)="+#(va)+" getDeref(0)="+#(va.getDeref(0));

   va.free();
   va.joinCC(va_1, null); // copy all elements of pa_a1 by value
   va.joinRR(va, va_2);   // copy elements of pa_2 by reference, keep ownership of own elements
   trace "va joinRR(va, va_2)="+#(va)+" getDeref(1)="+#(va.getDeref(1));

   // (note) do NOT use simple assign (=) in this case since the temporary object result of (va_1 + va_2) will
   //         be deleted after assignment to "va" !
   ValueArray vaAdd <= va_1 + va_2;
   trace "va va_1+va_2: "+vaAdd;
}



TestJoinIntArray();
trace " ";

TestJoinFloatArray();
trace " ";

TestJoinStringArray();
trace " ";

TestJoinPointerArray();
trace " ";

TestJoinValueArray();
trace " ";