// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// This file has been automatically generated. Please do not edit it manually.
// Generated by tests/ffi/generator/array_primitive_elements_test_generator.dart.
//
// SharedObjects=ffi_test_functions
// VMOptions=
// VMOptions=--deterministic --optimization-counter-threshold=90
// VMOptions=--use-slow-path
// VMOptions=--use-slow-path --stacktrace-every=100

import 'dart:ffi';
import 'dart:typed_data';

import 'package:expect/expect.dart';
import 'package:ffi/ffi.dart';

const int arrayLength = 5;

void main() {
  // Loop enough to trigger optimizations or stacktraces. See "VMOptions" above.
  for (int i = 0; i < 100; ++i) {
    testInt8ArrayElements();
    testInt8ArrayBackedByInt64ListElements();
    testMallocedInt8ArrayElements();
    testWriteToInt8ArrayElementsBackedByTypedData();
    testWriteToInt8ArrayElementsBackedByPointer();
    testInt8ArrayElementsFirstAndLast();
    testInt8ArrayElementsTypedDataListBackedByTypedData();
    testInt8ArrayElementsTypedDataListBackedByPointer();
    testInt16ArrayElements();
    testInt16ArrayBackedByInt64ListElements();
    testMallocedInt16ArrayElements();
    testWriteToInt16ArrayElementsBackedByTypedData();
    testWriteToInt16ArrayElementsBackedByPointer();
    testInt16ArrayElementsFirstAndLast();
    testInt16ArrayElementsTypedDataListBackedByTypedData();
    testInt16ArrayElementsTypedDataListBackedByPointer();
    testInt16Misaligned();
    testInt32ArrayElements();
    testInt32ArrayBackedByInt64ListElements();
    testMallocedInt32ArrayElements();
    testWriteToInt32ArrayElementsBackedByTypedData();
    testWriteToInt32ArrayElementsBackedByPointer();
    testInt32ArrayElementsFirstAndLast();
    testInt32ArrayElementsTypedDataListBackedByTypedData();
    testInt32ArrayElementsTypedDataListBackedByPointer();
    testInt32Misaligned();
    testInt64ArrayElements();
    testInt64ArrayBackedByInt64ListElements();
    testMallocedInt64ArrayElements();
    testWriteToInt64ArrayElementsBackedByTypedData();
    testWriteToInt64ArrayElementsBackedByPointer();
    testInt64ArrayElementsFirstAndLast();
    testInt64ArrayElementsTypedDataListBackedByTypedData();
    testInt64ArrayElementsTypedDataListBackedByPointer();
    testInt64Misaligned();
    testUint8ArrayElements();
    testUint8ArrayBackedByInt64ListElements();
    testMallocedUint8ArrayElements();
    testWriteToUint8ArrayElementsBackedByTypedData();
    testWriteToUint8ArrayElementsBackedByPointer();
    testUint8ArrayElementsFirstAndLast();
    testUint8ArrayElementsTypedDataListBackedByTypedData();
    testUint8ArrayElementsTypedDataListBackedByPointer();
    testUint16ArrayElements();
    testUint16ArrayBackedByInt64ListElements();
    testMallocedUint16ArrayElements();
    testWriteToUint16ArrayElementsBackedByTypedData();
    testWriteToUint16ArrayElementsBackedByPointer();
    testUint16ArrayElementsFirstAndLast();
    testUint16ArrayElementsTypedDataListBackedByTypedData();
    testUint16ArrayElementsTypedDataListBackedByPointer();
    testUint16Misaligned();
    testUint32ArrayElements();
    testUint32ArrayBackedByInt64ListElements();
    testMallocedUint32ArrayElements();
    testWriteToUint32ArrayElementsBackedByTypedData();
    testWriteToUint32ArrayElementsBackedByPointer();
    testUint32ArrayElementsFirstAndLast();
    testUint32ArrayElementsTypedDataListBackedByTypedData();
    testUint32ArrayElementsTypedDataListBackedByPointer();
    testUint32Misaligned();
    testUint64ArrayElements();
    testUint64ArrayBackedByInt64ListElements();
    testMallocedUint64ArrayElements();
    testWriteToUint64ArrayElementsBackedByTypedData();
    testWriteToUint64ArrayElementsBackedByPointer();
    testUint64ArrayElementsFirstAndLast();
    testUint64ArrayElementsTypedDataListBackedByTypedData();
    testUint64ArrayElementsTypedDataListBackedByPointer();
    testUint64Misaligned();
    testFloatArrayElements();
    testFloatArrayBackedByInt64ListElements();
    testMallocedFloatArrayElements();
    testWriteToFloatArrayElementsBackedByTypedData();
    testWriteToFloatArrayElementsBackedByPointer();
    testFloatArrayElementsFirstAndLast();
    testFloatArrayElementsTypedDataListBackedByTypedData();
    testFloatArrayElementsTypedDataListBackedByPointer();
    testFloatMisaligned();
    testDoubleArrayElements();
    testDoubleArrayBackedByInt64ListElements();
    testMallocedDoubleArrayElements();
    testWriteToDoubleArrayElementsBackedByTypedData();
    testWriteToDoubleArrayElementsBackedByPointer();
    testDoubleArrayElementsFirstAndLast();
    testDoubleArrayElementsTypedDataListBackedByTypedData();
    testDoubleArrayElementsTypedDataListBackedByPointer();
    testDoubleMisaligned();
    testBoolArrayElements();
    testBoolArrayBackedByInt64ListElements();
    testMallocedBoolArrayElements();
    testWriteToBoolArrayElementsBackedByTypedData();
    testWriteToBoolArrayElementsBackedByPointer();
    testBoolArrayElementsFirstAndLast();
    testWCharArrayElements();
    testWCharArrayBackedByInt64ListElements();
    testMallocedWCharArrayElements();
    testWriteToWCharArrayElementsBackedByTypedData();
    testWriteToWCharArrayElementsBackedByPointer();
    testWCharArrayElementsFirstAndLast();
  }
}

final class Int8ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int8> array;
}

void testInt8ArrayElements() {
  final struct = Struct.create<Int8ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testInt8ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Int8ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedInt8ArrayElements() {
  final struct = malloc<Int8ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToInt8ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Int8ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToInt8ArrayElementsBackedByPointer() {
  final struct = malloc<Int8ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testInt8ArrayElementsFirstAndLast() {
  final struct = Struct.create<Int8ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testInt8ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Int8ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Int8>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Int8>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int8>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int8List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int8>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int8List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testInt8ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Int8ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Int8>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int8>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int8List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int8>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int8List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

final class Int16ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int16> array;
}

void testInt16ArrayElements() {
  final struct = Struct.create<Int16ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testInt16ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Int16ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedInt16ArrayElements() {
  final struct = malloc<Int16ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToInt16ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Int16ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToInt16ArrayElementsBackedByPointer() {
  final struct = malloc<Int16ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testInt16ArrayElementsFirstAndLast() {
  final struct = Struct.create<Int16ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testInt16ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Int16ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Int16>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Int16>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int16>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int16List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int16>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int16List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testInt16ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Int16ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Int16>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int16>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int16List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int16>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int16List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedInt16ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int16> array;
}

void testInt16Misaligned() {
  final structPointer = malloc<PackedInt16ArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedInt16ArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class Int32ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int32> array;
}

void testInt32ArrayElements() {
  final struct = Struct.create<Int32ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testInt32ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Int32ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedInt32ArrayElements() {
  final struct = malloc<Int32ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToInt32ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Int32ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToInt32ArrayElementsBackedByPointer() {
  final struct = malloc<Int32ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testInt32ArrayElementsFirstAndLast() {
  final struct = Struct.create<Int32ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testInt32ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Int32ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Int32>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Int32>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int32>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int32List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int32>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int32List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testInt32ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Int32ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Int32>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int32>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int32List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int32>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int32List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedInt32ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int32> array;
}

void testInt32Misaligned() {
  final structPointer = malloc<PackedInt32ArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedInt32ArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class Int64ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int64> array;
}

void testInt64ArrayElements() {
  final struct = Struct.create<Int64ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testInt64ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Int64ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedInt64ArrayElements() {
  final struct = malloc<Int64ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToInt64ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Int64ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToInt64ArrayElementsBackedByPointer() {
  final struct = malloc<Int64ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testInt64ArrayElementsFirstAndLast() {
  final struct = Struct.create<Int64ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testInt64ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Int64ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Int64>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Int64>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int64>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int64List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int64>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int64List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testInt64ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Int64ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Int64>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Int64>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Int64List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Int64>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Int64List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedInt64ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Int64> array;
}

void testInt64Misaligned() {
  final structPointer = malloc<PackedInt64ArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedInt64ArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class Uint8ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint8> array;
}

void testUint8ArrayElements() {
  final struct = Struct.create<Uint8ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testUint8ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Uint8ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedUint8ArrayElements() {
  final struct = malloc<Uint8ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToUint8ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Uint8ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToUint8ArrayElementsBackedByPointer() {
  final struct = malloc<Uint8ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testUint8ArrayElementsFirstAndLast() {
  final struct = Struct.create<Uint8ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testUint8ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Uint8ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Uint8>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Uint8>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint8>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint8List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint8>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint8List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testUint8ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Uint8ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Uint8>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint8>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint8List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint8>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint8List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

final class Uint16ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint16> array;
}

void testUint16ArrayElements() {
  final struct = Struct.create<Uint16ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testUint16ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Uint16ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedUint16ArrayElements() {
  final struct = malloc<Uint16ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToUint16ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Uint16ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToUint16ArrayElementsBackedByPointer() {
  final struct = malloc<Uint16ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testUint16ArrayElementsFirstAndLast() {
  final struct = Struct.create<Uint16ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testUint16ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Uint16ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Uint16>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Uint16>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint16>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint16List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint16>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint16List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testUint16ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Uint16ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Uint16>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint16>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint16List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint16>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint16List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedUint16ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint16> array;
}

void testUint16Misaligned() {
  final structPointer = malloc<PackedUint16ArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedUint16ArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class Uint32ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint32> array;
}

void testUint32ArrayElements() {
  final struct = Struct.create<Uint32ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testUint32ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Uint32ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedUint32ArrayElements() {
  final struct = malloc<Uint32ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToUint32ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Uint32ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToUint32ArrayElementsBackedByPointer() {
  final struct = malloc<Uint32ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testUint32ArrayElementsFirstAndLast() {
  final struct = Struct.create<Uint32ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testUint32ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Uint32ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Uint32>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Uint32>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint32>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint32List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint32>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint32List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testUint32ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Uint32ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Uint32>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint32>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint32List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint32>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint32List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedUint32ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint32> array;
}

void testUint32Misaligned() {
  final structPointer = malloc<PackedUint32ArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedUint32ArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class Uint64ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint64> array;
}

void testUint64ArrayElements() {
  final struct = Struct.create<Uint64ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testUint64ArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<Uint64ArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedUint64ArrayElements() {
  final struct = malloc<Uint64ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToUint64ArrayElementsBackedByTypedData() {
  final struct = Struct.create<Uint64ArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToUint64ArrayElementsBackedByPointer() {
  final struct = malloc<Uint64ArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testUint64ArrayElementsFirstAndLast() {
  final struct = Struct.create<Uint64ArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testUint64ArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<Uint64ArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Uint64>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Uint64>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint64>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint64List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint64>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint64List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testUint64ArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<Uint64ArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Uint64>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Uint64>(), elements.elementSizeInBytes);

  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Uint64List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Uint64>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Uint64List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedUint64ArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Uint64> array;
}

void testUint64Misaligned() {
  final structPointer = malloc<PackedUint64ArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedUint64ArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class FloatArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Float> array;
}

void testFloatArrayElements() {
  final struct = Struct.create<FloatArrayStruct>();
  final array = struct.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testFloatArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<FloatArrayStruct>(list);
  final array = struct.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedFloatArrayElements() {
  final struct = malloc<FloatArrayStruct>();
  final array = struct.ref.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToFloatArrayElementsBackedByTypedData() {
  final struct = Struct.create<FloatArrayStruct>();
  final array = struct.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToFloatArrayElementsBackedByPointer() {
  final struct = malloc<FloatArrayStruct>();
  final array = struct.ref.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testFloatArrayElementsFirstAndLast() {
  final struct = Struct.create<FloatArrayStruct>();
  final elements = struct.array.elements;
  var value = 100.0 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100.0 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testFloatArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<FloatArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Float>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Float>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Float>(), elements.elementSizeInBytes);

  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Float32List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Float>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Float32List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testFloatArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<FloatArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Float>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Float>(), elements.elementSizeInBytes);

  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Float32List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Float>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Float32List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedFloatArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Float> array;
}

void testFloatMisaligned() {
  final structPointer = malloc<PackedFloatArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedFloatArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class DoubleArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Double> array;
}

void testDoubleArrayElements() {
  final struct = Struct.create<DoubleArrayStruct>();
  final array = struct.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testDoubleArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<DoubleArrayStruct>(list);
  final array = struct.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedDoubleArrayElements() {
  final struct = malloc<DoubleArrayStruct>();
  final array = struct.ref.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToDoubleArrayElementsBackedByTypedData() {
  final struct = Struct.create<DoubleArrayStruct>();
  final array = struct.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToDoubleArrayElementsBackedByPointer() {
  final struct = malloc<DoubleArrayStruct>();
  final array = struct.ref.array;
  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testDoubleArrayElementsFirstAndLast() {
  final struct = Struct.create<DoubleArrayStruct>();
  final elements = struct.array.elements;
  var value = 100.0 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100.0 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}

void testDoubleArrayElementsTypedDataListBackedByTypedData() {
  final struct = Struct.create<DoubleArrayStruct>();
  final array = struct.array;
  final elements = array.elements;
  Expect.equals(sizeOf<Double>(), elements.offsetInBytes);
  Expect.equals(sizeOf<Double>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Double>(), elements.elementSizeInBytes);

  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Float64List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Double>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Float64List.sublistView(elements, 1, arrayLength - 1),
  );
}

void testDoubleArrayElementsTypedDataListBackedByPointer() {
  final struct = malloc<DoubleArrayStruct>();
  final array = struct.ref.array;
  final elements = array.elements;
  Expect.equals(0, elements.offsetInBytes);
  Expect.equals(sizeOf<Double>() * arrayLength, elements.lengthInBytes);
  Expect.equals(sizeOf<Double>(), elements.elementSizeInBytes);

  final expected = <double>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100.0 + i;
    array[i] = value;
    expected.add(value);
  }

  Expect.equals(expected.first, elements.first);
  Expect.equals(expected.last, elements.last);

  // Removed one element from the beginning and one from the end.
  final view = Float64List.view(
    elements.buffer,
    elements.offsetInBytes + sizeOf<Double>(),
    arrayLength - 2,
  );
  Expect.listEquals(expected.sublist(1, arrayLength - 1), view);
  Expect.listEquals(
    expected.sublist(1, arrayLength - 1),
    Float64List.sublistView(elements, 1, arrayLength - 1),
  );
  malloc.free(struct);
}

@Packed(1)
final class PackedDoubleArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Double> array;
}

void testDoubleMisaligned() {
  final structPointer = malloc<PackedDoubleArrayStruct>();
  var array = structPointer.ref.array;
  var e = Expect.throwsArgumentError(() => array.elements);
  Expect.isTrue(
    e.message.contains(
      'Pointer address must be aligned to a multiple of the element size',
    ),
  );
  malloc.free(structPointer);

  final struct = Struct.create<PackedDoubleArrayStruct>();
  array = struct.array;
  e = Expect.throwsRangeError(() => array.elements);
  Expect.isTrue(e.message.contains('must be a multiple of BYTES_PER_ELEMENT'));
}

final class BoolArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<Bool> array;
}

void testBoolArrayElements() {
  final struct = Struct.create<BoolArrayStruct>();
  final array = struct.array;
  final expected = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = i.isEven;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testBoolArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<BoolArrayStruct>(list);
  final array = struct.array;
  final expected = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = i.isEven;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedBoolArrayElements() {
  final struct = malloc<BoolArrayStruct>();
  final array = struct.ref.array;
  final expected = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = i.isEven;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToBoolArrayElementsBackedByTypedData() {
  final struct = Struct.create<BoolArrayStruct>();
  final array = struct.array;
  final expected = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = i.isEven;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToBoolArrayElementsBackedByPointer() {
  final struct = malloc<BoolArrayStruct>();
  final array = struct.ref.array;
  final expected = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = i.isEven;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <bool>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testBoolArrayElementsFirstAndLast() {
  final struct = Struct.create<BoolArrayStruct>();
  final elements = struct.array.elements;
  var value = 3.isEven;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 4.isEven;
  elements.last = value;
  Expect.equals(value, elements.last);
}

final class WCharArrayStruct extends Struct {
  // Placeholder value before array to test the offset calculation logic.
  @Int8()
  external int placeholder;

  @Array(arrayLength)
  external Array<WChar> array;
}

void testWCharArrayElements() {
  final struct = Struct.create<WCharArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testWCharArrayBackedByInt64ListElements() {
  final list = Int64List(6);
  final struct = Struct.create<WCharArrayStruct>(list);
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
}

void testMallocedWCharArrayElements() {
  final struct = malloc<WCharArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  malloc.free(struct);
}

void testWriteToWCharArrayElementsBackedByTypedData() {
  final struct = Struct.create<WCharArrayStruct>();
  final array = struct.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
}

void testWriteToWCharArrayElementsBackedByPointer() {
  final struct = malloc<WCharArrayStruct>();
  final array = struct.ref.array;
  final expected = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    final value = 100 + i;
    array.elements[i] = value;
    expected.add(value);
  }
  Expect.listEquals(expected, array.elements);
  final actual = <int>[];
  for (int i = 0; i < arrayLength; i++) {
    actual.add(array[i]);
  }
  Expect.listEquals(expected, actual);
  malloc.free(struct);
}

void testWCharArrayElementsFirstAndLast() {
  final struct = Struct.create<WCharArrayStruct>();
  final elements = struct.array.elements;
  var value = 100 + 3;
  elements.first = value;
  Expect.equals(value, elements.first);
  value = 100 + 4;
  elements.last = value;
  Expect.equals(value, elements.last);
}
