mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-24 22:11:36 +00:00
Merge branch 'master' into poly-proc-fix
This commit is contained in:
@@ -380,6 +380,13 @@ glob_tests := []Glob_Test{
|
||||
},
|
||||
err = {},
|
||||
},
|
||||
{
|
||||
pattern = ODIN_ROOT + "tests/core/os/path.odin",
|
||||
matches = {
|
||||
ODIN_ROOT + "tests/core/os/path.odin",
|
||||
},
|
||||
err = {},
|
||||
},
|
||||
}
|
||||
|
||||
@(test)
|
||||
|
||||
@@ -425,3 +425,196 @@ test_memory_compare_zero :: proc(t: ^testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Runs identical append/inject/remove sequences for a #soa[dynamic] array
|
||||
// and an AoS [dynamic] reference, comparing all elements after each
|
||||
// stage. Covers appends, injections (interior, at the end, and past the
|
||||
// end where the gap must read as zero elements), unordered and ordered
|
||||
// removes.
|
||||
@(test)
|
||||
test_soa_array_append_inject_remove :: proc(t: ^testing.T) {
|
||||
check :: proc(t: ^testing.T, $E: typeid, mk: proc(i: int) -> E) {
|
||||
expect_same :: proc(t: ^testing.T, soa: #soa[dynamic]$T, model: [dynamic]T) {
|
||||
testing.expect_value(t, len(soa), len(model))
|
||||
for i in 0..<min(len(soa), len(model)) {
|
||||
testing.expect_value(t, soa[i], model[i])
|
||||
}
|
||||
}
|
||||
|
||||
soa: #soa[dynamic]E
|
||||
defer delete(soa)
|
||||
ref: [dynamic]E
|
||||
defer delete(ref)
|
||||
|
||||
// single appends
|
||||
for i in 0..<10 {
|
||||
n, err := append(&soa, mk(i))
|
||||
testing.expect_value(t, n, 1)
|
||||
testing.expect_value(t, err, nil)
|
||||
append(&ref, mk(i))
|
||||
}
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// batch appends
|
||||
buf: [32]E
|
||||
for i in 0..<32 { buf[i] = mk(123 + i) }
|
||||
BATCH_LEN :: 5
|
||||
n, err := append(&soa, ..buf[:BATCH_LEN])
|
||||
testing.expect_value(t, n, BATCH_LEN)
|
||||
testing.expect_value(t, err, nil)
|
||||
append(&ref, ..buf[:BATCH_LEN])
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
n, err = append(&soa, ..buf[:])
|
||||
testing.expect_value(t, n, 32)
|
||||
testing.expect_value(t, err, nil)
|
||||
append(&ref, ..buf[:])
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// single injections
|
||||
ok: bool
|
||||
ok, err = inject_at_soa(&soa, 0, mk(300))
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, 0, mk(300))
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
ok, err = inject_at_soa(&soa, len(soa)/2, mk(301))
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, len(ref)/2, mk(301))
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// inject at the end
|
||||
ok, err = inject_at_soa(&soa, len(soa), mk(302))
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, len(ref), mk(302))
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// batch injections
|
||||
ok, err = inject_at_soa(&soa, 3, ..buf[:BATCH_LEN])
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, 3, ..buf[:BATCH_LEN])
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
ok, err = inject_at_soa(&soa, len(soa), ..buf[:])
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, len(ref), ..buf[:])
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// injecting nothing is a no-op
|
||||
ok, err = inject_at_soa(&soa, 4, ..buf[:0])
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, 4, ..buf[:0])
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// single injection past the end: the gap [len, index) reads as zero
|
||||
// elements. Poison the spare capacity first (fresh heap pages are
|
||||
// already zero, which would hide a missing gap zero), then shrink back.
|
||||
for i in 0..<8 {
|
||||
n, err = append(&soa, mk(900 + i))
|
||||
testing.expect_value(t, n, 1)
|
||||
testing.expect_value(t, err, nil)
|
||||
}
|
||||
testing.expect_value(t, resize_soa(&soa, len(soa) - 8), nil)
|
||||
ok, err = inject_at_soa(&soa, len(soa) + 3, mk(500))
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, len(ref) + 3, mk(500))
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// batch injection past the end (its gap slots reuse the poison above)
|
||||
ok, err = inject_at_soa(&soa, len(soa) + 2, ..buf[:BATCH_LEN])
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, len(ref) + 2, ..buf[:BATCH_LEN])
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// unordered removes
|
||||
unordered_remove_soa(&soa, 20)
|
||||
unordered_remove(&ref, 20)
|
||||
unordered_remove_soa(&soa, 0)
|
||||
unordered_remove(&ref, 0)
|
||||
unordered_remove_soa(&soa, len(soa)-1)
|
||||
unordered_remove(&ref, len(ref)-1)
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// ordered removes
|
||||
ordered_remove_soa(&soa, 17)
|
||||
ordered_remove(&ref, 17)
|
||||
ordered_remove_soa(&soa, 0)
|
||||
ordered_remove(&ref, 0)
|
||||
ordered_remove_soa(&soa, len(soa)-1)
|
||||
ordered_remove(&ref, len(ref)-1)
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// interleaved removes, appends and injections
|
||||
for i in 0..<8 {
|
||||
unordered_remove_soa(&soa, i)
|
||||
unordered_remove(&ref, i)
|
||||
n, err = append(&soa, mk(200 + i))
|
||||
testing.expect_value(t, n, 1)
|
||||
testing.expect_value(t, err, nil)
|
||||
append(&ref, mk(200 + i))
|
||||
ok, err = inject_at_soa(&soa, i, mk(400 + i))
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, i, mk(400 + i))
|
||||
}
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// remove till empty, then reuse
|
||||
for len(soa) > 0 {
|
||||
unordered_remove_soa(&soa, 0)
|
||||
unordered_remove(&ref, 0)
|
||||
}
|
||||
testing.expect_value(t, len(soa), 0)
|
||||
|
||||
// inject into an empty array
|
||||
ok, err = inject_at_soa(&soa, 0, mk(998))
|
||||
testing.expect(t, ok)
|
||||
testing.expect_value(t, err, nil)
|
||||
inject_at(&ref, 0, mk(998))
|
||||
expect_same(t, soa, ref)
|
||||
|
||||
// non-zero append
|
||||
n, err = non_zero_append(&soa, mk(42))
|
||||
testing.expect_value(t, n, 1)
|
||||
testing.expect_value(t, err, nil)
|
||||
non_zero_append(&ref, mk(42))
|
||||
expect_same(t, soa, ref)
|
||||
}
|
||||
|
||||
// mixed field widths + padding
|
||||
Padded :: struct { a: u8, b: u64, c: u16 }
|
||||
check(t, Padded, proc(i: int) -> Padded { return {u8(i*3), u64(i)*257 + 7, u16(i*5 + 1)} })
|
||||
// array element type
|
||||
check(t, [4]u16, proc(i: int) -> [4]u16 { return {u16(i), u16(i + 1), u16(i*3), u16(i*7)} })
|
||||
// eight fields at varying widths, no two neighbouring fields share a stride
|
||||
Eight :: struct { a: u8, b: u16, c: u32, d: u64, e: i8, f: i16, g: f32, h: f64 }
|
||||
check(t, Eight, proc(i: int) -> Eight {
|
||||
return {
|
||||
u8(i), u16(i*3 + 1), u32(i)*5 + 2, u64(i)*7 + 3,
|
||||
i8(i >> 1), i16(i*11 + 4), f32(i)*1.5, f64(i)*2.25,
|
||||
}
|
||||
})
|
||||
// #packed struct with > 16 fields, field offsets diverging from default
|
||||
// layout (u8/u64 alternate, align_of == 1), and the field count takes
|
||||
// the type-erased batch appends compile time branch.
|
||||
Packed17 :: struct #packed {
|
||||
f0: u8, f1: u64, f2: u8, f3: u64, f4: u8, f5: u64, f6: u8, f7: u64,
|
||||
f8: u8, f9: u64, f10: u8, f11: u64, f12: u8, f13: u64, f14: u8, f15: u64,
|
||||
f16: u8,
|
||||
}
|
||||
check(t, Packed17, proc(i: int) -> Packed17 {
|
||||
return {
|
||||
u8(i), u64(i)*3 + 1, u8(i >> 1), u64(i)*5 + 2, u8(i >> 2), u64(i)*7 + 3, u8(i >> 3), u64(i)*11 + 4,
|
||||
u8(i >> 4), u64(i)*13 + 5, u8(i >> 5), u64(i)*17 + 6, u8(i >> 6), u64(i)*19 + 7, u8(i >> 7), u64(i)*23 + 8,
|
||||
u8(i*3),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,4 +5,5 @@ package tests_core
|
||||
@(require) import "crypto/bigint"
|
||||
@(require) import "hash"
|
||||
@(require) import "image"
|
||||
@(require) import "math/big"
|
||||
@(require) import "math/big"
|
||||
@(require) import "runtime"
|
||||
@@ -4,7 +4,9 @@ set -eu
|
||||
mkdir -p build
|
||||
pushd build
|
||||
ODIN=../../../odin
|
||||
COMMON="-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused-defineables"
|
||||
COMMON="-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused-defineables -microarch:native"
|
||||
COMMON_CHECK="-define:ODIN_TEST_FANCY=false -file -vet -strict-style -ignore-unused-defineables"
|
||||
|
||||
|
||||
set -x
|
||||
|
||||
@@ -82,12 +84,19 @@ fi
|
||||
$ODIN check ../test_issue_6484.odin -no-entry-point $COMMON
|
||||
$ODIN test ../test_issue_6753.odin $COMMON
|
||||
if [[ $($ODIN check ../test_issue_6874.odin $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 1 ]] ; then
|
||||
$ODIN check ../test_issue_6484.odin -no-entry-point $COMMON_CHECK
|
||||
echo "SUCCESSFUL 1/1"
|
||||
else
|
||||
echo "SUCCESSFUL 0/1"
|
||||
exit 1
|
||||
fi
|
||||
$ODIN check ../test_issue_6979.odin -no-entry-point $COMMON
|
||||
if [[ $($ODIN check ../test_issue_6874.odin $COMMON_CHECK 2>&1 >/dev/null | grep -c "Error:") -eq 1 ]] ; then
|
||||
echo "SUCCESSFUL 1/1"
|
||||
else
|
||||
echo "SUCCESSFUL 0/1"
|
||||
exit 1
|
||||
fi
|
||||
$ODIN check ../test_issue_6979.odin -no-entry-point $COMMON_CHECK
|
||||
$ODIN build ../test_issue_7037.odin $COMMON -o:none
|
||||
|
||||
if [[ $($ODIN build ../test_issue_7108.odin $COMMON 2>&1 >/dev/null | grep -c "Error:") -eq 2 ]] ; then
|
||||
|
||||
Reference in New Issue
Block a user