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

// fidl_experiment = output_index_json

#pragma once

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

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

namespace test_inheritance {

class SuperFooRequest;

class SuperFooResponse;

class SuperFooRequest {
 private:
  struct Storage_;

 public:
  SuperFooRequest(Storage_ storage) noexcept;
  SuperFooRequest(::std::string s) noexcept;

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

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

  bool operator==(const SuperFooRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_inheritance::SuperFooRequest, 16>::Equal(this, &other);
  }
  bool operator!=(const SuperFooRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_inheritance::SuperFooRequest, 16>::Equal(this, &other);
  }

  const ::std::string&
  s() const {
    return storage_.s;
  }

  ::std::string& s() {
    return storage_.s;
  }

  // Setter for s.
  //

  SuperFooRequest& s(::std::string value);

  SuperFooRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::std::string s;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_inheritance::SuperFooRequest, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_inheritance::SuperFooRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::std::string, fidl::internal::NaturalCodingConstraintString<>>{
      &Storage_::s, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class SuperFooResponse {
 private:
  struct Storage_;

 public:
  SuperFooResponse(Storage_ storage) noexcept;
  SuperFooResponse(int64_t y) noexcept;

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

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

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

  int64_t
  y() const {
    return storage_.y;
  }

  int64_t& y() {
    return storage_.y;
  }

  // Setter for y.
  //

  SuperFooResponse& y(int64_t value);

  SuperFooResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    int64_t y = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_inheritance::SuperFooResponse, 8>;
  friend struct ::fidl::internal::MemberVisitor<::test_inheritance::SuperFooResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, int64_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::y, 0});
  static constexpr auto kPadding = std::make_tuple();
};

inline SuperFooRequest::SuperFooRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline SuperFooRequest::SuperFooRequest(::std::string s) noexcept
    : storage_({.s = std::move(s)}) {}
inline SuperFooRequest::SuperFooRequest(const ::test_inheritance::SuperFooRequest& other) noexcept : ::test_inheritance::SuperFooRequest(other.CloneStorage_()) {}
inline SuperFooRequest& ::test_inheritance::SuperFooRequest::operator=(const ::test_inheritance::SuperFooRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline SuperFooRequest::SuperFooRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : SuperFooRequest(Storage_{
                                                                                                          .s = {},
                                                                                                      }) {}
inline SuperFooRequest& SuperFooRequest::s(::std::string value) {
  storage_.s = std::move(value);
  return *this;
}

inline SuperFooResponse::SuperFooResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline SuperFooResponse::SuperFooResponse(int64_t y) noexcept
    : storage_({.y = std::move(y)}) {}
inline SuperFooResponse::SuperFooResponse(const ::test_inheritance::SuperFooResponse& other) noexcept : ::test_inheritance::SuperFooResponse(other.CloneStorage_()) {}
inline SuperFooResponse& ::test_inheritance::SuperFooResponse::operator=(const ::test_inheritance::SuperFooResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline SuperFooResponse::SuperFooResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : SuperFooResponse(Storage_{
                                                                                                            .y = {},
                                                                                                        }) {}
inline SuperFooResponse& SuperFooResponse::y(int64_t value) {
  storage_.y = std::move(value);
  return *this;
}

}  // namespace test_inheritance
namespace fidl {

template <>
struct IsFidlType<::test_inheritance::SuperFooRequest> : public std::true_type {};

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

template <>
struct IsStruct<::test_inheritance::SuperFooRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_inheritance::SuperFooRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_inheritance::SuperFooRequest, 16> {};

template <>
struct IsFidlType<::test_inheritance::SuperFooResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_inheritance::SuperFooResponse> {
  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_inheritance::SuperFooResponse> : public std::true_type {};

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

#pragma clang diagnostic pop

}  // namespace fidl
