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

#pragma once

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

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

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

  uint8_t single_byte{};

  ::std::vector<uint8_t> many_bytes{};

  ::std::vector<uint8_t> only_one_k_bytes{};

  ::fidl::VectorPtr<uint8_t> opt_only_one_k_bytes{};

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

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

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

using ByteAndBytesPtr = ::std::unique_ptr<ByteAndBytes>;

}  // namespace byteandbytes
}  // namespace test
template <>
struct CodingTraits<::fidl::test::byteandbytes::ByteAndBytes>
    : public EncodableCodingTraits<::fidl::test::byteandbytes::ByteAndBytes,
                                   56> {};

template <>
struct HasPadding<::fidl::test::byteandbytes::ByteAndBytes>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::byteandbytes::ByteAndBytes>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::byteandbytes::ByteAndBytes>::value &&
          IsMemcpyCompatible<::fidl::VectorPtr<uint8_t>>::value &&
          IsMemcpyCompatible<::std::vector<uint8_t>>::value &&
          IsMemcpyCompatible<uint8_t>::value> {};

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

template <>
struct Equality<::fidl::test::byteandbytes::ByteAndBytes> {
  bool operator()(const ::fidl::test::byteandbytes::ByteAndBytes& _lhs,
                  const ::fidl::test::byteandbytes::ByteAndBytes& _rhs) const {
    if (!::fidl::Equals(_lhs.single_byte, _rhs.single_byte)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.many_bytes, _rhs.many_bytes)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.only_one_k_bytes, _rhs.only_one_k_bytes)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.opt_only_one_k_bytes, _rhs.opt_only_one_k_bytes)) {
      return false;
    }
    return true;
  }
};

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