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

// fidl_experiment = output_index_json

#pragma once

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

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#endif  // __Fuchsia__

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

namespace test_escaping {

class DocCommentWithQuotes;

extern const char* kBasic;

extern const char* kNull;

extern const char* kMax;

extern const char* kSmileLiteral;

extern const char* kSmileLower;

extern const char* kSmileUpper;

extern const char* kSmileLeadingZero;

extern const char* kDollar;

extern const char* kDollarBrace;

/// "pleaseescapethisdocommentproperly"
class DocCommentWithQuotes {
 private:
  struct Storage_;

 public:
  DocCommentWithQuotes(Storage_ storage) noexcept;
  DocCommentWithQuotes(uint8_t __reserved) noexcept;

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

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

  bool operator==(const DocCommentWithQuotes& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_escaping::DocCommentWithQuotes, 1>::Equal(this, &other);
  }
  bool operator!=(const DocCommentWithQuotes& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_escaping::DocCommentWithQuotes, 1>::Equal(this, &other);
  }

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

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

  // Setter for __reserved.
  //

  DocCommentWithQuotes& __reserved(uint8_t value);

  DocCommentWithQuotes(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

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

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_escaping::DocCommentWithQuotes, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_escaping::DocCommentWithQuotes>;
  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();
};

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

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

}  // namespace test_escaping
namespace fidl {

template <>
struct IsFidlType<::test_escaping::DocCommentWithQuotes> : public std::true_type {};

template <>
struct TypeTraits<::test_escaping::DocCommentWithQuotes> {
  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_escaping::DocCommentWithQuotes> : public std::true_type {};

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

#pragma clang diagnostic pop

}  // namespace fidl
