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

// fidl_experiment = output_index_json

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

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

::test_typesinprotocols::Struct::Storage_ test_typesinprotocols::Struct::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.__reserved)};
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

::test_typesinprotocols::Basic::Storage_ test_typesinprotocols::Basic::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.uint8),
      ::fidl::internal::NaturalClone(storage_.uint16),
      ::fidl::internal::NaturalClone(storage_.uint32),
      ::fidl::internal::NaturalClone(storage_.uint64),
      ::fidl::internal::NaturalClone(storage_.int8),
      ::fidl::internal::NaturalClone(storage_.int16),
      ::fidl::internal::NaturalClone(storage_.int32),
      ::fidl::internal::NaturalClone(storage_.int64),
      ::fidl::internal::NaturalClone(storage_.float32),
      ::fidl::internal::NaturalClone(storage_.float64),
      ::fidl::internal::NaturalClone(storage_.string),
      ::fidl::internal::NaturalClone(storage_.opt_string)};
}

::test_typesinprotocols::Compound::Storage_ test_typesinprotocols::Compound::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.bits),
      ::fidl::internal::NaturalClone(storage_.enum_),
      ::fidl::internal::NaturalClone(storage_.struct_),
      ::fidl::internal::NaturalClone(storage_.table),
      ::fidl::internal::NaturalClone(storage_.union_),
      ::fidl::internal::NaturalClone(storage_.opt_struct),
      ::fidl::internal::NaturalClone(storage_.opt_union)};
}

::test_typesinprotocols::ArrayBasic::Storage_ test_typesinprotocols::ArrayBasic::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.array_uint8),
      ::fidl::internal::NaturalClone(storage_.array_uint16),
      ::fidl::internal::NaturalClone(storage_.array_uint32),
      ::fidl::internal::NaturalClone(storage_.array_uint64),
      ::fidl::internal::NaturalClone(storage_.array_int8),
      ::fidl::internal::NaturalClone(storage_.array_int16),
      ::fidl::internal::NaturalClone(storage_.array_int32),
      ::fidl::internal::NaturalClone(storage_.array_int64),
      ::fidl::internal::NaturalClone(storage_.array_float32),
      ::fidl::internal::NaturalClone(storage_.array_float64),
      ::fidl::internal::NaturalClone(storage_.array_string),
      ::fidl::internal::NaturalClone(storage_.array_opt_string)};
}

::test_typesinprotocols::ArrayCompound::Storage_ test_typesinprotocols::ArrayCompound::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.array_bits),
      ::fidl::internal::NaturalClone(storage_.array_enum),
      ::fidl::internal::NaturalClone(storage_.array_struct),
      ::fidl::internal::NaturalClone(storage_.array_table),
      ::fidl::internal::NaturalClone(storage_.array_union),
      ::fidl::internal::NaturalClone(storage_.array_opt_struct),
      ::fidl::internal::NaturalClone(storage_.array_opt_union)};
}

::test_typesinprotocols::VectorBasic::Storage_ test_typesinprotocols::VectorBasic::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.vector_uint8),
      ::fidl::internal::NaturalClone(storage_.vector_uint16),
      ::fidl::internal::NaturalClone(storage_.vector_uint32),
      ::fidl::internal::NaturalClone(storage_.vector_uint64),
      ::fidl::internal::NaturalClone(storage_.vector_int8),
      ::fidl::internal::NaturalClone(storage_.vector_int16),
      ::fidl::internal::NaturalClone(storage_.vector_int32),
      ::fidl::internal::NaturalClone(storage_.vector_int64),
      ::fidl::internal::NaturalClone(storage_.vector_float32),
      ::fidl::internal::NaturalClone(storage_.vector_float64),
      ::fidl::internal::NaturalClone(storage_.vector_string),
      ::fidl::internal::NaturalClone(storage_.vector_opt_string)};
}

::test_typesinprotocols::VectorCompound::Storage_ test_typesinprotocols::VectorCompound::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.vector_bits),
      ::fidl::internal::NaturalClone(storage_.vector_enum),
      ::fidl::internal::NaturalClone(storage_.vector_struct),
      ::fidl::internal::NaturalClone(storage_.vector_table),
      ::fidl::internal::NaturalClone(storage_.vector_union),
      ::fidl::internal::NaturalClone(storage_.vector_opt_struct),
      ::fidl::internal::NaturalClone(storage_.vector_opt_union)};
}

::test_typesinprotocols::VectorOptional::Storage_ test_typesinprotocols::VectorOptional::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.opt_vector_uint8),
      ::fidl::internal::NaturalClone(storage_.opt_vector_string),
      ::fidl::internal::NaturalClone(storage_.opt_vector_struct),
      ::fidl::internal::NaturalClone(storage_.opt_vector_opt_struct)};
}

::test_typesinprotocols::ArrayVectorNested::Storage_ test_typesinprotocols::ArrayVectorNested::CloneStorage_() const {
  return Storage_{
      ::fidl::internal::NaturalClone(storage_.array_array_uint8),
      ::fidl::internal::NaturalClone(storage_.array_vector_uint8),
      ::fidl::internal::NaturalClone(storage_.vector_array_uint8),
      ::fidl::internal::NaturalClone(storage_.vector_vector_uint8)};
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

::test_typesinprotocols::Table::Storage_ test_typesinprotocols::Table::CloneStorage_() const {
  return Storage_{};
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

std::shared_ptr<::test_typesinprotocols::Union::Storage_> test_typesinprotocols::Union::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_>();
  }
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

std::shared_ptr<::test_typesinprotocols::ProtocolErrorBasicResult::Storage_> test_typesinprotocols::ProtocolErrorBasicResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorCompoundResult::Storage_> test_typesinprotocols::ProtocolErrorCompoundResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorArrayBasicResult::Storage_> test_typesinprotocols::ProtocolErrorArrayBasicResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorArrayCompoundResult::Storage_> test_typesinprotocols::ProtocolErrorArrayCompoundResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorVectorBasicResult::Storage_> test_typesinprotocols::ProtocolErrorVectorBasicResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorVectorCompoundResult::Storage_> test_typesinprotocols::ProtocolErrorVectorCompoundResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorVectorOptionalResult::Storage_> test_typesinprotocols::ProtocolErrorVectorOptionalResult::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_>();
  }
}

std::shared_ptr<::test_typesinprotocols::ProtocolErrorArrayVectorNestedResult::Storage_> test_typesinprotocols::ProtocolErrorArrayVectorNestedResult::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_>();
  }
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#pragma clang diagnostic pop
