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

// fidl_experiment = output_index_json

#pragma once

#include <cinttypes>
#include <string>

#include <lib/fidl/cpp/natural_types.h>
#include <lib/fidl/cpp/natural_coding_traits.h>

#include <fidl/test.union/cpp/markers.h>
#include <fidl/test.union/cpp/common_types.h>


#ifdef __Fuchsia__

  #include <lib/zx/channel.h>
  

#endif  // __Fuchsia__


#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_union {





class Pizza;


class Pasta;


class NullableUnionStruct;


class Empty;


class TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse;


class TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse;


class StructWithNullableUnion;


class UnionSandwich;





class PizzaOrPasta;



class ExplicitPizzaOrPasta;



class FlexiblePizzaOrPasta;



class StrictPizzaOrPasta;



class Union;



class FlexibleUnion;



class StrictUnion;



class FieldCollision;



class ExplicitUnion;



class ReverseOrdinalUnion;



class FlexibleFoo;



class StrictFoo;



class ExplicitFoo;



class ExplicitStrictFoo;



class OlderSimpleUnion;



class NewerSimpleUnion;



class StrictSimpleUnion;



class UnionContainingEmptyStruct;



class StrictBoundedUnion;



class ExplicitFlexibleUnion;



class UnionWithAttributes;



class EmptyFlexibleUnion;






  





class Pizza {
 private:
  struct Storage_;
 public:
  Pizza(Storage_ storage) noexcept;
    Pizza(::std::vector<::std::string> toppings) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |Pizza| only if all of its members are default constructible.
  Pizza() = default;
#pragma clang diagnostic pop

  Pizza(Pizza&&) noexcept = default;
  Pizza& operator=(Pizza&&) noexcept = default;
    Pizza(const Pizza& other) noexcept;
    Pizza& operator=(const Pizza& other) noexcept;

    bool operator==(const Pizza& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza, 16>::Equal(this, &other);
    }
    bool operator!=(const Pizza& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza, 16>::Equal(this, &other);
    }
    
      const ::std::vector<::std::string> &
    toppings() const {
      return storage_.toppings;
    }

    
    ::std::vector<::std::string>& toppings() {
      return storage_.toppings;
    }

    // Setter for toppings.
    //
    
    Pizza& toppings(::std::vector<::std::string> value);

  Pizza(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      ::std::vector<::std::string> toppings;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::Pizza>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::std::vector<::std::string>, fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintString<16>>>{
        &Storage_::toppings, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  





class Pasta {
 private:
  struct Storage_;
 public:
  Pasta(Storage_ storage) noexcept;
    Pasta(::std::string sauce) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |Pasta| only if all of its members are default constructible.
  Pasta() = default;
#pragma clang diagnostic pop

  Pasta(Pasta&&) noexcept = default;
  Pasta& operator=(Pasta&&) noexcept = default;
    Pasta(const Pasta& other) noexcept;
    Pasta& operator=(const Pasta& other) noexcept;

    bool operator==(const Pasta& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta, 16>::Equal(this, &other);
    }
    bool operator!=(const Pasta& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta, 16>::Equal(this, &other);
    }
    
      const ::std::string &
    sauce() const {
      return storage_.sauce;
    }

    
    ::std::string& sauce() {
      return storage_.sauce;
    }

    // Setter for sauce.
    //
    
    Pasta& sauce(::std::string value);

  Pasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      ::std::string sauce;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::Pasta>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::std::string, fidl::internal::NaturalCodingConstraintString<16>>{
        &Storage_::sauce, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  
  
  





class PizzaOrPasta {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::test_union::Pizza
        , ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  PizzaOrPasta(PizzaOrPasta&& other) noexcept
      : PizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  PizzaOrPasta& operator=(PizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    PizzaOrPasta(const PizzaOrPasta& other) noexcept : PizzaOrPasta(other.CloneStorage_()){}
    PizzaOrPasta& operator=(const PizzaOrPasta& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const PizzaOrPasta& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const PizzaOrPasta& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::PizzaOrPasta::Tag Which() const {
    return PizzaOrPasta::IndexToTag(storage_->index()).value();
  }
    static PizzaOrPasta WithPizza(::test_union::Pizza val) {
      return PizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the pizza member.
    //
    
    PizzaOrPasta& pizza(::test_union::Pizza value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static PizzaOrPasta WithPasta(::test_union::Pasta val) {
      return PizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the pasta member.
    //
    
    PizzaOrPasta& pasta(::test_union::Pasta value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  PizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::PizzaOrPasta>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit PizzaOrPasta(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::PizzaOrPasta::Tag tag) {
    switch (tag) {
        case ::test_union::PizzaOrPasta::Tag::kPizza: return 1;
        case ::test_union::PizzaOrPasta::Tag::kPasta: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::PizzaOrPasta::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::PizzaOrPasta::Tag::kPizza;
        case 2: return ::test_union::PizzaOrPasta::Tag::kPasta;
        default: return std::nullopt;
    }
  }

};


  
  
  





class ExplicitPizzaOrPasta {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::test_union::Pizza
        , ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 4,  // 0x4
  };

  ExplicitPizzaOrPasta(ExplicitPizzaOrPasta&& other) noexcept
      : ExplicitPizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitPizzaOrPasta& operator=(ExplicitPizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    ExplicitPizzaOrPasta(const ExplicitPizzaOrPasta& other) noexcept : ExplicitPizzaOrPasta(other.CloneStorage_()){}
    ExplicitPizzaOrPasta& operator=(const ExplicitPizzaOrPasta& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const ExplicitPizzaOrPasta& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const ExplicitPizzaOrPasta& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::ExplicitPizzaOrPasta::Tag Which() const {
    return ExplicitPizzaOrPasta::IndexToTag(storage_->index()).value();
  }
    static ExplicitPizzaOrPasta WithPizza(::test_union::Pizza val) {
      return ExplicitPizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the pizza member.
    //
    
    ExplicitPizzaOrPasta& pizza(::test_union::Pizza value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static ExplicitPizzaOrPasta WithPasta(::test_union::Pasta val) {
      return ExplicitPizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the pasta member.
    //
    
    ExplicitPizzaOrPasta& pasta(::test_union::Pasta value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  ExplicitPizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitPizzaOrPasta>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ExplicitPizzaOrPasta(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::ExplicitPizzaOrPasta::Tag tag) {
    switch (tag) {
        case ::test_union::ExplicitPizzaOrPasta::Tag::kPizza: return 1;
        case ::test_union::ExplicitPizzaOrPasta::Tag::kPasta: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitPizzaOrPasta::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::ExplicitPizzaOrPasta::Tag::kPizza;
        case 2: return ::test_union::ExplicitPizzaOrPasta::Tag::kPasta;
        default: return std::nullopt;
    }
  }

};


  
  
  





class FlexiblePizzaOrPasta {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::test_union::Pizza
        , ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  FlexiblePizzaOrPasta(FlexiblePizzaOrPasta&& other) noexcept
      : FlexiblePizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FlexiblePizzaOrPasta& operator=(FlexiblePizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    FlexiblePizzaOrPasta(const FlexiblePizzaOrPasta& other) noexcept : FlexiblePizzaOrPasta(other.CloneStorage_()){}
    FlexiblePizzaOrPasta& operator=(const FlexiblePizzaOrPasta& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const FlexiblePizzaOrPasta& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const FlexiblePizzaOrPasta& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::FlexiblePizzaOrPasta::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::FlexiblePizzaOrPasta::Tag Which() const {
    return FlexiblePizzaOrPasta::IndexToTag(storage_->index()).value();
  }
    static FlexiblePizzaOrPasta WithPizza(::test_union::Pizza val) {
      return FlexiblePizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the pizza member.
    //
    
    FlexiblePizzaOrPasta& pizza(::test_union::Pizza value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static FlexiblePizzaOrPasta WithPasta(::test_union::Pasta val) {
      return FlexiblePizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the pasta member.
    //
    
    FlexiblePizzaOrPasta& pasta(::test_union::Pasta value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  FlexiblePizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::FlexiblePizzaOrPasta>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit FlexiblePizzaOrPasta(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::FlexiblePizzaOrPasta::Tag tag) {
    switch (tag) {
        case ::test_union::FlexiblePizzaOrPasta::Tag::kPizza: return 1;
        case ::test_union::FlexiblePizzaOrPasta::Tag::kPasta: return 2;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FlexiblePizzaOrPasta::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::FlexiblePizzaOrPasta::Tag::kPizza;
        case 2: return ::test_union::FlexiblePizzaOrPasta::Tag::kPasta;
        default: return ::test_union::FlexiblePizzaOrPasta::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class StrictPizzaOrPasta {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::test_union::Pizza
        , ::test_union::Pasta>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPizza = 1,  // 0x1
    kPasta = 2,  // 0x2
  };

  StrictPizzaOrPasta(StrictPizzaOrPasta&& other) noexcept
      : StrictPizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictPizzaOrPasta& operator=(StrictPizzaOrPasta&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    StrictPizzaOrPasta(const StrictPizzaOrPasta& other) noexcept : StrictPizzaOrPasta(other.CloneStorage_()){}
    StrictPizzaOrPasta& operator=(const StrictPizzaOrPasta& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const StrictPizzaOrPasta& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const StrictPizzaOrPasta& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::StrictPizzaOrPasta::Tag Which() const {
    return StrictPizzaOrPasta::IndexToTag(storage_->index()).value();
  }
    static StrictPizzaOrPasta WithPizza(::test_union::Pizza val) {
      return StrictPizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> pizza() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> pizza() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the pizza member.
    //
    
    StrictPizzaOrPasta& pizza(::test_union::Pizza value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static StrictPizzaOrPasta WithPasta(::test_union::Pasta val) {
      return StrictPizzaOrPasta(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> pasta() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> pasta() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the pasta member.
    //
    
    StrictPizzaOrPasta& pasta(::test_union::Pasta value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  StrictPizzaOrPasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictPizzaOrPasta>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit StrictPizzaOrPasta(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::StrictPizzaOrPasta::Tag tag) {
    switch (tag) {
        case ::test_union::StrictPizzaOrPasta::Tag::kPizza: return 1;
        case ::test_union::StrictPizzaOrPasta::Tag::kPasta: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictPizzaOrPasta::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::StrictPizzaOrPasta::Tag::kPizza;
        case 2: return ::test_union::StrictPizzaOrPasta::Tag::kPasta;
        default: return std::nullopt;
    }
  }

};


  
  
  





class Union {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , ::std::string
        , ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,  // 0x1
    kStringNeedsConstructor = 2,  // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  Union(Union&& other) noexcept
      : Union(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  Union& operator=(Union&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    Union(const Union& other) noexcept : Union(other.CloneStorage_()){}
    Union& operator=(const Union& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const Union& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const Union& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::Union::Tag Which() const {
    return Union::IndexToTag(storage_->index()).value();
  }
    static Union WithPrimitive(int32_t val) {
      return Union(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the primitive member.
    //
    
    Union& primitive(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static Union WithStringNeedsConstructor(::std::string val) {
      return Union(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the string_needs_constructor member.
    //
    
    Union& string_needs_constructor(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }
    static Union WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string> val) {
      return Union(std::make_shared<Storage_>(
        std::in_place_index_t<3>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<3, Storage_> vector_string_also_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<3, Storage_> vector_string_also_needs_constructor() {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    // Sets the union to hold the vector_string_also_needs_constructor member.
    //
    
    Union& vector_string_also_needs_constructor(::std::vector<::std::string> value) {
      storage_->emplace<3>(std::move(value));
      return *this;
    }

  Union(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::Union>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintString<>>>());

  explicit Union(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::Union::Tag tag) {
    switch (tag) {
        case ::test_union::Union::Tag::kPrimitive: return 1;
        case ::test_union::Union::Tag::kStringNeedsConstructor: return 2;
        case ::test_union::Union::Tag::kVectorStringAlsoNeedsConstructor: return 3;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::Union::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::Union::Tag::kPrimitive;
        case 2: return ::test_union::Union::Tag::kStringNeedsConstructor;
        case 3: return ::test_union::Union::Tag::kVectorStringAlsoNeedsConstructor;
        default: return std::nullopt;
    }
  }

};


  
  
  





class FlexibleUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , ::std::string
        , ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,  // 0x1
    kStringNeedsConstructor = 2,  // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  FlexibleUnion(FlexibleUnion&& other) noexcept
      : FlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FlexibleUnion& operator=(FlexibleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    FlexibleUnion(const FlexibleUnion& other) noexcept : FlexibleUnion(other.CloneStorage_()){}
    FlexibleUnion& operator=(const FlexibleUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const FlexibleUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const FlexibleUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::FlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::FlexibleUnion::Tag Which() const {
    return FlexibleUnion::IndexToTag(storage_->index()).value();
  }
    static FlexibleUnion WithPrimitive(int32_t val) {
      return FlexibleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the primitive member.
    //
    
    FlexibleUnion& primitive(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static FlexibleUnion WithStringNeedsConstructor(::std::string val) {
      return FlexibleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the string_needs_constructor member.
    //
    
    FlexibleUnion& string_needs_constructor(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }
    static FlexibleUnion WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string> val) {
      return FlexibleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<3>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<3, Storage_> vector_string_also_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<3, Storage_> vector_string_also_needs_constructor() {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    // Sets the union to hold the vector_string_also_needs_constructor member.
    //
    
    FlexibleUnion& vector_string_also_needs_constructor(::std::vector<::std::string> value) {
      storage_->emplace<3>(std::move(value));
      return *this;
    }

  FlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::FlexibleUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintString<>>>());

  explicit FlexibleUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::FlexibleUnion::Tag tag) {
    switch (tag) {
        case ::test_union::FlexibleUnion::Tag::kPrimitive: return 1;
        case ::test_union::FlexibleUnion::Tag::kStringNeedsConstructor: return 2;
        case ::test_union::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor: return 3;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FlexibleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::FlexibleUnion::Tag::kPrimitive;
        case 2: return ::test_union::FlexibleUnion::Tag::kStringNeedsConstructor;
        case 3: return ::test_union::FlexibleUnion::Tag::kVectorStringAlsoNeedsConstructor;
        default: return ::test_union::FlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class StrictUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , ::std::string
        , ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,  // 0x1
    kStringNeedsConstructor = 2,  // 0x2
    kVectorStringAlsoNeedsConstructor = 3,  // 0x3
  };

  StrictUnion(StrictUnion&& other) noexcept
      : StrictUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictUnion& operator=(StrictUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    StrictUnion(const StrictUnion& other) noexcept : StrictUnion(other.CloneStorage_()){}
    StrictUnion& operator=(const StrictUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const StrictUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const StrictUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::StrictUnion::Tag Which() const {
    return StrictUnion::IndexToTag(storage_->index()).value();
  }
    static StrictUnion WithPrimitive(int32_t val) {
      return StrictUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the primitive member.
    //
    
    StrictUnion& primitive(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static StrictUnion WithStringNeedsConstructor(::std::string val) {
      return StrictUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the string_needs_constructor member.
    //
    
    StrictUnion& string_needs_constructor(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }
    static StrictUnion WithVectorStringAlsoNeedsConstructor(::std::vector<::std::string> val) {
      return StrictUnion(std::make_shared<Storage_>(
        std::in_place_index_t<3>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<3, Storage_> vector_string_also_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<3, Storage_> vector_string_also_needs_constructor() {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    // Sets the union to hold the vector_string_also_needs_constructor member.
    //
    
    StrictUnion& vector_string_also_needs_constructor(::std::vector<::std::string> value) {
      storage_->emplace<3>(std::move(value));
      return *this;
    }

  StrictUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintString<>>>());

  explicit StrictUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::StrictUnion::Tag tag) {
    switch (tag) {
        case ::test_union::StrictUnion::Tag::kPrimitive: return 1;
        case ::test_union::StrictUnion::Tag::kStringNeedsConstructor: return 2;
        case ::test_union::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor: return 3;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::StrictUnion::Tag::kPrimitive;
        case 2: return ::test_union::StrictUnion::Tag::kStringNeedsConstructor;
        case 3: return ::test_union::StrictUnion::Tag::kVectorStringAlsoNeedsConstructor;
        default: return std::nullopt;
    }
  }

};


  
  
  





class FieldCollision {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kFieldCollisionTag = 1,  // 0x1
  };

  FieldCollision(FieldCollision&& other) noexcept
      : FieldCollision(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FieldCollision& operator=(FieldCollision&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    FieldCollision(const FieldCollision& other) noexcept : FieldCollision(other.CloneStorage_()){}
    FieldCollision& operator=(const FieldCollision& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const FieldCollision& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const FieldCollision& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::FieldCollision::Tag Which() const {
    return FieldCollision::IndexToTag(storage_->index()).value();
  }
    static FieldCollision WithFieldCollisionTag(int32_t val) {
      return FieldCollision(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> field_collision_tag() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> field_collision_tag() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the field_collision_tag member.
    //
    
    FieldCollision& field_collision_tag(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }

  FieldCollision(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::FieldCollision>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit FieldCollision(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::FieldCollision::Tag tag) {
    switch (tag) {
        case ::test_union::FieldCollision::Tag::kFieldCollisionTag: return 1;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FieldCollision::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::FieldCollision::Tag::kFieldCollisionTag;
        default: return std::nullopt;
    }
  }

};


  
  
  





class ExplicitUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , ::std::string>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kPrimitive = 1,  // 0x1
    kStringNeedsConstructor = 3,  // 0x3
  };

  ExplicitUnion(ExplicitUnion&& other) noexcept
      : ExplicitUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitUnion& operator=(ExplicitUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    ExplicitUnion(const ExplicitUnion& other) noexcept : ExplicitUnion(other.CloneStorage_()){}
    ExplicitUnion& operator=(const ExplicitUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const ExplicitUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const ExplicitUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::ExplicitUnion::Tag Which() const {
    return ExplicitUnion::IndexToTag(storage_->index()).value();
  }
    static ExplicitUnion WithPrimitive(int32_t val) {
      return ExplicitUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> primitive() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> primitive() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the primitive member.
    //
    
    ExplicitUnion& primitive(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static ExplicitUnion WithStringNeedsConstructor(::std::string val) {
      return ExplicitUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> string_needs_constructor() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the string_needs_constructor member.
    //
    
    ExplicitUnion& string_needs_constructor(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  ExplicitUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>());

  explicit ExplicitUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::ExplicitUnion::Tag tag) {
    switch (tag) {
        case ::test_union::ExplicitUnion::Tag::kPrimitive: return 1;
        case ::test_union::ExplicitUnion::Tag::kStringNeedsConstructor: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::ExplicitUnion::Tag::kPrimitive;
        case 2: return ::test_union::ExplicitUnion::Tag::kStringNeedsConstructor;
        default: return std::nullopt;
    }
  }

};


  
  
  





class ReverseOrdinalUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , uint32_t
        , uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kFirst = 1,  // 0x1
    kSecond = 2,  // 0x2
  };

  ReverseOrdinalUnion(ReverseOrdinalUnion&& other) noexcept
      : ReverseOrdinalUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ReverseOrdinalUnion& operator=(ReverseOrdinalUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    ReverseOrdinalUnion(const ReverseOrdinalUnion& other) noexcept : ReverseOrdinalUnion(other.CloneStorage_()){}
    ReverseOrdinalUnion& operator=(const ReverseOrdinalUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const ReverseOrdinalUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const ReverseOrdinalUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::ReverseOrdinalUnion::Tag Which() const {
    return ReverseOrdinalUnion::IndexToTag(storage_->index()).value();
  }
    static ReverseOrdinalUnion WithFirst(uint32_t val) {
      return ReverseOrdinalUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> first() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> first() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the first member.
    //
    
    ReverseOrdinalUnion& first(uint32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static ReverseOrdinalUnion WithSecond(uint32_t val) {
      return ReverseOrdinalUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> second() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> second() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the second member.
    //
    
    ReverseOrdinalUnion& second(uint32_t value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  ReverseOrdinalUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::ReverseOrdinalUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ReverseOrdinalUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::ReverseOrdinalUnion::Tag tag) {
    switch (tag) {
        case ::test_union::ReverseOrdinalUnion::Tag::kFirst: return 1;
        case ::test_union::ReverseOrdinalUnion::Tag::kSecond: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ReverseOrdinalUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::ReverseOrdinalUnion::Tag::kFirst;
        case 2: return ::test_union::ReverseOrdinalUnion::Tag::kSecond;
        default: return std::nullopt;
    }
  }

};


  





class NullableUnionStruct {
 private:
  struct Storage_;
 public:
  NullableUnionStruct(Storage_ storage) noexcept;
    NullableUnionStruct(::fidl::Box<::test_union::Union> the_union) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |NullableUnionStruct| only if all of its members are default constructible.
  NullableUnionStruct() = default;
#pragma clang diagnostic pop

  NullableUnionStruct(NullableUnionStruct&&) noexcept = default;
  NullableUnionStruct& operator=(NullableUnionStruct&&) noexcept = default;
    NullableUnionStruct(const NullableUnionStruct& other) noexcept;
    NullableUnionStruct& operator=(const NullableUnionStruct& other) noexcept;

    bool operator==(const NullableUnionStruct& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::NullableUnionStruct, 16>::Equal(this, &other);
    }
    bool operator!=(const NullableUnionStruct& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::NullableUnionStruct, 16>::Equal(this, &other);
    }
    
      const ::fidl::Box<::test_union::Union> &
    the_union() const {
      return storage_.the_union;
    }

    
    ::fidl::Box<::test_union::Union>& the_union() {
      return storage_.the_union;
    }

    // Setter for the_union.
    //
    
    NullableUnionStruct& the_union(::fidl::Box<::test_union::Union> value);

  NullableUnionStruct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      ::fidl::Box<::test_union::Union> the_union;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::NullableUnionStruct, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::NullableUnionStruct>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::fidl::Box<::test_union::Union>, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::the_union, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  
  
  





class FlexibleFoo {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::std::string
        , int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  FlexibleFoo(FlexibleFoo&& other) noexcept
      : FlexibleFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  FlexibleFoo& operator=(FlexibleFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    FlexibleFoo(const FlexibleFoo& other) noexcept : FlexibleFoo(other.CloneStorage_()){}
    FlexibleFoo& operator=(const FlexibleFoo& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const FlexibleFoo& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const FlexibleFoo& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::FlexibleFoo::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::FlexibleFoo::Tag Which() const {
    return FlexibleFoo::IndexToTag(storage_->index()).value();
  }
    static FlexibleFoo WithS(::std::string val) {
      return FlexibleFoo(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> s() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> s() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the s member.
    //
    
    FlexibleFoo& s(::std::string value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static FlexibleFoo WithI(int32_t val) {
      return FlexibleFoo(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> i() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    FlexibleFoo& i(int32_t value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  FlexibleFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::FlexibleFoo>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit FlexibleFoo(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::FlexibleFoo::Tag tag) {
    switch (tag) {
        case ::test_union::FlexibleFoo::Tag::kS: return 1;
        case ::test_union::FlexibleFoo::Tag::kI: return 2;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::FlexibleFoo::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::FlexibleFoo::Tag::kS;
        case 2: return ::test_union::FlexibleFoo::Tag::kI;
        default: return ::test_union::FlexibleFoo::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class StrictFoo {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::std::string
        , int32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
  };

  StrictFoo(StrictFoo&& other) noexcept
      : StrictFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictFoo& operator=(StrictFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    StrictFoo(const StrictFoo& other) noexcept : StrictFoo(other.CloneStorage_()){}
    StrictFoo& operator=(const StrictFoo& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const StrictFoo& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const StrictFoo& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::StrictFoo::Tag Which() const {
    return StrictFoo::IndexToTag(storage_->index()).value();
  }
    static StrictFoo WithS(::std::string val) {
      return StrictFoo(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> s() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> s() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the s member.
    //
    
    StrictFoo& s(::std::string value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static StrictFoo WithI(int32_t val) {
      return StrictFoo(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> i() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    StrictFoo& i(int32_t value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  StrictFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictFoo>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit StrictFoo(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::StrictFoo::Tag tag) {
    switch (tag) {
        case ::test_union::StrictFoo::Tag::kS: return 1;
        case ::test_union::StrictFoo::Tag::kI: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictFoo::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::StrictFoo::Tag::kS;
        case 2: return ::test_union::StrictFoo::Tag::kI;
        default: return std::nullopt;
    }
  }

};


  
  
  





class ExplicitFoo {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , ::std::string>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  ExplicitFoo(ExplicitFoo&& other) noexcept
      : ExplicitFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitFoo& operator=(ExplicitFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    ExplicitFoo(const ExplicitFoo& other) noexcept : ExplicitFoo(other.CloneStorage_()){}
    ExplicitFoo& operator=(const ExplicitFoo& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const ExplicitFoo& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const ExplicitFoo& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::ExplicitFoo::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::ExplicitFoo::Tag Which() const {
    return ExplicitFoo::IndexToTag(storage_->index()).value();
  }
    static ExplicitFoo WithI(int32_t val) {
      return ExplicitFoo(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> i() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    ExplicitFoo& i(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static ExplicitFoo WithS(::std::string val) {
      return ExplicitFoo(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> s() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> s() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the s member.
    //
    
    ExplicitFoo& s(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  ExplicitFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitFoo>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>());

  explicit ExplicitFoo(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::ExplicitFoo::Tag tag) {
    switch (tag) {
        case ::test_union::ExplicitFoo::Tag::kI: return 1;
        case ::test_union::ExplicitFoo::Tag::kS: return 2;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitFoo::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::ExplicitFoo::Tag::kI;
        case 2: return ::test_union::ExplicitFoo::Tag::kS;
        default: return ::test_union::ExplicitFoo::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class ExplicitStrictFoo {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , ::std::string>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kI = 2,  // 0x2
    kS = 3,  // 0x3
  };

  ExplicitStrictFoo(ExplicitStrictFoo&& other) noexcept
      : ExplicitStrictFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitStrictFoo& operator=(ExplicitStrictFoo&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    ExplicitStrictFoo(const ExplicitStrictFoo& other) noexcept : ExplicitStrictFoo(other.CloneStorage_()){}
    ExplicitStrictFoo& operator=(const ExplicitStrictFoo& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const ExplicitStrictFoo& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const ExplicitStrictFoo& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::ExplicitStrictFoo::Tag Which() const {
    return ExplicitStrictFoo::IndexToTag(storage_->index()).value();
  }
    static ExplicitStrictFoo WithI(int32_t val) {
      return ExplicitStrictFoo(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> i() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    ExplicitStrictFoo& i(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static ExplicitStrictFoo WithS(::std::string val) {
      return ExplicitStrictFoo(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> s() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> s() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the s member.
    //
    
    ExplicitStrictFoo& s(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  ExplicitStrictFoo(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitStrictFoo>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>());

  explicit ExplicitStrictFoo(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::ExplicitStrictFoo::Tag tag) {
    switch (tag) {
        case ::test_union::ExplicitStrictFoo::Tag::kI: return 1;
        case ::test_union::ExplicitStrictFoo::Tag::kS: return 2;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitStrictFoo::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::ExplicitStrictFoo::Tag::kI;
        case 2: return ::test_union::ExplicitStrictFoo::Tag::kS;
        default: return std::nullopt;
    }
  }

};


  
  
  





class OlderSimpleUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int64_t
        , float>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  OlderSimpleUnion(OlderSimpleUnion&& other) noexcept
      : OlderSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  OlderSimpleUnion& operator=(OlderSimpleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    OlderSimpleUnion(const OlderSimpleUnion& other) noexcept : OlderSimpleUnion(other.CloneStorage_()){}
    OlderSimpleUnion& operator=(const OlderSimpleUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const OlderSimpleUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const OlderSimpleUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::OlderSimpleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::OlderSimpleUnion::Tag Which() const {
    return OlderSimpleUnion::IndexToTag(storage_->index()).value();
  }
    static OlderSimpleUnion WithI(int64_t val) {
      return OlderSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> i() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    OlderSimpleUnion& i(int64_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static OlderSimpleUnion WithF(float val) {
      return OlderSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> f() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> f() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the f member.
    //
    
    OlderSimpleUnion& f(float value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  OlderSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::OlderSimpleUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit OlderSimpleUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::OlderSimpleUnion::Tag tag) {
    switch (tag) {
        case ::test_union::OlderSimpleUnion::Tag::kI: return 1;
        case ::test_union::OlderSimpleUnion::Tag::kF: return 2;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::OlderSimpleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::OlderSimpleUnion::Tag::kI;
        case 2: return ::test_union::OlderSimpleUnion::Tag::kF;
        default: return ::test_union::OlderSimpleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class NewerSimpleUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int64_t
        , ::std::string
        , ::std::vector<::std::string>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kS = 2,  // 0x2
    kV = 3,  // 0x3
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  NewerSimpleUnion(NewerSimpleUnion&& other) noexcept
      : NewerSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  NewerSimpleUnion& operator=(NewerSimpleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    NewerSimpleUnion(const NewerSimpleUnion& other) noexcept : NewerSimpleUnion(other.CloneStorage_()){}
    NewerSimpleUnion& operator=(const NewerSimpleUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const NewerSimpleUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const NewerSimpleUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::NewerSimpleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::NewerSimpleUnion::Tag Which() const {
    return NewerSimpleUnion::IndexToTag(storage_->index()).value();
  }
    static NewerSimpleUnion WithI(int64_t val) {
      return NewerSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> i() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    NewerSimpleUnion& i(int64_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static NewerSimpleUnion WithS(::std::string val) {
      return NewerSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> s() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> s() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the s member.
    //
    
    NewerSimpleUnion& s(::std::string value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }
    static NewerSimpleUnion WithV(::std::vector<::std::string> val) {
      return NewerSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<3>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<3, Storage_> v() const {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<3, Storage_> v() {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    // Sets the union to hold the v member.
    //
    
    NewerSimpleUnion& v(::std::vector<::std::string> value) {
      storage_->emplace<3>(std::move(value));
      return *this;
    }

  NewerSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::NewerSimpleUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintString<>>>());

  explicit NewerSimpleUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::NewerSimpleUnion::Tag tag) {
    switch (tag) {
        case ::test_union::NewerSimpleUnion::Tag::kI: return 1;
        case ::test_union::NewerSimpleUnion::Tag::kS: return 2;
        case ::test_union::NewerSimpleUnion::Tag::kV: return 3;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::NewerSimpleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::NewerSimpleUnion::Tag::kI;
        case 2: return ::test_union::NewerSimpleUnion::Tag::kS;
        case 3: return ::test_union::NewerSimpleUnion::Tag::kV;
        default: return ::test_union::NewerSimpleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class StrictSimpleUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int32_t
        , float
        , ::std::string>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 2,  // 0x2
    kS = 3,  // 0x3
  };

  StrictSimpleUnion(StrictSimpleUnion&& other) noexcept
      : StrictSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictSimpleUnion& operator=(StrictSimpleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    StrictSimpleUnion(const StrictSimpleUnion& other) noexcept : StrictSimpleUnion(other.CloneStorage_()){}
    StrictSimpleUnion& operator=(const StrictSimpleUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const StrictSimpleUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const StrictSimpleUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::StrictSimpleUnion::Tag Which() const {
    return StrictSimpleUnion::IndexToTag(storage_->index()).value();
  }
    static StrictSimpleUnion WithI(int32_t val) {
      return StrictSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> i() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    StrictSimpleUnion& i(int32_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static StrictSimpleUnion WithF(float val) {
      return StrictSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> f() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> f() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the f member.
    //
    
    StrictSimpleUnion& f(float value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }
    static StrictSimpleUnion WithS(::std::string val) {
      return StrictSimpleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<3>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<3, Storage_> s() const {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<3, Storage_> s() {
      return ::fidl::internal::UnionMemberView<3, Storage_>(storage_);
    }

    // Sets the union to hold the s member.
    //
    
    StrictSimpleUnion& s(::std::string value) {
      storage_->emplace<3>(std::move(value));
      return *this;
    }

  StrictSimpleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictSimpleUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintString<>>());

  explicit StrictSimpleUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::StrictSimpleUnion::Tag tag) {
    switch (tag) {
        case ::test_union::StrictSimpleUnion::Tag::kI: return 1;
        case ::test_union::StrictSimpleUnion::Tag::kF: return 2;
        case ::test_union::StrictSimpleUnion::Tag::kS: return 3;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictSimpleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::StrictSimpleUnion::Tag::kI;
        case 2: return ::test_union::StrictSimpleUnion::Tag::kF;
        case 3: return ::test_union::StrictSimpleUnion::Tag::kS;
        default: return std::nullopt;
    }
  }

};


  





class Empty {
 private:
  struct Storage_;
 public:
  Empty(Storage_ storage) noexcept;
    Empty(uint8_t __reserved) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |Empty| only if all of its members are default constructible.
  Empty() = default;
#pragma clang diagnostic pop

  Empty(Empty&&) noexcept = default;
  Empty& operator=(Empty&&) noexcept = default;
    Empty(const Empty& other) noexcept;
    Empty& operator=(const Empty& other) noexcept;

    bool operator==(const Empty& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::Empty, 1>::Equal(this, &other);
    }
    bool operator!=(const Empty& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::Empty, 1>::Equal(this, &other);
    }
    
      uint8_t
    __reserved() const {
      return storage_.__reserved;
    }

    
    uint8_t& __reserved() {
      return storage_.__reserved;
    }

    // Setter for __reserved.
    //
    
    Empty& __reserved(uint8_t value);

  Empty(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      uint8_t __reserved
        =0u;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::Empty, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::Empty>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint8_t, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::__reserved, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  
  
  





class UnionContainingEmptyStruct {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::test_union::Empty>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kEmpty = 1,  // 0x1
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  UnionContainingEmptyStruct(UnionContainingEmptyStruct&& other) noexcept
      : UnionContainingEmptyStruct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  UnionContainingEmptyStruct& operator=(UnionContainingEmptyStruct&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    UnionContainingEmptyStruct(const UnionContainingEmptyStruct& other) noexcept : UnionContainingEmptyStruct(other.CloneStorage_()){}
    UnionContainingEmptyStruct& operator=(const UnionContainingEmptyStruct& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const UnionContainingEmptyStruct& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const UnionContainingEmptyStruct& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::UnionContainingEmptyStruct::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::UnionContainingEmptyStruct::Tag Which() const {
    return UnionContainingEmptyStruct::IndexToTag(storage_->index()).value();
  }
    static UnionContainingEmptyStruct WithEmpty(::test_union::Empty val) {
      return UnionContainingEmptyStruct(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> empty() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> empty() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the empty member.
    //
    
    UnionContainingEmptyStruct& empty(::test_union::Empty value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }

  UnionContainingEmptyStruct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::UnionContainingEmptyStruct>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit UnionContainingEmptyStruct(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::UnionContainingEmptyStruct::Tag tag) {
    switch (tag) {
        case ::test_union::UnionContainingEmptyStruct::Tag::kEmpty: return 1;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::UnionContainingEmptyStruct::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::UnionContainingEmptyStruct::Tag::kEmpty;
        default: return ::test_union::UnionContainingEmptyStruct::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class StrictBoundedUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , ::std::vector<uint8_t>>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kV = 1,  // 0x1
  };

  StrictBoundedUnion(StrictBoundedUnion&& other) noexcept
      : StrictBoundedUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  StrictBoundedUnion& operator=(StrictBoundedUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    StrictBoundedUnion(const StrictBoundedUnion& other) noexcept : StrictBoundedUnion(other.CloneStorage_()){}
    StrictBoundedUnion& operator=(const StrictBoundedUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const StrictBoundedUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const StrictBoundedUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }

  constexpr ::test_union::StrictBoundedUnion::Tag Which() const {
    return StrictBoundedUnion::IndexToTag(storage_->index()).value();
  }
    static StrictBoundedUnion WithV(::std::vector<uint8_t> val) {
      return StrictBoundedUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> v() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> v() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the v member.
    //
    
    StrictBoundedUnion& v(::std::vector<uint8_t> value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }

  StrictBoundedUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictBoundedUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintVector<fidl::internal::NaturalCodingConstraintEmpty, 10>>());

  explicit StrictBoundedUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::StrictBoundedUnion::Tag tag) {
    switch (tag) {
        case ::test_union::StrictBoundedUnion::Tag::kV: return 1;
      default: {
          decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::StrictBoundedUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::StrictBoundedUnion::Tag::kV;
        default: return std::nullopt;
    }
  }

};


  





class TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse {
 private:
  struct Storage_;
 public:
  TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(Storage_ storage) noexcept;
    TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(::test_union::StrictBoundedUnion xu) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse| only if all of its members are default constructible.
  TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse() = default;
#pragma clang diagnostic pop

  TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse&&) noexcept = default;
  TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& operator=(TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse&&) noexcept = default;
    TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(const TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& other) noexcept;
    TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& operator=(const TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& other) noexcept;

    bool operator==(const TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, 16>::Equal(this, &other);
    }
    bool operator!=(const TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, 16>::Equal(this, &other);
    }
    
      const ::test_union::StrictBoundedUnion &
    xu() const {
      return storage_.xu;
    }

    
    ::test_union::StrictBoundedUnion& xu() {
      return storage_.xu;
    }

    // Setter for xu.
    //
    
    TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& xu(::test_union::StrictBoundedUnion value);

  TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      ::test_union::StrictBoundedUnion xu;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_union::StrictBoundedUnion, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::xu, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  





class TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse {
 private:
  struct Storage_;
 public:
  TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(Storage_ storage) noexcept;
    TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(::test_union::OlderSimpleUnion xu) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse| only if all of its members are default constructible.
  TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse() = default;
#pragma clang diagnostic pop

  TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse&&) noexcept = default;
  TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& operator=(TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse&&) noexcept = default;
    TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(const TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& other) noexcept;
    TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& operator=(const TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& other) noexcept;

    bool operator==(const TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, 16>::Equal(this, &other);
    }
    bool operator!=(const TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, 16>::Equal(this, &other);
    }
    
      const ::test_union::OlderSimpleUnion &
    xu() const {
      return storage_.xu;
    }

    
    ::test_union::OlderSimpleUnion& xu() {
      return storage_.xu;
    }

    // Setter for xu.
    //
    
    TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& xu(::test_union::OlderSimpleUnion value);

  TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      ::test_union::OlderSimpleUnion xu;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_union::OlderSimpleUnion, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::xu, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  
  
  
  





class StructWithNullableUnion {
 private:
  struct Storage_;
 public:
  StructWithNullableUnion(Storage_ storage) noexcept;
    StructWithNullableUnion(::fidl::Box<::test_union::OlderSimpleUnion> x1) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |StructWithNullableUnion| only if all of its members are default constructible.
  StructWithNullableUnion() = default;
#pragma clang diagnostic pop

  StructWithNullableUnion(StructWithNullableUnion&&) noexcept = default;
  StructWithNullableUnion& operator=(StructWithNullableUnion&&) noexcept = default;
    StructWithNullableUnion(const StructWithNullableUnion& other) noexcept;
    StructWithNullableUnion& operator=(const StructWithNullableUnion& other) noexcept;

    bool operator==(const StructWithNullableUnion& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::StructWithNullableUnion, 16>::Equal(this, &other);
    }
    bool operator!=(const StructWithNullableUnion& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::StructWithNullableUnion, 16>::Equal(this, &other);
    }
    
      const ::fidl::Box<::test_union::OlderSimpleUnion> &
    x1() const {
      return storage_.x1;
    }

    
    ::fidl::Box<::test_union::OlderSimpleUnion>& x1() {
      return storage_.x1;
    }

    // Setter for x1.
    //
    
    StructWithNullableUnion& x1(::fidl::Box<::test_union::OlderSimpleUnion> value);

  StructWithNullableUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      ::fidl::Box<::test_union::OlderSimpleUnion> x1;
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::StructWithNullableUnion, 16>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::StructWithNullableUnion>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::fidl::Box<::test_union::OlderSimpleUnion>, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::x1, 0
      });
  static constexpr auto kPadding = std::make_tuple();

};


  
  
  
  
  





class ExplicitFlexibleUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int64_t
        , float>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kI = 1,  // 0x1
    kF = 4,  // 0x4
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  ExplicitFlexibleUnion(ExplicitFlexibleUnion&& other) noexcept
      : ExplicitFlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  ExplicitFlexibleUnion& operator=(ExplicitFlexibleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    ExplicitFlexibleUnion(const ExplicitFlexibleUnion& other) noexcept : ExplicitFlexibleUnion(other.CloneStorage_()){}
    ExplicitFlexibleUnion& operator=(const ExplicitFlexibleUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const ExplicitFlexibleUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const ExplicitFlexibleUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::ExplicitFlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::ExplicitFlexibleUnion::Tag Which() const {
    return ExplicitFlexibleUnion::IndexToTag(storage_->index()).value();
  }
    static ExplicitFlexibleUnion WithI(int64_t val) {
      return ExplicitFlexibleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> i() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> i() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the i member.
    //
    
    ExplicitFlexibleUnion& i(int64_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }
    static ExplicitFlexibleUnion WithF(float val) {
      return ExplicitFlexibleUnion(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<2, Storage_> f() const {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<2, Storage_> f() {
      return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
    }

    // Sets the union to hold the f member.
    //
    
    ExplicitFlexibleUnion& f(float value) {
      storage_->emplace<2>(std::move(value));
      return *this;
    }

  ExplicitFlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitFlexibleUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit ExplicitFlexibleUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::ExplicitFlexibleUnion::Tag tag) {
    switch (tag) {
        case ::test_union::ExplicitFlexibleUnion::Tag::kI: return 1;
        case ::test_union::ExplicitFlexibleUnion::Tag::kF: return 2;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::ExplicitFlexibleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::ExplicitFlexibleUnion::Tag::kI;
        case 2: return ::test_union::ExplicitFlexibleUnion::Tag::kF;
        default: return ::test_union::ExplicitFlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  





class UnionSandwich {
 private:
  struct Storage_;
 public:
  UnionSandwich(Storage_ storage) noexcept;
    UnionSandwich(uint32_t a, ::test_union::ExplicitFlexibleUnion u, uint32_t b) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |UnionSandwich| only if all of its members are default constructible.
  UnionSandwich() = default;
#pragma clang diagnostic pop

  UnionSandwich(UnionSandwich&&) noexcept = default;
  UnionSandwich& operator=(UnionSandwich&&) noexcept = default;
    UnionSandwich(const UnionSandwich& other) noexcept;
    UnionSandwich& operator=(const UnionSandwich& other) noexcept;

    bool operator==(const UnionSandwich& other) const noexcept {
      return ::fidl::internal::NaturalStructCodingTraits<::test_union::UnionSandwich, 32>::Equal(this, &other);
    }
    bool operator!=(const UnionSandwich& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<::test_union::UnionSandwich, 32>::Equal(this, &other);
    }
    
      uint32_t
    a() const {
      return storage_.a;
    }

    
    uint32_t& a() {
      return storage_.a;
    }

    // Setter for a.
    //
    
    UnionSandwich& a(uint32_t value);
    
      const ::test_union::ExplicitFlexibleUnion &
    u() const {
      return storage_.u;
    }

    
    ::test_union::ExplicitFlexibleUnion& u() {
      return storage_.u;
    }

    // Setter for u.
    //
    
    UnionSandwich& u(::test_union::ExplicitFlexibleUnion value);
    
      uint32_t
    b() const {
      return storage_.b;
    }

    
    uint32_t& b() {
      return storage_.b;
    }

    // Setter for b.
    //
    
    UnionSandwich& b(uint32_t value);

  UnionSandwich(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
      uint32_t a
        = {};
      ::test_union::ExplicitFlexibleUnion u;
      uint32_t b
        = {};
  };

  Storage_ storage_;
    Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_union::UnionSandwich, 32>;
  friend struct ::fidl::internal::MemberVisitor<::test_union::UnionSandwich>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::a, 0
      }, ::fidl::internal::NaturalStructMember<Storage_, ::test_union::ExplicitFlexibleUnion, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::u, 8
      }, ::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
        &Storage_::b, 24
      });
  static constexpr auto kPadding = std::make_tuple(::fidl::internal::NaturalStructPadding<uint64_t>{
        .offset = 0,
        .mask = 0xffffffff00000000,
      }, ::fidl::internal::NaturalStructPadding<uint64_t>{
        .offset = 24,
        .mask = 0xffffffff00000000,
      });

};


  
  
  
  
  





class UnionWithAttributes {
 private:
  using Storage_ =
    std::variant<
      std::monostate
        , int64_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kX = 1,  // 0x1
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  UnionWithAttributes(UnionWithAttributes&& other) noexcept
      : UnionWithAttributes(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  UnionWithAttributes& operator=(UnionWithAttributes&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    UnionWithAttributes(const UnionWithAttributes& other) noexcept : UnionWithAttributes(other.CloneStorage_()){}
    UnionWithAttributes& operator=(const UnionWithAttributes& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const UnionWithAttributes& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const UnionWithAttributes& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::UnionWithAttributes::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::UnionWithAttributes::Tag Which() const {
    return UnionWithAttributes::IndexToTag(storage_->index()).value();
  }
    static UnionWithAttributes WithX(int64_t val) {
      return UnionWithAttributes(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
    }

    const ::fidl::internal::UnionMemberView<1, Storage_> x() const {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    ::fidl::internal::UnionMemberView<1, Storage_> x() {
      return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
    }

    // Sets the union to hold the x member.
    //
    
    UnionWithAttributes& x(int64_t value) {
      storage_->emplace<1>(std::move(value));
      return *this;
    }

  UnionWithAttributes(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::UnionWithAttributes>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>()
      , ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit UnionWithAttributes(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::UnionWithAttributes::Tag tag) {
    switch (tag) {
        case ::test_union::UnionWithAttributes::Tag::kX: return 1;
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::UnionWithAttributes::Tag> IndexToTag(size_t index) {
    switch (index) {
        case 1: return ::test_union::UnionWithAttributes::Tag::kX;
        default: return ::test_union::UnionWithAttributes::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};


  
  
  





class EmptyFlexibleUnion {
 private:
  using Storage_ =
    std::variant<
      std::monostate>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  EmptyFlexibleUnion(EmptyFlexibleUnion&& other) noexcept
      : EmptyFlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  EmptyFlexibleUnion& operator=(EmptyFlexibleUnion&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
    EmptyFlexibleUnion(const EmptyFlexibleUnion& other) noexcept : EmptyFlexibleUnion(other.CloneStorage_()){}
    EmptyFlexibleUnion& operator=(const EmptyFlexibleUnion& other) noexcept {
      if (this != &other) {
        storage_ = other.CloneStorage_();
      }
      return *this;
    }

    bool operator==(const EmptyFlexibleUnion& other) const noexcept {
      return *storage_ == *other.storage_;
    }
    bool operator!=(const EmptyFlexibleUnion& other) const noexcept {
      return *storage_ != *other.storage_;
    }
  constexpr bool IsUnknown() const {
    return Which() == ::test_union::EmptyFlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  constexpr ::test_union::EmptyFlexibleUnion::Tag Which() const {
    return EmptyFlexibleUnion::IndexToTag(storage_->index()).value();
  }

  EmptyFlexibleUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
    std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_union::EmptyFlexibleUnion>;
  static constexpr auto kMembers = std::make_tuple(
    ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>());

  explicit EmptyFlexibleUnion(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_union::EmptyFlexibleUnion::Tag tag) {
    switch (tag) {
      default: {
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_union::EmptyFlexibleUnion::Tag> IndexToTag(size_t index) {
    switch (index) {
        default: return ::test_union::EmptyFlexibleUnion::Tag::_do_not_handle_this__write_a_default_case_instead;
    }
  }

};




  
  

  

  inline Pizza::Pizza(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline Pizza::Pizza(::std::vector<::std::string> toppings) noexcept
    : storage_({
      .toppings = std::move(toppings)
    }) {}
    inline Pizza::Pizza(const ::test_union::Pizza& other) noexcept : ::test_union::Pizza(other.CloneStorage_()){}
    inline Pizza& ::test_union::Pizza::operator=(const ::test_union::Pizza& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline Pizza::Pizza(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : Pizza(Storage_{
      .toppings ={},
  }) {}
    inline Pizza& Pizza::toppings(::std::vector<::std::string> value) {
      storage_.toppings = std::move(value);
      return *this;
    }

  
  
  
  

  

  inline Pasta::Pasta(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline Pasta::Pasta(::std::string sauce) noexcept
    : storage_({
      .sauce = std::move(sauce)
    }) {}
    inline Pasta::Pasta(const ::test_union::Pasta& other) noexcept : ::test_union::Pasta(other.CloneStorage_()){}
    inline Pasta& ::test_union::Pasta::operator=(const ::test_union::Pasta& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline Pasta::Pasta(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : Pasta(Storage_{
      .sauce ={},
  }) {}
    inline Pasta& Pasta::sauce(::std::string value) {
      storage_.sauce = std::move(value);
      return *this;
    }

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

  

  inline NullableUnionStruct::NullableUnionStruct(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline NullableUnionStruct::NullableUnionStruct(::fidl::Box<::test_union::Union> the_union) noexcept
    : storage_({
      .the_union = std::move(the_union)
    }) {}
    inline NullableUnionStruct::NullableUnionStruct(const ::test_union::NullableUnionStruct& other) noexcept : ::test_union::NullableUnionStruct(other.CloneStorage_()){}
    inline NullableUnionStruct& ::test_union::NullableUnionStruct::operator=(const ::test_union::NullableUnionStruct& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline NullableUnionStruct::NullableUnionStruct(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : NullableUnionStruct(Storage_{
      .the_union ={},
  }) {}
    inline NullableUnionStruct& NullableUnionStruct::the_union(::fidl::Box<::test_union::Union> value) {
      storage_.the_union = std::move(value);
      return *this;
    }

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

  

  inline Empty::Empty(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline Empty::Empty(uint8_t __reserved) noexcept
    : storage_({
      .__reserved = std::move(__reserved)
    }) {}
    inline Empty::Empty(const ::test_union::Empty& other) noexcept : ::test_union::Empty(other.CloneStorage_()){}
    inline Empty& ::test_union::Empty::operator=(const ::test_union::Empty& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline Empty::Empty(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : Empty(Storage_{
      .__reserved =0u,
  }) {}
    inline Empty& Empty::__reserved(uint8_t value) {
      storage_.__reserved = std::move(value);
      return *this;
    }

  
  
  
  
  
  
  
  

  

  inline TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(::test_union::StrictBoundedUnion xu) noexcept
    : storage_({
      .xu = std::move(xu)
    }) {}
    inline TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(const ::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& other) noexcept : ::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(other.CloneStorage_()){}
    inline TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& ::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::operator=(const ::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse(Storage_{
      .xu =::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
  }) {}
    inline TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse& TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse::xu(::test_union::StrictBoundedUnion value) {
      storage_.xu = std::move(value);
      return *this;
    }

  
  
  
  

  

  inline TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(::test_union::OlderSimpleUnion xu) noexcept
    : storage_({
      .xu = std::move(xu)
    }) {}
    inline TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(const ::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& other) noexcept : ::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(other.CloneStorage_()){}
    inline TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& ::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::operator=(const ::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse(Storage_{
      .xu =::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
  }) {}
    inline TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse& TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse::xu(::test_union::OlderSimpleUnion value) {
      storage_.xu = std::move(value);
      return *this;
    }

  
  
  
  
  
  

  

  inline StructWithNullableUnion::StructWithNullableUnion(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline StructWithNullableUnion::StructWithNullableUnion(::fidl::Box<::test_union::OlderSimpleUnion> x1) noexcept
    : storage_({
      .x1 = std::move(x1)
    }) {}
    inline StructWithNullableUnion::StructWithNullableUnion(const ::test_union::StructWithNullableUnion& other) noexcept : ::test_union::StructWithNullableUnion(other.CloneStorage_()){}
    inline StructWithNullableUnion& ::test_union::StructWithNullableUnion::operator=(const ::test_union::StructWithNullableUnion& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline StructWithNullableUnion::StructWithNullableUnion(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : StructWithNullableUnion(Storage_{
      .x1 ={},
  }) {}
    inline StructWithNullableUnion& StructWithNullableUnion::x1(::fidl::Box<::test_union::OlderSimpleUnion> value) {
      storage_.x1 = std::move(value);
      return *this;
    }

  
  
  
  
  
  

  

  inline UnionSandwich::UnionSandwich(Storage_ storage) noexcept : storage_(std::move(storage)) {}
    inline UnionSandwich::UnionSandwich(uint32_t a, ::test_union::ExplicitFlexibleUnion u, uint32_t b) noexcept
    : storage_({
      .a = std::move(a), 
      .u = std::move(u), 
      .b = std::move(b)
    }) {}
    inline UnionSandwich::UnionSandwich(const ::test_union::UnionSandwich& other) noexcept : ::test_union::UnionSandwich(other.CloneStorage_()){}
    inline UnionSandwich& ::test_union::UnionSandwich::operator=(const ::test_union::UnionSandwich& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }

  inline UnionSandwich::UnionSandwich(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : UnionSandwich(Storage_{
      .a ={},
      .u =::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
      .b ={},
  }) {}
    inline UnionSandwich& UnionSandwich::a(uint32_t value) {
      storage_.a = std::move(value);
      return *this;
    }
    inline UnionSandwich& UnionSandwich::u(::test_union::ExplicitFlexibleUnion value) {
      storage_.u = std::move(value);
      return *this;
    }
    inline UnionSandwich& UnionSandwich::b(uint32_t value) {
      storage_.b = std::move(value);
      return *this;
    }

  
  
  
  
  
  

}  // namespace test_union
namespace fidl {


  

  
  template <>
  struct IsFidlType<::test_union::Pizza> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::Pizza> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::Pizza> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::Pizza, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::Pizza, 16> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::Pasta> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::Pasta> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 16;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::Pasta> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::Pasta, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::Pasta, 16> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::NullableUnionStruct> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::NullableUnionStruct> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::NullableUnionStruct> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::NullableUnionStruct, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::NullableUnionStruct, 16> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::Empty> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::Empty> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 0;
    static constexpr uint32_t kPrimarySize = 1;
    static constexpr uint32_t kMaxOutOfLine = 0;
    static constexpr bool kHasPointer = false;
  };

  template <>
  struct IsStruct<::test_union::Empty> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::Empty, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalEmptyStructCodingTraits<::test_union::Empty> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 32;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolStrictUnionHenceResponseMayBeStackAllocatedResponse, 16> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 8;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::TestProtocolFlexibleUnionHenceResponseMustBeHeapAllocatedResponse, 16> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::StructWithNullableUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::StructWithNullableUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 8;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::StructWithNullableUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::StructWithNullableUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::StructWithNullableUnion, 16> {};

  
  

  
  template <>
  struct IsFidlType<::test_union::UnionSandwich> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::UnionSandwich> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 32;
    static constexpr uint32_t kMaxOutOfLine = 8;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsStruct<::test_union::UnionSandwich> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::UnionSandwich, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_union::UnionSandwich, 32> {};

  


  

  
  template <>
  struct IsFidlType<::test_union::PizzaOrPasta> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::PizzaOrPasta> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::PizzaOrPasta> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::PizzaOrPasta, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::PizzaOrPasta> {};


  

  
  template <>
  struct IsFidlType<::test_union::ExplicitPizzaOrPasta> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::ExplicitPizzaOrPasta> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::ExplicitPizzaOrPasta> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::ExplicitPizzaOrPasta, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitPizzaOrPasta> {};


  

  
  template <>
  struct IsFidlType<::test_union::FlexiblePizzaOrPasta> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::FlexiblePizzaOrPasta> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::FlexiblePizzaOrPasta> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::FlexiblePizzaOrPasta, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::FlexiblePizzaOrPasta> {};


  

  
  template <>
  struct IsFidlType<::test_union::StrictPizzaOrPasta> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::StrictPizzaOrPasta> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::StrictPizzaOrPasta> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::StrictPizzaOrPasta, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictPizzaOrPasta> {};


  

  
  template <>
  struct IsFidlType<::test_union::Union> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::Union> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::Union> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::Union, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::Union> {};


  

  
  template <>
  struct IsFidlType<::test_union::FlexibleUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::FlexibleUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::FlexibleUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::FlexibleUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::FlexibleUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::StrictUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::StrictUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::StrictUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::StrictUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::FieldCollision> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::FieldCollision> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 0;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::FieldCollision> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::FieldCollision, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::FieldCollision> {};


  

  
  template <>
  struct IsFidlType<::test_union::ExplicitUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::ExplicitUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::ExplicitUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::ExplicitUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::ReverseOrdinalUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::ReverseOrdinalUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 0;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::ReverseOrdinalUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::ReverseOrdinalUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::ReverseOrdinalUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::FlexibleFoo> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::FlexibleFoo> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::FlexibleFoo> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::FlexibleFoo, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::FlexibleFoo> {};


  

  
  template <>
  struct IsFidlType<::test_union::StrictFoo> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::StrictFoo> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::StrictFoo> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::StrictFoo, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictFoo> {};


  

  
  template <>
  struct IsFidlType<::test_union::ExplicitFoo> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::ExplicitFoo> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::ExplicitFoo> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::ExplicitFoo, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitFoo> {};


  

  
  template <>
  struct IsFidlType<::test_union::ExplicitStrictFoo> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::ExplicitStrictFoo> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::ExplicitStrictFoo> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::ExplicitStrictFoo, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitStrictFoo> {};


  

  
  template <>
  struct IsFidlType<::test_union::OlderSimpleUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::OlderSimpleUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 8;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::OlderSimpleUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::OlderSimpleUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::OlderSimpleUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::NewerSimpleUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::NewerSimpleUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 3;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::NewerSimpleUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::NewerSimpleUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::NewerSimpleUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::StrictSimpleUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::StrictSimpleUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 4294967295;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::StrictSimpleUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::StrictSimpleUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictSimpleUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::UnionContainingEmptyStruct> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::UnionContainingEmptyStruct> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 0;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::UnionContainingEmptyStruct> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::UnionContainingEmptyStruct, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::UnionContainingEmptyStruct> {};


  

  
  template <>
  struct IsFidlType<::test_union::StrictBoundedUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::StrictBoundedUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 2;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 32;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::StrictBoundedUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::StrictBoundedUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::StrictBoundedUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::ExplicitFlexibleUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::ExplicitFlexibleUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 8;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::ExplicitFlexibleUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::ExplicitFlexibleUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::ExplicitFlexibleUnion> {};


  

  
  template <>
  struct IsFidlType<::test_union::UnionWithAttributes> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::UnionWithAttributes> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 1;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 8;
    static constexpr bool kHasPointer = true;
  };

  template <>
  struct IsUnion<::test_union::UnionWithAttributes> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::UnionWithAttributes, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::UnionWithAttributes> {};


  

  
  template <>
  struct IsFidlType<::test_union::EmptyFlexibleUnion> : public std::true_type {};

  template<>
  struct TypeTraits<::test_union::EmptyFlexibleUnion> {
    static constexpr uint32_t kMaxNumHandles = 0;
    static constexpr uint32_t kMaxDepth = 0;
    static constexpr uint32_t kPrimarySize = 16;
    static constexpr uint32_t kMaxOutOfLine = 0;
    static constexpr bool kHasPointer = false;
  };

  template <>
  struct IsUnion<::test_union::EmptyFlexibleUnion> : public std::true_type {};

  template <>
  struct internal::NaturalCodingTraits<::test_union::EmptyFlexibleUnion, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_union::EmptyFlexibleUnion> {};





#pragma clang diagnostic pop

}  // namespace fidl

