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

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

::test_protocolpayloads::MainProtocolTwoWayImportWithErrorTopResponse::Storage_
test_protocolpayloads::MainProtocolTwoWayImportWithErrorTopResponse::
    CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.result)};
}

::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse::Storage_
test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResponse::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorTopResponse::Storage_
test_protocolpayloads::MainProtocolTwoWayAnonWithErrorTopResponse::
    CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.result)};
}

::test_protocolpayloads::MainProtocolOnImportWithErrorRequest::Storage_
test_protocolpayloads::MainProtocolOnImportWithErrorRequest::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.result)};
}

::test_protocolpayloads::MainProtocolOnAnonWithErrorResponse::Storage_
test_protocolpayloads::MainProtocolOnAnonWithErrorResponse::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolOnAnonWithErrorRequest::Storage_
test_protocolpayloads::MainProtocolOnAnonWithErrorRequest::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.result)};
}

::test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest::Storage_
test_protocolpayloads::MainProtocolTwoWayAnonWithErrorRequest::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolTwoWayAnonTopResponse::Storage_
test_protocolpayloads::MainProtocolTwoWayAnonTopResponse::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolTwoWayAnonRequest::Storage_
test_protocolpayloads::MainProtocolTwoWayAnonRequest::CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolOneWayAnonRequest::Storage_
test_protocolpayloads::MainProtocolOneWayAnonRequest::CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolOnAnonRequest::Storage_
test_protocolpayloads::MainProtocolOnAnonRequest::CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::LocalStructPayload::Storage_
test_protocolpayloads::LocalStructPayload::CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.a),
                  ::fidl::internal::NaturalClone(storage_.b)};
}

::test_protocolpayloads::MainProtocolTwoWayLocalWithErrorTopResponse::Storage_
test_protocolpayloads::MainProtocolTwoWayLocalWithErrorTopResponse::
    CloneStorage_() const {
  return Storage_{::fidl::internal::NaturalClone(storage_.result)};
}

::test_protocolpayloads::MainProtocolOnLocalWithErrorRequest::Storage_
test_protocolpayloads::MainProtocolOnLocalWithErrorRequest::CloneStorage_()
    const {
  return Storage_{::fidl::internal::NaturalClone(storage_.result)};
}

std::shared_ptr<
    ::test_protocolpayloads::MainProtocolTwoWayImportWithErrorResult::Storage_>
test_protocolpayloads::MainProtocolTwoWayImportWithErrorResult::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_protocolpayloads::MainProtocolTwoWayAnonWithErrorResult::Storage_>
test_protocolpayloads::MainProtocolTwoWayAnonWithErrorResult::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_protocolpayloads::MainProtocolOnImportWithErrorResult::Storage_>
test_protocolpayloads::MainProtocolOnImportWithErrorResult::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_protocolpayloads::MainProtocolOnAnonWithErrorResult::Storage_>
test_protocolpayloads::MainProtocolOnAnonWithErrorResult::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_protocolpayloads::MainProtocolTwoWayLocalWithErrorResult::Storage_>
test_protocolpayloads::MainProtocolTwoWayLocalWithErrorResult::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_protocolpayloads::MainProtocolOnLocalWithErrorResult::Storage_>
test_protocolpayloads::MainProtocolOnLocalWithErrorResult::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_>();
  }
}
