// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

/// Native tests.
class NativeLibrary {
  /// Holds the symbol lookup function.
  final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
      _lookup;

  /// The symbols are looked up in [dynamicLibrary].
  NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
      : _lookup = dynamicLibrary.lookup;

  /// The symbols are looked up with [lookup].
  NativeLibrary.fromLookup(
      ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
          lookup)
      : _lookup = lookup;

  bool Function1Bool(
    bool x,
  ) {
    return _Function1Bool(
          x ? 1 : 0,
        ) !=
        0;
  }

  late final _Function1Bool_ptr =
      _lookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Uint8)>>(
          'Function1Bool');
  late final _Function1Bool =
      _Function1Bool_ptr.asFunction<int Function(int)>();

  int Function1Uint8(
    int x,
  ) {
    return _Function1Uint8(
      x,
    );
  }

  late final _Function1Uint8_ptr =
      _lookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Uint8)>>(
          'Function1Uint8');
  late final _Function1Uint8 =
      _Function1Uint8_ptr.asFunction<int Function(int)>();

  int Function1Uint16(
    int x,
  ) {
    return _Function1Uint16(
      x,
    );
  }

  late final _Function1Uint16_ptr =
      _lookup<ffi.NativeFunction<ffi.Uint16 Function(ffi.Uint16)>>(
          'Function1Uint16');
  late final _Function1Uint16 =
      _Function1Uint16_ptr.asFunction<int Function(int)>();

  int Function1Uint32(
    int x,
  ) {
    return _Function1Uint32(
      x,
    );
  }

  late final _Function1Uint32_ptr =
      _lookup<ffi.NativeFunction<ffi.Uint32 Function(ffi.Uint32)>>(
          'Function1Uint32');
  late final _Function1Uint32 =
      _Function1Uint32_ptr.asFunction<int Function(int)>();

  int Function1Uint64(
    int x,
  ) {
    return _Function1Uint64(
      x,
    );
  }

  late final _Function1Uint64_ptr =
      _lookup<ffi.NativeFunction<ffi.Uint64 Function(ffi.Uint64)>>(
          'Function1Uint64');
  late final _Function1Uint64 =
      _Function1Uint64_ptr.asFunction<int Function(int)>();

  int Function1Int8(
    int x,
  ) {
    return _Function1Int8(
      x,
    );
  }

  late final _Function1Int8_ptr =
      _lookup<ffi.NativeFunction<ffi.Int8 Function(ffi.Int8)>>('Function1Int8');
  late final _Function1Int8 =
      _Function1Int8_ptr.asFunction<int Function(int)>();

  int Function1Int16(
    int x,
  ) {
    return _Function1Int16(
      x,
    );
  }

  late final _Function1Int16_ptr =
      _lookup<ffi.NativeFunction<ffi.Int16 Function(ffi.Int16)>>(
          'Function1Int16');
  late final _Function1Int16 =
      _Function1Int16_ptr.asFunction<int Function(int)>();

  int Function1Int32(
    int x,
  ) {
    return _Function1Int32(
      x,
    );
  }

  late final _Function1Int32_ptr =
      _lookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32)>>(
          'Function1Int32');
  late final _Function1Int32 =
      _Function1Int32_ptr.asFunction<int Function(int)>();

  int Function1Int64(
    int x,
  ) {
    return _Function1Int64(
      x,
    );
  }

  late final _Function1Int64_ptr =
      _lookup<ffi.NativeFunction<ffi.Int64 Function(ffi.Int64)>>(
          'Function1Int64');
  late final _Function1Int64 =
      _Function1Int64_ptr.asFunction<int Function(int)>();

  int Function1IntPtr(
    int x,
  ) {
    return _Function1IntPtr(
      x,
    );
  }

  late final _Function1IntPtr_ptr =
      _lookup<ffi.NativeFunction<ffi.IntPtr Function(ffi.IntPtr)>>(
          'Function1IntPtr');
  late final _Function1IntPtr =
      _Function1IntPtr_ptr.asFunction<int Function(int)>();

  double Function1Float(
    double x,
  ) {
    return _Function1Float(
      x,
    );
  }

  late final _Function1Float_ptr =
      _lookup<ffi.NativeFunction<ffi.Float Function(ffi.Float)>>(
          'Function1Float');
  late final _Function1Float =
      _Function1Float_ptr.asFunction<double Function(double)>();

  double Function1Double(
    double x,
  ) {
    return _Function1Double(
      x,
    );
  }

  late final _Function1Double_ptr =
      _lookup<ffi.NativeFunction<ffi.Double Function(ffi.Double)>>(
          'Function1Double');
  late final _Function1Double =
      _Function1Double_ptr.asFunction<double Function(double)>();

  ffi.Pointer<Struct1> getStruct1() {
    return _getStruct1();
  }

  late final _getStruct1_ptr =
      _lookup<ffi.NativeFunction<ffi.Pointer<Struct1> Function()>>(
          'getStruct1');
  late final _getStruct1 =
      _getStruct1_ptr.asFunction<ffi.Pointer<Struct1> Function()>();

  Struct3 Function1StructReturnByValue(
    int a,
    int b,
    int c,
  ) {
    return _Function1StructReturnByValue(
      a,
      b,
      c,
    );
  }

  late final _Function1StructReturnByValue_ptr = _lookup<
      ffi.NativeFunction<
          Struct3 Function(ffi.Int32, ffi.Int32,
              ffi.Int32)>>('Function1StructReturnByValue');
  late final _Function1StructReturnByValue = _Function1StructReturnByValue_ptr
      .asFunction<Struct3 Function(int, int, int)>();

  int Function1StructPassByValue(
    Struct3 sum_a_b_c,
  ) {
    return _Function1StructPassByValue(
      sum_a_b_c,
    );
  }

  late final _Function1StructPassByValue_ptr =
      _lookup<ffi.NativeFunction<ffi.Int32 Function(Struct3)>>(
          'Function1StructPassByValue');
  late final _Function1StructPassByValue =
      _Function1StructPassByValue_ptr.asFunction<int Function(Struct3)>();
}

class Struct1 extends ffi.Struct {
  @ffi.Int8()
  external int a;

  @ffi.Array.multi([3, 1, 2])
  external ffi.Array<ffi.Array<ffi.Array<ffi.Int32>>> data;
}

class Struct3 extends ffi.Struct {
  @ffi.Int32()
  external int a;

  @ffi.Int32()
  external int b;

  @ffi.Int32()
  external int c;
}
