// 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);
  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_ == Tag::kH; }

  ::zx::vmo& h() {
    EnsureStorageInitialized(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);

  Tag Which() const {
    switch (tag_) {
      case Tag::Invalid:
      case Tag::kH:
        return Tag(tag_);
      default:
        return 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() != Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_.bytes;
  }
  const std::vector<zx::handle>* UnknownHandles() const {
    if (Which() != 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>(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);
  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{};

  TableWithHandle table_with_handle{};

  UnionWithHandle union_with_handle{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset);
  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
}  // namespace fidl
namespace fidl {

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) {
    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) {
    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__
}  // namespace fidl

//
// Proxies and stubs declarations
//
namespace fidl {
namespace test {
namespace handlesintypes {}  // namespace handlesintypes
}  // namespace test
}  // namespace fidl
