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

// fidl_experiment = output_index_json

#pragma once

#include "lib/fidl/cpp/internal/header.h"

namespace test {
namespace drivertwoway {

//
// Domain objects declarations
//

class TwoWayAddRequest;

class TwoWayAddResponse;

class TwoWayAddRequest final {
 public:
  static const fidl_type_t* FidlType;

  uint16_t addend1{};

  uint16_t addend2{};

  static inline ::std::unique_ptr<TwoWayAddRequest> New() { return ::std::make_unique<TwoWayAddRequest>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TwoWayAddRequest* value, size_t _offset);
  zx_status_t Clone(TwoWayAddRequest* result) const;
};

inline zx_status_t Clone(const ::test::drivertwoway::TwoWayAddRequest& _value,
                         ::test::drivertwoway::TwoWayAddRequest* _result) {
  return _value.Clone(_result);
}

using TwoWayAddRequestPtr = ::std::unique_ptr<TwoWayAddRequest>;

class TwoWayAddResponse final {
 public:
  static const fidl_type_t* FidlType;

  uint16_t sum{};

  static inline ::std::unique_ptr<TwoWayAddResponse> New() { return ::std::make_unique<TwoWayAddResponse>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TwoWayAddResponse* value, size_t _offset);
  zx_status_t Clone(TwoWayAddResponse* result) const;
};

inline zx_status_t Clone(const ::test::drivertwoway::TwoWayAddResponse& _value,
                         ::test::drivertwoway::TwoWayAddResponse* _result) {
  return _value.Clone(_result);
}

using TwoWayAddResponsePtr = ::std::unique_ptr<TwoWayAddResponse>;

}  // namespace drivertwoway
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::drivertwoway::TwoWayAddRequest>
    : public EncodableCodingTraits<::test::drivertwoway::TwoWayAddRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::drivertwoway::TwoWayAddRequest> : public internal::BoolConstant<
                                                                        !HasPadding<::test::drivertwoway::TwoWayAddRequest>::value && IsMemcpyCompatible<uint16_t>::value> {};

inline zx_status_t Clone(const ::test::drivertwoway::TwoWayAddRequest& value,
                         ::test::drivertwoway::TwoWayAddRequest* result) {
  return ::test::drivertwoway::Clone(value, result);
}

template <>
struct Equality<::test::drivertwoway::TwoWayAddRequest> {
  bool operator()(const ::test::drivertwoway::TwoWayAddRequest& _lhs, const ::test::drivertwoway::TwoWayAddRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.addend1, _rhs.addend1)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.addend2, _rhs.addend2)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::drivertwoway::TwoWayAddResponse>
    : public EncodableCodingTraits<::test::drivertwoway::TwoWayAddResponse, 2> {};

template <>
struct IsMemcpyCompatible<::test::drivertwoway::TwoWayAddResponse> : public internal::BoolConstant<
                                                                         !HasPadding<::test::drivertwoway::TwoWayAddResponse>::value && IsMemcpyCompatible<uint16_t>::value> {};

inline zx_status_t Clone(const ::test::drivertwoway::TwoWayAddResponse& value,
                         ::test::drivertwoway::TwoWayAddResponse* result) {
  return ::test::drivertwoway::Clone(value, result);
}

template <>
struct Equality<::test::drivertwoway::TwoWayAddResponse> {
  bool operator()(const ::test::drivertwoway::TwoWayAddResponse& _lhs, const ::test::drivertwoway::TwoWayAddResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.sum, _rhs.sum)) {
      return false;
    }
    return true;
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
