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

// fidl_experiment = output_index_json

#include <fidl/test.handlesintypes/cpp/type_conversions.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace fidl {
namespace internal {

#ifdef __Fuchsia__

::test_handlesintypes::HandlesInTypes WireNaturalConversionTraits<::test_handlesintypes::wire::HandlesInTypes, ::test_handlesintypes::HandlesInTypes>::ToNatural(::test_handlesintypes::wire::HandlesInTypes src) {
  return ::test_handlesintypes::HandlesInTypes{{
      .normal_handle = WireNaturalConversionTraits<::zx::vmo, ::zx::vmo>::ToNatural(std::move(src.normal_handle)),
      .handle_in_vec = WireNaturalConversionTraits<::fidl::VectorView<::zx::vmo>, ::std::vector<::zx::vmo>>::ToNatural(std::move(src.handle_in_vec)),
      .handle_in_array = WireNaturalConversionTraits<::fidl::Array<::zx::vmo, 5>, ::std::array<::zx::vmo, 5>>::ToNatural(std::move(src.handle_in_array)),
      .handle_in_mixed_vec_array = WireNaturalConversionTraits<::fidl::VectorView<::fidl::Array<::zx::vmo, 5>>, ::std::vector<::std::array<::zx::vmo, 5>>>::ToNatural(std::move(src.handle_in_mixed_vec_array)),
      .table_with_handle = WireNaturalConversionTraits<::test_handlesintypes::wire::TableWithHandle, ::test_handlesintypes::TableWithHandle>::ToNatural(std::move(src.table_with_handle)),
      .union_with_handle = WireNaturalConversionTraits<::test_handlesintypes::wire::UnionWithHandle, ::test_handlesintypes::UnionWithHandle>::ToNatural(std::move(src.union_with_handle)),
  }};
}
::test_handlesintypes::wire::HandlesInTypes WireNaturalConversionTraits<::test_handlesintypes::wire::HandlesInTypes, ::test_handlesintypes::HandlesInTypes>::ToWire(fidl::AnyArena& arena, ::test_handlesintypes::HandlesInTypes src) {
  return ::test_handlesintypes::wire::HandlesInTypes{
      .normal_handle = WireNaturalConversionTraits<::zx::vmo, ::zx::vmo>::ToWire(arena, std::move(src.normal_handle())),
      .handle_in_vec = WireNaturalConversionTraits<::fidl::VectorView<::zx::vmo>, ::std::vector<::zx::vmo>>::ToWire(arena, std::move(src.handle_in_vec())),
      .handle_in_array = WireNaturalConversionTraits<::fidl::Array<::zx::vmo, 5>, ::std::array<::zx::vmo, 5>>::ToWire(arena, std::move(src.handle_in_array())),
      .handle_in_mixed_vec_array = WireNaturalConversionTraits<::fidl::VectorView<::fidl::Array<::zx::vmo, 5>>, ::std::vector<::std::array<::zx::vmo, 5>>>::ToWire(arena, std::move(src.handle_in_mixed_vec_array())),
      .table_with_handle = WireNaturalConversionTraits<::test_handlesintypes::wire::TableWithHandle, ::test_handlesintypes::TableWithHandle>::ToWire(arena, std::move(src.table_with_handle())),
      .union_with_handle = WireNaturalConversionTraits<::test_handlesintypes::wire::UnionWithHandle, ::test_handlesintypes::UnionWithHandle>::ToWire(arena, std::move(src.union_with_handle())),
  };
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_handlesintypes::EmptyResourceStruct WireNaturalConversionTraits<::test_handlesintypes::wire::EmptyResourceStruct, ::test_handlesintypes::EmptyResourceStruct>::ToNatural(::test_handlesintypes::wire::EmptyResourceStruct src) {
  return ::test_handlesintypes::EmptyResourceStruct(WireNaturalConversionTraits<uint8_t, uint8_t>::ToNatural(std::move(src.__reserved)));
}
::test_handlesintypes::wire::EmptyResourceStruct WireNaturalConversionTraits<::test_handlesintypes::wire::EmptyResourceStruct, ::test_handlesintypes::EmptyResourceStruct>::ToWire(fidl::AnyArena& arena, ::test_handlesintypes::EmptyResourceStruct src) {
  return ::test_handlesintypes::wire::EmptyResourceStruct{
      .__reserved = WireNaturalConversionTraits<uint8_t, uint8_t>::ToWire(arena, std::move(src.__reserved())),
  };
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_handlesintypes::TableWithHandle WireNaturalConversionTraits<::test_handlesintypes::wire::TableWithHandle, ::test_handlesintypes::TableWithHandle>::ToNatural(::test_handlesintypes::wire::TableWithHandle src) {
  ::test_handlesintypes::TableWithHandle dst;
  if (src.has_h()) {
    dst.h() =
        WireNaturalConversionTraits<::zx::vmo, ::zx::vmo>::ToNatural(std::move(src.h()));
  }

  return dst;
}
::test_handlesintypes::wire::TableWithHandle WireNaturalConversionTraits<::test_handlesintypes::wire::TableWithHandle, ::test_handlesintypes::TableWithHandle>::ToWire(fidl::AnyArena& arena, ::test_handlesintypes::TableWithHandle src) {
  auto builder = ::test_handlesintypes::wire::TableWithHandle::Builder(arena);
  if (src.h().has_value()) {
    builder.h(
        WireNaturalConversionTraits<::zx::vmo, ::zx::vmo>::ToWire(arena, std::move(src.h().value())));
  }
  return builder.Build();
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_handlesintypes::EmptyResourceTable WireNaturalConversionTraits<::test_handlesintypes::wire::EmptyResourceTable, ::test_handlesintypes::EmptyResourceTable>::ToNatural(::test_handlesintypes::wire::EmptyResourceTable src) {
  ::test_handlesintypes::EmptyResourceTable dst;

  return dst;
}
::test_handlesintypes::wire::EmptyResourceTable WireNaturalConversionTraits<::test_handlesintypes::wire::EmptyResourceTable, ::test_handlesintypes::EmptyResourceTable>::ToWire(fidl::AnyArena& arena, ::test_handlesintypes::EmptyResourceTable src) {
  auto builder = ::test_handlesintypes::wire::EmptyResourceTable::Builder(arena);
  return builder.Build();
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_handlesintypes::UnionWithHandle WireNaturalConversionTraits<::test_handlesintypes::wire::UnionWithHandle, ::test_handlesintypes::UnionWithHandle>::ToNatural(::test_handlesintypes::wire::UnionWithHandle src) {
  switch (src.Which()) {
    case ::test_handlesintypes::wire::UnionWithHandle::Tag::kH:
      return ::test_handlesintypes::UnionWithHandle::WithH(
          WireNaturalConversionTraits<::zx::vmo, ::zx::vmo>::ToNatural(std::move(src.h())));
    default:
      return ::test_handlesintypes::UnionWithHandle(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{});
  }
}
::test_handlesintypes::wire::UnionWithHandle WireNaturalConversionTraits<::test_handlesintypes::wire::UnionWithHandle, ::test_handlesintypes::UnionWithHandle>::ToWire(fidl::AnyArena& arena, ::test_handlesintypes::UnionWithHandle src) {
  switch (src.Which()) {
    case ::test_handlesintypes::UnionWithHandle::Tag::kH:
      return ::test_handlesintypes::wire::UnionWithHandle::WithH(
          WireNaturalConversionTraits<::zx::vmo, ::zx::vmo>::ToWire(arena, std::move(src.h().value())));
    default:
      return ::test_handlesintypes::wire::UnionWithHandle();
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::test_handlesintypes::EmptyResourceUnion WireNaturalConversionTraits<::test_handlesintypes::wire::EmptyResourceUnion, ::test_handlesintypes::EmptyResourceUnion>::ToNatural(::test_handlesintypes::wire::EmptyResourceUnion src) {
  switch (src.Which()) {
    default:
      return ::test_handlesintypes::EmptyResourceUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{});
  }
}
::test_handlesintypes::wire::EmptyResourceUnion WireNaturalConversionTraits<::test_handlesintypes::wire::EmptyResourceUnion, ::test_handlesintypes::EmptyResourceUnion>::ToWire(fidl::AnyArena& arena, ::test_handlesintypes::EmptyResourceUnion src) {
  switch (src.Which()) {
    default:
      return ::test_handlesintypes::wire::EmptyResourceUnion();
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__
#pragma clang diagnostic pop

}  // namespace internal
}  // namespace fidl
