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

#pragma once

#include <test/someotherlibrary/cpp/fidl.h>

#include "lib/fidl/cpp/internal/header.h"
namespace test {
namespace typealiases {

//
// Domain objects declarations
//

enum class obj_type : uint32_t {

  NONE = 0u,

  CHANNEL = 4u,
};

inline zx_status_t Clone(::test::typealiases::obj_type value,
                         ::test::typealiases::obj_type* result) {
  *result = value;
  return ZX_OK;
}

class ExampleOfUseOfAliases;

#ifdef __Fuchsia__

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

  uint32_t field_of_u32{};

  ::std::vector<::std::string> field_of_vec_of_strings{};

  ::std::vector<::std::string> field_of_vec_of_strings_at_most_nine{};

  ::std::vector<::std::string> field_of_vec_of_strings_at_most_5{};

  ::std::vector<::test::someotherlibrary::ReferenceMe> field_of_vec_of_ref_me_at_most_5{};

  ::zx::channel field_of_channel{};

  ::zx::channel field_of_client_end{};

  ::zx::channel field_of_nullable_client_end{};

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

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

inline zx_status_t Clone(const ::test::typealiases::ExampleOfUseOfAliases& _value,
                         ::test::typealiases::ExampleOfUseOfAliases* _result) {
  return _value.Clone(_result);
}

using ExampleOfUseOfAliasesPtr = ::std::unique_ptr<ExampleOfUseOfAliases>;
#endif  // __Fuchsia__

}  // namespace typealiases
}  // namespace test
namespace fidl {
template <>
struct CodingTraits<::test::typealiases::obj_type> {
  static constexpr size_t inline_size_v2 = sizeof(::test::typealiases::obj_type);
  static void Encode(Encoder* encoder, ::test::typealiases::obj_type* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::typealiases::obj_type* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::typealiases::obj_type>(underlying);
  }
};

inline zx_status_t Clone(::test::typealiases::obj_type value,
                         ::test::typealiases::obj_type* result) {
  return ::test::typealiases::Clone(value, result);
}
template <>
struct Equality<::test::typealiases::obj_type> {
  bool operator()(const ::test::typealiases::obj_type& _lhs, const ::test::typealiases::obj_type& _rhs) const {
    return _lhs == _rhs;
  }
};

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::typealiases::ExampleOfUseOfAliases>
    : public EncodableCodingTraits<::test::typealiases::ExampleOfUseOfAliases, 88> {};

template <>
struct HasPadding<::test::typealiases::ExampleOfUseOfAliases> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::typealiases::ExampleOfUseOfAliases> : public internal::BoolConstant<
                                                                            !HasPadding<::test::typealiases::ExampleOfUseOfAliases>::value && IsMemcpyCompatible<uint32_t>::value && IsMemcpyCompatible<::std::vector<::std::string>>::value && IsMemcpyCompatible<::std::vector<::test::someotherlibrary::ReferenceMe>>::value && IsMemcpyCompatible<::zx::channel>::value> {};

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

template <>
struct Equality<::test::typealiases::ExampleOfUseOfAliases> {
  bool operator()(const ::test::typealiases::ExampleOfUseOfAliases& _lhs, const ::test::typealiases::ExampleOfUseOfAliases& _rhs) const {
    if (!::fidl::Equals(_lhs.field_of_u32, _rhs.field_of_u32)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_vec_of_strings, _rhs.field_of_vec_of_strings)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_vec_of_strings_at_most_nine, _rhs.field_of_vec_of_strings_at_most_nine)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_vec_of_strings_at_most_5, _rhs.field_of_vec_of_strings_at_most_5)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_vec_of_ref_me_at_most_5, _rhs.field_of_vec_of_ref_me_at_most_5)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_channel, _rhs.field_of_channel)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_client_end, _rhs.field_of_client_end)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.field_of_nullable_client_end, _rhs.field_of_nullable_client_end)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

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