// Copyright (c) 2013, 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.

// @dart = 2.6

/// Lists that efficiently handle fixed sized data
/// (for example, unsigned 8 byte integers) and SIMD numeric types.
///
/// To use this library in your code:
///
///     import 'dart:typed_data';
///
/// {@category Core}
library dart.typed_data;

import "dart:_internal" show Since, UnmodifiableListBase;

part "unmodifiable_typed_data.dart";

/**
 * A sequence of bytes underlying a typed data object.
 *
 * Used to process large quantities of binary or numerical data
 * more efficiently using a typed view.
 */
abstract class ByteBuffer {
  /**
   * Returns the length of this byte buffer, in bytes.
   */
  int get lengthInBytes;

  /**
   * Creates a [Uint8List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Uint8List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes] and contains [length] bytes.
   * If [length] is omitted, the range extends to the end of the buffer.
   *
   * The start index and length must describe a valid range of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `length` must not be negative, and
   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
   */
  Uint8List asUint8List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Int8List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Int8List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes] and contains [length] bytes.
   * If [length] is omitted, the range extends to the end of the buffer.
   *
   * The start index and length must describe a valid range of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `length` must not be negative, and
   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
   */
  Int8List asInt8List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Uint8ClampedList] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Uint8ClampedList` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes] and contains [length] bytes.
   * If [length] is omitted, the range extends to the end of the buffer.
   *
   * The start index and length must describe a valid range of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `length` must not be negative, and
   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
   */
  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Uint16List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Uint16List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 16-bit aligned,
   * and contains [length] 16-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not even, the last byte can't be part of the view.
   *
   * The start index and length must describe a valid 16-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by two,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
   */
  Uint16List asUint16List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Int16List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Int16List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 16-bit aligned,
   * and contains [length] 16-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not even, the last byte can't be part of the view.
   *
   * The start index and length must describe a valid 16-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by two,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 2` must not be greater than [lengthInBytes].
   */
  Int16List asInt16List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Uint32List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Uint32List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
   * and contains [length] 32-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by four, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 32-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by four,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
   */
  Uint32List asUint32List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Int32List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Int32List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
   * and contains [length] 32-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by four, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 32-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by four,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
   */
  Int32List asInt32List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Uint64List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Uint64List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
   * and contains [length] 64-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 64-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by eight,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
   */
  Uint64List asUint64List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Int64List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Int64List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
   * and contains [length] 64-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 64-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by eight,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
   */
  Int64List asInt64List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Int32x4List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Int32x4List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
   * and contains [length] 128-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 128-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by sixteen,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
   */
  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Float32List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Float32List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 32-bit aligned,
   * and contains [length] 32-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by four, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 32-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by four,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 4` must not be greater than [lengthInBytes].
   */
  Float32List asFloat32List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Float64List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Float64List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 64-bit aligned,
   * and contains [length] 64-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by eight, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 64-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by eight,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 8` must not be greater than [lengthInBytes].
   */
  Float64List asFloat64List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Float32x4List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Float32x4List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
   * and contains [length] 128-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 128-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by sixteen,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
   */
  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [Float64x2List] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `Float64x2List` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes], which must be 128-bit aligned,
   * and contains [length] 128-bit integers.
   * If [length] is omitted, the range extends as far towards the end of
   * the buffer as possible -
   * if [lengthInBytes] is not divisible by 16, the last bytes can't be part
   * of the view.
   *
   * The start index and length must describe a valid 128-bit aligned range
   * of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `offsetInBytes` must be divisible by sixteen,
   * * `length` must not be negative, and
   * * `offsetInBytes + length * 16` must not be greater than [lengthInBytes].
   */
  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]);

  /**
   * Creates a [ByteData] _view_ of a region of this byte buffer.
   *
   * The view is backed by the bytes of this byte buffer.
   * Any changes made to the `ByteData` will also change the buffer,
   * and vice versa.
   *
   * The viewed region start at [offsetInBytes] and contains [length] bytes.
   * If [length] is omitted, the range extends to the end of the buffer.
   *
   * The start index and length must describe a valid range of the buffer:
   *
   * * `offsetInBytes` must not be negative,
   * * `length` must not be negative, and
   * * `offsetInBytes + length` must not be greater than [lengthInBytes].
   */
  ByteData asByteData([int offsetInBytes = 0, int length]);
}

/**
 * A typed view of a sequence of bytes.
 */
abstract class TypedData {
  /**
   * Returns the number of bytes in the representation of each element in this
   * list.
   */
  int get elementSizeInBytes;

  /**
   * Returns the offset in bytes into the underlying byte buffer of this view.
   */
  int get offsetInBytes;

  /**
   * Returns the length of this view, in bytes.
   */
  int get lengthInBytes;

  /**
   * Returns the byte buffer associated with this object.
   */
  ByteBuffer get buffer;
}

abstract class _TypedIntList extends TypedData {
  /**
   * Returns the concatenation of this list and [other].
   *
   * If other is also a typed-data integer list, the returned list will
   * be a type-data integer list capable of containing all the elements of
   * this list and of [other].
   * Otherwise the returned list will be a normal growable `List<int>`.
   */
  List<int> operator +(List<int> other);
}

abstract class _TypedFloatList extends TypedData {
  /**
   * Returns the concatenation of this list and [other].
   *
   * If other is also a typed-data floating point number list,
   * the returned list will be a type-data float list capable of containing
   * all the elements of this list and of [other].
   * Otherwise the returned list will be a normal growable `List<double>`.
   */
  List<double> operator +(List<double> other);
}

/**
 * Describes endianness to be used when accessing or updating a
 * sequence of bytes.
 */
class Endian {
  final bool _littleEndian;
  const Endian._(this._littleEndian);

  static const Endian big = const Endian._(false);
  static const Endian little = const Endian._(true);
  static final Endian host =
      (new ByteData.view(new Uint16List.fromList([1]).buffer)).getInt8(0) == 1
          ? little
          : big;
}

/**
 * A fixed-length, random-access sequence of bytes that also provides random
 * and unaligned access to the fixed-width integers and floating point
 * numbers represented by those bytes.
 *
 * `ByteData` may be used to pack and unpack data from external sources
 * (such as networks or files systems), and to process large quantities
 * of numerical data more efficiently than would be possible
 * with ordinary [List] implementations.
 * `ByteData` can save space, by eliminating the need for object headers,
 * and time, by eliminating the need for data copies.
 * Finally, `ByteData` may be used to intentionally reinterpret the bytes
 * representing one arithmetic type as another.
 * For example this code fragment determine what 32-bit signed integer
 * is represented by the bytes of a 32-bit floating point number
 * (both stored as big endian):
 *
 *     var bdata = new ByteData(8);
 *     bdata.setFloat32(0, 3.04);
 *     int huh = bdata.getInt32(0); // 0x40428f5c
 */
abstract class ByteData implements TypedData {
  /**
   * Creates a [ByteData] of the specified length (in elements), all of
   * whose bytes are initially zero.
   */
  @pragma("vm:entry-point")
  external factory ByteData(int length);

  /**
   * Creates an [ByteData] _view_ of the specified region in [buffer].
   *
   * Changes in the [ByteData] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `ByteData.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * ByteData.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [ByteData.sublistView]
   * which includes this computation.
   * ```dart
   * ByteData.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory ByteData.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asByteData(offsetInBytes, length);
  }

  /**
   * Creates a [ByteData] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   */
  @Since("2.8")
  factory ByteData.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    return data.buffer.asByteData(
        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
  }

  /**
   * Returns the (possibly negative) integer represented by the byte at the
   * specified [byteOffset] in this object, in two's complement binary
   * representation.
   *
   * The return value will be between -128 and 127, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * greater than or equal to the length of this object.
   */
  int getInt8(int byteOffset);

  /**
   * Sets the byte at the specified [byteOffset] in this object to the
   * two's complement binary representation of the specified [value], which
   * must fit in a single byte.
   *
   * In other words, [value] must be between -128 and 127, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * greater than or equal to the length of this object.
   */
  void setInt8(int byteOffset, int value);

  /**
   * Returns the positive integer represented by the byte at the specified
   * [byteOffset] in this object, in unsigned binary form.
   *
   * The return value will be between 0 and 255, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * greater than or equal to the length of this object.
   */
  int getUint8(int byteOffset);

  /**
   * Sets the byte at the specified [byteOffset] in this object to the
   * unsigned binary representation of the specified [value], which must fit
   * in a single byte.
   *
   * In other words, [value] must be between 0 and 255, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative,
   * or greater than or equal to the length of this object.
   */
  void setUint8(int byteOffset, int value);

  /**
   * Returns the (possibly negative) integer represented by the two bytes at
   * the specified [byteOffset] in this object, in two's complement binary
   * form.
   *
   * The return value will be between -2<sup>15</sup> and 2<sup>15</sup> - 1,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  int getInt16(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the two bytes starting at the specified [byteOffset] in this
   * object to the two's complement binary representation of the specified
   * [value], which must fit in two bytes.
   *
   * In other words, [value] must lie
   * between -2<sup>15</sup> and 2<sup>15</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]);

  /**
   * Returns the positive integer represented by the two bytes starting
   * at the specified [byteOffset] in this object, in unsigned binary
   * form.
   *
   * The return value will be between 0 and  2<sup>16</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  int getUint16(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the two bytes starting at the specified [byteOffset] in this object
   * to the unsigned binary representation of the specified [value],
   * which must fit in two bytes.
   *
   * In other words, [value] must be between
   * 0 and 2<sup>16</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 2` is greater than the length of this object.
   */
  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]);

  /**
   * Returns the (possibly negative) integer represented by the four bytes at
   * the specified [byteOffset] in this object, in two's complement binary
   * form.
   *
   * The return value will be between -2<sup>31</sup> and 2<sup>31</sup> - 1,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  int getInt32(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the four bytes starting at the specified [byteOffset] in this
   * object to the two's complement binary representation of the specified
   * [value], which must fit in four bytes.
   *
   * In other words, [value] must lie
   * between -2<sup>31</sup> and 2<sup>31</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]);

  /**
   * Returns the positive integer represented by the four bytes starting
   * at the specified [byteOffset] in this object, in unsigned binary
   * form.
   *
   * The return value will be between 0 and  2<sup>32</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  int getUint32(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the four bytes starting at the specified [byteOffset] in this object
   * to the unsigned binary representation of the specified [value],
   * which must fit in four bytes.
   *
   * In other words, [value] must be between
   * 0 and 2<sup>32</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]);

  /**
   * Returns the (possibly negative) integer represented by the eight bytes at
   * the specified [byteOffset] in this object, in two's complement binary
   * form.
   *
   * The return value will be between -2<sup>63</sup> and 2<sup>63</sup> - 1,
   * inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  int getInt64(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the eight bytes starting at the specified [byteOffset] in this
   * object to the two's complement binary representation of the specified
   * [value], which must fit in eight bytes.
   *
   * In other words, [value] must lie
   * between -2<sup>63</sup> and 2<sup>63</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]);

  /**
   * Returns the positive integer represented by the eight bytes starting
   * at the specified [byteOffset] in this object, in unsigned binary
   * form.
   *
   * The return value will be between 0 and  2<sup>64</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  int getUint64(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the eight bytes starting at the specified [byteOffset] in this object
   * to the unsigned binary representation of the specified [value],
   * which must fit in eight bytes.
   *
   * In other words, [value] must be between
   * 0 and 2<sup>64</sup> - 1, inclusive.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]);

  /**
   * Returns the floating point number represented by the four bytes at
   * the specified [byteOffset] in this object, in IEEE 754
   * single-precision binary floating-point format (binary32).
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  double getFloat32(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the four bytes starting at the specified [byteOffset] in this
   * object to the IEEE 754 single-precision binary floating-point
   * (binary32) representation of the specified [value].
   *
   * **Note that this method can lose precision.** The input [value] is
   * a 64-bit floating point value, which will be converted to 32-bit
   * floating point value by IEEE 754 rounding rules before it is stored.
   * If [value] cannot be represented exactly as a binary32, it will be
   * converted to the nearest binary32 value.  If two binary32 values are
   * equally close, the one whose least significant bit is zero will be used.
   * Note that finite (but large) values can be converted to infinity, and
   * small non-zero values can be converted to zero.
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 4` is greater than the length of this object.
   */
  void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]);

  /**
   * Returns the floating point number represented by the eight bytes at
   * the specified [byteOffset] in this object, in IEEE 754
   * double-precision binary floating-point format (binary64).
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  double getFloat64(int byteOffset, [Endian endian = Endian.big]);

  /**
   * Sets the eight bytes starting at the specified [byteOffset] in this
   * object to the IEEE 754 double-precision binary floating-point
   * (binary64) representation of the specified [value].
   *
   * Throws [RangeError] if [byteOffset] is negative, or
   * `byteOffset + 8` is greater than the length of this object.
   */
  void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]);
}

/**
 * A fixed-length list of 8-bit signed integers.
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low eight bits,
 * interpreted as a signed 8-bit two's complement integer with values in the
 * range -128 to +127.
 */
abstract class Int8List implements List<int>, _TypedIntList {
  /**
   * Creates an [Int8List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
   */
  external factory Int8List(int length);

  /**
   * Creates a [Int8List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
   * bytes.
   */
  external factory Int8List.fromList(List<int> elements);

  /**
   * Creates an [Int8List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Int8List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Int8List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Int8List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Int8List.sublistView]
   * which includes this computation.
   * ```dart
   * Int8List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Int8List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asInt8List(offsetInBytes, length);
  }

  /**
   * Creates an [Int8List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   */
  @Since("2.8")
  factory Int8List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    return data.buffer.asInt8List(
        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is an `Int8List` containing the elements of this list at
   * positions greater than or equal to [start] and less than [end] in the same
   * order as they occur in this list.
   *
   * ```dart
   * var numbers = Int8List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Int8List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Int8List sublist(int start, [int end]);

  static const int bytesPerElement = 1;
}

/**
 * A fixed-length list of 8-bit unsigned integers.
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low eight bits,
 * interpreted as an unsigned 8-bit integer with values in the
 * range 0 to 255.
 */
abstract class Uint8List implements List<int>, _TypedIntList {
  /**
   * Creates a [Uint8List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
   */
  external factory Uint8List(int length);

  /**
   * Creates a [Uint8List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
   * bytes.
   */
  external factory Uint8List.fromList(List<int> elements);

  /**
   * Creates a [Uint8List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Uint8List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Uint8List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Uint8List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Uint8List.sublistView]
   * which includes this computation.
   * ```dart
   * Uint8List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Uint8List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asUint8List(offsetInBytes, length);
  }

  /**
   * Creates a [Uint8List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   */
  @Since("2.8")
  factory Uint8List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    return data.buffer.asUint8List(
        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
  }

  /**
   * Returns a concatenation of this list and [other].
   *
   * If [other] is also a typed-data list, then the return list will be a
   * typed data list capable of holding both unsigned 8-bit integers and
   * the elements of [other], otherwise it'll be a normal list of integers.
   */
  List<int> operator +(List<int> other);

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Uint8List` containing the elements of this list at
   * positions greater than or equal to [start] and less than [end] in the same
   * order as they occur in this list.
   *
   * ```dart
   * var numbers = Uint8List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Uint8List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Uint8List sublist(int start, [int end]);

  static const int bytesPerElement = 1;
}

/**
 * A fixed-length list of 8-bit unsigned integers.
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are clamped to an unsigned eight bit value.
 * That is, all values below zero are stored as zero
 * and all values above 255 are stored as 255.
 */
abstract class Uint8ClampedList implements List<int>, _TypedIntList {
  /**
   * Creates a [Uint8ClampedList] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely [length] bytes.
   */
  external factory Uint8ClampedList(int length);

  /**
   * Creates a [Uint8ClampedList] of the same size as the [elements]
   * list and copies over the values clamping when needed.
   *
   * Values are clamped to fit in the list when they are copied,
   * the same way storing values clamps them.
   *
   * The list is backed by a [ByteBuffer] containing precisely `elements.length`
   * bytes.
   */
  external factory Uint8ClampedList.fromList(List<int> elements);

  /**
   * Creates a [Uint8ClampedList] _view_ of the specified region in the
   * specified byte [buffer].
   *
   * Changes in the [Uint8List] will be visible in the byte buffer
   * and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Uint8ClampedList.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Uint8ClampedList.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Uint8ClampedList.sublistView]
   * which includes this computation.
   * ```dart
   * Uint8ClampedList.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Uint8ClampedList.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asUint8ClampedList(offsetInBytes, length);
  }

  /**
   * Creates a [Uint8ClampedList] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   */
  @Since("2.8")
  factory Uint8ClampedList.sublistView(TypedData data,
      [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    return data.buffer.asUint8ClampedList(
        data.offsetInBytes + start * elementSize, (end - start) * elementSize);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Uint8ClampedList` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Uint8ClampedList.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Uint8ClampedList
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Uint8ClampedList sublist(int start, [int end]);

  static const int bytesPerElement = 1;
}

/**
 * A fixed-length list of 16-bit signed integers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low 16 bits,
 * interpreted as a signed 16-bit two's complement integer with values in the
 * range -32768 to +32767.
 */
abstract class Int16List implements List<int>, _TypedIntList {
  /**
   * Creates an [Int16List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 2 bytes.
   */
  external factory Int16List(int length);

  /**
   * Creates a [Int16List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 2 bytes.
   */
  external factory Int16List.fromList(List<int> elements);

  /**
   * Creates an [Int16List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Int16List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Int16List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Int16List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Int16List.sublistView]
   * which includes this computation.
   * ```dart
   * Int16List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Int16List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asInt16List(offsetInBytes, length);
  }

  /**
   * Creates an [Int16List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of two.
   */
  @Since("2.8")
  factory Int16List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asInt16List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is an `Int16List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Int16List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Int16List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Int16List sublist(int start, [int end]);

  static const int bytesPerElement = 2;
}

/**
 * A fixed-length list of 16-bit unsigned integers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low 16 bits,
 * interpreted as an unsigned 16-bit integer with values in the
 * range 0 to 65535.
 */
abstract class Uint16List implements List<int>, _TypedIntList {
  /**
   * Creates a [Uint16List] of the specified length (in elements), all
   * of whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 2 bytes.
   */
  external factory Uint16List(int length);

  /**
   * Creates a [Uint16List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 2 bytes.
   */
  external factory Uint16List.fromList(List<int> elements);

  /**
   * Creates a [Uint16List] _view_ of the specified region in
   * the specified byte buffer.
   *
   * Changes in the [Uint16List] will be visible in the byte buffer
   * and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Uint16List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Uint16List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Uint16List.sublistView]
   * which includes this computation.
   * ```dart
   * Uint16List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Uint16List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asUint16List(offsetInBytes, length);
  }

  /**
   * Creates a [Uint16List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of two.
   */
  @Since("2.8")
  factory Uint16List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asUint16List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Uint16List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Uint16List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Uint16List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Uint16List sublist(int start, [int end]);

  static const int bytesPerElement = 2;
}

/**
 * A fixed-length list of 32-bit signed integers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low 32 bits,
 * interpreted as a signed 32-bit two's complement integer with values in the
 * range -2147483648 to 2147483647.
 */
abstract class Int32List implements List<int>, _TypedIntList {
  /**
   * Creates an [Int32List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 4 bytes.
   */
  external factory Int32List(int length);

  /**
   * Creates a [Int32List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 4 bytes.
   */
  external factory Int32List.fromList(List<int> elements);

  /**
   * Creates an [Int32List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Int32List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Int32List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Int32List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Int32List.sublistView]
   * which includes this computation.
   * ```dart
   * Int32List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Int32List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asInt32List(offsetInBytes, length);
  }

  /**
   * Creates an [Int32List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of four.
   */
  @Since("2.8")
  factory Int32List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asInt32List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is an `Int32List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Int32List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Int32List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Int32List sublist(int start, [int end]);

  static const int bytesPerElement = 4;
}

/**
 * A fixed-length list of 32-bit unsigned integers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low 32 bits,
 * interpreted as an unsigned 32-bit integer with values in the
 * range 0 to 4294967295.
 */
abstract class Uint32List implements List<int>, _TypedIntList {
  /**
   * Creates a [Uint32List] of the specified length (in elements), all
   * of whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 4 bytes.
   */
  external factory Uint32List(int length);

  /**
   * Creates a [Uint32List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 4 bytes.
   */
  external factory Uint32List.fromList(List<int> elements);

  /**
   * Creates a [Uint32List] _view_ of the specified region in
   * the specified byte buffer.
   *
   * Changes in the [Uint32List] will be visible in the byte buffer
   * and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Uint32List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Uint32List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Uint32List.sublistView]
   * which includes this computation.
   * ```dart
   * Uint32List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Uint32List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asUint32List(offsetInBytes, length);
  }

  /**
   * Creates a [Uint32List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of four.
   */
  @Since("2.8")
  factory Uint32List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asUint32List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Uint32List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Uint32List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Uint32List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Uint32List sublist(int start, [int end]);

  static const int bytesPerElement = 4;
}

/**
 * A fixed-length list of 64-bit signed integers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low 64 bits,
 * interpreted as a signed 64-bit two's complement integer with values in the
 * range -9223372036854775808 to +9223372036854775807.
 */
abstract class Int64List implements List<int>, _TypedIntList {
  /**
   * Creates an [Int64List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 8 bytes.
   */
  external factory Int64List(int length);

  /**
   * Creates a [Int64List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 8 bytes.
   */
  external factory Int64List.fromList(List<int> elements);

  /**
   * Creates an [Int64List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Int64List] will be visible in the byte buffer
   * and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Int64List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Int64List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Int64List.sublistView]
   * which includes this computation.
   * ```dart
   * Int64List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Int64List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asInt64List(offsetInBytes, length);
  }

  /**
   * Creates an [Int64List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of eight.
   */
  @Since("2.8")
  factory Int64List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asInt64List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is an `Int64List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Int64List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Int64List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Int64List sublist(int start, [int end]);

  static const int bytesPerElement = 8;
}

/**
 * A fixed-length list of 64-bit unsigned integers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation can be considerably
 * more space- and time-efficient than the default [List] implementation.
 *
 * Integers stored in the list are truncated to their low 64 bits,
 * interpreted as an unsigned 64-bit integer with values in the
 * range 0 to 18446744073709551615.
 */
abstract class Uint64List implements List<int>, _TypedIntList {
  /**
   * Creates a [Uint64List] of the specified length (in elements), all
   * of whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 8 bytes.
   */
  external factory Uint64List(int length);

  /**
   * Creates a [Uint64List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 8 bytes.
   */
  external factory Uint64List.fromList(List<int> elements);

  /**
   * Creates an [Uint64List] _view_ of the specified region in
   * the specified byte buffer.
   *
   * Changes in the [Uint64List] will be visible in the byte buffer
   * and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Uint64List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Uint64List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Uint64List.sublistView]
   * which includes this computation.
   * ```dart
   * Uint64List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Uint64List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asUint64List(offsetInBytes, length);
  }

  /**
   * Creates a [Uint64List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of eight.
   */
  @Since("2.8")
  factory Uint64List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asUint64List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Uint64List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Uint64List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Uint64List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Uint64List sublist(int start, [int end]);

  static const int bytesPerElement = 8;
}

/**
 * A fixed-length list of IEEE 754 single-precision binary floating-point
 * numbers that is viewable as a [TypedData].
 *
 * For long lists, this
 * implementation can be considerably more space- and time-efficient than
 * the default [List] implementation.
 *
 * Double values stored in the list are converted to the nearest
 * single-precision value. Values read are converted to a double
 * value with the same value.
 */
abstract class Float32List implements List<double>, _TypedFloatList {
  /**
   * Creates a [Float32List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 4 bytes.
   */
  external factory Float32List(int length);

  /**
   * Creates a [Float32List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * Values are truncated to fit in the list when they are copied,
   * the same way storing values truncates them.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 4 bytes.
   */
  external factory Float32List.fromList(List<double> elements);

  /**
   * Creates a [Float32List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Float32List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Float32List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Float32List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Float32List.sublistView]
   * which includes this computation.
   * ```dart
   * Float32List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Float32List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asFloat32List(offsetInBytes, length);
  }

  /**
   * Creates an [Float32List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of four.
   */
  @Since("2.8")
  factory Float32List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asFloat32List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Float32List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Float32List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Float32List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Float32List sublist(int start, [int end]);

  static const int bytesPerElement = 4;
}

/**
 * A fixed-length list of IEEE 754 double-precision binary floating-point
 * numbers  that is viewable as a [TypedData].
 *
 * For long lists, this
 * implementation can be considerably more space- and time-efficient than
 * the default [List] implementation.
 */
abstract class Float64List implements List<double>, _TypedFloatList {
  /**
   * Creates a [Float64List] of the specified length (in elements), all of
   * whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 8 bytes.
   */
  external factory Float64List(int length);

  /**
   * Creates a [Float64List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 8 bytes.
   */
  external factory Float64List.fromList(List<double> elements);

  /**
   * Creates a [Float64List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Float64List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Float64List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Float64List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Float64List.sublistView]
   * which includes this computation.
   * ```dart
   * Float64List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Float64List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asFloat64List(offsetInBytes, length);
  }

  /**
   * Creates a [Float64List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of eight.
   */
  @Since("2.8")
  factory Float64List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asFloat64List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Float64List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Float64List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Float64List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Float64List sublist(int start, [int end]);

  static const int bytesPerElement = 8;
}

/**
 * A fixed-length list of Float32x4 numbers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation will be considerably more
 * space- and time-efficient than the default [List] implementation.
 */
abstract class Float32x4List implements List<Float32x4>, TypedData {
  /**
   * Creates a [Float32x4List] of the specified length (in elements),
   * all of whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 16 bytes.
   */
  external factory Float32x4List(int length);

  /**
   * Creates a [Float32x4List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 16 bytes.
   */
  external factory Float32x4List.fromList(List<Float32x4> elements);

  /**
   * Creates a [Float32x4List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Float32x4List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Float32x4List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Float32x4List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Float32x4List.sublistView]
   * which includes this computation.
   * ```dart
   * Float32x4List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Float32x4List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asFloat32x4List(offsetInBytes, length);
  }

  /**
   * Creates a [Float32x4List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of sixteen.
   */
  @Since("2.8")
  factory Float32x4List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asFloat32x4List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns the concatenation of this list and [other].
   *
   * If [other] is also a [Float32x4List], the result is a new [Float32x4List],
   * otherwise the result is a normal growable `List<Float32x4>`.
   */
  List<Float32x4> operator +(List<Float32x4> other);

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Float32x4List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Float32x4List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Float32x4List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Float32x4List sublist(int start, [int end]);

  static const int bytesPerElement = 16;
}

/**
 * A fixed-length list of Int32x4 numbers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation will be considerably more
 * space- and time-efficient than the default [List] implementation.
 */
abstract class Int32x4List implements List<Int32x4>, TypedData {
  /**
   * Creates a [Int32x4List] of the specified length (in elements),
   * all of whose elements are initially zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 16 bytes.
   */
  external factory Int32x4List(int length);

  /**
   * Creates a [Int32x4List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 16 bytes.
   */
  external factory Int32x4List.fromList(List<Int32x4> elements);

  /**
   * Creates a [Int32x4List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Int32x4List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Int32x4List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Int32x4List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Int32x4List.sublistView]
   * which includes this computation.
   * ```dart
   * Int32x4List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Int32x4List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asInt32x4List(offsetInBytes, length);
  }

  /**
   * Creates an [Int32x4List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of sixteen.
   */
  @Since("2.8")
  factory Int32x4List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asInt32x4List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns the concatenation of this list and [other].
   *
   * If [other] is also a [Int32x4List], the result is a new [Int32x4List],
   * otherwise the result is a normal growable `List<Int32x4>`.
   */
  List<Int32x4> operator +(List<Int32x4> other);

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is an `Int32x4list` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Int32x4list.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Int32x4list
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Int32x4List sublist(int start, [int end]);

  static const int bytesPerElement = 16;
}

/**
 * A fixed-length list of Float64x2 numbers that is viewable as a
 * [TypedData].
 *
 * For long lists, this implementation will be considerably more
 * space- and time-efficient than the default [List] implementation.
 */
abstract class Float64x2List implements List<Float64x2>, TypedData {
  /**
   * Creates a [Float64x2List] of the specified length (in elements),
   * all of whose elements have all lanes set to zero.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * [length] times 16 bytes.
   */
  external factory Float64x2List(int length);

  /**
   * Creates a [Float64x2List] with the same length as the [elements] list
   * and copies over the elements.
   *
   * The list is backed by a [ByteBuffer] containing precisely
   * `elements.length` times 16 bytes.
   */
  external factory Float64x2List.fromList(List<Float64x2> elements);

  /**
   * Returns the concatenation of this list and [other].
   *
   * If [other] is also a [Float64x2List], the result is a new [Float64x2List],
   * otherwise the result is a normal growable `List<Float64x2>`.
   */
  List<Float64x2> operator +(List<Float64x2> other);

  /**
   * Creates a [Float64x2List] _view_ of the specified region in [buffer].
   *
   * Changes in the [Float64x2List] will be visible in the byte
   * buffer and vice versa.
   * If the [offsetInBytes] index of the region is not specified,
   * it defaults to zero (the first byte in the byte buffer).
   * If the length is not specified, it defaults to `null`,
   * which indicates that the view extends to the end of the byte buffer.
   *
   * Throws [RangeError] if [offsetInBytes] or [length] are negative, or
   * if [offsetInBytes] + ([length] * elementSizeInBytes) is greater than
   * the length of [buffer].
   *
   * Throws [ArgumentError] if [offsetInBytes] is not a multiple of
   * [bytesPerElement].
   *
   * Note that when creating a view from a [TypedData] list or byte data,
   * that list or byte data may itself be a view on a larger buffer
   * with a [TypedData.offsetInBytes] greater than zero.
   * Merely doing `Float64x2List.view(other.buffer, 0, count)` may not
   * point to the bytes you intended. Instead you may need to do:
   * ```dart
   * Float64x2List.view(other.buffer, other.offsetInBytes, count)
   * ```
   * Alternatively, use [Float64x2List.sublistView]
   * which includes this computation.
   * ```dart
   * Float64x2List.sublistView(other, 0, count)
   * ```
   * (The third argument is an end index rather than a length, so if
   * you start from a position greater than zero, you need not
   * reduce the count correspondingly).
   */
  factory Float64x2List.view(ByteBuffer buffer,
      [int offsetInBytes = 0, int length]) {
    return buffer.asFloat64x2List(offsetInBytes, length);
  }

  /**
   * Creates an [Float64x2List] view on a range of elements of [data].
   *
   * Creates a view on the range of `data.buffer` which corresponds
   * to the elements of [data] from [start] until [end].
   * If [data] is a typed data list, like [Uint16List], then the view is on
   * the bytes of the elements with indices from [start] until [end].
   * If [data] is a [ByteData], it's treated like a list of bytes.
   *
   * If provided, [start] and [end] must satisfy
   *
   * 0 &le; `start` &le; `end` &le; *elementCount*
   *
   * where *elementCount* is the number of elements in [data], which
   * is the same as the [List.length] of a typed data list.
   *
   * If omitted, [start] defaults to zero and [end] to *elementCount*.
   *
   * The start and end indices of the range of bytes being viewed must be
   * multiples of sixteen.
   */
  @Since("2.8")
  factory Float64x2List.sublistView(TypedData data, [int start = 0, int end]) {
    int elementSize = data.elementSizeInBytes;
    end = RangeError.checkValidRange(
        start, end, data.lengthInBytes ~/ elementSize);
    int byteLength = (end - start) * elementSize;
    if (byteLength % bytesPerElement != 0) {
      throw ArgumentError("The number of bytes to view must be a multiple of " +
          "$bytesPerElement");
    }
    return data.buffer.asFloat64x2List(data.offsetInBytes + start * elementSize,
        byteLength ~/ bytesPerElement);
  }

  /**
   * Returns a new list containing the elements between [start] and [end].
   *
   * The new list is a `Float64x2List` containing the elements of this
   * list at positions greater than or equal to [start] and less than [end] in
   * the same order as they occur in this list.
   *
   * ```dart
   * var numbers = Float64x2List.fromList([0, 1, 2, 3, 4]);
   * print(numbers.sublist(1, 3)); // [1, 2]
   * print(numbers.sublist(1, 3).runtimeType); // Float64x2List
   * ```
   *
   * If [end] is omitted, it defaults to the [length] of this list.
   *
   * ```dart
   * print(numbers.sublist(1)); // [1, 2, 3, 4]
   * ```
   *
   * The `start` and `end` positions must satisfy the relations
   * 0 ≤ `start` ≤ `end` ≤ `this.length`
   * If `end` is equal to `start`, then the returned list is empty.
   */
  Float64x2List sublist(int start, [int end]);

  static const int bytesPerElement = 16;
}

/**
 * Float32x4 immutable value type and operations.
 *
 * Float32x4 stores 4 32-bit floating point values in "lanes".
 * The lanes are "x", "y", "z", and "w" respectively.
 */
abstract class Float32x4 {
  external factory Float32x4(double x, double y, double z, double w);
  external factory Float32x4.splat(double v);
  external factory Float32x4.zero();
  external factory Float32x4.fromInt32x4Bits(Int32x4 x);

  /// Sets the x and y lanes to their respective values in [v] and sets the z
  /// and w lanes to 0.0.
  external factory Float32x4.fromFloat64x2(Float64x2 v);

  /// Addition operator.
  Float32x4 operator +(Float32x4 other);

  /// Negate operator.
  Float32x4 operator -();

  /// Subtraction operator.
  Float32x4 operator -(Float32x4 other);

  /// Multiplication operator.
  Float32x4 operator *(Float32x4 other);

  /// Division operator.
  Float32x4 operator /(Float32x4 other);

  /// Relational less than.
  Int32x4 lessThan(Float32x4 other);

  /// Relational less than or equal.
  Int32x4 lessThanOrEqual(Float32x4 other);

  /// Relational greater than.
  Int32x4 greaterThan(Float32x4 other);

  /// Relational greater than or equal.
  Int32x4 greaterThanOrEqual(Float32x4 other);

  /// Relational equal.
  Int32x4 equal(Float32x4 other);

  /// Relational not-equal.
  Int32x4 notEqual(Float32x4 other);

  /// Returns a copy of [this] each lane being scaled by [s].
  /// Equivalent to this * new Float32x4.splat(s)
  Float32x4 scale(double s);

  /// Returns the lane-wise absolute value of this [Float32x4].
  Float32x4 abs();

  /// Lane-wise clamp [this] to be in the range [lowerLimit]-[upperLimit].
  Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit);

  /// Extracted x value.
  double get x;

  /// Extracted y value.
  double get y;

  /// Extracted z value.
  double get z;

  /// Extracted w value.
  double get w;

  /// Extract the sign bits from each lane return them in the first 4 bits.
  /// "x" lane is bit 0.
  /// "y" lane is bit 1.
  /// "z" lane is bit 2.
  /// "w" lane is bit 3.
  int get signMask;

  /// Mask passed to [shuffle] or [shuffleMix].
  static const int xxxx = 0x0;
  static const int xxxy = 0x40;
  static const int xxxz = 0x80;
  static const int xxxw = 0xC0;
  static const int xxyx = 0x10;
  static const int xxyy = 0x50;
  static const int xxyz = 0x90;
  static const int xxyw = 0xD0;
  static const int xxzx = 0x20;
  static const int xxzy = 0x60;
  static const int xxzz = 0xA0;
  static const int xxzw = 0xE0;
  static const int xxwx = 0x30;
  static const int xxwy = 0x70;
  static const int xxwz = 0xB0;
  static const int xxww = 0xF0;
  static const int xyxx = 0x4;
  static const int xyxy = 0x44;
  static const int xyxz = 0x84;
  static const int xyxw = 0xC4;
  static const int xyyx = 0x14;
  static const int xyyy = 0x54;
  static const int xyyz = 0x94;
  static const int xyyw = 0xD4;
  static const int xyzx = 0x24;
  static const int xyzy = 0x64;
  static const int xyzz = 0xA4;
  static const int xyzw = 0xE4;
  static const int xywx = 0x34;
  static const int xywy = 0x74;
  static const int xywz = 0xB4;
  static const int xyww = 0xF4;
  static const int xzxx = 0x8;
  static const int xzxy = 0x48;
  static const int xzxz = 0x88;
  static const int xzxw = 0xC8;
  static const int xzyx = 0x18;
  static const int xzyy = 0x58;
  static const int xzyz = 0x98;
  static const int xzyw = 0xD8;
  static const int xzzx = 0x28;
  static const int xzzy = 0x68;
  static const int xzzz = 0xA8;
  static const int xzzw = 0xE8;
  static const int xzwx = 0x38;
  static const int xzwy = 0x78;
  static const int xzwz = 0xB8;
  static const int xzww = 0xF8;
  static const int xwxx = 0xC;
  static const int xwxy = 0x4C;
  static const int xwxz = 0x8C;
  static const int xwxw = 0xCC;
  static const int xwyx = 0x1C;
  static const int xwyy = 0x5C;
  static const int xwyz = 0x9C;
  static const int xwyw = 0xDC;
  static const int xwzx = 0x2C;
  static const int xwzy = 0x6C;
  static const int xwzz = 0xAC;
  static const int xwzw = 0xEC;
  static const int xwwx = 0x3C;
  static const int xwwy = 0x7C;
  static const int xwwz = 0xBC;
  static const int xwww = 0xFC;
  static const int yxxx = 0x1;
  static const int yxxy = 0x41;
  static const int yxxz = 0x81;
  static const int yxxw = 0xC1;
  static const int yxyx = 0x11;
  static const int yxyy = 0x51;
  static const int yxyz = 0x91;
  static const int yxyw = 0xD1;
  static const int yxzx = 0x21;
  static const int yxzy = 0x61;
  static const int yxzz = 0xA1;
  static const int yxzw = 0xE1;
  static const int yxwx = 0x31;
  static const int yxwy = 0x71;
  static const int yxwz = 0xB1;
  static const int yxww = 0xF1;
  static const int yyxx = 0x5;
  static const int yyxy = 0x45;
  static const int yyxz = 0x85;
  static const int yyxw = 0xC5;
  static const int yyyx = 0x15;
  static const int yyyy = 0x55;
  static const int yyyz = 0x95;
  static const int yyyw = 0xD5;
  static const int yyzx = 0x25;
  static const int yyzy = 0x65;
  static const int yyzz = 0xA5;
  static const int yyzw = 0xE5;
  static const int yywx = 0x35;
  static const int yywy = 0x75;
  static const int yywz = 0xB5;
  static const int yyww = 0xF5;
  static const int yzxx = 0x9;
  static const int yzxy = 0x49;
  static const int yzxz = 0x89;
  static const int yzxw = 0xC9;
  static const int yzyx = 0x19;
  static const int yzyy = 0x59;
  static const int yzyz = 0x99;
  static const int yzyw = 0xD9;
  static const int yzzx = 0x29;
  static const int yzzy = 0x69;
  static const int yzzz = 0xA9;
  static const int yzzw = 0xE9;
  static const int yzwx = 0x39;
  static const int yzwy = 0x79;
  static const int yzwz = 0xB9;
  static const int yzww = 0xF9;
  static const int ywxx = 0xD;
  static const int ywxy = 0x4D;
  static const int ywxz = 0x8D;
  static const int ywxw = 0xCD;
  static const int ywyx = 0x1D;
  static const int ywyy = 0x5D;
  static const int ywyz = 0x9D;
  static const int ywyw = 0xDD;
  static const int ywzx = 0x2D;
  static const int ywzy = 0x6D;
  static const int ywzz = 0xAD;
  static const int ywzw = 0xED;
  static const int ywwx = 0x3D;
  static const int ywwy = 0x7D;
  static const int ywwz = 0xBD;
  static const int ywww = 0xFD;
  static const int zxxx = 0x2;
  static const int zxxy = 0x42;
  static const int zxxz = 0x82;
  static const int zxxw = 0xC2;
  static const int zxyx = 0x12;
  static const int zxyy = 0x52;
  static const int zxyz = 0x92;
  static const int zxyw = 0xD2;
  static const int zxzx = 0x22;
  static const int zxzy = 0x62;
  static const int zxzz = 0xA2;
  static const int zxzw = 0xE2;
  static const int zxwx = 0x32;
  static const int zxwy = 0x72;
  static const int zxwz = 0xB2;
  static const int zxww = 0xF2;
  static const int zyxx = 0x6;
  static const int zyxy = 0x46;
  static const int zyxz = 0x86;
  static const int zyxw = 0xC6;
  static const int zyyx = 0x16;
  static const int zyyy = 0x56;
  static const int zyyz = 0x96;
  static const int zyyw = 0xD6;
  static const int zyzx = 0x26;
  static const int zyzy = 0x66;
  static const int zyzz = 0xA6;
  static const int zyzw = 0xE6;
  static const int zywx = 0x36;
  static const int zywy = 0x76;
  static const int zywz = 0xB6;
  static const int zyww = 0xF6;
  static const int zzxx = 0xA;
  static const int zzxy = 0x4A;
  static const int zzxz = 0x8A;
  static const int zzxw = 0xCA;
  static const int zzyx = 0x1A;
  static const int zzyy = 0x5A;
  static const int zzyz = 0x9A;
  static const int zzyw = 0xDA;
  static const int zzzx = 0x2A;
  static const int zzzy = 0x6A;
  static const int zzzz = 0xAA;
  static const int zzzw = 0xEA;
  static const int zzwx = 0x3A;
  static const int zzwy = 0x7A;
  static const int zzwz = 0xBA;
  static const int zzww = 0xFA;
  static const int zwxx = 0xE;
  static const int zwxy = 0x4E;
  static const int zwxz = 0x8E;
  static const int zwxw = 0xCE;
  static const int zwyx = 0x1E;
  static const int zwyy = 0x5E;
  static const int zwyz = 0x9E;
  static const int zwyw = 0xDE;
  static const int zwzx = 0x2E;
  static const int zwzy = 0x6E;
  static const int zwzz = 0xAE;
  static const int zwzw = 0xEE;
  static const int zwwx = 0x3E;
  static const int zwwy = 0x7E;
  static const int zwwz = 0xBE;
  static const int zwww = 0xFE;
  static const int wxxx = 0x3;
  static const int wxxy = 0x43;
  static const int wxxz = 0x83;
  static const int wxxw = 0xC3;
  static const int wxyx = 0x13;
  static const int wxyy = 0x53;
  static const int wxyz = 0x93;
  static const int wxyw = 0xD3;
  static const int wxzx = 0x23;
  static const int wxzy = 0x63;
  static const int wxzz = 0xA3;
  static const int wxzw = 0xE3;
  static const int wxwx = 0x33;
  static const int wxwy = 0x73;
  static const int wxwz = 0xB3;
  static const int wxww = 0xF3;
  static const int wyxx = 0x7;
  static const int wyxy = 0x47;
  static const int wyxz = 0x87;
  static const int wyxw = 0xC7;
  static const int wyyx = 0x17;
  static const int wyyy = 0x57;
  static const int wyyz = 0x97;
  static const int wyyw = 0xD7;
  static const int wyzx = 0x27;
  static const int wyzy = 0x67;
  static const int wyzz = 0xA7;
  static const int wyzw = 0xE7;
  static const int wywx = 0x37;
  static const int wywy = 0x77;
  static const int wywz = 0xB7;
  static const int wyww = 0xF7;
  static const int wzxx = 0xB;
  static const int wzxy = 0x4B;
  static const int wzxz = 0x8B;
  static const int wzxw = 0xCB;
  static const int wzyx = 0x1B;
  static const int wzyy = 0x5B;
  static const int wzyz = 0x9B;
  static const int wzyw = 0xDB;
  static const int wzzx = 0x2B;
  static const int wzzy = 0x6B;
  static const int wzzz = 0xAB;
  static const int wzzw = 0xEB;
  static const int wzwx = 0x3B;
  static const int wzwy = 0x7B;
  static const int wzwz = 0xBB;
  static const int wzww = 0xFB;
  static const int wwxx = 0xF;
  static const int wwxy = 0x4F;
  static const int wwxz = 0x8F;
  static const int wwxw = 0xCF;
  static const int wwyx = 0x1F;
  static const int wwyy = 0x5F;
  static const int wwyz = 0x9F;
  static const int wwyw = 0xDF;
  static const int wwzx = 0x2F;
  static const int wwzy = 0x6F;
  static const int wwzz = 0xAF;
  static const int wwzw = 0xEF;
  static const int wwwx = 0x3F;
  static const int wwwy = 0x7F;
  static const int wwwz = 0xBF;
  static const int wwww = 0xFF;

  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
  Float32x4 shuffle(int mask);

  /// Shuffle the lane values in [this] and [other]. The returned
  /// Float32x4 will have XY lanes from [this] and ZW lanes from [other].
  /// Uses the same [mask] as [shuffle].
  Float32x4 shuffleMix(Float32x4 other, int mask);

  /// Returns a new [Float32x4] copied from [this] with a new x value.
  Float32x4 withX(double x);

  /// Returns a new [Float32x4] copied from [this] with a new y value.
  Float32x4 withY(double y);

  /// Returns a new [Float32x4] copied from [this] with a new z value.
  Float32x4 withZ(double z);

  /// Returns a new [Float32x4] copied from [this] with a new w value.
  Float32x4 withW(double w);

  /// Returns the lane-wise minimum value in [this] or [other].
  Float32x4 min(Float32x4 other);

  /// Returns the lane-wise maximum value in [this] or [other].
  Float32x4 max(Float32x4 other);

  /// Returns the square root of [this].
  Float32x4 sqrt();

  /// Returns the reciprocal of [this].
  Float32x4 reciprocal();

  /// Returns the square root of the reciprocal of [this].
  Float32x4 reciprocalSqrt();
}

/**
 * Int32x4 and operations.
 *
 * Int32x4 stores 4 32-bit bit-masks in "lanes".
 * The lanes are "x", "y", "z", and "w" respectively.
 */
abstract class Int32x4 {
  external factory Int32x4(int x, int y, int z, int w);
  external factory Int32x4.bool(bool x, bool y, bool z, bool w);
  external factory Int32x4.fromFloat32x4Bits(Float32x4 x);

  /// The bit-wise or operator.
  Int32x4 operator |(Int32x4 other);

  /// The bit-wise and operator.
  Int32x4 operator &(Int32x4 other);

  /// The bit-wise xor operator.
  Int32x4 operator ^(Int32x4 other);

  /// Addition operator.
  Int32x4 operator +(Int32x4 other);

  /// Subtraction operator.
  Int32x4 operator -(Int32x4 other);

  /// Extract 32-bit mask from x lane.
  int get x;

  /// Extract 32-bit mask from y lane.
  int get y;

  /// Extract 32-bit mask from z lane.
  int get z;

  /// Extract 32-bit mask from w lane.
  int get w;

  /// Extract the top bit from each lane return them in the first 4 bits.
  /// "x" lane is bit 0.
  /// "y" lane is bit 1.
  /// "z" lane is bit 2.
  /// "w" lane is bit 3.
  int get signMask;

  /// Mask passed to [shuffle] or [shuffleMix].
  static const int xxxx = 0x0;
  static const int xxxy = 0x40;
  static const int xxxz = 0x80;
  static const int xxxw = 0xC0;
  static const int xxyx = 0x10;
  static const int xxyy = 0x50;
  static const int xxyz = 0x90;
  static const int xxyw = 0xD0;
  static const int xxzx = 0x20;
  static const int xxzy = 0x60;
  static const int xxzz = 0xA0;
  static const int xxzw = 0xE0;
  static const int xxwx = 0x30;
  static const int xxwy = 0x70;
  static const int xxwz = 0xB0;
  static const int xxww = 0xF0;
  static const int xyxx = 0x4;
  static const int xyxy = 0x44;
  static const int xyxz = 0x84;
  static const int xyxw = 0xC4;
  static const int xyyx = 0x14;
  static const int xyyy = 0x54;
  static const int xyyz = 0x94;
  static const int xyyw = 0xD4;
  static const int xyzx = 0x24;
  static const int xyzy = 0x64;
  static const int xyzz = 0xA4;
  static const int xyzw = 0xE4;
  static const int xywx = 0x34;
  static const int xywy = 0x74;
  static const int xywz = 0xB4;
  static const int xyww = 0xF4;
  static const int xzxx = 0x8;
  static const int xzxy = 0x48;
  static const int xzxz = 0x88;
  static const int xzxw = 0xC8;
  static const int xzyx = 0x18;
  static const int xzyy = 0x58;
  static const int xzyz = 0x98;
  static const int xzyw = 0xD8;
  static const int xzzx = 0x28;
  static const int xzzy = 0x68;
  static const int xzzz = 0xA8;
  static const int xzzw = 0xE8;
  static const int xzwx = 0x38;
  static const int xzwy = 0x78;
  static const int xzwz = 0xB8;
  static const int xzww = 0xF8;
  static const int xwxx = 0xC;
  static const int xwxy = 0x4C;
  static const int xwxz = 0x8C;
  static const int xwxw = 0xCC;
  static const int xwyx = 0x1C;
  static const int xwyy = 0x5C;
  static const int xwyz = 0x9C;
  static const int xwyw = 0xDC;
  static const int xwzx = 0x2C;
  static const int xwzy = 0x6C;
  static const int xwzz = 0xAC;
  static const int xwzw = 0xEC;
  static const int xwwx = 0x3C;
  static const int xwwy = 0x7C;
  static const int xwwz = 0xBC;
  static const int xwww = 0xFC;
  static const int yxxx = 0x1;
  static const int yxxy = 0x41;
  static const int yxxz = 0x81;
  static const int yxxw = 0xC1;
  static const int yxyx = 0x11;
  static const int yxyy = 0x51;
  static const int yxyz = 0x91;
  static const int yxyw = 0xD1;
  static const int yxzx = 0x21;
  static const int yxzy = 0x61;
  static const int yxzz = 0xA1;
  static const int yxzw = 0xE1;
  static const int yxwx = 0x31;
  static const int yxwy = 0x71;
  static const int yxwz = 0xB1;
  static const int yxww = 0xF1;
  static const int yyxx = 0x5;
  static const int yyxy = 0x45;
  static const int yyxz = 0x85;
  static const int yyxw = 0xC5;
  static const int yyyx = 0x15;
  static const int yyyy = 0x55;
  static const int yyyz = 0x95;
  static const int yyyw = 0xD5;
  static const int yyzx = 0x25;
  static const int yyzy = 0x65;
  static const int yyzz = 0xA5;
  static const int yyzw = 0xE5;
  static const int yywx = 0x35;
  static const int yywy = 0x75;
  static const int yywz = 0xB5;
  static const int yyww = 0xF5;
  static const int yzxx = 0x9;
  static const int yzxy = 0x49;
  static const int yzxz = 0x89;
  static const int yzxw = 0xC9;
  static const int yzyx = 0x19;
  static const int yzyy = 0x59;
  static const int yzyz = 0x99;
  static const int yzyw = 0xD9;
  static const int yzzx = 0x29;
  static const int yzzy = 0x69;
  static const int yzzz = 0xA9;
  static const int yzzw = 0xE9;
  static const int yzwx = 0x39;
  static const int yzwy = 0x79;
  static const int yzwz = 0xB9;
  static const int yzww = 0xF9;
  static const int ywxx = 0xD;
  static const int ywxy = 0x4D;
  static const int ywxz = 0x8D;
  static const int ywxw = 0xCD;
  static const int ywyx = 0x1D;
  static const int ywyy = 0x5D;
  static const int ywyz = 0x9D;
  static const int ywyw = 0xDD;
  static const int ywzx = 0x2D;
  static const int ywzy = 0x6D;
  static const int ywzz = 0xAD;
  static const int ywzw = 0xED;
  static const int ywwx = 0x3D;
  static const int ywwy = 0x7D;
  static const int ywwz = 0xBD;
  static const int ywww = 0xFD;
  static const int zxxx = 0x2;
  static const int zxxy = 0x42;
  static const int zxxz = 0x82;
  static const int zxxw = 0xC2;
  static const int zxyx = 0x12;
  static const int zxyy = 0x52;
  static const int zxyz = 0x92;
  static const int zxyw = 0xD2;
  static const int zxzx = 0x22;
  static const int zxzy = 0x62;
  static const int zxzz = 0xA2;
  static const int zxzw = 0xE2;
  static const int zxwx = 0x32;
  static const int zxwy = 0x72;
  static const int zxwz = 0xB2;
  static const int zxww = 0xF2;
  static const int zyxx = 0x6;
  static const int zyxy = 0x46;
  static const int zyxz = 0x86;
  static const int zyxw = 0xC6;
  static const int zyyx = 0x16;
  static const int zyyy = 0x56;
  static const int zyyz = 0x96;
  static const int zyyw = 0xD6;
  static const int zyzx = 0x26;
  static const int zyzy = 0x66;
  static const int zyzz = 0xA6;
  static const int zyzw = 0xE6;
  static const int zywx = 0x36;
  static const int zywy = 0x76;
  static const int zywz = 0xB6;
  static const int zyww = 0xF6;
  static const int zzxx = 0xA;
  static const int zzxy = 0x4A;
  static const int zzxz = 0x8A;
  static const int zzxw = 0xCA;
  static const int zzyx = 0x1A;
  static const int zzyy = 0x5A;
  static const int zzyz = 0x9A;
  static const int zzyw = 0xDA;
  static const int zzzx = 0x2A;
  static const int zzzy = 0x6A;
  static const int zzzz = 0xAA;
  static const int zzzw = 0xEA;
  static const int zzwx = 0x3A;
  static const int zzwy = 0x7A;
  static const int zzwz = 0xBA;
  static const int zzww = 0xFA;
  static const int zwxx = 0xE;
  static const int zwxy = 0x4E;
  static const int zwxz = 0x8E;
  static const int zwxw = 0xCE;
  static const int zwyx = 0x1E;
  static const int zwyy = 0x5E;
  static const int zwyz = 0x9E;
  static const int zwyw = 0xDE;
  static const int zwzx = 0x2E;
  static const int zwzy = 0x6E;
  static const int zwzz = 0xAE;
  static const int zwzw = 0xEE;
  static const int zwwx = 0x3E;
  static const int zwwy = 0x7E;
  static const int zwwz = 0xBE;
  static const int zwww = 0xFE;
  static const int wxxx = 0x3;
  static const int wxxy = 0x43;
  static const int wxxz = 0x83;
  static const int wxxw = 0xC3;
  static const int wxyx = 0x13;
  static const int wxyy = 0x53;
  static const int wxyz = 0x93;
  static const int wxyw = 0xD3;
  static const int wxzx = 0x23;
  static const int wxzy = 0x63;
  static const int wxzz = 0xA3;
  static const int wxzw = 0xE3;
  static const int wxwx = 0x33;
  static const int wxwy = 0x73;
  static const int wxwz = 0xB3;
  static const int wxww = 0xF3;
  static const int wyxx = 0x7;
  static const int wyxy = 0x47;
  static const int wyxz = 0x87;
  static const int wyxw = 0xC7;
  static const int wyyx = 0x17;
  static const int wyyy = 0x57;
  static const int wyyz = 0x97;
  static const int wyyw = 0xD7;
  static const int wyzx = 0x27;
  static const int wyzy = 0x67;
  static const int wyzz = 0xA7;
  static const int wyzw = 0xE7;
  static const int wywx = 0x37;
  static const int wywy = 0x77;
  static const int wywz = 0xB7;
  static const int wyww = 0xF7;
  static const int wzxx = 0xB;
  static const int wzxy = 0x4B;
  static const int wzxz = 0x8B;
  static const int wzxw = 0xCB;
  static const int wzyx = 0x1B;
  static const int wzyy = 0x5B;
  static const int wzyz = 0x9B;
  static const int wzyw = 0xDB;
  static const int wzzx = 0x2B;
  static const int wzzy = 0x6B;
  static const int wzzz = 0xAB;
  static const int wzzw = 0xEB;
  static const int wzwx = 0x3B;
  static const int wzwy = 0x7B;
  static const int wzwz = 0xBB;
  static const int wzww = 0xFB;
  static const int wwxx = 0xF;
  static const int wwxy = 0x4F;
  static const int wwxz = 0x8F;
  static const int wwxw = 0xCF;
  static const int wwyx = 0x1F;
  static const int wwyy = 0x5F;
  static const int wwyz = 0x9F;
  static const int wwyw = 0xDF;
  static const int wwzx = 0x2F;
  static const int wwzy = 0x6F;
  static const int wwzz = 0xAF;
  static const int wwzw = 0xEF;
  static const int wwwx = 0x3F;
  static const int wwwy = 0x7F;
  static const int wwwz = 0xBF;
  static const int wwww = 0xFF;

  /// Shuffle the lane values. [mask] must be one of the 256 shuffle constants.
  Int32x4 shuffle(int mask);

  /// Shuffle the lane values in [this] and [other]. The returned
  /// Int32x4 will have XY lanes from [this] and ZW lanes from [other].
  /// Uses the same [mask] as [shuffle].
  Int32x4 shuffleMix(Int32x4 other, int mask);

  /// Returns a new [Int32x4] copied from [this] with a new x value.
  Int32x4 withX(int x);

  /// Returns a new [Int32x4] copied from [this] with a new y value.
  Int32x4 withY(int y);

  /// Returns a new [Int32x4] copied from [this] with a new z value.
  Int32x4 withZ(int z);

  /// Returns a new [Int32x4] copied from [this] with a new w value.
  Int32x4 withW(int w);

  /// Extracted x value. Returns false for 0, true for any other value.
  bool get flagX;

  /// Extracted y value. Returns false for 0, true for any other value.
  bool get flagY;

  /// Extracted z value. Returns false for 0, true for any other value.
  bool get flagZ;

  /// Extracted w value. Returns false for 0, true for any other value.
  bool get flagW;

  /// Returns a new [Int32x4] copied from [this] with a new x value.
  Int32x4 withFlagX(bool x);

  /// Returns a new [Int32x4] copied from [this] with a new y value.
  Int32x4 withFlagY(bool y);

  /// Returns a new [Int32x4] copied from [this] with a new z value.
  Int32x4 withFlagZ(bool z);

  /// Returns a new [Int32x4] copied from [this] with a new w value.
  Int32x4 withFlagW(bool w);

  /// Merge [trueValue] and [falseValue] based on [this]' bit mask:
  /// Select bit from [trueValue] when bit in [this] is on.
  /// Select bit from [falseValue] when bit in [this] is off.
  Float32x4 select(Float32x4 trueValue, Float32x4 falseValue);
}

/**
 * Float64x2 immutable value type and operations.
 *
 * Float64x2 stores 2 64-bit floating point values in "lanes".
 * The lanes are "x" and "y" respectively.
 */
abstract class Float64x2 {
  external factory Float64x2(double x, double y);
  external factory Float64x2.splat(double v);
  external factory Float64x2.zero();

  /// Uses the "x" and "y" lanes from [v].
  external factory Float64x2.fromFloat32x4(Float32x4 v);

  /// Addition operator.
  Float64x2 operator +(Float64x2 other);

  /// Negate operator.
  Float64x2 operator -();

  /// Subtraction operator.
  Float64x2 operator -(Float64x2 other);

  /// Multiplication operator.
  Float64x2 operator *(Float64x2 other);

  /// Division operator.
  Float64x2 operator /(Float64x2 other);

  /// Returns a copy of [this] each lane being scaled by [s].
  /// Equivalent to this * new Float64x2.splat(s)
  Float64x2 scale(double s);

  /// Returns the lane-wise absolute value of this [Float64x2].
  Float64x2 abs();

  /// Lane-wise clamp [this] to be in the range [lowerLimit]-[upperLimit].
  Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit);

  /// Extracted x value.
  double get x;

  /// Extracted y value.
  double get y;

  /// Extract the sign bits from each lane return them in the first 2 bits.
  /// "x" lane is bit 0.
  /// "y" lane is bit 1.
  int get signMask;

  /// Returns a new [Float64x2] copied from [this] with a new x value.
  Float64x2 withX(double x);

  /// Returns a new [Float64x2] copied from [this] with a new y value.
  Float64x2 withY(double y);

  /// Returns the lane-wise minimum value in [this] or [other].
  Float64x2 min(Float64x2 other);

  /// Returns the lane-wise maximum value in [this] or [other].
  Float64x2 max(Float64x2 other);

  /// Returns the lane-wise square root of [this].
  Float64x2 sqrt();
}
