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

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

auto ::test_placementofattributes::wire::ExampleXUnion::Which() const
    -> ::test_placementofattributes::wire::ExampleXUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::test_placementofattributes::wire::ExampleXUnion::Ordinal::kVariant:
      return static_cast<
          ::test_placementofattributes::wire::ExampleXUnion::Tag>(ordinal_);
    default:
      return ::test_placementofattributes::wire::ExampleXUnion::Tag::kUnknown;
  }
}

void ::test_placementofattributes::wire::ExampleXUnion::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExampleXUnion) == sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(ExampleXUnion, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(ExampleXUnion, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}

void ::test_placementofattributes::wire::ExampleUnion::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ExampleUnion) == sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(ExampleUnion, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(ExampleUnion, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}

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

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