// WARNING: This file is machine generated by fidlgen.

#pragma once

#include <fidl/test/nullable/cpp/fidl.h>
#include <zx/cpp/libfuzzer.h>

#include "lib/fidl/cpp/fuzzing/traits.h"
#include "lib/fidl/cpp/internal/header.h"
// For ::std::max_element().
#include <algorithm>
// For uint64_t.
#include <stdint.h>

namespace fuzzing {

using StructWithNullableVector =
    ::fidl::test::nullable::StructWithNullableVector;
using StructWithNullableUnion = ::fidl::test::nullable::StructWithNullableUnion;
using StructWithNullableStruct =
    ::fidl::test::nullable::StructWithNullableStruct;
using StructWithNullableString =
    ::fidl::test::nullable::StructWithNullableString;
using StructWithNullableRequest =
    ::fidl::test::nullable::StructWithNullableRequest;
using StructWithNullableProtocol =
    ::fidl::test::nullable::StructWithNullableProtocol;
using StructWithNullableHandle =
    ::fidl::test::nullable::StructWithNullableHandle;
using SimpleUnion = ::fidl::test::nullable::SimpleUnion;
using Int32Wrapper = ::fidl::test::nullable::Int32Wrapper;

template <>
struct MinSize<StructWithNullableVector> {
  operator size_t() { return MinSize<::fidl::VectorPtr<int32_t>>(); }
};
template <>
struct Allocate<StructWithNullableVector> {
  StructWithNullableVector operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableVector>());
    StructWithNullableVector out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableVector>()) / 1;
    size_t out_size;
    out_size = MinSize<::fidl::VectorPtr<int32_t>>() + slack_per_member;
    out.val = Allocate<::fidl::VectorPtr<int32_t>>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StructWithNullableUnion> {
  operator size_t() {
    return MinSize<::std::unique_ptr<::fidl::test::nullable::SimpleUnion>>();
  }
};
template <>
struct Allocate<StructWithNullableUnion> {
  StructWithNullableUnion operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableUnion>());
    StructWithNullableUnion out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableUnion>()) / 1;
    size_t out_size;
    out_size =
        MinSize<::std::unique_ptr<::fidl::test::nullable::SimpleUnion>>() +
        slack_per_member;
    out.val =
        Allocate<::std::unique_ptr<::fidl::test::nullable::SimpleUnion>>{}(
            src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StructWithNullableStruct> {
  operator size_t() {
    return MinSize<::std::unique_ptr<::fidl::test::nullable::Int32Wrapper>>();
  }
};
template <>
struct Allocate<StructWithNullableStruct> {
  StructWithNullableStruct operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableStruct>());
    StructWithNullableStruct out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableStruct>()) / 1;
    size_t out_size;
    out_size =
        MinSize<::std::unique_ptr<::fidl::test::nullable::Int32Wrapper>>() +
        slack_per_member;
    out.val =
        Allocate<::std::unique_ptr<::fidl::test::nullable::Int32Wrapper>>{}(
            src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StructWithNullableString> {
  operator size_t() { return MinSize<::fidl::StringPtr>(); }
};
template <>
struct Allocate<StructWithNullableString> {
  StructWithNullableString operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableString>());
    StructWithNullableString out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableString>()) / 1;
    size_t out_size;
    out_size = MinSize<::fidl::StringPtr>() + slack_per_member;
    out.val = Allocate<::fidl::StringPtr>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StructWithNullableRequest> {
  operator size_t() {
    return MinSize<
        ::fidl::InterfaceRequest<::fidl::test::nullable::SimpleProtocol>>();
  }
};
template <>
struct Allocate<StructWithNullableRequest> {
  StructWithNullableRequest operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableRequest>());
    StructWithNullableRequest out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableRequest>()) / 1;
    size_t out_size;
    out_size = MinSize<::fidl::InterfaceRequest<
                   ::fidl::test::nullable::SimpleProtocol>>() +
               slack_per_member;
    out.val = Allocate<
        ::fidl::InterfaceRequest<::fidl::test::nullable::SimpleProtocol>>{}(
        src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StructWithNullableProtocol> {
  operator size_t() {
    return MinSize<
        ::fidl::InterfaceHandle<::fidl::test::nullable::SimpleProtocol>>();
  }
};
template <>
struct Allocate<StructWithNullableProtocol> {
  StructWithNullableProtocol operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableProtocol>());
    StructWithNullableProtocol out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableProtocol>()) / 1;
    size_t out_size;
    out_size =
        MinSize<
            ::fidl::InterfaceHandle<::fidl::test::nullable::SimpleProtocol>>() +
        slack_per_member;
    out.val = Allocate<
        ::fidl::InterfaceHandle<::fidl::test::nullable::SimpleProtocol>>{}(
        src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StructWithNullableHandle> {
  operator size_t() { return MinSize<::zx::vmo>(); }
};
template <>
struct Allocate<StructWithNullableHandle> {
  StructWithNullableHandle operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<StructWithNullableHandle>());
    StructWithNullableHandle out;
    const size_t slack_per_member =
        (*size - MinSize<StructWithNullableHandle>()) / 1;
    size_t out_size;
    out_size = MinSize<::zx::vmo>() + slack_per_member;
    out.val = Allocate<::zx::vmo>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<SimpleUnion> {
  operator size_t() {
    size_t sizes[] = {0, MinSize<int32_t>(), MinSize<float>()};
    return 1 + *std::max_element(sizes, sizes + 2 + 1);
  }
};
template <>
struct Allocate<SimpleUnion> {
  static_assert(2 > 0, "xunion must have at least one member");

  SimpleUnion operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<SimpleUnion>());

    uint8_t selector;
    ZX_ASSERT(src->CopyBytes(&selector, 1));
    (*size)++;

    SimpleUnion out;
    switch (selector % 2) {
      case 0: {
        out.set_a(Allocate<int32_t>{}(src, size));
        break;
      }
      case 1: {
        out.set_b(Allocate<float>{}(src, size));
        break;
      }
    }

    return out;
  }
};
template <>
struct MinSize<Int32Wrapper> {
  operator size_t() { return MinSize<int32_t>(); }
};
template <>
struct Allocate<Int32Wrapper> {
  Int32Wrapper operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<Int32Wrapper>());
    Int32Wrapper out;
    const size_t slack_per_member = (*size - MinSize<Int32Wrapper>()) / 1;
    size_t out_size;
    out_size = MinSize<int32_t>() + slack_per_member;
    out.val = Allocate<int32_t>{}(src, &out_size);
    return out;
  }
};

}  // namespace fuzzing
