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

  ::std::array<uint32_t, 2>& a() {
    EnsureStorageInitialized(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);

  Tag Which() const { return 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>(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);
  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_ == Tag::kA; }

  ::std::array<uint32_t, 100>& a() {
    EnsureStorageInitialized(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);

  Tag Which() const { return 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>(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);
  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);
  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);
  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);
  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
}  // namespace fidl
namespace fidl {

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) {
    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) {
    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

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