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

#pragma once

#include "lib/fidl/cpp/internal/natural_types_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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info =
                  cpp17::nullopt);
  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
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
