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

#pragma once

#include "lib/fidl/cpp/internal/header.h"

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace handlesintypes {

enum class obj_type : uint32_t {

  NONE = 0u,

  VMO = 3u,
};

inline zx_status_t Clone(::fidl::test::handlesintypes::obj_type value,
                         ::fidl::test::handlesintypes::obj_type* result) {
  *result = value;
  return ZX_OK;
}

class UnionWithHandle;

class TableWithHandle;

class HandlesInTypes;

#ifdef __Fuchsia__

class UnionWithHandle final {
 public:
  static const fidl_type_t* FidlType;

  UnionWithHandle();
  ~UnionWithHandle();

  UnionWithHandle(UnionWithHandle&&);
  UnionWithHandle& operator=(UnionWithHandle&&);

  static UnionWithHandle WithH(::zx::vmo&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    kH = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<UnionWithHandle> New() {
    return ::std::make_unique<UnionWithHandle>();
  }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  static void Decode(::fidl::Decoder* decoder, UnionWithHandle* value,
                     size_t offset);
  zx_status_t Clone(UnionWithHandle* result) const;

  bool has_invalid_tag() const { return tag_ == Invalid; }

  bool is_h() const {
    return tag_ == ::fidl::test::handlesintypes::UnionWithHandle::Tag::kH;
  }

  ::zx::vmo& h() {
    EnsureStorageInitialized(
        ::fidl::test::handlesintypes::UnionWithHandle::Tag::kH);
    return h_;
  }

  const ::zx::vmo& h() const {
    ZX_ASSERT(is_h());
    return h_;
  }
  UnionWithHandle& set_h(::zx::vmo value);
  UnionWithHandle& SetUnknownData(fidl_xunion_tag_t ordinal,
                                  std::vector<uint8_t> bytes,
                                  std::vector<zx::handle> handles);

  ::fidl::test::handlesintypes::UnionWithHandle::Tag Which() const {
    switch (tag_) {
      case ::fidl::test::handlesintypes::UnionWithHandle::Tag::Invalid:
      case ::fidl::test::handlesintypes::UnionWithHandle::Tag::kH:
        return ::fidl::test::handlesintypes::UnionWithHandle::Tag(tag_);
      default:
        return ::fidl::test::handlesintypes::UnionWithHandle::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal()
  // only when you need access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const { return tag_; }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() !=
        ::fidl::test::handlesintypes::UnionWithHandle::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_.bytes;
  }
  const std::vector<zx::handle>* UnknownHandles() const {
    if (Which() !=
        ::fidl::test::handlesintypes::UnionWithHandle::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_.handles;
  }

  friend ::fidl::Equality<::fidl::test::handlesintypes::UnionWithHandle>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(
      ::fidl::test::handlesintypes::UnionWithHandle::Tag::Invalid);
  union {
    ::zx::vmo h_;
    ::fidl::UnknownData unknown_data_;
  };
};

inline zx_status_t Clone(
    const ::fidl::test::handlesintypes::UnionWithHandle& value,
    ::fidl::test::handlesintypes::UnionWithHandle* result) {
  return value.Clone(result);
}

using UnionWithHandlePtr = ::std::unique_ptr<UnionWithHandle>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class TableWithHandle final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const ::zx::vmo& h() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return h_value_.value;
  }
  bool has_h() const { return field_presence_.IsSet<0>(); }

  ::zx::vmo* mutable_h() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&h_value_.value);
    }
    return &h_value_.value;
  }
  TableWithHandle& set_h(::zx::vmo _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&h_value_.value, std::move(_value));
    } else {
      h_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_h() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&h_value_.value);
  }

  const std::map<uint64_t, ::fidl::UnknownData>& UnknownData() const {
    return _unknown_data;
  }

  void SetUnknownDataEntry(uint32_t ordinal, ::fidl::UnknownData&& data) {
    auto ord = static_cast<uint64_t>(ordinal);
    ZX_ASSERT(!IsOrdinalKnown(ord));
    _unknown_data.insert({ord, std::move(data)});
  }

  TableWithHandle();
  TableWithHandle(TableWithHandle&& other);
  ~TableWithHandle();
  TableWithHandle& operator=(TableWithHandle&& other);

  static inline ::std::unique_ptr<TableWithHandle> New() {
    return ::std::make_unique<TableWithHandle>();
  }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TableWithHandle* _value,
                     size_t _offset);
  zx_status_t Clone(TableWithHandle* _result) const;

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    size_t max_ordinal =
        static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
    for (const auto& data : _unknown_data) {
      if (data.first > max_ordinal) {
        max_ordinal = data.first;
      }
    }
    return max_ordinal;
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_h {
    ValueUnion_h() {}
    ~ValueUnion_h() {}

    ::zx::vmo value;
  };
  ValueUnion_h h_value_;
  std::map<uint64_t, ::fidl::UnknownData> _unknown_data;
};

using TableWithHandlePtr = ::std::unique_ptr<TableWithHandle>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class HandlesInTypes final {
 public:
  static const fidl_type_t* FidlType;

  ::zx::vmo normal_handle{};

  ::std::vector<::zx::vmo> handle_in_vec{};

  ::std::array<::zx::vmo, 5> handle_in_array{};

  ::std::vector<::std::array<::zx::vmo, 5>> handle_in_mixed_vec_array{};

  ::fidl::test::handlesintypes::TableWithHandle table_with_handle{};

  ::fidl::test::handlesintypes::UnionWithHandle union_with_handle{};

  static inline ::std::unique_ptr<HandlesInTypes> New() {
    return ::std::make_unique<HandlesInTypes>();
  }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, HandlesInTypes* value,
                     size_t _offset);
  zx_status_t Clone(HandlesInTypes* result) const;
};

inline zx_status_t Clone(
    const ::fidl::test::handlesintypes::HandlesInTypes& _value,
    ::fidl::test::handlesintypes::HandlesInTypes* _result) {
  return _value.Clone(_result);
}

using HandlesInTypesPtr = ::std::unique_ptr<HandlesInTypes>;
#endif  // __Fuchsia__

}  // namespace handlesintypes
}  // namespace test
template <>
struct CodingTraits<::fidl::test::handlesintypes::obj_type> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::handlesintypes::obj_type);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::handlesintypes::obj_type);
  static void Encode(
      Encoder* encoder, ::fidl::test::handlesintypes::obj_type* value,
      size_t offset,
      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder,
                     ::fidl::test::handlesintypes::obj_type* value,
                     size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::handlesintypes::obj_type>(underlying);
  }
};

inline zx_status_t Clone(::fidl::test::handlesintypes::obj_type value,
                         ::fidl::test::handlesintypes::obj_type* result) {
  return ::fidl::test::handlesintypes::Clone(value, result);
}
template <>
struct Equality<::fidl::test::handlesintypes::obj_type> {
  bool operator()(const ::fidl::test::handlesintypes::obj_type& _lhs,
                  const ::fidl::test::handlesintypes::obj_type& _rhs) const {
    return _lhs == _rhs;
  }
};

#ifdef __Fuchsia__

template <>
struct IsFidlXUnion<::fidl::test::handlesintypes::UnionWithHandle>
    : public std::true_type {};

template <>
struct CodingTraits<::fidl::test::handlesintypes::UnionWithHandle>
    : public EncodableCodingTraits<
          ::fidl::test::handlesintypes::UnionWithHandle, 24> {};

template <>
struct CodingTraits<
    std::unique_ptr<::fidl::test::handlesintypes::UnionWithHandle>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<::fidl::test::handlesintypes::UnionWithHandle>* value,
      size_t offset,
      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::test::handlesintypes::UnionWithHandle>* value,
      size_t offset) {
    fidl_xunion_t* encoded = decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::fidl::test::handlesintypes::UnionWithHandle);

    ::fidl::test::handlesintypes::UnionWithHandle::Decode(decoder, value->get(),
                                                          offset);
  }
};

inline zx_status_t Clone(
    const ::fidl::test::handlesintypes::UnionWithHandle& value,
    ::fidl::test::handlesintypes::UnionWithHandle* result) {
  return ::fidl::test::handlesintypes::Clone(value, result);
}

template <>
struct Equality<::fidl::test::handlesintypes::UnionWithHandle> {
  bool operator()(
      const ::fidl::test::handlesintypes::UnionWithHandle& _lhs,
      const ::fidl::test::handlesintypes::UnionWithHandle& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::handlesintypes::UnionWithHandle::Tag::Invalid):
        return true;
      case ::fidl::test::handlesintypes::UnionWithHandle::Tag::kH:
        return ::fidl::Equals(_lhs.h_, _rhs.h_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::fidl::test::handlesintypes::TableWithHandle>
    : public EncodableCodingTraits<
          ::fidl::test::handlesintypes::TableWithHandle, 16> {};

inline zx_status_t Clone(
    const ::fidl::test::handlesintypes::TableWithHandle& _value,
    ::fidl::test::handlesintypes::TableWithHandle* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::fidl::test::handlesintypes::TableWithHandle> {
  bool operator()(
      const ::fidl::test::handlesintypes::TableWithHandle& _lhs,
      const ::fidl::test::handlesintypes::TableWithHandle& _rhs) const {
    if (_lhs.has_h()) {
      if (!_rhs.has_h()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.h(), _rhs.h())) {
        return false;
      }
    } else if (_rhs.has_h()) {
      return false;
    }
    return ::fidl::Equals(_lhs.UnknownData(), _rhs.UnknownData());
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::fidl::test::handlesintypes::HandlesInTypes>
    : public EncodableCodingTraits<::fidl::test::handlesintypes::HandlesInTypes,
                                   104> {};

template <>
struct HasPadding<::fidl::test::handlesintypes::HandlesInTypes>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::handlesintypes::HandlesInTypes>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::handlesintypes::HandlesInTypes>::value &&
          IsMemcpyCompatible<
              ::fidl::test::handlesintypes::TableWithHandle>::value &&
          IsMemcpyCompatible<
              ::fidl::test::handlesintypes::UnionWithHandle>::value &&
          IsMemcpyCompatible<::std::array<::zx::vmo, 5>>::value &&
          IsMemcpyCompatible<
              ::std::vector<::std::array<::zx::vmo, 5>>>::value &&
          IsMemcpyCompatible<::std::vector<::zx::vmo>>::value &&
          IsMemcpyCompatible<::zx::vmo>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::handlesintypes::HandlesInTypes& value,
    ::fidl::test::handlesintypes::HandlesInTypes* result) {
  return ::fidl::test::handlesintypes::Clone(value, result);
}

template <>
struct Equality<::fidl::test::handlesintypes::HandlesInTypes> {
  bool operator()(
      const ::fidl::test::handlesintypes::HandlesInTypes& _lhs,
      const ::fidl::test::handlesintypes::HandlesInTypes& _rhs) const {
    if (!::fidl::Equals(_lhs.normal_handle, _rhs.normal_handle)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.handle_in_vec, _rhs.handle_in_vec)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.handle_in_array, _rhs.handle_in_array)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.handle_in_mixed_vec_array,
                        _rhs.handle_in_mixed_vec_array)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.table_with_handle, _rhs.table_with_handle)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.union_with_handle, _rhs.union_with_handle)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

//
// Proxies and stubs declarations
//
}  // namespace fidl
