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

// fidl_experiment = output_index_json

#pragma once

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

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.exampleusing/cpp/natural_types.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_placementofattributes {

class ExampleProtocolMethodRequest;

class ExampleStruct;

class ExampleTable;

class ExampleUnion;

using Alias = uint32_t;

constexpr uint32_t kExampleConst = 0u;

class ExampleProtocolMethodRequest {
 private:
  struct Storage_;

 public:
  ExampleProtocolMethodRequest(Storage_ storage) noexcept;
  ExampleProtocolMethodRequest(::test_exampleusing::Empty arg) noexcept;

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

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

  bool operator==(const ExampleProtocolMethodRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleProtocolMethodRequest, 1>::Equal(this, &other);
  }
  bool operator!=(const ExampleProtocolMethodRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleProtocolMethodRequest, 1>::Equal(this, &other);
  }

  const ::test_exampleusing::Empty&
  arg() const {
    return storage_.arg;
  }

  ::test_exampleusing::Empty& arg() {
    return storage_.arg;
  }

  // Setter for arg.
  //

  ExampleProtocolMethodRequest& arg(::test_exampleusing::Empty value);

  ExampleProtocolMethodRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::test_exampleusing::Empty arg;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleProtocolMethodRequest, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_placementofattributes::ExampleProtocolMethodRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_exampleusing::Empty, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::arg, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class ExampleStruct {
 private:
  struct Storage_;

 public:
  ExampleStruct(Storage_ storage) noexcept;
  ExampleStruct(uint32_t member) noexcept;

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

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

  bool operator==(const ExampleStruct& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleStruct, 4>::Equal(this, &other);
  }
  bool operator!=(const ExampleStruct& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleStruct, 4>::Equal(this, &other);
  }

  uint32_t
  member() const {
    return storage_.member;
  }

  uint32_t& member() {
    return storage_.member;
  }

  // Setter for member.
  //

  ExampleStruct& member(uint32_t value);

  ExampleStruct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint32_t member = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleStruct, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_placementofattributes::ExampleStruct>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::member, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class ExampleTable {
 private:
  struct Storage_;

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

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

  const std::optional<uint32_t>& member() const { return storage_.member; }
  ::std::optional<uint32_t>& member() { return storage_.member; }

  // Setter for member.
  //

  ExampleTable& member(std::optional<uint32_t> value);

  ExampleTable(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::optional<uint32_t> member;
  };

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

class ExampleUnion {
 private:
  using Storage_ =
      std::variant<
          std::monostate, uint32_t>;

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

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

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

  constexpr ::test_placementofattributes::ExampleUnion::Tag Which() const {
    return ExampleUnion::IndexToTag(storage_->index()).value();
  }
  static ExampleUnion WithVariant(uint32_t val) {
    return ExampleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

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

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

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

  ExampleUnion& variant(uint32_t value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  ExampleUnion(::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_placementofattributes::ExampleUnion>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

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

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

  static constexpr std::optional<::test_placementofattributes::ExampleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_placementofattributes::ExampleUnion::Tag::kVariant;
      default:
        return std::nullopt;
    }
  }
};

inline ExampleProtocolMethodRequest::ExampleProtocolMethodRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline ExampleProtocolMethodRequest::ExampleProtocolMethodRequest(::test_exampleusing::Empty arg) noexcept
    : storage_({.arg = std::move(arg)}) {}
inline ExampleProtocolMethodRequest::ExampleProtocolMethodRequest(const ::test_placementofattributes::ExampleProtocolMethodRequest& other) noexcept : ::test_placementofattributes::ExampleProtocolMethodRequest(other.CloneStorage_()) {}
inline ExampleProtocolMethodRequest& ::test_placementofattributes::ExampleProtocolMethodRequest::operator=(const ::test_placementofattributes::ExampleProtocolMethodRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline ExampleProtocolMethodRequest::ExampleProtocolMethodRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ExampleProtocolMethodRequest(Storage_{
                                                                                                                                    .arg = ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
                                                                                                                                }) {}
inline ExampleProtocolMethodRequest& ExampleProtocolMethodRequest::arg(::test_exampleusing::Empty value) {
  storage_.arg = std::move(value);
  return *this;
}

inline ExampleStruct::ExampleStruct(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline ExampleStruct::ExampleStruct(uint32_t member) noexcept
    : storage_({.member = std::move(member)}) {}
inline ExampleStruct::ExampleStruct(const ::test_placementofattributes::ExampleStruct& other) noexcept : ::test_placementofattributes::ExampleStruct(other.CloneStorage_()) {}
inline ExampleStruct& ::test_placementofattributes::ExampleStruct::operator=(const ::test_placementofattributes::ExampleStruct & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline ExampleStruct::ExampleStruct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ExampleStruct(Storage_{
                                                                                                      .member = {},
                                                                                                  }) {}
inline ExampleStruct& ExampleStruct::member(uint32_t value) {
  storage_.member = std::move(value);
  return *this;
}

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

inline ExampleTable::ExampleTable(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ExampleTable(Storage_{}) {}
inline ExampleTable& ExampleTable::member(std::optional<uint32_t> value) {
  storage_.member = std::move(value);
  return *this;
}

}  // namespace test_placementofattributes
namespace fidl {

template <>
struct IsFidlType<::test_placementofattributes::ExampleProtocolMethodRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_placementofattributes::ExampleProtocolMethodRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_placementofattributes::ExampleProtocolMethodRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_placementofattributes::ExampleProtocolMethodRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleProtocolMethodRequest, 1> {};

template <>
struct IsFidlType<::test_placementofattributes::ExampleStruct> : public std::true_type {};

template <>
struct TypeTraits<::test_placementofattributes::ExampleStruct> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_placementofattributes::ExampleStruct> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_placementofattributes::ExampleStruct, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_placementofattributes::ExampleStruct, 4> {};

template <>
struct IsFidlType<::test_placementofattributes::ExampleTable> : public std::true_type {};

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

template <>
struct IsTable<::test_placementofattributes::ExampleTable> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_placementofattributes::ExampleTable, ::fidl::internal::NaturalCodingConstraintEmpty> : public ::fidl::internal::NaturalTableCodingTraits<::test_placementofattributes::ExampleTable> {};

template <>
struct IsFidlType<::test_placementofattributes::ExampleUnion> : public std::true_type {};

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

template <>
struct IsUnion<::test_placementofattributes::ExampleUnion> : public std::true_type {};

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

template <>
struct internal::NaturalCodingTraits<::test_placementofattributes::ExampleBits, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::NaturalEncoder* encoder, ::test_placementofattributes::ExampleBits* value, size_t offset, size_t recursion_depth) {
    if (unlikely(static_cast<uint32_t>(*value) & ~1ull)) {
      encoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
    *encoder->template GetPtr<::test_placementofattributes::ExampleBits>(offset) = *value;
  }
  static void Decode(internal::NaturalDecoder* decoder, ::test_placementofattributes::ExampleBits* value, size_t offset, size_t recursion_depth) {
    *value = *decoder->template GetPtr<::test_placementofattributes::ExampleBits>(offset);
    if (unlikely(static_cast<uint32_t>(*value) & ~1ull)) {
      decoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
  }
};

template <>
struct internal::NaturalCodingTraits<::test_placementofattributes::ExampleEnum, ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::NaturalEncoder* encoder, ::test_placementofattributes::ExampleEnum* value, size_t offset, size_t recursion_depth) {
    switch (*value) {
      case ::test_placementofattributes::ExampleEnum::kMember:
        break;
      default:
        encoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
    *encoder->template GetPtr<::test_placementofattributes::ExampleEnum>(offset) = *value;
  }
  static void Decode(internal::NaturalDecoder* decoder, ::test_placementofattributes::ExampleEnum* value, size_t offset, size_t recursion_depth) {
    *value = *decoder->template GetPtr<::test_placementofattributes::ExampleEnum>(offset);
    switch (*value) {
      case ::test_placementofattributes::ExampleEnum::kMember:
        break;
      default:
        decoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
  }
};

#pragma clang diagnostic pop

}  // namespace fidl
