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

#pragma once

#include <fidl/test.drivertwoway/cpp/common_types.h>
#include <fidl/test.drivertwoway/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_drivertwoway {
class TwoWayAddTopResponse;

class TwoWayAddRequest;

extern "C" const fidl_type_t test_drivertwoway_TwoWayAddTopResponseTable;

class TwoWayAddTopResponse {
 private:
  struct Storage_;

 public:
  TwoWayAddTopResponse(Storage_ storage) noexcept
      : storage_(std::move(storage)) {}
  TwoWayAddTopResponse(uint16_t sum) noexcept
      : storage_({.sum = std::move(sum)}) {}

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

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

  bool operator==(const TwoWayAddTopResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<
        ::test_drivertwoway::TwoWayAddTopResponse, 2>::Equal(this, &other);
  }
  bool operator!=(const TwoWayAddTopResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<
        ::test_drivertwoway::TwoWayAddTopResponse, 2>::Equal(this, &other);
  }

  uint16_t sum() const { return storage_.sum; }

  uint16_t& sum() { return storage_.sum; }

  TwoWayAddTopResponse(
      ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : TwoWayAddTopResponse(Storage_{
            .sum = {},
        }) {}

 private:
  struct Storage_ final {
    uint16_t sum = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_drivertwoway::TwoWayAddTopResponse, 2>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_drivertwoway::TwoWayAddTopResponse>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::sum, 0});
  static constexpr auto kPadding = std::make_tuple();
};

extern "C" const fidl_type_t test_drivertwoway_TwoWayAddRequestTable;

class TwoWayAddRequest {
 private:
  struct Storage_;

 public:
  TwoWayAddRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  TwoWayAddRequest(uint16_t addend1, uint16_t addend2) noexcept
      : storage_(
            {.addend1 = std::move(addend1), .addend2 = std::move(addend2)}) {}

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

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

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

  uint16_t addend1() const { return storage_.addend1; }

  uint16_t& addend1() { return storage_.addend1; }

  uint16_t addend2() const { return storage_.addend2; }

  uint16_t& addend2() { return storage_.addend2; }

  TwoWayAddRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : TwoWayAddRequest(Storage_{
            .addend1 = {},
            .addend2 = {},
        }) {}

 private:
  struct Storage_ final {
    uint16_t addend1 = {};
    uint16_t addend2 = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<
      ::test_drivertwoway::TwoWayAddRequest, 4>;
  friend struct ::fidl::internal::MemberVisitor<
      ::test_drivertwoway::TwoWayAddRequest>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalStructMember<
          Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::addend1, 0},
      ::fidl::internal::NaturalStructMember<
          Storage_, uint16_t, fidl::internal::NaturalCodingConstraintEmpty>{
          &Storage_::addend2, 2});
  static constexpr auto kPadding = std::make_tuple();
};

}  // namespace test_drivertwoway
namespace fidl {

extern "C" const fidl_type_t test_drivertwoway_TwoWayAddTopResponseTable;

template <>
struct IsFidlType<::test_drivertwoway::TwoWayAddTopResponse>
    : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_drivertwoway::TwoWayAddTopResponse>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_drivertwoway_TwoWayAddTopResponseTable;
};

template <>
struct internal::NaturalCodingTraits<
    ::test_drivertwoway::TwoWayAddTopResponse,
    ::fidl::internal::NaturalCodingConstraintEmpty>
    final : public ::fidl::internal::NaturalStructCodingTraits<
                ::test_drivertwoway::TwoWayAddTopResponse, 2> {};

extern "C" const fidl_type_t test_drivertwoway_TwoWayAddRequestTable;

template <>
struct IsFidlType<::test_drivertwoway::TwoWayAddRequest>
    : public std::true_type {};

template <>
struct ::fidl::internal::TypeTraits<::test_drivertwoway::TwoWayAddRequest>
    final {
 public:
  static constexpr const fidl_type_t* kCodingTable =
      &test_drivertwoway_TwoWayAddRequestTable;
};

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

}  // namespace fidl
