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

#pragma once

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

namespace fidl {
namespace test {
namespace structs {

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

using BasicStructPtr = ::std::unique_ptr<BasicStruct>;
}  // namespace structs
}  // namespace test
}  // namespace fidl
namespace fidl {

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

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

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

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

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

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

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

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