// 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 unionsandwich {

//
// Domain objects declarations
//

class UnionSize8Alignment4;

class SandwichUnionSize8Alignment4;

class UnionSize12Alignment4;

class SandwichUnionSize12Alignment4;

class StructSize16Alignment8;

class UnionSize24Alignment8;

class SandwichUnionSize24Alignment8;

class UnionSize36Alignment4;

class SandwichUnionSize36Alignment4;

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

  UnionSize8Alignment4();
  ~UnionSize8Alignment4();

  UnionSize8Alignment4(UnionSize8Alignment4&&);
  UnionSize8Alignment4& operator=(UnionSize8Alignment4&&);

  static UnionSize8Alignment4 WithVariant(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kVariant = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

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

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_variant() const { return tag_ == ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant; }

  uint32_t& variant() {
    EnsureStorageInitialized(::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant);
    return variant_;
  }

  const uint32_t& variant() const {
    ZX_ASSERT(is_variant());
    return variant_;
  }
  UnionSize8Alignment4& set_variant(uint32_t value);

  ::test::unionsandwich::UnionSize8Alignment4::Tag Which() const {
    return ::test::unionsandwich::UnionSize8Alignment4::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::unionsandwich::UnionSize8Alignment4>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize8Alignment4::Tag::Invalid);
  union {
    uint32_t variant_;
  };
};

inline zx_status_t Clone(const ::test::unionsandwich::UnionSize8Alignment4& value,
                         ::test::unionsandwich::UnionSize8Alignment4* result) {
  return value.Clone(result);
}

using UnionSize8Alignment4Ptr = ::std::unique_ptr<UnionSize8Alignment4>;

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

  uint32_t before{};

  ::test::unionsandwich::UnionSize8Alignment4 union_;

  uint32_t after{};

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

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

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

using SandwichUnionSize8Alignment4Ptr = ::std::unique_ptr<SandwichUnionSize8Alignment4>;

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

  UnionSize12Alignment4();
  ~UnionSize12Alignment4();

  UnionSize12Alignment4(UnionSize12Alignment4&&);
  UnionSize12Alignment4& operator=(UnionSize12Alignment4&&);

  static UnionSize12Alignment4 WithVariant(::std::array<uint8_t, 6>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kVariant = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

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

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_variant() const { return tag_ == ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant; }

  ::std::array<uint8_t, 6>& variant() {
    EnsureStorageInitialized(::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant);
    return variant_;
  }

  const ::std::array<uint8_t, 6>& variant() const {
    ZX_ASSERT(is_variant());
    return variant_;
  }
  UnionSize12Alignment4& set_variant(::std::array<uint8_t, 6> value);

  ::test::unionsandwich::UnionSize12Alignment4::Tag Which() const {
    return ::test::unionsandwich::UnionSize12Alignment4::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::unionsandwich::UnionSize12Alignment4>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize12Alignment4::Tag::Invalid);
  union {
    ::std::array<uint8_t, 6> variant_;
  };
};

inline zx_status_t Clone(const ::test::unionsandwich::UnionSize12Alignment4& value,
                         ::test::unionsandwich::UnionSize12Alignment4* result) {
  return value.Clone(result);
}

using UnionSize12Alignment4Ptr = ::std::unique_ptr<UnionSize12Alignment4>;

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

  uint32_t before{};

  ::test::unionsandwich::UnionSize12Alignment4 union_;

  int32_t after{};

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

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

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

using SandwichUnionSize12Alignment4Ptr = ::std::unique_ptr<SandwichUnionSize12Alignment4>;

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

  uint64_t f1{};

  uint64_t f2{};

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

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

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

using StructSize16Alignment8Ptr = ::std::unique_ptr<StructSize16Alignment8>;

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

  UnionSize24Alignment8();
  ~UnionSize24Alignment8();

  UnionSize24Alignment8(UnionSize24Alignment8&&);
  UnionSize24Alignment8& operator=(UnionSize24Alignment8&&);

  static UnionSize24Alignment8 WithVariant(::test::unionsandwich::StructSize16Alignment8&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kVariant = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

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

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_variant() const { return tag_ == ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant; }

  ::test::unionsandwich::StructSize16Alignment8& variant() {
    EnsureStorageInitialized(::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant);
    return variant_;
  }

  const ::test::unionsandwich::StructSize16Alignment8& variant() const {
    ZX_ASSERT(is_variant());
    return variant_;
  }
  UnionSize24Alignment8& set_variant(::test::unionsandwich::StructSize16Alignment8 value);

  ::test::unionsandwich::UnionSize24Alignment8::Tag Which() const {
    return ::test::unionsandwich::UnionSize24Alignment8::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::unionsandwich::UnionSize24Alignment8>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize24Alignment8::Tag::Invalid);
  union {
    ::test::unionsandwich::StructSize16Alignment8 variant_;
  };
};

inline zx_status_t Clone(const ::test::unionsandwich::UnionSize24Alignment8& value,
                         ::test::unionsandwich::UnionSize24Alignment8* result) {
  return value.Clone(result);
}

using UnionSize24Alignment8Ptr = ::std::unique_ptr<UnionSize24Alignment8>;

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

  uint32_t before{};

  ::test::unionsandwich::UnionSize24Alignment8 union_;

  uint32_t after{};

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

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

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

using SandwichUnionSize24Alignment8Ptr = ::std::unique_ptr<SandwichUnionSize24Alignment8>;

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

  UnionSize36Alignment4();
  ~UnionSize36Alignment4();

  UnionSize36Alignment4(UnionSize36Alignment4&&);
  UnionSize36Alignment4& operator=(UnionSize36Alignment4&&);

  static UnionSize36Alignment4 WithVariant(::std::array<uint8_t, 32>&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kVariant = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

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

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_variant() const { return tag_ == ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant; }

  ::std::array<uint8_t, 32>& variant() {
    EnsureStorageInitialized(::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant);
    return variant_;
  }

  const ::std::array<uint8_t, 32>& variant() const {
    ZX_ASSERT(is_variant());
    return variant_;
  }
  UnionSize36Alignment4& set_variant(::std::array<uint8_t, 32> value);

  ::test::unionsandwich::UnionSize36Alignment4::Tag Which() const {
    return ::test::unionsandwich::UnionSize36Alignment4::Tag(tag_);
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }

  friend ::fidl::Equality<::test::unionsandwich::UnionSize36Alignment4>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize36Alignment4::Tag::Invalid);
  union {
    ::std::array<uint8_t, 32> variant_;
  };
};

inline zx_status_t Clone(const ::test::unionsandwich::UnionSize36Alignment4& value,
                         ::test::unionsandwich::UnionSize36Alignment4* result) {
  return value.Clone(result);
}

using UnionSize36Alignment4Ptr = ::std::unique_ptr<UnionSize36Alignment4>;

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

  uint32_t before{};

  ::test::unionsandwich::UnionSize36Alignment4 union_;

  uint32_t after{};

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

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

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

using SandwichUnionSize36Alignment4Ptr = ::std::unique_ptr<SandwichUnionSize36Alignment4>;

}  // namespace unionsandwich
}  // namespace test
namespace fidl {

template <>
struct IsFidlXUnion<::test::unionsandwich::UnionSize8Alignment4> : public std::true_type {};

template <>
struct CodingTraits<::test::unionsandwich::UnionSize8Alignment4>
    : public EncodableCodingTraits<::test::unionsandwich::UnionSize8Alignment4, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::unionsandwich::UnionSize8Alignment4>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::unionsandwich::UnionSize8Alignment4>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::unionsandwich::UnionSize8Alignment4>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::unionsandwich::UnionSize8Alignment4);

    ::test::unionsandwich::UnionSize8Alignment4::Decode(_decoder, value->get(), offset);
  }
};

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

template <>
struct Equality<::test::unionsandwich::UnionSize8Alignment4> {
  bool operator()(const ::test::unionsandwich::UnionSize8Alignment4& _lhs, const ::test::unionsandwich::UnionSize8Alignment4& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize8Alignment4::Tag::Invalid):
        return true;
      case ::test::unionsandwich::UnionSize8Alignment4::Tag::kVariant:
        return ::fidl::Equals(_lhs.variant_, _rhs.variant_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::unionsandwich::SandwichUnionSize8Alignment4>
    : public EncodableCodingTraits<::test::unionsandwich::SandwichUnionSize8Alignment4, 32> {};

template <>
struct HasPadding<::test::unionsandwich::SandwichUnionSize8Alignment4> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::unionsandwich::SandwichUnionSize8Alignment4> : public internal::BoolConstant<
                                                                                     !HasPadding<::test::unionsandwich::SandwichUnionSize8Alignment4>::value && IsMemcpyCompatible<uint32_t>::value && IsMemcpyCompatible<::test::unionsandwich::UnionSize8Alignment4>::value> {};

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

template <>
struct Equality<::test::unionsandwich::SandwichUnionSize8Alignment4> {
  bool operator()(const ::test::unionsandwich::SandwichUnionSize8Alignment4& _lhs, const ::test::unionsandwich::SandwichUnionSize8Alignment4& _rhs) const {
    if (!::fidl::Equals(_lhs.before, _rhs.before)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.union_, _rhs.union_)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.after, _rhs.after)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::unionsandwich::UnionSize12Alignment4> : public std::true_type {};

template <>
struct CodingTraits<::test::unionsandwich::UnionSize12Alignment4>
    : public EncodableCodingTraits<::test::unionsandwich::UnionSize12Alignment4, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::unionsandwich::UnionSize12Alignment4>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::unionsandwich::UnionSize12Alignment4>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::unionsandwich::UnionSize12Alignment4>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::unionsandwich::UnionSize12Alignment4);

    ::test::unionsandwich::UnionSize12Alignment4::Decode(_decoder, value->get(), offset);
  }
};

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

template <>
struct Equality<::test::unionsandwich::UnionSize12Alignment4> {
  bool operator()(const ::test::unionsandwich::UnionSize12Alignment4& _lhs, const ::test::unionsandwich::UnionSize12Alignment4& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize12Alignment4::Tag::Invalid):
        return true;
      case ::test::unionsandwich::UnionSize12Alignment4::Tag::kVariant:
        return ::fidl::Equals(_lhs.variant_, _rhs.variant_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::unionsandwich::SandwichUnionSize12Alignment4>
    : public EncodableCodingTraits<::test::unionsandwich::SandwichUnionSize12Alignment4, 32> {};

template <>
struct HasPadding<::test::unionsandwich::SandwichUnionSize12Alignment4> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::unionsandwich::SandwichUnionSize12Alignment4> : public internal::BoolConstant<
                                                                                      !HasPadding<::test::unionsandwich::SandwichUnionSize12Alignment4>::value && IsMemcpyCompatible<uint32_t>::value && IsMemcpyCompatible<::test::unionsandwich::UnionSize12Alignment4>::value && IsMemcpyCompatible<int32_t>::value> {};

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

template <>
struct Equality<::test::unionsandwich::SandwichUnionSize12Alignment4> {
  bool operator()(const ::test::unionsandwich::SandwichUnionSize12Alignment4& _lhs, const ::test::unionsandwich::SandwichUnionSize12Alignment4& _rhs) const {
    if (!::fidl::Equals(_lhs.before, _rhs.before)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.union_, _rhs.union_)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.after, _rhs.after)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::unionsandwich::StructSize16Alignment8>
    : public EncodableCodingTraits<::test::unionsandwich::StructSize16Alignment8, 16> {};

template <>
struct IsMemcpyCompatible<::test::unionsandwich::StructSize16Alignment8> : public internal::BoolConstant<
                                                                               !HasPadding<::test::unionsandwich::StructSize16Alignment8>::value && IsMemcpyCompatible<uint64_t>::value> {};

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

template <>
struct Equality<::test::unionsandwich::StructSize16Alignment8> {
  bool operator()(const ::test::unionsandwich::StructSize16Alignment8& _lhs, const ::test::unionsandwich::StructSize16Alignment8& _rhs) const {
    if (!::fidl::Equals(_lhs.f1, _rhs.f1)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.f2, _rhs.f2)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::unionsandwich::UnionSize24Alignment8> : public std::true_type {};

template <>
struct CodingTraits<::test::unionsandwich::UnionSize24Alignment8>
    : public EncodableCodingTraits<::test::unionsandwich::UnionSize24Alignment8, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::unionsandwich::UnionSize24Alignment8>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::unionsandwich::UnionSize24Alignment8>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::unionsandwich::UnionSize24Alignment8>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::unionsandwich::UnionSize24Alignment8);

    ::test::unionsandwich::UnionSize24Alignment8::Decode(_decoder, value->get(), offset);
  }
};

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

template <>
struct Equality<::test::unionsandwich::UnionSize24Alignment8> {
  bool operator()(const ::test::unionsandwich::UnionSize24Alignment8& _lhs, const ::test::unionsandwich::UnionSize24Alignment8& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize24Alignment8::Tag::Invalid):
        return true;
      case ::test::unionsandwich::UnionSize24Alignment8::Tag::kVariant:
        return ::fidl::Equals(_lhs.variant_, _rhs.variant_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::unionsandwich::SandwichUnionSize24Alignment8>
    : public EncodableCodingTraits<::test::unionsandwich::SandwichUnionSize24Alignment8, 32> {};

template <>
struct HasPadding<::test::unionsandwich::SandwichUnionSize24Alignment8> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::unionsandwich::SandwichUnionSize24Alignment8> : public internal::BoolConstant<
                                                                                      !HasPadding<::test::unionsandwich::SandwichUnionSize24Alignment8>::value && IsMemcpyCompatible<uint32_t>::value && IsMemcpyCompatible<::test::unionsandwich::UnionSize24Alignment8>::value> {};

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

template <>
struct Equality<::test::unionsandwich::SandwichUnionSize24Alignment8> {
  bool operator()(const ::test::unionsandwich::SandwichUnionSize24Alignment8& _lhs, const ::test::unionsandwich::SandwichUnionSize24Alignment8& _rhs) const {
    if (!::fidl::Equals(_lhs.before, _rhs.before)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.union_, _rhs.union_)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.after, _rhs.after)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::unionsandwich::UnionSize36Alignment4> : public std::true_type {};

template <>
struct CodingTraits<::test::unionsandwich::UnionSize36Alignment4>
    : public EncodableCodingTraits<::test::unionsandwich::UnionSize36Alignment4, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::unionsandwich::UnionSize36Alignment4>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::unionsandwich::UnionSize36Alignment4>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::unionsandwich::UnionSize36Alignment4>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::unionsandwich::UnionSize36Alignment4);

    ::test::unionsandwich::UnionSize36Alignment4::Decode(_decoder, value->get(), offset);
  }
};

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

template <>
struct Equality<::test::unionsandwich::UnionSize36Alignment4> {
  bool operator()(const ::test::unionsandwich::UnionSize36Alignment4& _lhs, const ::test::unionsandwich::UnionSize36Alignment4& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::unionsandwich::UnionSize36Alignment4::Tag::Invalid):
        return true;
      case ::test::unionsandwich::UnionSize36Alignment4::Tag::kVariant:
        return ::fidl::Equals(_lhs.variant_, _rhs.variant_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::unionsandwich::SandwichUnionSize36Alignment4>
    : public EncodableCodingTraits<::test::unionsandwich::SandwichUnionSize36Alignment4, 32> {};

template <>
struct HasPadding<::test::unionsandwich::SandwichUnionSize36Alignment4> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::unionsandwich::SandwichUnionSize36Alignment4> : public internal::BoolConstant<
                                                                                      !HasPadding<::test::unionsandwich::SandwichUnionSize36Alignment4>::value && IsMemcpyCompatible<uint32_t>::value && IsMemcpyCompatible<::test::unionsandwich::UnionSize36Alignment4>::value> {};

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

template <>
struct Equality<::test::unionsandwich::SandwichUnionSize36Alignment4> {
  bool operator()(const ::test::unionsandwich::SandwichUnionSize36Alignment4& _lhs, const ::test::unionsandwich::SandwichUnionSize36Alignment4& _rhs) const {
    if (!::fidl::Equals(_lhs.before, _rhs.before)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.union_, _rhs.union_)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.after, _rhs.after)) {
      return false;
    }
    return true;
  }
};

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