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

#pragma once

#include <fidl/test.doccomments/cpp/common_types.h>
#include <fidl/test.doccomments/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__

namespace test_doccomments {
class Struct;

class Table;

class StrictUnion;

class FlexibleUnion;

extern "C" const fidl_type_t test_doccomments_TableTable;

/// table comment #1
///
/// table comment #3
class Table {
 private:
  struct Storage_;

 public:
  Table(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  Table() noexcept = default;
  Table(Table&&) noexcept = default;
  Table& operator=(Table&&) noexcept = default;
  Table(const Table& other) noexcept : Table(other.CloneStorage_()) {}
  Table& operator=(const Table& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }
  bool operator==(const Table& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<
        ::test_doccomments::Table>::Equal(this, &other);
  }
  bool operator!=(const Table& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<
        ::test_doccomments::Table>::Equal(this, &other);
  }

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

  /// table field comment #1
  ///
  /// table field comment #3
  const std::optional<int32_t>& field() const { return storage_.field; }
  /// table field comment #1
  ///
  /// table field comment #3
  ::std::optional<int32_t>& field() { return storage_.field; }

  Table(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : Table(Storage_{}) {}

 private:
  struct Storage_ final {
    /// table field comment #1
    ///
    /// table field comment #3
    ::std::optional<int32_t> field{};
  };

  // TODO(https://fxbug.dev/91252): Box the storage.
  Storage_ storage_;
  Storage_ CloneStorage_() const;
  friend struct ::fidl::internal::NaturalTableCodingTraits<
      ::test_doccomments::Table>;
  friend struct ::fidl::internal::MemberVisitor<::test_doccomments::Table>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalTableMember<
          Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
          1, &Storage_::field});
};

extern "C" const fidl_type_t test_doccomments_StructTable;

/// struct comment #1
///
/// struct comment #3
class Struct {
 private:
  struct Storage_;

 public:
  Struct(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  Struct(int32_t field) noexcept : storage_({.field = std::move(field)}) {}

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

  Struct(Struct&&) noexcept = default;
  Struct& operator=(Struct&&) noexcept = default;
  Struct(const Struct& other) noexcept : Struct(other.CloneStorage_()) {}
  Struct& operator=(const Struct& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

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

  /// struct member comment #1
  ///
  /// struct member comment #3
  int32_t field() const { return storage_.field; }

  /// struct member comment #1
  ///
  /// struct member comment #3
  int32_t& field() { return storage_.field; }

  Struct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : Struct(Storage_{
            .field = {},
        }) {}

 private:
  struct Storage_ final {
    /// struct member comment #1
    ///
    /// struct member comment #3
    int32_t field = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_doccomments::Struct, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_doccomments::Struct>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::field, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_doccomments_StrictUnionTable;

/// strict union comment #1
///
/// strict union comment #3
class StrictUnion {
 private:
  using Storage_ = std::variant<std::monostate, int32_t>;

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

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

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

  constexpr ::test_doccomments::StrictUnion::Tag Which() const {
    return StrictUnion::IndexToTag(storage_->index()).value();
  }
  static StrictUnion WithField(int32_t val) {
    return StrictUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

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

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

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

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

  static constexpr std::optional<::test_doccomments::StrictUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_doccomments::StrictUnion::Tag::kField;
      default:
        return std::nullopt;
    }
  }
};

extern "C" const fidl_type_t test_doccomments_FlexibleUnionTable;

/// flexible union comment #1
///
/// flexible union comment #3
class FlexibleUnion {
 private:
  using Storage_ = std::variant<std::monostate, int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_union_tag_t {
    kField = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  // Create an unknown value of this union.
  FlexibleUnion() : storage_(std::make_shared<Storage_>()) {}

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

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

  constexpr ::test_doccomments::FlexibleUnion::Tag Which() const {
    return FlexibleUnion::IndexToTag(storage_->index()).value();
  }
  static FlexibleUnion WithField(int32_t val) {
    return FlexibleUnion(
        std::make_shared<Storage_>(std::in_place_index_t<1>{}, std::move(val)));
  }

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

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

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

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

  static constexpr std::optional<::test_doccomments::FlexibleUnion::Tag>
  IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_doccomments::FlexibleUnion::Tag::kField;
      default:
        return ::test_doccomments::FlexibleUnion::Tag::kUnknown;
    }
  }
};

/// const comment #1
///
/// const comment #3
constexpr int32_t kC = 4u;

}  // namespace test_doccomments
namespace fidl {

extern "C" const fidl_type_t test_doccomments_StructTable;

template <>
struct IsFidlType<::test_doccomments::Struct> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_doccomments::Struct> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_doccomments_StructTable;
};

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

extern "C" const fidl_type_t test_doccomments_TableTable;

template <>
struct IsFidlType<::test_doccomments::Table> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_doccomments::Table> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_doccomments_TableTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_doccomments::Table, ::fidl::internal::NaturalCodingConstraintEmpty>
    : public ::fidl::internal::NaturalTableCodingTraits<
          ::test_doccomments::Table> {};

extern "C" const fidl_type_t test_doccomments_StrictUnionTable;

template <>
struct IsFidlType<::test_doccomments::StrictUnion> : public std::true_type {};
template <>
struct IsUnion<::test_doccomments::StrictUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_doccomments::StrictUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_doccomments_StrictUnionTable;
};

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

extern "C" const fidl_type_t test_doccomments_FlexibleUnionTable;

template <>
struct IsFidlType<::test_doccomments::FlexibleUnion> : public std::true_type {};
template <>
struct IsUnion<::test_doccomments::FlexibleUnion> : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_doccomments::FlexibleUnion> final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_doccomments_FlexibleUnionTable;
};

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

template <>
struct internal::NaturalCodingTraits<
    ::test_doccomments::MyStrictBits,
    ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = false;

  static void Encode(internal::NaturalEncoder* encoder,
                     ::test_doccomments::MyStrictBits* value, size_t offset,
                     size_t recursion_depth) {
    if (static_cast<uint32_t>(*value) & ~3ull) {
      encoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
    *encoder->template GetPtr<::test_doccomments::MyStrictBits>(offset) =
        *value;
  }
  static void Decode(internal::NaturalDecoder* decoder,
                     ::test_doccomments::MyStrictBits* value, size_t offset,
                     size_t recursion_depth) {
    *value =
        *decoder->template GetPtr<::test_doccomments::MyStrictBits>(offset);
    if (static_cast<uint32_t>(*value) & ~3ull) {
      decoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
  }
};
template <>
struct internal::NaturalCodingTraits<
    ::test_doccomments::MyFlexibleBits,
    ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = true;

  static void Encode(internal::NaturalEncoder* encoder,
                     ::test_doccomments::MyFlexibleBits* value, size_t offset,
                     size_t recursion_depth) {
    *encoder->template GetPtr<::test_doccomments::MyFlexibleBits>(offset) =
        *value;
  }
  static void Decode(internal::NaturalDecoder* decoder,
                     ::test_doccomments::MyFlexibleBits* value, size_t offset,
                     size_t recursion_depth) {
    *value =
        *decoder->template GetPtr<::test_doccomments::MyFlexibleBits>(offset);
  }
};

template <>
struct internal::NaturalCodingTraits<
    ::test_doccomments::MyStrictEnum,
    ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = false;

  static void Encode(internal::NaturalEncoder* encoder,
                     ::test_doccomments::MyStrictEnum* value, size_t offset,
                     size_t recursion_depth) {
    switch (*value) {
      case ::test_doccomments::MyStrictEnum::kFoo:
      case ::test_doccomments::MyStrictEnum::kBar:
        break;
      default:
        encoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
    *encoder->template GetPtr<::test_doccomments::MyStrictEnum>(offset) =
        *value;
  }
  static void Decode(internal::NaturalDecoder* decoder,
                     ::test_doccomments::MyStrictEnum* value, size_t offset,
                     size_t recursion_depth) {
    *value =
        *decoder->template GetPtr<::test_doccomments::MyStrictEnum>(offset);
    switch (*value) {
      case ::test_doccomments::MyStrictEnum::kFoo:
      case ::test_doccomments::MyStrictEnum::kBar:
        break;
      default:
        decoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
  }
};
template <>
struct internal::NaturalCodingTraits<
    ::test_doccomments::MyFlexibleEnum,
    ::fidl::internal::NaturalCodingConstraintEmpty> {
  static constexpr size_t inline_size_v2 = sizeof(uint32_t);
  static constexpr bool is_memcpy_compatible = true;

  static void Encode(internal::NaturalEncoder* encoder,
                     ::test_doccomments::MyFlexibleEnum* value, size_t offset,
                     size_t recursion_depth) {
    *encoder->template GetPtr<::test_doccomments::MyFlexibleEnum>(offset) =
        *value;
  }
  static void Decode(internal::NaturalDecoder* decoder,
                     ::test_doccomments::MyFlexibleEnum* value, size_t offset,
                     size_t recursion_depth) {
    *value =
        *decoder->template GetPtr<::test_doccomments::MyFlexibleEnum>(offset);
  }
};

}  // namespace fidl
