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

// fidl_experiment = output_index_json

#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
