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

#pragma once

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


namespace test {
namespace name {

class Union;

class Union {
 public:
  Union();
  ~Union();

  Union(Union&&);
  Union& operator=(Union&&);

  enum class Tag : fidl_union_tag_t {
    kPrimitive = 0,
    kStringNeedsConstructor = 1,
    kVectorStringAlsoNeedsConstructor = 2,
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

  void Encode(::fidl::Encoder* encoder, size_t offset);
  static void Decode(::fidl::Decoder* decoder, Union* value, size_t offset);
  zx_status_t Clone(Union* result) const;

  bool has_invalid_tag() const { return Which() == Tag::Invalid; }

  bool is_Primitive() const { return Which() == Tag(0); }
  
  int32_t& Primitive() {
    if (!is_Primitive()) {
      value_.emplace<0 + 1>();
    }
    return value_.template get<0 + 1>();
  }
  
  const int32_t& Primitive() const { return value_.template get<0 + 1>(); }
  void set_Primitive(int32_t value);

  bool is_StringNeedsConstructor() const { return Which() == Tag(1); }
  
  ::std::string& StringNeedsConstructor() {
    if (!is_StringNeedsConstructor()) {
      value_.emplace<1 + 1>();
    }
    return value_.template get<1 + 1>();
  }
  
  const ::std::string& StringNeedsConstructor() const { return value_.template get<1 + 1>(); }
  void set_StringNeedsConstructor(::std::string value);

  bool is_VectorStringAlsoNeedsConstructor() const { return Which() == Tag(2); }
  
  ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() {
    if (!is_VectorStringAlsoNeedsConstructor()) {
      value_.emplace<2 + 1>();
    }
    return value_.template get<2 + 1>();
  }
  
  const ::std::vector<::std::string>& VectorStringAlsoNeedsConstructor() const { return value_.template get<2 + 1>(); }
  void set_VectorStringAlsoNeedsConstructor(::std::vector<::std::string> value);

  Tag Which() const {
    size_t index = value_.index();
    if (index == 0) {
      return Tag::Invalid;
    } else {
      return Tag(index - 1);
    }
  }

 private:
  friend bool operator==(const Union& lhs, const Union& rhs);

  using Variant = fit::internal::variant<fit::internal::monostate, int32_t, ::std::string, ::std::vector<::std::string>>;
  Variant value_;
};

bool operator==(const Union& lhs, const Union& rhs);
inline bool operator!=(const Union& lhs, const Union& rhs) {
  return !(lhs == rhs);
}

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

using UnionPtr = ::std::unique_ptr<Union>;
}  // namespace name
}  // namespace test
namespace fidl {

template <>
struct CodingTraits<::test::name::Union>
    : public EncodableCodingTraits<::test::name::Union, 24> {};

inline zx_status_t Clone(const ::test::name::Union& value,
                         ::test::name::Union* result) {
  return ::test::name::Clone(value, result);
}}  // namespace fidl
