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

#pragma once

#include <zx/cpp/natural_types.h>

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

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace nullable {
class StructWithNullableVector;

class StructWithNullableUnion;

class StructWithNullableStruct;

class StructWithNullableString;

class StructWithNullableRequest;

class StructWithNullableProtocol;

class StructWithNullableHandle;

#ifdef __Fuchsia__

class SimpleProtocol;
using SimpleProtocolHandle = ::fidl::InterfaceHandle<SimpleProtocol>;
#endif  // __Fuchsia__

class SimpleUnion;

class Int32Wrapper;

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

  ::fidl::VectorPtr<int32_t> val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableVector& _value,
    ::fidl::test::nullable::StructWithNullableVector* _result) {
  return _value.Clone(_result);
}

using StructWithNullableVectorPtr = ::std::unique_ptr<StructWithNullableVector>;

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

  ::std::unique_ptr<::fidl::test::nullable::SimpleUnion> val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableUnion& _value,
    ::fidl::test::nullable::StructWithNullableUnion* _result) {
  return _value.Clone(_result);
}

using StructWithNullableUnionPtr = ::std::unique_ptr<StructWithNullableUnion>;

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

  ::std::unique_ptr<::fidl::test::nullable::Int32Wrapper> val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableStruct& _value,
    ::fidl::test::nullable::StructWithNullableStruct* _result) {
  return _value.Clone(_result);
}

using StructWithNullableStructPtr = ::std::unique_ptr<StructWithNullableStruct>;

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

  ::fidl::StringPtr val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableString& _value,
    ::fidl::test::nullable::StructWithNullableString* _result) {
  return _value.Clone(_result);
}

using StructWithNullableStringPtr = ::std::unique_ptr<StructWithNullableString>;

#ifdef __Fuchsia__

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

  ::fidl::InterfaceRequest<::fidl::test::nullable::SimpleProtocol> val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableRequest& _value,
    ::fidl::test::nullable::StructWithNullableRequest* _result) {
  return _value.Clone(_result);
}

using StructWithNullableRequestPtr =
    ::std::unique_ptr<StructWithNullableRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceHandle<::fidl::test::nullable::SimpleProtocol> val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableProtocol& _value,
    ::fidl::test::nullable::StructWithNullableProtocol* _result) {
  return _value.Clone(_result);
}

using StructWithNullableProtocolPtr =
    ::std::unique_ptr<StructWithNullableProtocol>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::vmo val{};

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

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

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableHandle& _value,
    ::fidl::test::nullable::StructWithNullableHandle* _result) {
  return _value.Clone(_result);
}

using StructWithNullableHandlePtr = ::std::unique_ptr<StructWithNullableHandle>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t fidl_test_nullable_SimpleProtocolAddRequestTable;

}  // namespace _internal
class SimpleProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Add(::fidl::Encoder* _encoder, int32_t* a,
                                          int32_t* b) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, a, 16);

    ::fidl::Encode(_encoder, b, 20);

    fidl_trace(DidHLCPPEncode,
               &::fidl::test::nullable::_internal::
                   fidl_test_nullable_SimpleProtocolAddRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};
namespace _internal {
extern "C" const fidl_type_t fidl_test_nullable_SimpleProtocolAddResponseTable;

}  // namespace _internal
class SimpleProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Add(::fidl::Encoder* _encoder,
                                          int32_t* sum) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, sum, 16);

    fidl_trace(DidHLCPPEncode,
               &::fidl::test::nullable::_internal::
                   fidl_test_nullable_SimpleProtocolAddResponseTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

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

  SimpleUnion();
  ~SimpleUnion();

  SimpleUnion(SimpleUnion&&);
  SimpleUnion& operator=(SimpleUnion&&);

  static SimpleUnion WithA(int32_t&&);
  static SimpleUnion WithB(float&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kA = 1,  // 0x1
    kB = 2,  // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  static void Decode(::fidl::Decoder* decoder, SimpleUnion* value,
                     size_t offset);
  zx_status_t Clone(SimpleUnion* result) const;

  bool has_invalid_tag() const { return tag_ == Invalid; }

  bool is_a() const {
    return tag_ == ::fidl::test::nullable::SimpleUnion::Tag::kA;
  }

  int32_t& a() {
    EnsureStorageInitialized(::fidl::test::nullable::SimpleUnion::Tag::kA);
    return a_;
  }

  const int32_t& a() const {
    ZX_ASSERT(is_a());
    return a_;
  }
  SimpleUnion& set_a(int32_t value);

  bool is_b() const {
    return tag_ == ::fidl::test::nullable::SimpleUnion::Tag::kB;
  }

  float& b() {
    EnsureStorageInitialized(::fidl::test::nullable::SimpleUnion::Tag::kB);
    return b_;
  }

  const float& b() const {
    ZX_ASSERT(is_b());
    return b_;
  }
  SimpleUnion& set_b(float value);

  ::fidl::test::nullable::SimpleUnion::Tag Which() const {
    return ::fidl::test::nullable::SimpleUnion::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal()
  // only when you need access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const { return tag_; }

  friend ::fidl::Equality<::fidl::test::nullable::SimpleUnion>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(
      ::fidl::test::nullable::SimpleUnion::Tag::Invalid);
  union {
    int32_t a_;
    float b_;
  };
};

inline zx_status_t Clone(const ::fidl::test::nullable::SimpleUnion& value,
                         ::fidl::test::nullable::SimpleUnion* result) {
  return value.Clone(result);
}

using SimpleUnionPtr = ::std::unique_ptr<SimpleUnion>;

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

  int32_t val{};

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

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

inline zx_status_t Clone(const ::fidl::test::nullable::Int32Wrapper& _value,
                         ::fidl::test::nullable::Int32Wrapper* _result) {
  return _value.Clone(_result);
}

using Int32WrapperPtr = ::std::unique_ptr<Int32Wrapper>;

}  // namespace nullable
}  // namespace test
template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableVector>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableVector, 16> {};

template <>
struct HasPadding<::fidl::test::nullable::StructWithNullableVector>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableVector>
    : public internal::BoolConstant<
          !HasPadding<
              ::fidl::test::nullable::StructWithNullableVector>::value &&
          IsMemcpyCompatible<::fidl::VectorPtr<int32_t>>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableVector& value,
    ::fidl::test::nullable::StructWithNullableVector* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableVector> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableVector& _lhs,
      const ::fidl::test::nullable::StructWithNullableVector& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableUnion>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableUnion, 24> {};

template <>
struct HasPadding<::fidl::test::nullable::StructWithNullableUnion>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableUnion>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::nullable::StructWithNullableUnion>::value &&
          IsMemcpyCompatible<
              ::std::unique_ptr<::fidl::test::nullable::SimpleUnion>>::value> {
};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableUnion& value,
    ::fidl::test::nullable::StructWithNullableUnion* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableUnion> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableUnion& _lhs,
      const ::fidl::test::nullable::StructWithNullableUnion& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableStruct>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableStruct, 8> {};

template <>
struct HasPadding<::fidl::test::nullable::StructWithNullableStruct>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableStruct>
    : public internal::BoolConstant<
          !HasPadding<
              ::fidl::test::nullable::StructWithNullableStruct>::value &&
          IsMemcpyCompatible<
              ::std::unique_ptr<::fidl::test::nullable::Int32Wrapper>>::value> {
};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableStruct& value,
    ::fidl::test::nullable::StructWithNullableStruct* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableStruct> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableStruct& _lhs,
      const ::fidl::test::nullable::StructWithNullableStruct& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableString>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableString, 16> {};

template <>
struct HasPadding<::fidl::test::nullable::StructWithNullableString>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableString>
    : public internal::BoolConstant<
          !HasPadding<
              ::fidl::test::nullable::StructWithNullableString>::value &&
          IsMemcpyCompatible<::fidl::StringPtr>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableString& value,
    ::fidl::test::nullable::StructWithNullableString* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableString> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableString& _lhs,
      const ::fidl::test::nullable::StructWithNullableString& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableRequest>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableRequest, 4> {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableRequest>
    : public internal::BoolConstant<
          !HasPadding<
              ::fidl::test::nullable::StructWithNullableRequest>::value &&
          IsMemcpyCompatible<::fidl::InterfaceRequest<
              ::fidl::test::nullable::SimpleProtocol>>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableRequest& value,
    ::fidl::test::nullable::StructWithNullableRequest* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableRequest> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableRequest& _lhs,
      const ::fidl::test::nullable::StructWithNullableRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableProtocol>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableProtocol, 4> {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableProtocol>
    : public internal::BoolConstant<
          !HasPadding<
              ::fidl::test::nullable::StructWithNullableProtocol>::value &&
          IsMemcpyCompatible<::fidl::InterfaceHandle<
              ::fidl::test::nullable::SimpleProtocol>>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableProtocol& value,
    ::fidl::test::nullable::StructWithNullableProtocol* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableProtocol> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableProtocol& _lhs,
      const ::fidl::test::nullable::StructWithNullableProtocol& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::fidl::test::nullable::StructWithNullableHandle>
    : public EncodableCodingTraits<
          ::fidl::test::nullable::StructWithNullableHandle, 4> {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::StructWithNullableHandle>
    : public internal::BoolConstant<
          !HasPadding<
              ::fidl::test::nullable::StructWithNullableHandle>::value &&
          IsMemcpyCompatible<::zx::vmo>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::nullable::StructWithNullableHandle& value,
    ::fidl::test::nullable::StructWithNullableHandle* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::StructWithNullableHandle> {
  bool operator()(
      const ::fidl::test::nullable::StructWithNullableHandle& _lhs,
      const ::fidl::test::nullable::StructWithNullableHandle& _rhs) const {
    if (!::fidl::Equals(_lhs.val, _rhs.val)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

template <>
struct IsFidlXUnion<::fidl::test::nullable::SimpleUnion>
    : public std::true_type {};

template <>
struct CodingTraits<::fidl::test::nullable::SimpleUnion>
    : public EncodableCodingTraits<::fidl::test::nullable::SimpleUnion, 24> {};

template <>
struct CodingTraits<std::unique_ptr<::fidl::test::nullable::SimpleUnion>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<::fidl::test::nullable::SimpleUnion>* value,
      size_t offset,
      cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<::fidl::test::nullable::SimpleUnion>* value,
      size_t offset) {
    fidl_xunion_t* encoded = decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::fidl::test::nullable::SimpleUnion);

    ::fidl::test::nullable::SimpleUnion::Decode(decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::fidl::test::nullable::SimpleUnion& value,
                         ::fidl::test::nullable::SimpleUnion* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

template <>
struct Equality<::fidl::test::nullable::SimpleUnion> {
  bool operator()(const ::fidl::test::nullable::SimpleUnion& _lhs,
                  const ::fidl::test::nullable::SimpleUnion& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::nullable::SimpleUnion::Tag::Invalid):
        return true;
      case ::fidl::test::nullable::SimpleUnion::Tag::kA:
        return ::fidl::Equals(_lhs.a_, _rhs.a_);
      case ::fidl::test::nullable::SimpleUnion::Tag::kB:
        return ::fidl::Equals(_lhs.b_, _rhs.b_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::fidl::test::nullable::Int32Wrapper>
    : public EncodableCodingTraits<::fidl::test::nullable::Int32Wrapper, 4> {};

template <>
struct IsMemcpyCompatible<::fidl::test::nullable::Int32Wrapper>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::nullable::Int32Wrapper>::value &&
          IsMemcpyCompatible<int32_t>::value> {};

inline zx_status_t Clone(const ::fidl::test::nullable::Int32Wrapper& value,
                         ::fidl::test::nullable::Int32Wrapper* result) {
  return ::fidl::test::nullable::Clone(value, result);
}

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

}  // namespace fidl
