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

// fidl_experiment = output_index_json

#include <fidl/test.anonymous/cpp/natural_types.h>

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

::test_anonymous::OverrideTest::Storage_ test_anonymous::OverrideTest::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.op),
      ::fidl::internal::NaturalClone(storage_.left),
      ::fidl::internal::NaturalClone(storage_.right)};
}

::test_anonymous::TableData::Storage_ test_anonymous::TableData::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.data)};
}

::test_anonymous::SomeProtocolSomeMethodRequest::Storage_ test_anonymous::SomeProtocolSomeMethodRequest::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.union_member),
      ::fidl::internal::NaturalClone(storage_.table_member)};
}

::test_anonymous::SomeProtocolSomeMethodResponse::Storage_ test_anonymous::SomeProtocolSomeMethodResponse::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.bits_member)};
}

::test_anonymous::FunctionApplication::Storage_ test_anonymous::FunctionApplication::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.func),
      ::fidl::internal::NaturalClone(storage_.args),
      ::fidl::internal::NaturalClone(storage_.flags)};
}

::test_anonymous::TableMember::Storage_ test_anonymous::TableMember::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.table_data)};
}

std::shared_ptr<::test_anonymous::Expression::Storage_> test_anonymous::Expression::CloneStorage_() const {
  const Storage_& storage = *storage_;
  switch (storage_->index()) {
    case 1:
      return std::make_shared<Storage_>(
          std::in_place_index<1>,
          ::fidl::internal::NaturalClone(std::get<1>(storage)));
    case 2:
      return std::make_shared<Storage_>(
          std::in_place_index<2>,
          ::fidl::internal::NaturalClone(std::get<2>(storage)));
    case 3:
      return std::make_shared<Storage_>(
          std::in_place_index<3>,
          ::fidl::internal::NaturalClone(std::get<3>(storage)));
    default:
      return std::make_shared<Storage_>();
  }
}

std::shared_ptr<::test_anonymous::UnionMember::Storage_> test_anonymous::UnionMember::CloneStorage_() const {
  const Storage_& storage = *storage_;
  switch (storage_->index()) {
    case 1:
      return std::make_shared<Storage_>(
          std::in_place_index<1>,
          ::fidl::internal::NaturalClone(std::get<1>(storage)));
    default:
      return std::make_shared<Storage_>();
  }
}

std::shared_ptr<::test_anonymous::SomeProtocolSomeMethodResult::Storage_> test_anonymous::SomeProtocolSomeMethodResult::CloneStorage_() const {
  const Storage_& storage = *storage_;
  switch (storage_->index()) {
    case 1:
      return std::make_shared<Storage_>(
          std::in_place_index<1>,
          ::fidl::internal::NaturalClone(std::get<1>(storage)));
    case 2:
      return std::make_shared<Storage_>(
          std::in_place_index<2>,
          ::fidl::internal::NaturalClone(std::get<2>(storage)));
    default:
      return std::make_shared<Storage_>();
  }
}

#pragma clang diagnostic pop
