// 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 vectors {

class ExampleUseOfVectors;

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

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

  ::std::vector<::std::vector<bool>> vector_of_vector_of_bool{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset);
  static void Decode(::fidl::Decoder* _decoder, ExampleUseOfVectors* value,
                     size_t _offset);
  zx_status_t Clone(ExampleUseOfVectors* result) const;
};

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

using ExampleUseOfVectorsPtr = ::std::unique_ptr<ExampleUseOfVectors>;
}  // namespace vectors
}  // namespace test
}  // namespace fidl
namespace fidl {

template <>
struct CodingTraits<::fidl::test::vectors::ExampleUseOfVectors>
    : public EncodableCodingTraits<::fidl::test::vectors::ExampleUseOfVectors,
                                   32> {};

template <>
struct HasPadding<::fidl::test::vectors::ExampleUseOfVectors>
    : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fidl::test::vectors::ExampleUseOfVectors>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::vectors::ExampleUseOfVectors>::value &&
          IsMemcpyCompatible<::std::vector<::std::vector<bool>>>::value &&
          IsMemcpyCompatible<::std::vector<uint8_t>>::value> {};

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

template <>
struct Equality<::fidl::test::vectors::ExampleUseOfVectors> {
  bool operator()(
      const ::fidl::test::vectors::ExampleUseOfVectors& _lhs,
      const ::fidl::test::vectors::ExampleUseOfVectors& _rhs) const {
    if (!::fidl::Equals(_lhs.vector_of_uint8, _rhs.vector_of_uint8)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.vector_of_vector_of_bool,
                        _rhs.vector_of_vector_of_bool)) {
      return false;
    }
    return true;
  }
};
}  // namespace fidl

//
// Proxies and stubs declarations
//
namespace fidl {
namespace test {
namespace vectors {}  // namespace vectors
}  // namespace test
}  // namespace fidl
