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

#pragma once

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

namespace test {
namespace struct_ {

//
// Domain objects declarations
//

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

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

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

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

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

template <>
struct Equality<::test::struct_::Simple> {
  bool operator()(const ::test::struct_::Simple& _lhs, const ::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<::test::struct_::BasicStruct>
    : public EncodableCodingTraits<::test::struct_::BasicStruct, 24> {};

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

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

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

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