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

#pragma once

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

namespace test {
namespace byteandbytes {

//
// Domain objects declarations
//

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 ::test::byteandbytes::ByteAndBytes& _value,
                         ::test::byteandbytes::ByteAndBytes* _result) {
  return _value.Clone(_result);
}

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

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

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

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

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

template <>
struct Equality<::test::byteandbytes::ByteAndBytes> {
  bool operator()(const ::test::byteandbytes::ByteAndBytes& _lhs, const ::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
