// 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 struct_ {
class Simple;

class BasicStruct;

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

  uint8_t f1{};

  bool f2{};

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

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

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

using SimplePtr = ::std::unique_ptr<Simple>;

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

  uint32_t x{};

  ::std::string y{};

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

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

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

using BasicStructPtr = ::std::unique_ptr<BasicStruct>;

}  // namespace struct_
}  // namespace test
template <>
struct CodingTraits<::fidl::test::struct_::Simple>
    : public EncodableCodingTraits<::fidl::test::struct_::Simple, 2> {};

template <>
struct IsMemcpyCompatible<::fidl::test::struct_::Simple>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::struct_::Simple>::value &&
          IsMemcpyCompatible<bool>::value &&
          IsMemcpyCompatible<uint8_t>::value> {};

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

template <>
struct Equality<::fidl::test::struct_::Simple> {
  bool operator()(const ::fidl::test::struct_::Simple& _lhs,
                  const ::fidl::test::struct_::Simple& _rhs) const {
    if (!::fidl::Equals(_lhs.f1, _rhs.f1)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.f2, _rhs.f2)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fidl::test::struct_::BasicStruct>
    : public EncodableCodingTraits<::fidl::test::struct_::BasicStruct, 24> {};

template <>
struct HasPadding<::fidl::test::struct_::BasicStruct> : public std::true_type {
};

template <>
struct IsMemcpyCompatible<::fidl::test::struct_::BasicStruct>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::struct_::BasicStruct>::value &&
          IsMemcpyCompatible<::std::string>::value &&
          IsMemcpyCompatible<uint32_t>::value> {};

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

template <>
struct Equality<::fidl::test::struct_::BasicStruct> {
  bool operator()(const ::fidl::test::struct_::BasicStruct& _lhs,
                  const ::fidl::test::struct_::BasicStruct& _rhs) const {
    if (!::fidl::Equals(_lhs.x, _rhs.x)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.y, _rhs.y)) {
      return false;
    }
    return true;
  }
};

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