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

#pragma once

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

namespace test {
namespace arrays {

//
// Domain objects declarations
//

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_ == ::test::arrays::UnionSmallArray::Tag::kA; }

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

  ::test::arrays::UnionSmallArray::Tag Which() const {
    return ::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<::test::arrays::UnionSmallArray>;

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

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

inline zx_status_t Clone(const ::test::arrays::UnionSmallArray& value,
                         ::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_ == ::test::arrays::UnionLargeArray::Tag::kA; }

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

  ::test::arrays::UnionLargeArray::Tag Which() const {
    return ::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<::test::arrays::UnionLargeArray>;

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

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

inline zx_status_t Clone(const ::test::arrays::UnionLargeArray& value,
                         ::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);
  }

  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 {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

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

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);
  }

  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 {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

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

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 ::test::arrays::StructSmallArray& _value,
                         ::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 ::test::arrays::StructLargeArray& _value,
                         ::test::arrays::StructLargeArray* _result) {
  return _value.Clone(_result);
}

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::test::arrays::UnionSmallArray>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::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 ::test::arrays::UnionSmallArray);

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

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::test::arrays::UnionLargeArray>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::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 ::test::arrays::UnionLargeArray);

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

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

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

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

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

inline zx_status_t Clone(const ::test::arrays::TableSmallArray& _value,
                         ::test::arrays::TableSmallArray* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::arrays::TableSmallArray> {
  bool operator()(const ::test::arrays::TableSmallArray& _lhs, const ::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 true;
  }
};
template <>
struct CodingTraits<::test::arrays::TableLargeArray>
    : public EncodableCodingTraits<::test::arrays::TableLargeArray, 16> {};

inline zx_status_t Clone(const ::test::arrays::TableLargeArray& _value,
                         ::test::arrays::TableLargeArray* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::arrays::TableLargeArray> {
  bool operator()(const ::test::arrays::TableLargeArray& _lhs, const ::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 true;
  }
};
template <>
struct CodingTraits<::test::arrays::StructSmallArray>
    : public EncodableCodingTraits<::test::arrays::StructSmallArray, 8> {};

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

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

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

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

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

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

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