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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.arrays/cpp/common_types.h>
#include <fidl/test.arrays/cpp/markers.h>
#include <lib/fidl/cpp/natural_coding_traits.h>
#include <lib/fidl/cpp/natural_types.h>

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_arrays {

class StructSmallArray;

class StructLargeArray;

class TableSmallArray;

class TableLargeArray;

class UnionSmallArray;

class UnionLargeArray;

class StructSmallArray {
 private:
  struct Storage_;

 public:
  StructSmallArray(Storage_ storage) noexcept;
  StructSmallArray(::std::array<uint32_t, 2> a) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |StructSmallArray| only if all of its members are default constructible.
  StructSmallArray() = default;
#pragma clang diagnostic pop

  StructSmallArray(StructSmallArray&&) noexcept = default;
  StructSmallArray& operator=(StructSmallArray&&) noexcept = default;
  StructSmallArray(const StructSmallArray& other) noexcept;
  StructSmallArray& operator=(const StructSmallArray& other) noexcept;

  bool operator==(const StructSmallArray& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructSmallArray, 8>::Equal(this, &other);
  }
  bool operator!=(const StructSmallArray& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructSmallArray, 8>::Equal(this, &other);
  }

  const ::std::array<uint32_t, 2>&
  a() const {
    return storage_.a;
  }

  ::std::array<uint32_t, 2>& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  StructSmallArray& a(::std::array<uint32_t, 2> value);

  StructSmallArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::array<uint32_t, 2> a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructSmallArray, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_arrays::StructSmallArray>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::std::array<uint32_t, 2>, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class StructLargeArray {
 private:
  struct Storage_;

 public:
  StructLargeArray(Storage_ storage) noexcept;
  StructLargeArray(::std::array<uint32_t, 100> a) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |StructLargeArray| only if all of its members are default constructible.
  StructLargeArray() = default;
#pragma clang diagnostic pop

  StructLargeArray(StructLargeArray&&) noexcept = default;
  StructLargeArray& operator=(StructLargeArray&&) noexcept = default;
  StructLargeArray(const StructLargeArray& other) noexcept;
  StructLargeArray& operator=(const StructLargeArray& other) noexcept;

  bool operator==(const StructLargeArray& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructLargeArray, 400>::Equal(this, &other);
  }
  bool operator!=(const StructLargeArray& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructLargeArray, 400>::Equal(this, &other);
  }

  const ::std::array<uint32_t, 100>&
  a() const {
    return storage_.a;
  }

  ::std::array<uint32_t, 100>& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  StructLargeArray& a(::std::array<uint32_t, 100> value);

  StructLargeArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::array<uint32_t, 100> a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructLargeArray, 400>;
  friend struct ::fidl::internal::MemberVisitor<::test_arrays::StructLargeArray>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::std::array<uint32_t, 100>, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class TableSmallArray {
 private:
  struct Storage_;

 public:
  TableSmallArray(Storage_ storage) noexcept;
  TableSmallArray() noexcept = default;
  TableSmallArray(TableSmallArray&&) noexcept = default;
  TableSmallArray& operator=(TableSmallArray&&) noexcept = default;
  TableSmallArray(const TableSmallArray& other) noexcept;
  TableSmallArray& operator=(const TableSmallArray& other) noexcept;
  bool operator==(const TableSmallArray& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableSmallArray>::Equal(this, &other);
  }
  bool operator!=(const TableSmallArray& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableSmallArray>::Equal(this, &other);
  }

  bool IsEmpty() const {
    return !(storage_.a.has_value());
  }

  const std::optional<::std::array<uint32_t, 2>>& a() const { return storage_.a; }
  ::std::optional<::std::array<uint32_t, 2>>& a() { return storage_.a; }

  // Setter for a.
  //

  TableSmallArray& a(std::optional<::std::array<uint32_t, 2>> value);

  TableSmallArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<::std::array<uint32_t, 2>> a;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableSmallArray>;
  friend struct ::fidl::internal::MemberVisitor<::test_arrays::TableSmallArray>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, ::std::array<uint32_t, 2>, fidl::internal::NaturalCodingConstraintEmpty>{
      1, &Storage_::a});
};

class TableLargeArray {
 private:
  struct Storage_;

 public:
  TableLargeArray(Storage_ storage) noexcept;
  TableLargeArray() noexcept = default;
  TableLargeArray(TableLargeArray&&) noexcept = default;
  TableLargeArray& operator=(TableLargeArray&&) noexcept = default;
  TableLargeArray(const TableLargeArray& other) noexcept;
  TableLargeArray& operator=(const TableLargeArray& other) noexcept;
  bool operator==(const TableLargeArray& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableLargeArray>::Equal(this, &other);
  }
  bool operator!=(const TableLargeArray& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableLargeArray>::Equal(this, &other);
  }

  bool IsEmpty() const {
    return !(storage_.a.has_value());
  }

  const std::optional<::std::array<uint32_t, 100>>& a() const { return storage_.a; }
  ::std::optional<::std::array<uint32_t, 100>>& a() { return storage_.a; }

  // Setter for a.
  //

  TableLargeArray& a(std::optional<::std::array<uint32_t, 100>> value);

  TableLargeArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<::std::array<uint32_t, 100>> a;
  };

  // TODO(https://fxbug.dev/42172795): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableLargeArray>;
  friend struct ::fidl::internal::MemberVisitor<::test_arrays::TableLargeArray>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalTableMember<Storage_, ::std::array<uint32_t, 100>, fidl::internal::NaturalCodingConstraintEmpty>{
      1, &Storage_::a});
};

class UnionSmallArray {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::std::array<uint32_t, 2>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kA = 1,  // 0x1
  };

  UnionSmallArray(UnionSmallArray&& other) noexcept
      : UnionSmallArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  UnionSmallArray& operator=(UnionSmallArray&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  UnionSmallArray(const UnionSmallArray& other) noexcept : UnionSmallArray(other.CloneStorage_()) {}
  UnionSmallArray& operator=(const UnionSmallArray& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const UnionSmallArray& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const UnionSmallArray& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_arrays::UnionSmallArray::Tag Which() const {
    return UnionSmallArray::IndexToTag(storage_->index()).value();
  }
  static UnionSmallArray WithA(::std::array<uint32_t, 2> val) {
    return UnionSmallArray(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> a() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> a() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the a member.
  //

  UnionSmallArray& a(::std::array<uint32_t, 2> value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  UnionSmallArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_arrays::UnionSmallArray>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit UnionSmallArray(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_arrays::UnionSmallArray::Tag tag) {
    switch (tag) {
      case ::test_arrays::UnionSmallArray::Tag::kA:
        return 1;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_arrays::UnionSmallArray::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_arrays::UnionSmallArray::Tag::kA;
      default:
        return std::nullopt;
    }
  }
};

class UnionLargeArray {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::std::array<uint32_t, 100>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kA = 1,  // 0x1
  };

  UnionLargeArray(UnionLargeArray&& other) noexcept
      : UnionLargeArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  UnionLargeArray& operator=(UnionLargeArray&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  UnionLargeArray(const UnionLargeArray& other) noexcept : UnionLargeArray(other.CloneStorage_()) {}
  UnionLargeArray& operator=(const UnionLargeArray& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const UnionLargeArray& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const UnionLargeArray& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_arrays::UnionLargeArray::Tag Which() const {
    return UnionLargeArray::IndexToTag(storage_->index()).value();
  }
  static UnionLargeArray WithA(::std::array<uint32_t, 100> val) {
    return UnionLargeArray(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> a() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> a() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the a member.
  //

  UnionLargeArray& a(::std::array<uint32_t, 100> value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  UnionLargeArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_arrays::UnionLargeArray>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit UnionLargeArray(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_arrays::UnionLargeArray::Tag tag) {
    switch (tag) {
      case ::test_arrays::UnionLargeArray::Tag::kA:
        return 1;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_arrays::UnionLargeArray::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_arrays::UnionLargeArray::Tag::kA;
      default:
        return std::nullopt;
    }
  }
};

inline StructSmallArray::StructSmallArray(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline StructSmallArray::StructSmallArray(::std::array<uint32_t, 2> a) noexcept
    : storage_({.a = std::move(a)}) {}
inline StructSmallArray::StructSmallArray(const ::test_arrays::StructSmallArray& other) noexcept : ::test_arrays::StructSmallArray(other.CloneStorage_()) {}
inline StructSmallArray& ::test_arrays::StructSmallArray::operator=(const ::test_arrays::StructSmallArray & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline StructSmallArray::StructSmallArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : StructSmallArray(Storage_{
                                                                                                            .a = ::fidl::internal::DefaultConstructPossiblyInvalidObject<::std::array<uint32_t, 2>>::Make(),
                                                                                                        }) {}
inline StructSmallArray& StructSmallArray::a(::std::array<uint32_t, 2> value) {
  storage_.a = std::move(value);
  return *this;
}

inline StructLargeArray::StructLargeArray(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline StructLargeArray::StructLargeArray(::std::array<uint32_t, 100> a) noexcept
    : storage_({.a = std::move(a)}) {}
inline StructLargeArray::StructLargeArray(const ::test_arrays::StructLargeArray& other) noexcept : ::test_arrays::StructLargeArray(other.CloneStorage_()) {}
inline StructLargeArray& ::test_arrays::StructLargeArray::operator=(const ::test_arrays::StructLargeArray & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline StructLargeArray::StructLargeArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : StructLargeArray(Storage_{
                                                                                                            .a = ::fidl::internal::DefaultConstructPossiblyInvalidObject<::std::array<uint32_t, 100>>::Make(),
                                                                                                        }) {}
inline StructLargeArray& StructLargeArray::a(::std::array<uint32_t, 100> value) {
  storage_.a = std::move(value);
  return *this;
}

inline TableSmallArray::TableSmallArray(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline TableSmallArray::TableSmallArray(const ::test_arrays::TableSmallArray& other) noexcept : TableSmallArray(other.CloneStorage_()) {}
inline TableSmallArray& ::test_arrays::TableSmallArray::operator=(const TableSmallArray & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline TableSmallArray::TableSmallArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : TableSmallArray(Storage_{}) {}
inline TableSmallArray& TableSmallArray::a(std::optional<::std::array<uint32_t, 2>> value) {
  storage_.a = std::move(value);
  return *this;
}

inline TableLargeArray::TableLargeArray(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline TableLargeArray::TableLargeArray(const ::test_arrays::TableLargeArray& other) noexcept : TableLargeArray(other.CloneStorage_()) {}
inline TableLargeArray& ::test_arrays::TableLargeArray::operator=(const TableLargeArray & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline TableLargeArray::TableLargeArray(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : TableLargeArray(Storage_{}) {}
inline TableLargeArray& TableLargeArray::a(std::optional<::std::array<uint32_t, 100>> value) {
  storage_.a = std::move(value);
  return *this;
}

}  // namespace test_arrays
namespace fidl {

template <>
struct IsFidlType<::test_arrays::StructSmallArray> : public std::true_type {};

template <>
struct TypeTraits<::test_arrays::StructSmallArray> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 8;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_arrays::StructSmallArray> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_arrays::StructSmallArray, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructSmallArray, 8> {};

template <>
struct IsFidlType<::test_arrays::StructLargeArray> : public std::true_type {};

template <>
struct TypeTraits<::test_arrays::StructLargeArray> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 400;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_arrays::StructLargeArray> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_arrays::StructLargeArray, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_arrays::StructLargeArray, 400> {};

template <>
struct IsFidlType<::test_arrays::TableSmallArray> : public std::true_type {};

template <>
struct TypeTraits<::test_arrays::TableSmallArray> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_arrays::TableSmallArray> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_arrays::TableSmallArray, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableSmallArray> {};

template <>
struct IsFidlType<::test_arrays::TableLargeArray> : public std::true_type {};

template <>
struct TypeTraits<::test_arrays::TableLargeArray> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 408;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsTable<::test_arrays::TableLargeArray> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_arrays::TableLargeArray, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_arrays::TableLargeArray> {};

template <>
struct IsFidlType<::test_arrays::UnionSmallArray> : public std::true_type {};

template <>
struct TypeTraits<::test_arrays::UnionSmallArray> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_arrays::UnionSmallArray> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_arrays::UnionSmallArray, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_arrays::UnionSmallArray> {};

template <>
struct IsFidlType<::test_arrays::UnionLargeArray> : public std::true_type {};

template <>
struct TypeTraits<::test_arrays::UnionLargeArray> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 400;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_arrays::UnionLargeArray> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_arrays::UnionLargeArray, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_arrays::UnionLargeArray> {};

#pragma clang diagnostic pop

}  // namespace fidl
