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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.driveroneway/cpp/common_types.h>
#include <fidl/test.driveroneway/cpp/markers.h>
#include <lib/fidl/cpp/natural_coding_traits.h>
#include <lib/fidl/cpp/natural_types.h>

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#include <lib/fidl_driver/cpp/natural_types.h>
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

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

namespace test_driveroneway {

class Payload;

class OneWaySendRequest;

class Payload {
 private:
  struct Storage_;

 public:
  Payload(Storage_ storage) noexcept;
  Payload(uint32_t value) noexcept;

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

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

  bool operator==(const Payload& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::Payload, 4>::Equal(this, &other);
  }
  bool operator!=(const Payload& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::Payload, 4>::Equal(this, &other);
  }

  uint32_t
  value() const {
    return storage_.value;
  }

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

  // Setter for value.
  //

  Payload& value(uint32_t value);

  Payload(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    uint32_t value = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::Payload, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_driveroneway::Payload>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, uint32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::value, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class OneWaySendRequest {
 private:
  struct Storage_;

 public:
  OneWaySendRequest(Storage_ storage) noexcept;
  OneWaySendRequest(::test_driveroneway::Payload payload) noexcept;

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

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

  bool operator==(const OneWaySendRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::OneWaySendRequest, 4>::Equal(this, &other);
  }
  bool operator!=(const OneWaySendRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::OneWaySendRequest, 4>::Equal(this, &other);
  }

  const ::test_driveroneway::Payload&
  payload() const {
    return storage_.payload;
  }

  ::test_driveroneway::Payload& payload() {
    return storage_.payload;
  }

  // Setter for payload.
  //

  OneWaySendRequest& payload(::test_driveroneway::Payload value);

  OneWaySendRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::test_driveroneway::Payload payload;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::OneWaySendRequest, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_driveroneway::OneWaySendRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_driveroneway::Payload, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::payload, 0});
  static constexpr auto kPadding = std::make_tuple();
};

inline Payload::Payload(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline Payload::Payload(uint32_t value) noexcept
    : storage_({.value = std::move(value)}) {}
inline Payload::Payload(const ::test_driveroneway::Payload& other) noexcept : ::test_driveroneway::Payload(other.CloneStorage_()) {}
inline Payload& ::test_driveroneway::Payload::operator=(const ::test_driveroneway::Payload & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

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

inline OneWaySendRequest::OneWaySendRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline OneWaySendRequest::OneWaySendRequest(::test_driveroneway::Payload payload) noexcept
    : storage_({.payload = std::move(payload)}) {}
inline OneWaySendRequest::OneWaySendRequest(const ::test_driveroneway::OneWaySendRequest& other) noexcept : ::test_driveroneway::OneWaySendRequest(other.CloneStorage_()) {}
inline OneWaySendRequest& ::test_driveroneway::OneWaySendRequest::operator=(const ::test_driveroneway::OneWaySendRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline OneWaySendRequest::OneWaySendRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : OneWaySendRequest(Storage_{
                                                                                                              .payload = ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
                                                                                                          }) {}
inline OneWaySendRequest& OneWaySendRequest::payload(::test_driveroneway::Payload value) {
  storage_.payload = std::move(value);
  return *this;
}

}  // namespace test_driveroneway
namespace fidl {

template <>
struct IsFidlType<::test_driveroneway::Payload> : public std::true_type {};

template <>
struct TypeTraits<::test_driveroneway::Payload> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_driveroneway::Payload> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_driveroneway::Payload, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::Payload, 4> {};

template <>
struct IsFidlType<::test_driveroneway::OneWaySendRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_driveroneway::OneWaySendRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_driveroneway::OneWaySendRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_driveroneway::OneWaySendRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_driveroneway::OneWaySendRequest, 4> {};

#pragma clang diagnostic pop

}  // namespace fidl
