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

#pragma once

#include <fidl/test/doccomments/cpp/fidl.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 Table = ::fidl::test::doccomments::Table;
using Struct = ::fidl::test::doccomments::Struct;
using StrictUnion = ::fidl::test::doccomments::StrictUnion;
using Service = ::fidl::test::doccomments::Service;
using MyStrictEnum = ::fidl::test::doccomments::MyStrictEnum;
using MyStrictBits = ::fidl::test::doccomments::MyStrictBits;
using MyFlexibleEnum = ::fidl::test::doccomments::MyFlexibleEnum;
using MyFlexibleBits = ::fidl::test::doccomments::MyFlexibleBits;
using FlexibleUnion = ::fidl::test::doccomments::FlexibleUnion;

template <>
struct MinSize<Table> {
  operator size_t() { return MinSize<int32_t>(); }
};
template <>
struct Allocate<Table> {
  Table operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<Table>());
    Table out;
    const size_t slack_per_member = (*size - MinSize<Table>()) / 1;
    size_t out_size;
    out_size = MinSize<int32_t>() + slack_per_member;
    out.set_Field(Allocate<int32_t>{}(src, &out_size));
    return out;
  }
};
template <>
struct MinSize<Struct> {
  operator size_t() { return MinSize<int32_t>(); }
};
template <>
struct Allocate<Struct> {
  Struct operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<Struct>());
    Struct out;
    const size_t slack_per_member = (*size - MinSize<Struct>()) / 1;
    size_t out_size;
    out_size = MinSize<int32_t>() + slack_per_member;
    out.Field = Allocate<int32_t>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<StrictUnion> {
  operator size_t() {
    size_t sizes[] = {0, MinSize<int32_t>()};
    return 1 + *std::max_element(sizes, sizes + 1 + 1);
  }
};
template <>
struct Allocate<StrictUnion> {
  static_assert(1 > 0, "xunion must have at least one member");

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

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

    StrictUnion out;
    switch (selector % 1) {
      case 0: {
        out.set_Field(Allocate<int32_t>{}(src, size));
        break;
      }
    }

    return out;
  }
};
template <>
struct MinSize<MyStrictEnum> {
  operator size_t() { return sizeof(uint64_t); }
};
template <>
struct Allocate<MyStrictEnum> {
  MyStrictEnum operator()(FuzzInput* src, size_t* size) {
    MyStrictEnum out;
    uint64_t selector;
    ZX_ASSERT(*size >= sizeof(uint64_t));
    ZX_ASSERT(src->CopyObject(&selector));
    *size = sizeof(uint64_t);

    switch (selector % 2) {
      case 0:
        out = MyStrictEnum::FOO;
        break;
      case 1:
        out = MyStrictEnum::BAR;
        break;
    }

    return out;
  }
};
template <>
struct MinSize<MyStrictBits> {
  operator size_t() { return sizeof(MyStrictBits); }
};
template <>
struct Allocate<MyStrictBits> {
  MyStrictBits operator()(FuzzInput* src, size_t* size) {
    MyStrictBits out;
    ZX_ASSERT(*size >= sizeof(MyStrictBits));
    ZX_ASSERT(src->CopyObject(&out));
    *size = sizeof(MyStrictBits);
    return out;
  }
};
template <>
struct MinSize<MyFlexibleEnum> {
  operator size_t() { return sizeof(uint64_t); }
};
template <>
struct Allocate<MyFlexibleEnum> {
  MyFlexibleEnum operator()(FuzzInput* src, size_t* size) {
    MyFlexibleEnum out;
    uint64_t selector;
    ZX_ASSERT(*size >= sizeof(uint64_t));
    ZX_ASSERT(src->CopyObject(&selector));
    *size = sizeof(uint64_t);

    switch (selector % 2) {
      case 0:
        out = MyFlexibleEnum::FOO;
        break;
      case 1:
        out = MyFlexibleEnum::BAR;
        break;
    }

    return out;
  }
};
template <>
struct MinSize<MyFlexibleBits> {
  operator size_t() { return sizeof(MyFlexibleBits); }
};
template <>
struct Allocate<MyFlexibleBits> {
  MyFlexibleBits operator()(FuzzInput* src, size_t* size) {
    MyFlexibleBits out;
    ZX_ASSERT(*size >= sizeof(MyFlexibleBits));
    ZX_ASSERT(src->CopyObject(&out));
    *size = sizeof(MyFlexibleBits);
    return out;
  }
};
template <>
struct MinSize<FlexibleUnion> {
  operator size_t() {
    size_t sizes[] = {0, MinSize<int32_t>()};
    return 1 + *std::max_element(sizes, sizes + 1 + 1);
  }
};
template <>
struct Allocate<FlexibleUnion> {
  static_assert(1 > 0, "xunion must have at least one member");

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

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

    FlexibleUnion out;
    switch (selector % 1) {
      case 0: {
        out.set_Field(Allocate<int32_t>{}(src, size));
        break;
      }
    }

    return out;
  }
};

}  // namespace fuzzing
