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

// fidl_experiment = output_index_json

#pragma once

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

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

//
// Domain objects declarations
//

enum class obj_type : uint32_t {

  NONE = 0u,

  CHANNEL = 4u,
};

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

class ExampleOfUseOfAliases;

using u32 = uint32_t;

using vec_of_strings = ::std::vector<::std::string>;

using vec_of_strings_at_most_5 = ::std::vector<::std::string>;

#ifdef __Fuchsia__

using channel = ::zx::channel;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

using alias_of_channel = ::zx::channel;

#endif  // __Fuchsia__

using ReferenceMe = ::test::someotherlibrary::ReferenceMe;

#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::aliases::ExampleOfUseOfAliases& _value,
                         ::test::aliases::ExampleOfUseOfAliases* _result) {
  return _value.Clone(_result);
}

using ExampleOfUseOfAliasesPtr = ::std::unique_ptr<ExampleOfUseOfAliases>;

#endif  // __Fuchsia__

}  // namespace aliases
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::aliases::obj_type> {
  static constexpr size_t kInlineSize = sizeof(::test::aliases::obj_type);
  static void Encode(Encoder* encoder, ::test::aliases::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::aliases::obj_type* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::aliases::obj_type>(underlying);
  }
};

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

#ifdef __Fuchsia__

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

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

template <>
struct IsMemcpyCompatible<::test::aliases::ExampleOfUseOfAliases> : public internal::BoolConstant<
                                                                        !HasPadding<::test::aliases::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::aliases::ExampleOfUseOfAliases& value,
                         ::test::aliases::ExampleOfUseOfAliases* result) {
  return ::test::aliases::Clone(value, result);
}

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