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

// fidl_experiment = output_index_json

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

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

#ifdef __Fuchsia__
void ::test_handlesintypes::wire::HandlesInTypes::_CloseHandles() {
  normal_handle.reset();
  for (auto& e_1 : handle_in_vec) {
    e_1.reset();
  }
  for (auto& e_1 : handle_in_array) {
    e_1.reset();
  }
  for (auto& e_1 : handle_in_mixed_vec_array) {
    for (auto& e_2 : e_1) {
      e_2.reset();
    }
  }
  table_with_handle._CloseHandles();
  union_with_handle._CloseHandles();
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_handlesintypes::wire::EmptyResourceStruct::_CloseHandles() {
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

auto ::test_handlesintypes::wire::UnionWithHandle::Which() const -> ::test_handlesintypes::wire::UnionWithHandle::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH:
      return static_cast<::test_handlesintypes::wire::UnionWithHandle::Tag>(ordinal_);
    default:
      return ::test_handlesintypes::wire::UnionWithHandle::Tag::_do_not_handle_this__write_a_default_case_instead;
  }
}

void ::test_handlesintypes::wire::UnionWithHandle::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(UnionWithHandle) == sizeof(fidl_union_t));
  static_assert(offsetof(UnionWithHandle, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(UnionWithHandle, envelope_) == offsetof(fidl_union_t, envelope));
}
::test_handlesintypes::wire::UnionWithHandle::~UnionWithHandle() {
  switch (ordinal_) {
    case ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH:
      envelope_.As<::zx::vmo>().clear_data();
      break;
    default:
      break;
  }
}

void ::test_handlesintypes::wire::UnionWithHandle::_Move(UnionWithHandle&& other) {
  ordinal_ = other.ordinal_;
  switch (ordinal_) {
    case ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH:
      envelope_.As<::zx::vmo>() = std::move(other.envelope_.As<::zx::vmo>());
      break;
    default:
      break;
  }
}

void ::test_handlesintypes::wire::UnionWithHandle::_CloseHandles() {
  switch (ordinal_) {
    case ::test_handlesintypes::wire::UnionWithHandle::Ordinal::kH: {
      h().reset();
      break;
    }
    default:
      break;
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

auto ::test_handlesintypes::wire::EmptyResourceUnion::Which() const -> ::test_handlesintypes::wire::EmptyResourceUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  return ::test_handlesintypes::wire::EmptyResourceUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
}

void ::test_handlesintypes::wire::EmptyResourceUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(EmptyResourceUnion) == sizeof(fidl_union_t));
  static_assert(offsetof(EmptyResourceUnion, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(EmptyResourceUnion, envelope_) == offsetof(fidl_union_t, envelope));
}
::test_handlesintypes::wire::EmptyResourceUnion::~EmptyResourceUnion() {
  switch (ordinal_) {
    default:
      break;
  }
}

void ::test_handlesintypes::wire::EmptyResourceUnion::_Move(EmptyResourceUnion&& other) {
  ordinal_ = other.ordinal_;
  switch (ordinal_) {
    default:
      break;
  }
}

void ::test_handlesintypes::wire::EmptyResourceUnion::_CloseHandles() {
  switch (ordinal_) {
    default:
      break;
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

bool ::fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_handlesintypes::wire::TableWithHandle>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!h_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_handlesintypes::wire::TableWithHandle::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

void ::test_handlesintypes::wire::TableWithHandle::_CloseHandles() {
  if (has_h()) {
    h().reset();
  }
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

bool ::fidl::WireTableFrame<::test_handlesintypes::wire::EmptyResourceTable>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_handlesintypes::wire::EmptyResourceTable>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  return max_ordinal;
}

bool ::test_handlesintypes::wire::EmptyResourceTable::HasUnknownData() const {
  if (max_ordinal_ > 0) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

void ::test_handlesintypes::wire::EmptyResourceTable::_CloseHandles() {
}

#endif  // __Fuchsia__

#pragma clang diagnostic pop
