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

#pragma once

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

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace arrays {
class UnionSmallArray;

class UnionLargeArray;

class TableSmallArray;

class TableLargeArray;

class StructSmallArray;

class StructLargeArray;

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

  UnionSmallArray();
  ~UnionSmallArray();

  UnionSmallArray(UnionSmallArray&&);
  UnionSmallArray& operator=(UnionSmallArray&&);

  static UnionSmallArray WithA(::std::array<uint32_t, 2>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

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

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

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

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

  bool is_a() const {
    return tag_ == ::fidl::test::arrays::UnionSmallArray::Tag::kA;
  }

  ::std::array<uint32_t, 2>& a() {
    EnsureStorageInitialized(::fidl::test::arrays::UnionSmallArray::Tag::kA);
    return a_;
  }

  const ::std::array<uint32_t, 2>& a() const {
    ZX_ASSERT(is_a());
    return a_;
  }
  UnionSmallArray& set_a(::std::array<uint32_t, 2> value);

  ::fidl::test::arrays::UnionSmallArray::Tag Which() const {
    return ::fidl::test::arrays::UnionSmallArray::Tag(tag_);
  }

  // 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_; }

  friend ::fidl::Equality<::fidl::test::arrays::UnionSmallArray>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(
      ::fidl::test::arrays::UnionSmallArray::Tag::Invalid);
  union {
    ::std::array<uint32_t, 2> a_;
  };
};

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

using UnionSmallArrayPtr = ::std::unique_ptr<UnionSmallArray>;

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

  UnionLargeArray();
  ~UnionLargeArray();

  UnionLargeArray(UnionLargeArray&&);
  UnionLargeArray& operator=(UnionLargeArray&&);

  static UnionLargeArray WithA(::std::array<uint32_t, 100>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

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

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

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

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

  bool is_a() const {
    return tag_ == ::fidl::test::arrays::UnionLargeArray::Tag::kA;
  }

  ::std::array<uint32_t, 100>& a() {
    EnsureStorageInitialized(::fidl::test::arrays::UnionLargeArray::Tag::kA);
    return a_;
  }

  const ::std::array<uint32_t, 100>& a() const {
    ZX_ASSERT(is_a());
    return a_;
  }
  UnionLargeArray& set_a(::std::array<uint32_t, 100> value);

  ::fidl::test::arrays::UnionLargeArray::Tag Which() const {
    return ::fidl::test::arrays::UnionLargeArray::Tag(tag_);
  }

  // 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_; }

  friend ::fidl::Equality<::fidl::test::arrays::UnionLargeArray>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(
      ::fidl::test::arrays::UnionLargeArray::Tag::Invalid);
  union {
    ::std::array<uint32_t, 100> a_;
  };
};

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

using UnionLargeArrayPtr = ::std::unique_ptr<UnionLargeArray>;

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

  const ::std::array<uint32_t, 2>& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const { return field_presence_.IsSet<0>(); }

  ::std::array<uint32_t, 2>* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  TableSmallArray& set_a(::std::array<uint32_t, 2> _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

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

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

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

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TableSmallArray* _value,
                     size_t _offset);
  zx_status_t Clone(TableSmallArray* _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_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    ::std::array<uint32_t, 2> value;
  };
  ValueUnion_a a_value_;
  std::map<uint64_t, std::vector<uint8_t>> _unknown_data;
};

using TableSmallArrayPtr = ::std::unique_ptr<TableSmallArray>;

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

  const ::std::array<uint32_t, 100>& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const { return field_presence_.IsSet<0>(); }

  ::std::array<uint32_t, 100>* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  TableLargeArray& set_a(::std::array<uint32_t, 100> _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

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

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

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

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TableLargeArray* _value,
                     size_t _offset);
  zx_status_t Clone(TableLargeArray* _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_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    ::std::array<uint32_t, 100> value;
  };
  ValueUnion_a a_value_;
  std::map<uint64_t, std::vector<uint8_t>> _unknown_data;
};

using TableLargeArrayPtr = ::std::unique_ptr<TableLargeArray>;

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

  ::std::array<uint32_t, 2> a{};

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

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

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

using StructSmallArrayPtr = ::std::unique_ptr<StructSmallArray>;

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

  ::std::array<uint32_t, 100> a{};

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

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

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

using StructLargeArrayPtr = ::std::unique_ptr<StructLargeArray>;

}  // namespace arrays
}  // namespace test
template <>
struct IsFidlXUnion<::fidl::test::arrays::UnionSmallArray>
    : public std::true_type {};

template <>
struct CodingTraits<::fidl::test::arrays::UnionSmallArray>
    : public EncodableCodingTraits<::fidl::test::arrays::UnionSmallArray, 24> {
};

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

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<::fidl::test::arrays::UnionSmallArray>* 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::arrays::UnionSmallArray>* 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::arrays::UnionSmallArray);

    ::fidl::test::arrays::UnionSmallArray::Decode(decoder, value->get(),
                                                  offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::arrays::UnionSmallArray::Tag::Invalid):
        return true;
      case ::fidl::test::arrays::UnionSmallArray::Tag::kA:
        return ::fidl::Equals(_lhs.a_, _rhs.a_);

      default:
        return false;
    }
  }
};
template <>
struct IsFidlXUnion<::fidl::test::arrays::UnionLargeArray>
    : public std::true_type {};

template <>
struct CodingTraits<::fidl::test::arrays::UnionLargeArray>
    : public EncodableCodingTraits<::fidl::test::arrays::UnionLargeArray, 24> {
};

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

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<::fidl::test::arrays::UnionLargeArray>* 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::arrays::UnionLargeArray>* 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::arrays::UnionLargeArray);

    ::fidl::test::arrays::UnionLargeArray::Decode(decoder, value->get(),
                                                  offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::arrays::UnionLargeArray::Tag::Invalid):
        return true;
      case ::fidl::test::arrays::UnionLargeArray::Tag::kA:
        return ::fidl::Equals(_lhs.a_, _rhs.a_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::fidl::test::arrays::TableSmallArray>
    : public EncodableCodingTraits<::fidl::test::arrays::TableSmallArray, 16> {
};

inline zx_status_t Clone(const ::fidl::test::arrays::TableSmallArray& _value,
                         ::fidl::test::arrays::TableSmallArray* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::fidl::test::arrays::TableSmallArray> {
  bool operator()(const ::fidl::test::arrays::TableSmallArray& _lhs,
                  const ::fidl::test::arrays::TableSmallArray& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return ::fidl::Equals(_lhs.UnknownData(), _rhs.UnknownData());
  }
};
template <>
struct CodingTraits<::fidl::test::arrays::TableLargeArray>
    : public EncodableCodingTraits<::fidl::test::arrays::TableLargeArray, 16> {
};

inline zx_status_t Clone(const ::fidl::test::arrays::TableLargeArray& _value,
                         ::fidl::test::arrays::TableLargeArray* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::fidl::test::arrays::TableLargeArray> {
  bool operator()(const ::fidl::test::arrays::TableLargeArray& _lhs,
                  const ::fidl::test::arrays::TableLargeArray& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return ::fidl::Equals(_lhs.UnknownData(), _rhs.UnknownData());
  }
};
template <>
struct CodingTraits<::fidl::test::arrays::StructSmallArray>
    : public EncodableCodingTraits<::fidl::test::arrays::StructSmallArray, 8> {
};

template <>
struct IsMemcpyCompatible<::fidl::test::arrays::StructSmallArray>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::arrays::StructSmallArray>::value &&
          IsMemcpyCompatible<::std::array<uint32_t, 2>>::value> {};

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

template <>
struct Equality<::fidl::test::arrays::StructSmallArray> {
  bool operator()(const ::fidl::test::arrays::StructSmallArray& _lhs,
                  const ::fidl::test::arrays::StructSmallArray& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fidl::test::arrays::StructLargeArray>
    : public EncodableCodingTraits<::fidl::test::arrays::StructLargeArray,
                                   400> {};

template <>
struct IsMemcpyCompatible<::fidl::test::arrays::StructLargeArray>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::arrays::StructLargeArray>::value &&
          IsMemcpyCompatible<::std::array<uint32_t, 100>>::value> {};

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

template <>
struct Equality<::fidl::test::arrays::StructLargeArray> {
  bool operator()(const ::fidl::test::arrays::StructLargeArray& _lhs,
                  const ::fidl::test::arrays::StructLargeArray& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    return true;
  }
};

}  // namespace fidl
