/**
 * Generated by the Emboss compiler.  DO NOT EDIT!
 */
#ifndef TESTDATA_ALIGNMENTS_EMB_H_
#define TESTDATA_ALIGNMENTS_EMB_H_
#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <type_traits>
#include <utility>

#include "runtime/cpp/emboss_cpp_util.h"
#include "runtime/cpp/emboss_enum_view.h"
#include "runtime/cpp/emboss_prelude.h"
#include "runtime/cpp/emboss_text_util.h"

/* NOLINTBEGIN */
namespace emboss {
namespace test {
namespace Alignments {}  // namespace Alignments

template <class Storage>
class GenericAlignmentsView;

namespace Placeholder4 {}  // namespace Placeholder4

template <class Storage>
class GenericPlaceholder4View;

namespace Placeholder6 {}  // namespace Placeholder6

template <class Storage>
class GenericPlaceholder6View;

namespace Alignments {}  // namespace Alignments

template <class View>
struct EmbossReservedInternalIsGenericAlignmentsView;

template <class Storage>
class GenericAlignmentsView final {
 public:
  GenericAlignmentsView() : backing_() {}
  explicit GenericAlignmentsView(Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericAlignmentsView(
      const GenericAlignmentsView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericAlignmentsView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericAlignmentsView(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAlignmentsView(Arg0&& emboss_reserved_local_arg0,
                                 Arg1&& emboss_reserved_local_arg1,
                                 Args&&... emboss_reserved_local_args)
      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
                 ::std::forward<Args>(emboss_reserved_local_args)...) {}

  template <typename OtherStorage>
  GenericAlignmentsView<Storage>& operator=(
      const GenericAlignmentsView<OtherStorage>& emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_zero_offset().Known()) return false;
    if (has_zero_offset().ValueOrDefault() && !zero_offset().Ok()) return false;

    if (!has_zero_offset_substructure().Known()) return false;
    if (has_zero_offset_substructure().ValueOrDefault() &&
        !zero_offset_substructure().Ok())
      return false;

    if (!has_two_offset_substructure().Known()) return false;
    if (has_two_offset_substructure().ValueOrDefault() &&
        !two_offset_substructure().Ok())
      return false;

    if (!has_three_offset().Known()) return false;
    if (has_three_offset().ValueOrDefault() && !three_offset().Ok())
      return false;

    if (!has_four_offset().Known()) return false;
    if (has_four_offset().ValueOrDefault() && !four_offset().Ok()) return false;

    if (!has_eleven_offset().Known()) return false;
    if (has_eleven_offset().ValueOrDefault() && !eleven_offset().Ok())
      return false;

    if (!has_twelve_offset().Known()) return false;
    if (has_twelve_offset().ValueOrDefault() && !twelve_offset().Ok())
      return false;

    if (!has_zero_offset_four_stride_array().Known()) return false;
    if (has_zero_offset_four_stride_array().ValueOrDefault() &&
        !zero_offset_four_stride_array().Ok())
      return false;

    if (!has_zero_offset_six_stride_array().Known()) return false;
    if (has_zero_offset_six_stride_array().ValueOrDefault() &&
        !zero_offset_six_stride_array().Ok())
      return false;

    if (!has_three_offset_four_stride_array().Known()) return false;
    if (has_three_offset_four_stride_array().ValueOrDefault() &&
        !three_offset_four_stride_array().Ok())
      return false;

    if (!has_four_offset_six_stride_array().Known()) return false;
    if (has_four_offset_six_stride_array().ValueOrDefault() &&
        !four_offset_six_stride_array().Ok())
      return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_zero_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_zero_offset().Known()) return false;

    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
        !has_zero_offset().ValueOrDefault())
      return false;
    if (has_zero_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_zero_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
        has_zero_offset().ValueOrDefault() &&
        !zero_offset().Equals(emboss_reserved_local_other.zero_offset()))
      return false;

    if (!has_zero_offset_substructure().Known()) return false;
    if (!emboss_reserved_local_other.has_zero_offset_substructure().Known())
      return false;

    if (emboss_reserved_local_other.has_zero_offset_substructure()
            .ValueOrDefault() &&
        !has_zero_offset_substructure().ValueOrDefault())
      return false;
    if (has_zero_offset_substructure().ValueOrDefault() &&
        !emboss_reserved_local_other.has_zero_offset_substructure()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_zero_offset_substructure()
            .ValueOrDefault() &&
        has_zero_offset_substructure().ValueOrDefault() &&
        !zero_offset_substructure().Equals(
            emboss_reserved_local_other.zero_offset_substructure()))
      return false;

    if (!has_two_offset_substructure().Known()) return false;
    if (!emboss_reserved_local_other.has_two_offset_substructure().Known())
      return false;

    if (emboss_reserved_local_other.has_two_offset_substructure()
            .ValueOrDefault() &&
        !has_two_offset_substructure().ValueOrDefault())
      return false;
    if (has_two_offset_substructure().ValueOrDefault() &&
        !emboss_reserved_local_other.has_two_offset_substructure()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_two_offset_substructure()
            .ValueOrDefault() &&
        has_two_offset_substructure().ValueOrDefault() &&
        !two_offset_substructure().Equals(
            emboss_reserved_local_other.two_offset_substructure()))
      return false;

    if (!has_three_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_three_offset().Known()) return false;

    if (emboss_reserved_local_other.has_three_offset().ValueOrDefault() &&
        !has_three_offset().ValueOrDefault())
      return false;
    if (has_three_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_three_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_three_offset().ValueOrDefault() &&
        has_three_offset().ValueOrDefault() &&
        !three_offset().Equals(emboss_reserved_local_other.three_offset()))
      return false;

    if (!has_four_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_four_offset().Known()) return false;

    if (emboss_reserved_local_other.has_four_offset().ValueOrDefault() &&
        !has_four_offset().ValueOrDefault())
      return false;
    if (has_four_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_four_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_four_offset().ValueOrDefault() &&
        has_four_offset().ValueOrDefault() &&
        !four_offset().Equals(emboss_reserved_local_other.four_offset()))
      return false;

    if (!has_eleven_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_eleven_offset().Known()) return false;

    if (emboss_reserved_local_other.has_eleven_offset().ValueOrDefault() &&
        !has_eleven_offset().ValueOrDefault())
      return false;
    if (has_eleven_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_eleven_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_eleven_offset().ValueOrDefault() &&
        has_eleven_offset().ValueOrDefault() &&
        !eleven_offset().Equals(emboss_reserved_local_other.eleven_offset()))
      return false;

    if (!has_twelve_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_twelve_offset().Known()) return false;

    if (emboss_reserved_local_other.has_twelve_offset().ValueOrDefault() &&
        !has_twelve_offset().ValueOrDefault())
      return false;
    if (has_twelve_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_twelve_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_twelve_offset().ValueOrDefault() &&
        has_twelve_offset().ValueOrDefault() &&
        !twelve_offset().Equals(emboss_reserved_local_other.twelve_offset()))
      return false;

    if (!has_zero_offset_four_stride_array().Known()) return false;
    if (!emboss_reserved_local_other.has_zero_offset_four_stride_array()
             .Known())
      return false;

    if (emboss_reserved_local_other.has_zero_offset_four_stride_array()
            .ValueOrDefault() &&
        !has_zero_offset_four_stride_array().ValueOrDefault())
      return false;
    if (has_zero_offset_four_stride_array().ValueOrDefault() &&
        !emboss_reserved_local_other.has_zero_offset_four_stride_array()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_zero_offset_four_stride_array()
            .ValueOrDefault() &&
        has_zero_offset_four_stride_array().ValueOrDefault() &&
        !zero_offset_four_stride_array().Equals(
            emboss_reserved_local_other.zero_offset_four_stride_array()))
      return false;

    if (!has_zero_offset_six_stride_array().Known()) return false;
    if (!emboss_reserved_local_other.has_zero_offset_six_stride_array().Known())
      return false;

    if (emboss_reserved_local_other.has_zero_offset_six_stride_array()
            .ValueOrDefault() &&
        !has_zero_offset_six_stride_array().ValueOrDefault())
      return false;
    if (has_zero_offset_six_stride_array().ValueOrDefault() &&
        !emboss_reserved_local_other.has_zero_offset_six_stride_array()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_zero_offset_six_stride_array()
            .ValueOrDefault() &&
        has_zero_offset_six_stride_array().ValueOrDefault() &&
        !zero_offset_six_stride_array().Equals(
            emboss_reserved_local_other.zero_offset_six_stride_array()))
      return false;

    if (!has_three_offset_four_stride_array().Known()) return false;
    if (!emboss_reserved_local_other.has_three_offset_four_stride_array()
             .Known())
      return false;

    if (emboss_reserved_local_other.has_three_offset_four_stride_array()
            .ValueOrDefault() &&
        !has_three_offset_four_stride_array().ValueOrDefault())
      return false;
    if (has_three_offset_four_stride_array().ValueOrDefault() &&
        !emboss_reserved_local_other.has_three_offset_four_stride_array()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_three_offset_four_stride_array()
            .ValueOrDefault() &&
        has_three_offset_four_stride_array().ValueOrDefault() &&
        !three_offset_four_stride_array().Equals(
            emboss_reserved_local_other.three_offset_four_stride_array()))
      return false;

    if (!has_four_offset_six_stride_array().Known()) return false;
    if (!emboss_reserved_local_other.has_four_offset_six_stride_array().Known())
      return false;

    if (emboss_reserved_local_other.has_four_offset_six_stride_array()
            .ValueOrDefault() &&
        !has_four_offset_six_stride_array().ValueOrDefault())
      return false;
    if (has_four_offset_six_stride_array().ValueOrDefault() &&
        !emboss_reserved_local_other.has_four_offset_six_stride_array()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_four_offset_six_stride_array()
            .ValueOrDefault() &&
        has_four_offset_six_stride_array().ValueOrDefault() &&
        !four_offset_six_stride_array().Equals(
            emboss_reserved_local_other.four_offset_six_stride_array()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
        !has_zero_offset().ValueOr(false))
      return false;
    if (has_zero_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_zero_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
        has_zero_offset().ValueOr(false) &&
        !zero_offset().UncheckedEquals(
            emboss_reserved_local_other.zero_offset()))
      return false;

    if (emboss_reserved_local_other.has_zero_offset_substructure().ValueOr(
            false) &&
        !has_zero_offset_substructure().ValueOr(false))
      return false;
    if (has_zero_offset_substructure().ValueOr(false) &&
        !emboss_reserved_local_other.has_zero_offset_substructure().ValueOr(
            false))
      return false;

    if (emboss_reserved_local_other.has_zero_offset_substructure().ValueOr(
            false) &&
        has_zero_offset_substructure().ValueOr(false) &&
        !zero_offset_substructure().UncheckedEquals(
            emboss_reserved_local_other.zero_offset_substructure()))
      return false;

    if (emboss_reserved_local_other.has_two_offset_substructure().ValueOr(
            false) &&
        !has_two_offset_substructure().ValueOr(false))
      return false;
    if (has_two_offset_substructure().ValueOr(false) &&
        !emboss_reserved_local_other.has_two_offset_substructure().ValueOr(
            false))
      return false;

    if (emboss_reserved_local_other.has_two_offset_substructure().ValueOr(
            false) &&
        has_two_offset_substructure().ValueOr(false) &&
        !two_offset_substructure().UncheckedEquals(
            emboss_reserved_local_other.two_offset_substructure()))
      return false;

    if (emboss_reserved_local_other.has_three_offset().ValueOr(false) &&
        !has_three_offset().ValueOr(false))
      return false;
    if (has_three_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_three_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_three_offset().ValueOr(false) &&
        has_three_offset().ValueOr(false) &&
        !three_offset().UncheckedEquals(
            emboss_reserved_local_other.three_offset()))
      return false;

    if (emboss_reserved_local_other.has_four_offset().ValueOr(false) &&
        !has_four_offset().ValueOr(false))
      return false;
    if (has_four_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_four_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_four_offset().ValueOr(false) &&
        has_four_offset().ValueOr(false) &&
        !four_offset().UncheckedEquals(
            emboss_reserved_local_other.four_offset()))
      return false;

    if (emboss_reserved_local_other.has_eleven_offset().ValueOr(false) &&
        !has_eleven_offset().ValueOr(false))
      return false;
    if (has_eleven_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_eleven_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_eleven_offset().ValueOr(false) &&
        has_eleven_offset().ValueOr(false) &&
        !eleven_offset().UncheckedEquals(
            emboss_reserved_local_other.eleven_offset()))
      return false;

    if (emboss_reserved_local_other.has_twelve_offset().ValueOr(false) &&
        !has_twelve_offset().ValueOr(false))
      return false;
    if (has_twelve_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_twelve_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_twelve_offset().ValueOr(false) &&
        has_twelve_offset().ValueOr(false) &&
        !twelve_offset().UncheckedEquals(
            emboss_reserved_local_other.twelve_offset()))
      return false;

    if (emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOr(
            false) &&
        !has_zero_offset_four_stride_array().ValueOr(false))
      return false;
    if (has_zero_offset_four_stride_array().ValueOr(false) &&
        !emboss_reserved_local_other.has_zero_offset_four_stride_array()
             .ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOr(
            false) &&
        has_zero_offset_four_stride_array().ValueOr(false) &&
        !zero_offset_four_stride_array().UncheckedEquals(
            emboss_reserved_local_other.zero_offset_four_stride_array()))
      return false;

    if (emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOr(
            false) &&
        !has_zero_offset_six_stride_array().ValueOr(false))
      return false;
    if (has_zero_offset_six_stride_array().ValueOr(false) &&
        !emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOr(
            false))
      return false;

    if (emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOr(
            false) &&
        has_zero_offset_six_stride_array().ValueOr(false) &&
        !zero_offset_six_stride_array().UncheckedEquals(
            emboss_reserved_local_other.zero_offset_six_stride_array()))
      return false;

    if (emboss_reserved_local_other.has_three_offset_four_stride_array()
            .ValueOr(false) &&
        !has_three_offset_four_stride_array().ValueOr(false))
      return false;
    if (has_three_offset_four_stride_array().ValueOr(false) &&
        !emboss_reserved_local_other.has_three_offset_four_stride_array()
             .ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_three_offset_four_stride_array()
            .ValueOr(false) &&
        has_three_offset_four_stride_array().ValueOr(false) &&
        !three_offset_four_stride_array().UncheckedEquals(
            emboss_reserved_local_other.three_offset_four_stride_array()))
      return false;

    if (emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOr(
            false) &&
        !has_four_offset_six_stride_array().ValueOr(false))
      return false;
    if (has_four_offset_six_stride_array().ValueOr(false) &&
        !emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOr(
            false))
      return false;

    if (emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOr(
            false) &&
        has_four_offset_six_stride_array().ValueOr(false) &&
        !four_offset_six_stride_array().UncheckedEquals(
            emboss_reserved_local_other.four_offset_six_stride_array()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream* emboss_reserved_local_stream) const {
    ::std::string emboss_reserved_local_brace;
    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                      &emboss_reserved_local_brace))
      return false;
    if (emboss_reserved_local_brace != "{") return false;
    for (;;) {
      ::std::string emboss_reserved_local_name;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_name))
        return false;
      if (emboss_reserved_local_name == ",")
        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                          &emboss_reserved_local_name))
          return false;
      if (emboss_reserved_local_name == "}") return true;
      ::std::string emboss_reserved_local_colon;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_colon))
        return false;
      if (emboss_reserved_local_colon != ":") return false;
      if (emboss_reserved_local_name == "zero_offset") {
        if (!zero_offset().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "zero_offset_substructure") {
        if (!zero_offset_substructure().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "two_offset_substructure") {
        if (!two_offset_substructure().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "three_offset") {
        if (!three_offset().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "four_offset") {
        if (!four_offset().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "eleven_offset") {
        if (!eleven_offset().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "twelve_offset") {
        if (!twelve_offset().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "zero_offset_four_stride_array") {
        if (!zero_offset_four_stride_array().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "zero_offset_six_stride_array") {
        if (!zero_offset_six_stride_array().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "three_offset_four_stride_array") {
        if (!three_offset_four_stride_array().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "four_offset_six_stride_array") {
        if (!four_offset_six_stride_array().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      return false;
    }
  }

  template <class Stream>
  void WriteToTextStream(
      Stream* emboss_reserved_local_stream,
      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
        emboss_reserved_local_options.PlusOneIndent();
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write("{\n");
    } else {
      emboss_reserved_local_stream->Write("{");
    }
    bool emboss_reserved_local_wrote_field = false;
    if (has_zero_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_offset().IsAggregate() || zero_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("zero_offset: ");
        zero_offset().WriteToTextStream(emboss_reserved_local_stream,
                                        emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !zero_offset().IsAggregate() && !zero_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# zero_offset: UNREADABLE\n");
      }
    }

    if (has_zero_offset_substructure().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_offset_substructure().IsAggregate() ||
          zero_offset_substructure().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("zero_offset_substructure: ");
        zero_offset_substructure().WriteToTextStream(
            emboss_reserved_local_stream, emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !zero_offset_substructure().IsAggregate() &&
                 !zero_offset_substructure().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write(
            "# zero_offset_substructure: UNREADABLE\n");
      }
    }

    if (has_two_offset_substructure().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          two_offset_substructure().IsAggregate() ||
          two_offset_substructure().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("two_offset_substructure: ");
        two_offset_substructure().WriteToTextStream(
            emboss_reserved_local_stream, emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !two_offset_substructure().IsAggregate() &&
                 !two_offset_substructure().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write(
            "# two_offset_substructure: UNREADABLE\n");
      }
    }

    if (has_three_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          three_offset().IsAggregate() || three_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("three_offset: ");
        three_offset().WriteToTextStream(emboss_reserved_local_stream,
                                         emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !three_offset().IsAggregate() && !three_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# three_offset: UNREADABLE\n");
      }
    }

    if (has_four_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          four_offset().IsAggregate() || four_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("four_offset: ");
        four_offset().WriteToTextStream(emboss_reserved_local_stream,
                                        emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !four_offset().IsAggregate() && !four_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# four_offset: UNREADABLE\n");
      }
    }

    if (has_eleven_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          eleven_offset().IsAggregate() || eleven_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("eleven_offset: ");
        eleven_offset().WriteToTextStream(emboss_reserved_local_stream,
                                          emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !eleven_offset().IsAggregate() && !eleven_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# eleven_offset: UNREADABLE\n");
      }
    }

    if (has_twelve_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          twelve_offset().IsAggregate() || twelve_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("twelve_offset: ");
        twelve_offset().WriteToTextStream(emboss_reserved_local_stream,
                                          emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !twelve_offset().IsAggregate() && !twelve_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# twelve_offset: UNREADABLE\n");
      }
    }

    if (has_zero_offset_four_stride_array().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_offset_four_stride_array().IsAggregate() ||
          zero_offset_four_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("zero_offset_four_stride_array: ");
        zero_offset_four_stride_array().WriteToTextStream(
            emboss_reserved_local_stream, emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !zero_offset_four_stride_array().IsAggregate() &&
                 !zero_offset_four_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write(
            "# zero_offset_four_stride_array: UNREADABLE\n");
      }
    }

    if (has_zero_offset_six_stride_array().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_offset_six_stride_array().IsAggregate() ||
          zero_offset_six_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("zero_offset_six_stride_array: ");
        zero_offset_six_stride_array().WriteToTextStream(
            emboss_reserved_local_stream, emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !zero_offset_six_stride_array().IsAggregate() &&
                 !zero_offset_six_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write(
            "# zero_offset_six_stride_array: UNREADABLE\n");
      }
    }

    if (has_three_offset_four_stride_array().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          three_offset_four_stride_array().IsAggregate() ||
          three_offset_four_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("three_offset_four_stride_array: ");
        three_offset_four_stride_array().WriteToTextStream(
            emboss_reserved_local_stream, emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !three_offset_four_stride_array().IsAggregate() &&
                 !three_offset_four_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write(
            "# three_offset_four_stride_array: UNREADABLE\n");
      }
    }

    if (has_four_offset_six_stride_array().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          four_offset_six_stride_array().IsAggregate() ||
          four_offset_six_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("four_offset_six_stride_array: ");
        four_offset_six_stride_array().WriteToTextStream(
            emboss_reserved_local_stream, emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !four_offset_six_stride_array().IsAggregate() &&
                 !four_offset_six_stride_array().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write(
            "# four_offset_six_stride_array: UNREADABLE\n");
      }
    }

    (void)emboss_reserved_local_wrote_field;
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write(
          emboss_reserved_local_options.current_indent());
      emboss_reserved_local_stream->Write("}");
    } else {
      emboss_reserved_local_stream->Write(" }");
    }
  }

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

  zero_offset() const;
  ::emboss::support::Maybe<bool> has_zero_offset() const;

 public:
  typename ::emboss::test::GenericPlaceholder6View<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

  zero_offset_substructure() const;
  ::emboss::support::Maybe<bool> has_zero_offset_substructure() const;

 public:
  typename ::emboss::test::GenericPlaceholder6View<
      typename Storage::template OffsetStorageType</**/ 0, 2>>

  two_offset_substructure() const;
  ::emboss::support::Maybe<bool> has_two_offset_substructure() const;

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 3>>

  three_offset() const;
  ::emboss::support::Maybe<bool> has_three_offset() const;

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 4>>

  four_offset() const;
  ::emboss::support::Maybe<bool> has_four_offset() const;

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 11>>

  eleven_offset() const;
  ::emboss::support::Maybe<bool> has_eleven_offset() const;

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 12>>

  twelve_offset() const;
  ::emboss::support::Maybe<bool> has_twelve_offset() const;

 public:
  typename ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8>

  zero_offset_four_stride_array() const;
  ::emboss::support::Maybe<bool> has_zero_offset_four_stride_array() const;

 public:
  typename ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder6View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 0>::template OffsetStorageType</**/ 6, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 0>, 6, 8>

  zero_offset_six_stride_array() const;
  ::emboss::support::Maybe<bool> has_zero_offset_six_stride_array() const;

 public:
  typename ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 3>::template OffsetStorageType</**/ 4, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 3>, 4, 8>

  three_offset_four_stride_array() const;
  ::emboss::support::Maybe<bool> has_three_offset_four_stride_array() const;

 public:
  typename ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder6View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 4>::template OffsetStorageType</**/ 6, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 4>, 6, 8>

  four_offset_six_stride_array() const;
  ::emboss::support::Maybe<bool> has_four_offset_six_stride_array() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
    EmbossReservedDollarVirtualMaxSizeInBytesView(
        const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView(
        EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView& operator=(
        EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
    EmbossReservedDollarVirtualMinSizeInBytesView(
        const EmbossReservedDollarVirtualMinSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView(
        EmbossReservedDollarVirtualMinSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualMinSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView& operator=(
        EmbossReservedDollarVirtualMinSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericAlignmentsView;
};
using AlignmentsView =
    GenericAlignmentsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AlignmentsWriter =
    GenericAlignmentsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

template <class View>
struct EmbossReservedInternalIsGenericAlignmentsView {
  static constexpr const bool value = false;
};

template <class Storage>
struct EmbossReservedInternalIsGenericAlignmentsView<
    GenericAlignmentsView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericAlignmentsView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeAlignmentsView(T&& emboss_reserved_local_arg) {
  return GenericAlignmentsView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericAlignmentsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeAlignmentsView(T* emboss_reserved_local_data,
                   ::std::size_t emboss_reserved_local_size) {
  return GenericAlignmentsView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericAlignmentsView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedAlignmentsView(T* emboss_reserved_local_data,
                          ::std::size_t emboss_reserved_local_size) {
  return GenericAlignmentsView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace Placeholder4 {}  // namespace Placeholder4

template <class View>
struct EmbossReservedInternalIsGenericPlaceholder4View;

template <class Storage>
class GenericPlaceholder4View final {
 public:
  GenericPlaceholder4View() : backing_() {}
  explicit GenericPlaceholder4View(Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericPlaceholder4View(
      const GenericPlaceholder4View<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericPlaceholder4View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericPlaceholder4View(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericPlaceholder4View(Arg0&& emboss_reserved_local_arg0,
                                   Arg1&& emboss_reserved_local_arg1,
                                   Args&&... emboss_reserved_local_args)
      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
                 ::std::forward<Args>(emboss_reserved_local_args)...) {}

  template <typename OtherStorage>
  GenericPlaceholder4View<Storage>& operator=(
      const GenericPlaceholder4View<OtherStorage>&
          emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_dummy().Known()) return false;
    if (has_dummy().ValueOrDefault() && !dummy().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
    if (!has_dummy().Known()) return false;
    if (!emboss_reserved_local_other.has_dummy().Known()) return false;

    if (emboss_reserved_local_other.has_dummy().ValueOrDefault() &&
        !has_dummy().ValueOrDefault())
      return false;
    if (has_dummy().ValueOrDefault() &&
        !emboss_reserved_local_other.has_dummy().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_dummy().ValueOrDefault() &&
        has_dummy().ValueOrDefault() &&
        !dummy().Equals(emboss_reserved_local_other.dummy()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_dummy().ValueOr(false) &&
        !has_dummy().ValueOr(false))
      return false;
    if (has_dummy().ValueOr(false) &&
        !emboss_reserved_local_other.has_dummy().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_dummy().ValueOr(false) &&
        has_dummy().ValueOr(false) &&
        !dummy().UncheckedEquals(emboss_reserved_local_other.dummy()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream* emboss_reserved_local_stream) const {
    ::std::string emboss_reserved_local_brace;
    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                      &emboss_reserved_local_brace))
      return false;
    if (emboss_reserved_local_brace != "{") return false;
    for (;;) {
      ::std::string emboss_reserved_local_name;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_name))
        return false;
      if (emboss_reserved_local_name == ",")
        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                          &emboss_reserved_local_name))
          return false;
      if (emboss_reserved_local_name == "}") return true;
      ::std::string emboss_reserved_local_colon;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_colon))
        return false;
      if (emboss_reserved_local_colon != ":") return false;
      if (emboss_reserved_local_name == "dummy") {
        if (!dummy().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      return false;
    }
  }

  template <class Stream>
  void WriteToTextStream(
      Stream* emboss_reserved_local_stream,
      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
        emboss_reserved_local_options.PlusOneIndent();
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write("{\n");
    } else {
      emboss_reserved_local_stream->Write("{");
    }
    bool emboss_reserved_local_wrote_field = false;
    if (has_dummy().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          dummy().IsAggregate() || dummy().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("dummy: ");
        dummy().WriteToTextStream(emboss_reserved_local_stream,
                                  emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !dummy().IsAggregate() && !dummy().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# dummy: UNREADABLE\n");
      }
    }

    (void)emboss_reserved_local_wrote_field;
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write(
          emboss_reserved_local_options.current_indent());
      emboss_reserved_local_stream->Write("}");
    } else {
      emboss_reserved_local_stream->Write(" }");
    }
  }

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::BigEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

  dummy() const;
  ::emboss::support::Maybe<bool> has_dummy() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
    EmbossReservedDollarVirtualMaxSizeInBytesView(
        const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView(
        EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView& operator=(
        EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
    EmbossReservedDollarVirtualMinSizeInBytesView(
        const EmbossReservedDollarVirtualMinSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView(
        EmbossReservedDollarVirtualMinSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualMinSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView& operator=(
        EmbossReservedDollarVirtualMinSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericPlaceholder4View;
};
using Placeholder4View =
    GenericPlaceholder4View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using Placeholder4Writer =
    GenericPlaceholder4View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

template <class View>
struct EmbossReservedInternalIsGenericPlaceholder4View {
  static constexpr const bool value = false;
};

template <class Storage>
struct EmbossReservedInternalIsGenericPlaceholder4View<
    GenericPlaceholder4View<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericPlaceholder4View<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakePlaceholder4View(T&& emboss_reserved_local_arg) {
  return GenericPlaceholder4View<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericPlaceholder4View<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakePlaceholder4View(T* emboss_reserved_local_data,
                     ::std::size_t emboss_reserved_local_size) {
  return GenericPlaceholder4View<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericPlaceholder4View<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedPlaceholder4View(T* emboss_reserved_local_data,
                            ::std::size_t emboss_reserved_local_size) {
  return GenericPlaceholder4View<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace Placeholder6 {}  // namespace Placeholder6

template <class View>
struct EmbossReservedInternalIsGenericPlaceholder6View;

template <class Storage>
class GenericPlaceholder6View final {
 public:
  GenericPlaceholder6View() : backing_() {}
  explicit GenericPlaceholder6View(Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericPlaceholder6View(
      const GenericPlaceholder6View<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericPlaceholder6View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericPlaceholder6View(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericPlaceholder6View(Arg0&& emboss_reserved_local_arg0,
                                   Arg1&& emboss_reserved_local_arg1,
                                   Args&&... emboss_reserved_local_args)
      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
                 ::std::forward<Args>(emboss_reserved_local_args)...) {}

  template <typename OtherStorage>
  GenericPlaceholder6View<Storage>& operator=(
      const GenericPlaceholder6View<OtherStorage>&
          emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_zero_offset().Known()) return false;
    if (has_zero_offset().ValueOrDefault() && !zero_offset().Ok()) return false;

    if (!has_two_offset().Known()) return false;
    if (has_two_offset().ValueOrDefault() && !two_offset().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
    if (!has_zero_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_zero_offset().Known()) return false;

    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
        !has_zero_offset().ValueOrDefault())
      return false;
    if (has_zero_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_zero_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
        has_zero_offset().ValueOrDefault() &&
        !zero_offset().Equals(emboss_reserved_local_other.zero_offset()))
      return false;

    if (!has_two_offset().Known()) return false;
    if (!emboss_reserved_local_other.has_two_offset().Known()) return false;

    if (emboss_reserved_local_other.has_two_offset().ValueOrDefault() &&
        !has_two_offset().ValueOrDefault())
      return false;
    if (has_two_offset().ValueOrDefault() &&
        !emboss_reserved_local_other.has_two_offset().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_two_offset().ValueOrDefault() &&
        has_two_offset().ValueOrDefault() &&
        !two_offset().Equals(emboss_reserved_local_other.two_offset()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
        !has_zero_offset().ValueOr(false))
      return false;
    if (has_zero_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_zero_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
        has_zero_offset().ValueOr(false) &&
        !zero_offset().UncheckedEquals(
            emboss_reserved_local_other.zero_offset()))
      return false;

    if (emboss_reserved_local_other.has_two_offset().ValueOr(false) &&
        !has_two_offset().ValueOr(false))
      return false;
    if (has_two_offset().ValueOr(false) &&
        !emboss_reserved_local_other.has_two_offset().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_two_offset().ValueOr(false) &&
        has_two_offset().ValueOr(false) &&
        !two_offset().UncheckedEquals(emboss_reserved_local_other.two_offset()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream* emboss_reserved_local_stream) const {
    ::std::string emboss_reserved_local_brace;
    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                      &emboss_reserved_local_brace))
      return false;
    if (emboss_reserved_local_brace != "{") return false;
    for (;;) {
      ::std::string emboss_reserved_local_name;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_name))
        return false;
      if (emboss_reserved_local_name == ",")
        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                          &emboss_reserved_local_name))
          return false;
      if (emboss_reserved_local_name == "}") return true;
      ::std::string emboss_reserved_local_colon;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_colon))
        return false;
      if (emboss_reserved_local_colon != ":") return false;
      if (emboss_reserved_local_name == "zero_offset") {
        if (!zero_offset().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "two_offset") {
        if (!two_offset().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      return false;
    }
  }

  template <class Stream>
  void WriteToTextStream(
      Stream* emboss_reserved_local_stream,
      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
        emboss_reserved_local_options.PlusOneIndent();
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write("{\n");
    } else {
      emboss_reserved_local_stream->Write("{");
    }
    bool emboss_reserved_local_wrote_field = false;
    if (has_zero_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_offset().IsAggregate() || zero_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("zero_offset: ");
        zero_offset().WriteToTextStream(emboss_reserved_local_stream,
                                        emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !zero_offset().IsAggregate() && !zero_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# zero_offset: UNREADABLE\n");
      }
    }

    if (has_two_offset().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          two_offset().IsAggregate() || two_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("two_offset: ");
        two_offset().WriteToTextStream(emboss_reserved_local_stream,
                                       emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !two_offset().IsAggregate() && !two_offset().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# two_offset: UNREADABLE\n");
      }
    }

    (void)emboss_reserved_local_wrote_field;
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write(
          emboss_reserved_local_options.current_indent());
      emboss_reserved_local_stream->Write("}");
    } else {
      emboss_reserved_local_stream->Write(" }");
    }
  }

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

  zero_offset() const;
  ::emboss::support::Maybe<bool> has_zero_offset() const;

 public:
  typename ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 2>>

  two_offset() const;
  ::emboss::support::Maybe<bool> has_two_offset() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
    EmbossReservedDollarVirtualMaxSizeInBytesView(
        const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView(
        EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMaxSizeInBytesView& operator=(
        EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
    EmbossReservedDollarVirtualMinSizeInBytesView(
        const EmbossReservedDollarVirtualMinSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView(
        EmbossReservedDollarVirtualMinSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualMinSizeInBytesView&) = default;
    EmbossReservedDollarVirtualMinSizeInBytesView& operator=(
        EmbossReservedDollarVirtualMinSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream* emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions&
                               emboss_reserved_local_options) const {
      ::emboss::support::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericPlaceholder6View;
};
using Placeholder6View =
    GenericPlaceholder6View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using Placeholder6Writer =
    GenericPlaceholder6View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

template <class View>
struct EmbossReservedInternalIsGenericPlaceholder6View {
  static constexpr const bool value = false;
};

template <class Storage>
struct EmbossReservedInternalIsGenericPlaceholder6View<
    GenericPlaceholder6View<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericPlaceholder6View<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakePlaceholder6View(T&& emboss_reserved_local_arg) {
  return GenericPlaceholder6View<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericPlaceholder6View<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakePlaceholder6View(T* emboss_reserved_local_data,
                     ::std::size_t emboss_reserved_local_size) {
  return GenericPlaceholder6View<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericPlaceholder6View<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedPlaceholder6View(T* emboss_reserved_local_data,
                            ::std::size_t emboss_reserved_local_size) {
  return GenericPlaceholder6View<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace Alignments {}  // namespace Alignments

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 0>>

GenericAlignmentsView<Storage>::zero_offset() const {
  if (has_zero_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 0>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_zero_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder6View<
    typename Storage::template OffsetStorageType</**/ 0, 0>>

GenericAlignmentsView<Storage>::zero_offset_substructure() const {
  if (has_zero_offset_substructure().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(6LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder6View<
          typename Storage::template OffsetStorageType</**/ 0, 0>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder6View<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_zero_offset_substructure() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder6View<
    typename Storage::template OffsetStorageType</**/ 0, 2>>

GenericAlignmentsView<Storage>::two_offset_substructure() const {
  if (has_two_offset_substructure().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(6LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(2LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder6View<
          typename Storage::template OffsetStorageType</**/ 0, 2>>

          (backing_.template GetOffsetStorage<0, 2>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder6View<
      typename Storage::template OffsetStorageType</**/ 0, 2>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_two_offset_substructure() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 3>>

GenericAlignmentsView<Storage>::three_offset() const {
  if (has_three_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(3LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 3>>

          (backing_.template GetOffsetStorage<0, 3>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 3>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_three_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 4>>

GenericAlignmentsView<Storage>::four_offset() const {
  if (has_four_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 4>>

          (backing_.template GetOffsetStorage<0, 4>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 4>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_four_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 11>>

GenericAlignmentsView<Storage>::eleven_offset() const {
  if (has_eleven_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(11LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 11>>

          (backing_.template GetOffsetStorage<0, 11>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 11>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_eleven_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 12>>

GenericAlignmentsView<Storage>::twelve_offset() const {
  if (has_twelve_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(12LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 12>>

          (backing_.template GetOffsetStorage<0, 12>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 12>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_twelve_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::GenericPlaceholder4View<
        typename Storage::template OffsetStorageType<
            /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

    ,
    typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8>

GenericAlignmentsView<Storage>::zero_offset_four_stride_array() const {
  if (has_zero_offset_four_stride_array().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(12LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::support::GenericArrayView<
          typename ::emboss::test::GenericPlaceholder4View<
              typename Storage::template OffsetStorageType<
                  /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

          ,
          typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_zero_offset_four_stride_array() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::GenericPlaceholder6View<
        typename Storage::template OffsetStorageType<
            /**/ 0, 0>::template OffsetStorageType</**/ 6, 0>>

    ,
    typename Storage::template OffsetStorageType</**/ 0, 0>, 6, 8>

GenericAlignmentsView<Storage>::zero_offset_six_stride_array() const {
  if (has_zero_offset_six_stride_array().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(24LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::support::GenericArrayView<
          typename ::emboss::test::GenericPlaceholder6View<
              typename Storage::template OffsetStorageType<
                  /**/ 0, 0>::template OffsetStorageType</**/ 6, 0>>

          ,
          typename Storage::template OffsetStorageType</**/ 0, 0>, 6, 8>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder6View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 0>::template OffsetStorageType</**/ 6, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 0>, 6, 8>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_zero_offset_six_stride_array() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::GenericPlaceholder4View<
        typename Storage::template OffsetStorageType<
            /**/ 0, 3>::template OffsetStorageType</**/ 4, 0>>

    ,
    typename Storage::template OffsetStorageType</**/ 0, 3>, 4, 8>

GenericAlignmentsView<Storage>::three_offset_four_stride_array() const {
  if (has_three_offset_four_stride_array().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(12LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(3LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::support::GenericArrayView<
          typename ::emboss::test::GenericPlaceholder4View<
              typename Storage::template OffsetStorageType<
                  /**/ 0, 3>::template OffsetStorageType</**/ 4, 0>>

          ,
          typename Storage::template OffsetStorageType</**/ 0, 3>, 4, 8>

          (backing_.template GetOffsetStorage<0, 3>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 3>::template OffsetStorageType</**/ 4, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 3>, 4, 8>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_three_offset_four_stride_array() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::GenericPlaceholder6View<
        typename Storage::template OffsetStorageType<
            /**/ 0, 4>::template OffsetStorageType</**/ 6, 0>>

    ,
    typename Storage::template OffsetStorageType</**/ 0, 4>, 6, 8>

GenericAlignmentsView<Storage>::four_offset_six_stride_array() const {
  if (has_four_offset_six_stride_array().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(24LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::support::GenericArrayView<
          typename ::emboss::test::GenericPlaceholder6View<
              typename Storage::template OffsetStorageType<
                  /**/ 0, 4>::template OffsetStorageType</**/ 6, 0>>

          ,
          typename Storage::template OffsetStorageType</**/ 0, 4>, 6, 8>

          (backing_.template GetOffsetStorage<0, 4>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericPlaceholder6View<
          typename Storage::template OffsetStorageType<
              /**/ 0, 4>::template OffsetStorageType</**/ 6, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 4>, 6, 8>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAlignmentsView<Storage>::has_four_offset_six_stride_array() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace Alignments {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(28LL))
      .ValueOrDefault();
}
}  // namespace Alignments

template <class Storage>
inline constexpr ::std::int32_t GenericAlignmentsView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return Alignments::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAlignmentsView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return Alignments::IntrinsicSizeInBytes();
}

namespace Alignments {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(28LL))
      .ValueOrDefault();
}
}  // namespace Alignments

template <class Storage>
inline constexpr ::std::int32_t GenericAlignmentsView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Alignments::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAlignmentsView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Alignments::MaxSizeInBytes();
}

namespace Alignments {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(28LL))
      .ValueOrDefault();
}
}  // namespace Alignments

template <class Storage>
inline constexpr ::std::int32_t GenericAlignmentsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Alignments::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAlignmentsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Alignments::MinSizeInBytes();
}
namespace Placeholder4 {}  // namespace Placeholder4

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::BigEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        32>>

GenericPlaceholder4View<Storage>::dummy() const {
  if (has_dummy().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              32, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::BigEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              32>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::BigEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericPlaceholder4View<Storage>::has_dummy() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace Placeholder4 {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(4LL))
      .ValueOrDefault();
}
}  // namespace Placeholder4

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder4View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return Placeholder4::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder4View<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return Placeholder4::IntrinsicSizeInBytes();
}

namespace Placeholder4 {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(4LL))
      .ValueOrDefault();
}
}  // namespace Placeholder4

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder4View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Placeholder4::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder4View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Placeholder4::MaxSizeInBytes();
}

namespace Placeholder4 {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(4LL))
      .ValueOrDefault();
}
}  // namespace Placeholder4

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder4View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Placeholder4::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder4View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Placeholder4::MinSizeInBytes();
}
namespace Placeholder6 {}  // namespace Placeholder6

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 0>>

GenericPlaceholder6View<Storage>::zero_offset() const {
  if (has_zero_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 0>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericPlaceholder6View<Storage>::has_zero_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericPlaceholder4View<
    typename Storage::template OffsetStorageType</**/ 0, 2>>

GenericPlaceholder6View<Storage>::two_offset() const {
  if (has_two_offset().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(2LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
      return ::emboss::test::GenericPlaceholder4View<
          typename Storage::template OffsetStorageType</**/ 0, 2>>

          (backing_.template GetOffsetStorage<0, 2>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericPlaceholder4View<
      typename Storage::template OffsetStorageType</**/ 0, 2>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericPlaceholder6View<Storage>::has_two_offset() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace Placeholder6 {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(6LL))
      .ValueOrDefault();
}
}  // namespace Placeholder6

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder6View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return Placeholder6::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder6View<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return Placeholder6::IntrinsicSizeInBytes();
}

namespace Placeholder6 {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(6LL))
      .ValueOrDefault();
}
}  // namespace Placeholder6

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder6View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Placeholder6::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder6View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Placeholder6::MaxSizeInBytes();
}

namespace Placeholder6 {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(6LL))
      .ValueOrDefault();
}
}  // namespace Placeholder6

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder6View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Placeholder6::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericPlaceholder6View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Placeholder6::MinSizeInBytes();
}

}  // namespace test

}  // namespace emboss

/* NOLINTEND */

#endif  // TESTDATA_ALIGNMENTS_EMB_H_
