/**
 * Generated by the Emboss compiler.  DO NOT EDIT!
 */
#ifndef TESTDATA_REQUIRES_EMB_H_
#define TESTDATA_REQUIRES_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_prelude.h"

#include "runtime/cpp/emboss_enum_view.h"

#include "runtime/cpp/emboss_text_util.h"



/* NOLINTBEGIN */
namespace emboss {
namespace test {
namespace RequiresIntegers {

}  // namespace RequiresIntegers


template <class Storage>
class GenericRequiresIntegersView;

namespace RequiresBools {
namespace EmbossReservedAnonymousField2 {

}  // namespace EmbossReservedAnonymousField2


template <class Storage>
class GenericEmbossReservedAnonymousField2View;


}  // namespace RequiresBools


template <class Storage>
class GenericRequiresBoolsView;

namespace RequiresEnums {
enum class Enum : ::std::uint64_t;


}  // namespace RequiresEnums


template <class Storage>
class GenericRequiresEnumsView;

namespace RequiresWithOptionalFields {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1


template <class Storage>
class GenericEmbossReservedAnonymousField1View;


}  // namespace RequiresWithOptionalFields


template <class Storage>
class GenericRequiresWithOptionalFieldsView;

namespace RequiresInArrayElements {
namespace Element {

}  // namespace Element


template <class Storage>
class GenericElementView;


}  // namespace RequiresInArrayElements


template <class Storage>
class GenericRequiresInArrayElementsView;


namespace RequiresIntegers {
struct EmbossReservedValidatorForZeroThroughNine {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL))))).ValueOrDefault();
  }
};


}  // namespace RequiresIntegers



namespace RequiresIntegers {
struct EmbossReservedValidatorForTenThroughTwenty {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL))))).ValueOrDefault();
  }
};


}  // namespace RequiresIntegers



namespace RequiresIntegers {
struct EmbossReservedValidatorForDisjoint {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)))), ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL)))))).ValueOrDefault();
  }
};


}  // namespace RequiresIntegers








namespace RequiresIntegers {

}  // namespace RequiresIntegers


template <class View>
struct EmbossReservedInternalIsGenericRequiresIntegersView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericRequiresIntegersView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericRequiresIntegersView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericRequiresIntegersView(
       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>
  GenericRequiresIntegersView<Storage> &operator=(
      const GenericRequiresIntegersView<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_zero_through_nine().Known()) return false;
    if (has_zero_through_nine().ValueOrDefault() && !zero_through_nine().Ok()) return false;

    if (!has_ten_through_twenty().Known()) return false;
    if (has_ten_through_twenty().ValueOrDefault() && !ten_through_twenty().Ok()) return false;

    if (!has_disjoint().Known()) return false;
    if (has_disjoint().ValueOrDefault() && !disjoint().Ok()) return false;

    if (!has_ztn_plus_ttt().Known()) return false;
    if (has_ztn_plus_ttt().ValueOrDefault() && !ztn_plus_ttt().Ok()) return false;

    if (!has_alias_of_zero_through_nine().Known()) return false;
    if (has_alias_of_zero_through_nine().ValueOrDefault() && !alias_of_zero_through_nine().Ok()) return false;

    if (!has_zero_through_nine_plus_five().Known()) return false;
    if (has_zero_through_nine_plus_five().ValueOrDefault() && !zero_through_nine_plus_five().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;


    if (!(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((zero_through_nine().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(zero_through_nine().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>((ten_through_twenty().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(ten_through_twenty().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))))).ValueOr(false))
      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(
      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_zero_through_nine().Known()) return false;
    if (!emboss_reserved_local_other.has_zero_through_nine().Known()) return false;

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

    if (emboss_reserved_local_other.has_zero_through_nine().ValueOrDefault() &&
        has_zero_through_nine().ValueOrDefault() &&
        !zero_through_nine().Equals(emboss_reserved_local_other.zero_through_nine()))
      return false;



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

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

    if (emboss_reserved_local_other.has_ten_through_twenty().ValueOrDefault() &&
        has_ten_through_twenty().ValueOrDefault() &&
        !ten_through_twenty().Equals(emboss_reserved_local_other.ten_through_twenty()))
      return false;



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

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

    if (emboss_reserved_local_other.has_disjoint().ValueOrDefault() &&
        has_disjoint().ValueOrDefault() &&
        !disjoint().Equals(emboss_reserved_local_other.disjoint()))
      return false;

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

    if (emboss_reserved_local_other.has_zero_through_nine().ValueOr(false) &&
        has_zero_through_nine().ValueOr(false) &&
        !zero_through_nine().UncheckedEquals(emboss_reserved_local_other.zero_through_nine()))
      return false;



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

    if (emboss_reserved_local_other.has_ten_through_twenty().ValueOr(false) &&
        has_ten_through_twenty().ValueOr(false) &&
        !ten_through_twenty().UncheckedEquals(emboss_reserved_local_other.ten_through_twenty()))
      return false;



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

    if (emboss_reserved_local_other.has_disjoint().ValueOr(false) &&
        has_disjoint().ValueOr(false) &&
        !disjoint().UncheckedEquals(emboss_reserved_local_other.disjoint()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericRequiresIntegersView<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_through_nine") {
        if (!zero_through_nine().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

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

      if (emboss_reserved_local_name == "zero_through_nine_plus_five") {
        if (!zero_through_nine_plus_five().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_through_nine().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_through_nine().IsAggregate() || zero_through_nine().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_through_nine: ");
        zero_through_nine().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_through_nine().IsAggregate() && !zero_through_nine().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_through_nine: UNREADABLE\n");
      }
    }

    if (has_ten_through_twenty().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          ten_through_twenty().IsAggregate() || ten_through_twenty().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("ten_through_twenty: ");
        ten_through_twenty().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() &&
                 !ten_through_twenty().IsAggregate() && !ten_through_twenty().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("# ten_through_twenty: UNREADABLE\n");
      }
    }

    if (has_disjoint().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          disjoint().IsAggregate() || disjoint().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("disjoint: ");
        disjoint().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() &&
                 !disjoint().IsAggregate() && !disjoint().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("# disjoint: UNREADABLE\n");
      }
    }

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

    if (has_alias_of_zero_through_nine().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          alias_of_zero_through_nine().IsAggregate() || alias_of_zero_through_nine().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("alias_of_zero_through_nine: ");
        alias_of_zero_through_nine().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() &&
                 !alias_of_zero_through_nine().IsAggregate() && !alias_of_zero_through_nine().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("# alias_of_zero_through_nine: UNREADABLE\n");
      }
    }

    if (has_zero_through_nine_plus_five().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          zero_through_nine_plus_five().IsAggregate() || zero_through_nine_plus_five().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_through_nine_plus_five: ");
        zero_through_nine_plus_five().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_through_nine_plus_five().IsAggregate() && !zero_through_nine_plus_five().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_through_nine_plus_five: 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<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 zero_through_nine() const;
  ::emboss::support::Maybe<bool> has_zero_through_nine() const;

 public:
  typename ::emboss::prelude::IntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 ten_through_twenty() const;
  ::emboss::support::Maybe<bool> has_ten_through_twenty() const;

 public:
  typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

 disjoint() const;
  ::emboss::support::Maybe<bool> has_disjoint() const;

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

    explicit EmbossReservedVirtualZtnPlusTttView(
        const GenericRequiresIntegersView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualZtnPlusTttView() = delete;
    EmbossReservedVirtualZtnPlusTttView(const EmbossReservedVirtualZtnPlusTttView &) = default;
    EmbossReservedVirtualZtnPlusTttView(EmbossReservedVirtualZtnPlusTttView &&) = default;
    EmbossReservedVirtualZtnPlusTttView &operator=(const EmbossReservedVirtualZtnPlusTttView &) =
        default;
    EmbossReservedVirtualZtnPlusTttView &operator=(EmbossReservedVirtualZtnPlusTttView &&) =
        default;
    ~EmbossReservedVirtualZtnPlusTttView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_ztn_plus_ttt().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    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; }



   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.zero_through_nine();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 = view_.ten_through_twenty();
      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);

      return emboss_reserved_local_subexpr_5;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(19LL)))).ValueOr(false);
    }

    const GenericRequiresIntegersView view_;
  };
  EmbossReservedVirtualZtnPlusTttView ztn_plus_ttt() const;
  ::emboss::support::Maybe<bool> has_ztn_plus_ttt() const;

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

    explicit EmbossReservedVirtualAliasOfZeroThroughNineView(
        const GenericRequiresIntegersView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAliasOfZeroThroughNineView() = delete;
    EmbossReservedVirtualAliasOfZeroThroughNineView(const EmbossReservedVirtualAliasOfZeroThroughNineView &) = default;
    EmbossReservedVirtualAliasOfZeroThroughNineView(EmbossReservedVirtualAliasOfZeroThroughNineView &&) = default;
    EmbossReservedVirtualAliasOfZeroThroughNineView &operator=(const EmbossReservedVirtualAliasOfZeroThroughNineView &) =
        default;
    EmbossReservedVirtualAliasOfZeroThroughNineView &operator=(EmbossReservedVirtualAliasOfZeroThroughNineView &&) =
        default;
    ~EmbossReservedVirtualAliasOfZeroThroughNineView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_alias_of_zero_through_nine().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    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; }

    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
      return view_.zero_through_nine().TryToWrite(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    void Write(::std::int32_t emboss_reserved_local_value) {
      const bool result = TryToWrite(emboss_reserved_local_value);
      (void)result;
      EMBOSS_CHECK(result);
    }
    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
      view_.zero_through_nine().UncheckedWrite((::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value)).ValueOrDefault());
    }
    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
      if (!ValueIsOk(emboss_reserved_local_value)) return false;
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
      return view_.zero_through_nine().CouldWriteValue(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    template <class Stream>
    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
      return ::emboss::support::ReadIntegerFromTextStream(
          this, emboss_reserved_local_stream);
    }



   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.zero_through_nine();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

      return emboss_reserved_local_subexpr_2;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)))).ValueOr(false);
    }

    const GenericRequiresIntegersView view_;
  };
  EmbossReservedVirtualAliasOfZeroThroughNineView alias_of_zero_through_nine() const;
  ::emboss::support::Maybe<bool> has_alias_of_zero_through_nine() const;

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

    explicit EmbossReservedVirtualZeroThroughNinePlusFiveView(
        const GenericRequiresIntegersView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualZeroThroughNinePlusFiveView() = delete;
    EmbossReservedVirtualZeroThroughNinePlusFiveView(const EmbossReservedVirtualZeroThroughNinePlusFiveView &) = default;
    EmbossReservedVirtualZeroThroughNinePlusFiveView(EmbossReservedVirtualZeroThroughNinePlusFiveView &&) = default;
    EmbossReservedVirtualZeroThroughNinePlusFiveView &operator=(const EmbossReservedVirtualZeroThroughNinePlusFiveView &) =
        default;
    EmbossReservedVirtualZeroThroughNinePlusFiveView &operator=(EmbossReservedVirtualZeroThroughNinePlusFiveView &&) =
        default;
    ~EmbossReservedVirtualZeroThroughNinePlusFiveView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_zero_through_nine_plus_five().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    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; }

    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
      return view_.zero_through_nine().TryToWrite(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    void Write(::std::int32_t emboss_reserved_local_value) {
      const bool result = TryToWrite(emboss_reserved_local_value);
      (void)result;
      EMBOSS_CHECK(result);
    }
    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
      view_.zero_through_nine().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)))).ValueOrDefault());
    }
    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
      if (!ValueIsOk(emboss_reserved_local_value)) return false;
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
      return view_.zero_through_nine().CouldWriteValue(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    template <class Stream>
    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
      return ::emboss::support::ReadIntegerFromTextStream(
          this, emboss_reserved_local_stream);
    }



   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.zero_through_nine();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));

      return emboss_reserved_local_subexpr_3;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOr(false);
    }

    const GenericRequiresIntegersView view_;
  };
  EmbossReservedVirtualZeroThroughNinePlusFiveView zero_through_nine_plus_five() const;
  ::emboss::support::Maybe<bool> has_zero_through_nine_plus_five() 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 GenericRequiresIntegersView;
};
using RequiresIntegersView =
    GenericRequiresIntegersView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using RequiresIntegersWriter =
    GenericRequiresIntegersView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericRequiresIntegersView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeRequiresIntegersView( T &&emboss_reserved_local_arg) {
  return GenericRequiresIntegersView<
      /**/ ::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 GenericRequiresIntegersView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeRequiresIntegersView( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericRequiresIntegersView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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









namespace RequiresBools {


namespace EmbossReservedAnonymousField2 {
struct EmbossReservedValidatorForMustBeTrue {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::Maybe</**/bool>(emboss_reserved_local_value)).ValueOrDefault();
  }
};


}  // namespace EmbossReservedAnonymousField2



namespace EmbossReservedAnonymousField2 {
struct EmbossReservedValidatorForMustBeFalse {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::Equal</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(emboss_reserved_local_value), ::emboss::support::Maybe</**/bool>(false))).ValueOrDefault();
  }
};


}  // namespace EmbossReservedAnonymousField2





namespace EmbossReservedAnonymousField2 {

}  // namespace EmbossReservedAnonymousField2


template <class View>
struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericEmbossReservedAnonymousField2View(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericEmbossReservedAnonymousField2View(
       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>
  GenericEmbossReservedAnonymousField2View<Storage> &operator=(
      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_a().Known()) return false;
    if (has_a().ValueOrDefault() && !a().Ok()) return false;

    if (!has_b().Known()) return false;
    if (has_b().ValueOrDefault() && !b().Ok()) return false;

    if (!has_must_be_true().Known()) return false;
    if (has_must_be_true().ValueOrDefault() && !must_be_true().Ok()) return false;

    if (!has_must_be_false().Known()) return false;
    if (has_must_be_false().ValueOrDefault() && !must_be_false().Ok()) return false;

    if (!has_IntrinsicSizeInBits().Known()) return false;
    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;

    if (!has_MaxSizeInBits().Known()) return false;
    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;

    if (!has_MinSizeInBits().Known()) return false;
    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;



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


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

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

    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
        has_a().ValueOrDefault() &&
        !a().Equals(emboss_reserved_local_other.a()))
      return false;



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

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

    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
        has_b().ValueOrDefault() &&
        !b().Equals(emboss_reserved_local_other.b()))
      return false;



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

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

    if (emboss_reserved_local_other.has_must_be_true().ValueOrDefault() &&
        has_must_be_true().ValueOrDefault() &&
        !must_be_true().Equals(emboss_reserved_local_other.must_be_true()))
      return false;



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

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

    if (emboss_reserved_local_other.has_must_be_false().ValueOrDefault() &&
        has_must_be_false().ValueOrDefault() &&
        !must_be_false().Equals(emboss_reserved_local_other.must_be_false()))
      return false;

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

    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
        has_a().ValueOr(false) &&
        !a().UncheckedEquals(emboss_reserved_local_other.a()))
      return false;



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

    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
        has_b().ValueOr(false) &&
        !b().UncheckedEquals(emboss_reserved_local_other.b()))
      return false;



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

    if (emboss_reserved_local_other.has_must_be_true().ValueOr(false) &&
        has_must_be_true().ValueOr(false) &&
        !must_be_true().UncheckedEquals(emboss_reserved_local_other.must_be_true()))
      return false;



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

    if (emboss_reserved_local_other.has_must_be_false().ValueOr(false) &&
        has_must_be_false().ValueOr(false) &&
        !must_be_false().UncheckedEquals(emboss_reserved_local_other.must_be_false()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBits().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 == "a") {
        if (!a().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

      if (emboss_reserved_local_name == "must_be_false") {
        if (!must_be_false().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_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          a().IsAggregate() || a().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("a: ");
        a().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() &&
                 !a().IsAggregate() && !a().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("# a: UNREADABLE\n");
      }
    }

    if (has_b().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b().IsAggregate() || b().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("b: ");
        b().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() &&
                 !b().IsAggregate() && !b().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("# b: UNREADABLE\n");
      }
    }

    if (has_must_be_true().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          must_be_true().IsAggregate() || must_be_true().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("must_be_true: ");
        must_be_true().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() &&
                 !must_be_true().IsAggregate() && !must_be_true().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("# must_be_true: UNREADABLE\n");
      }
    }

    if (has_must_be_false().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          must_be_false().IsAggregate() || must_be_false().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("must_be_false: ");
        must_be_false().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() &&
                 !must_be_false().IsAggregate() && !must_be_false().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("# must_be_false: 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::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

 a() const;
  ::emboss::support::Maybe<bool> has_a() const;

 public:
  typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 1>>

 b() const;
  ::emboss::support::Maybe<bool> has_b() const;

 public:
  typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

 must_be_true() const;
  ::emboss::support::Maybe<bool> has_must_be_true() const;

 public:
  typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
    typename Storage::template OffsetStorageType</**/0, 3>>

 must_be_false() const;
  ::emboss::support::Maybe<bool> has_must_be_false() const;

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

    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
        default;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
        default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = 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 EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

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

    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
        default;
    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
        default;
    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = 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 EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
    return EmbossReservedDollarVirtualMaxSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

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

    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
        default;
    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
        default;
    ~EmbossReservedDollarVirtualMinSizeInBitsView() = 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 EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
    return EmbossReservedDollarVirtualMinSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }



 private:
  Storage backing_;
  
  

  template <class OtherStorage>
  friend class GenericEmbossReservedAnonymousField2View;
};
using EmbossReservedAnonymousField2View =
    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using EmbossReservedAnonymousField2Writer =
    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericEmbossReservedAnonymousField2View<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeEmbossReservedAnonymousField2View( T &&emboss_reserved_local_arg) {
  return GenericEmbossReservedAnonymousField2View<
      /**/ ::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 GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeEmbossReservedAnonymousField2View( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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

}  // namespace RequiresBools


template <class View>
struct EmbossReservedInternalIsGenericRequiresBoolsView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericRequiresBoolsView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericRequiresBoolsView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericRequiresBoolsView(
       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>
  GenericRequiresBoolsView<Storage> &operator=(
      const GenericRequiresBoolsView<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() && !emboss_reserved_anonymous_field_2().Ok()) return false;

    if (!has_b_must_be_false().Known()) return false;
    if (has_b_must_be_false().ValueOrDefault() && !b_must_be_false().Ok()) return false;

    if (!has_alias_of_a_must_be_true().Known()) return false;
    if (has_alias_of_a_must_be_true().ValueOrDefault() && !alias_of_a_must_be_true().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;

    if (!has_a().Known()) return false;
    if (has_a().ValueOrDefault() && !a().Ok()) return false;

    if (!has_b().Known()) return false;
    if (has_b().ValueOrDefault() && !b().Ok()) return false;

    if (!has_must_be_true().Known()) return false;
    if (has_must_be_true().ValueOrDefault() && !must_be_true().Ok()) return false;

    if (!has_must_be_false().Known()) return false;
    if (has_must_be_false().ValueOrDefault() && !must_be_false().Ok()) return false;


    if (!(::emboss::support::Or</**/bool, bool, bool, bool>((a().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(a().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()), (b().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()))).ValueOr(false))
      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(
      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().Known()) return false;

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

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
        has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
        !emboss_reserved_anonymous_field_2().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
      return false;

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

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
        has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
        !emboss_reserved_anonymous_field_2().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericRequiresBoolsView<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 == "a") {
        if (!a().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

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

      if (emboss_reserved_local_name == "alias_of_a_must_be_true") {
        if (!alias_of_a_must_be_true().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_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          a().IsAggregate() || a().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("a: ");
        a().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() &&
                 !a().IsAggregate() && !a().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("# a: UNREADABLE\n");
      }
    }

    if (has_b().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b().IsAggregate() || b().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("b: ");
        b().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() &&
                 !b().IsAggregate() && !b().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("# b: UNREADABLE\n");
      }
    }

    if (has_must_be_true().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          must_be_true().IsAggregate() || must_be_true().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("must_be_true: ");
        must_be_true().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() &&
                 !must_be_true().IsAggregate() && !must_be_true().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("# must_be_true: UNREADABLE\n");
      }
    }

    if (has_must_be_false().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          must_be_false().IsAggregate() || must_be_false().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("must_be_false: ");
        must_be_false().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() &&
                 !must_be_false().IsAggregate() && !must_be_false().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("# must_be_false: UNREADABLE\n");
      }
    }

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

    if (has_alias_of_a_must_be_true().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          alias_of_a_must_be_true().IsAggregate() || alias_of_a_must_be_true().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("alias_of_a_must_be_true: ");
        alias_of_a_must_be_true().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() &&
                 !alias_of_a_must_be_true().IsAggregate() && !alias_of_a_must_be_true().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("# alias_of_a_must_be_true: 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; }

 private:
  typename ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 emboss_reserved_anonymous_field_2() const;
  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_2() const;

 public:
  auto a() const -> decltype(this->emboss_reserved_anonymous_field_2().a()) {
   return has_a().ValueOrDefault() ? emboss_reserved_anonymous_field_2().a()
                                          : decltype(this->emboss_reserved_anonymous_field_2().a())();
  }
  ::emboss::support::Maybe<bool> has_a() const;

 public:
  auto b() const -> decltype(this->emboss_reserved_anonymous_field_2().b()) {
   return has_b().ValueOrDefault() ? emboss_reserved_anonymous_field_2().b()
                                          : decltype(this->emboss_reserved_anonymous_field_2().b())();
  }
  ::emboss::support::Maybe<bool> has_b() const;

 public:
  auto must_be_true() const -> decltype(this->emboss_reserved_anonymous_field_2().must_be_true()) {
   return has_must_be_true().ValueOrDefault() ? emboss_reserved_anonymous_field_2().must_be_true()
                                          : decltype(this->emboss_reserved_anonymous_field_2().must_be_true())();
  }
  ::emboss::support::Maybe<bool> has_must_be_true() const;

 public:
  auto must_be_false() const -> decltype(this->emboss_reserved_anonymous_field_2().must_be_false()) {
   return has_must_be_false().ValueOrDefault() ? emboss_reserved_anonymous_field_2().must_be_false()
                                          : decltype(this->emboss_reserved_anonymous_field_2().must_be_false())();
  }
  ::emboss::support::Maybe<bool> has_must_be_false() const;

 public:
  class EmbossReservedVirtualBMustBeFalseView final {
   public:
    using ValueType = bool;

    explicit EmbossReservedVirtualBMustBeFalseView(
        const GenericRequiresBoolsView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualBMustBeFalseView() = delete;
    EmbossReservedVirtualBMustBeFalseView(const EmbossReservedVirtualBMustBeFalseView &) = default;
    EmbossReservedVirtualBMustBeFalseView(EmbossReservedVirtualBMustBeFalseView &&) = default;
    EmbossReservedVirtualBMustBeFalseView &operator=(const EmbossReservedVirtualBMustBeFalseView &) =
        default;
    EmbossReservedVirtualBMustBeFalseView &operator=(EmbossReservedVirtualBMustBeFalseView &&) =
        default;
    ~EmbossReservedVirtualBMustBeFalseView() = default;

    bool Read() const {
      EMBOSS_CHECK(view_.has_b_must_be_false().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    bool UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    template <class Stream>
    void WriteToTextStream(Stream *emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions
                               &emboss_reserved_local_options) const {
      ::emboss::support::WriteBooleanViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }



   private:
    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.b();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/bool>(false));

      return emboss_reserved_local_subexpr_3;
    }

    static constexpr bool ValueIsOk(
        bool emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe</**/bool>(emboss_reserved_local_value).ValueOr(false);
    }

    const GenericRequiresBoolsView view_;
  };
  EmbossReservedVirtualBMustBeFalseView b_must_be_false() const;
  ::emboss::support::Maybe<bool> has_b_must_be_false() const;

 public:
  class EmbossReservedVirtualAliasOfAMustBeTrueView final {
   public:
    using ValueType = bool;

    explicit EmbossReservedVirtualAliasOfAMustBeTrueView(
        const GenericRequiresBoolsView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAliasOfAMustBeTrueView() = delete;
    EmbossReservedVirtualAliasOfAMustBeTrueView(const EmbossReservedVirtualAliasOfAMustBeTrueView &) = default;
    EmbossReservedVirtualAliasOfAMustBeTrueView(EmbossReservedVirtualAliasOfAMustBeTrueView &&) = default;
    EmbossReservedVirtualAliasOfAMustBeTrueView &operator=(const EmbossReservedVirtualAliasOfAMustBeTrueView &) =
        default;
    EmbossReservedVirtualAliasOfAMustBeTrueView &operator=(EmbossReservedVirtualAliasOfAMustBeTrueView &&) =
        default;
    ~EmbossReservedVirtualAliasOfAMustBeTrueView() = default;

    bool Read() const {
      EMBOSS_CHECK(view_.has_alias_of_a_must_be_true().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    bool UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    template <class Stream>
    void WriteToTextStream(Stream *emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions
                               &emboss_reserved_local_options) const {
      ::emboss::support::WriteBooleanViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

    bool TryToWrite(bool emboss_reserved_local_value) {
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
      return view_.a().TryToWrite(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    void Write(bool emboss_reserved_local_value) {
      const bool result = TryToWrite(emboss_reserved_local_value);
      (void)result;
      EMBOSS_CHECK(result);
    }
    void UncheckedWrite(bool emboss_reserved_local_value) {
      view_.a().UncheckedWrite((::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value)).ValueOrDefault());
    }
    bool CouldWriteValue(bool emboss_reserved_local_value) {
      if (!ValueIsOk(emboss_reserved_local_value)) return false;
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
      return view_.a().CouldWriteValue(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    template <class Stream>
    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
      return ::emboss::support::ReadIntegerFromTextStream(
          this, emboss_reserved_local_stream);
    }



   private:
    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.a();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());

      return emboss_reserved_local_subexpr_2;
    }

    static constexpr bool ValueIsOk(
        bool emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe</**/bool>(emboss_reserved_local_value).ValueOr(false);
    }

    const GenericRequiresBoolsView view_;
  };
  EmbossReservedVirtualAliasOfAMustBeTrueView alias_of_a_must_be_true() const;
  ::emboss::support::Maybe<bool> has_alias_of_a_must_be_true() 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 GenericRequiresBoolsView;
};
using RequiresBoolsView =
    GenericRequiresBoolsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using RequiresBoolsWriter =
    GenericRequiresBoolsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericRequiresBoolsView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeRequiresBoolsView( T &&emboss_reserved_local_arg) {
  return GenericRequiresBoolsView<
      /**/ ::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 GenericRequiresBoolsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeRequiresBoolsView( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericRequiresBoolsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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


namespace RequiresEnums {
struct EmbossReservedValidatorForC {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0))), ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1))))).ValueOrDefault();
  }
};


}  // namespace RequiresEnums







namespace RequiresEnums {
enum class Enum : ::std::uint64_t {
  EN0 = static_cast</**/::std::int32_t>(0LL),
  EN1 = static_cast</**/::std::int32_t>(1LL),
  EN2 = static_cast</**/::std::int32_t>(2LL),
  EN3 = static_cast</**/::std::int32_t>(3LL),

};
template <class Enum>
class EnumTraits;

template <>
class EnumTraits<Enum> final {
 public:
  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
                                   Enum *emboss_reserved_local_result) {
    if (emboss_reserved_local_name == nullptr) return false;
    if (!strcmp("EN0", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Enum::EN0;
      return true;
    }

    if (!strcmp("EN1", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Enum::EN1;
      return true;
    }

    if (!strcmp("EN2", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Enum::EN2;
      return true;
    }

    if (!strcmp("EN3", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Enum::EN3;
      return true;
    }

    return false;
  }

  static const char *TryToGetNameFromEnum(
      Enum emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Enum::EN0: return "EN0";

      case Enum::EN1: return "EN1";

      case Enum::EN2: return "EN2";

      case Enum::EN3: return "EN3";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(Enum emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Enum::EN0: return true;

      case Enum::EN1: return true;

      case Enum::EN2: return true;

      case Enum::EN3: return true;

      default:
        return false;
    }
  }

  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
                                       Enum emboss_reserved_local_value) {
    const char *emboss_reserved_local_name =
        TryToGetNameFromEnum(emboss_reserved_local_value);
    if (emboss_reserved_local_name == nullptr) {
      emboss_reserved_local_os
          << static_cast</**/ ::std::underlying_type<Enum>::type>(
                 emboss_reserved_local_value);
    } else {
      emboss_reserved_local_os << emboss_reserved_local_name;
    }
    return emboss_reserved_local_os;
  }
};

static inline bool TryToGetEnumFromName(
    const char *emboss_reserved_local_name,
    Enum *emboss_reserved_local_result) {
  return EnumTraits<Enum>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

static inline const char *TryToGetNameFromEnum(
    Enum emboss_reserved_local_value) {
  return EnumTraits<Enum>::TryToGetNameFromEnum(
      emboss_reserved_local_value);
}

static inline bool EnumIsKnown(Enum emboss_reserved_local_value) {
  return EnumTraits<Enum>::EnumIsKnown(emboss_reserved_local_value);
}

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    Enum emboss_reserved_local_value) {
  return EnumTraits<Enum>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}

}  // namespace RequiresEnums


template <class View>
struct EmbossReservedInternalIsGenericRequiresEnumsView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericRequiresEnumsView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericRequiresEnumsView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericRequiresEnumsView(
       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>
  GenericRequiresEnumsView<Storage> &operator=(
      const GenericRequiresEnumsView<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

    using Enum = ::emboss::test::RequiresEnums::Enum;

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


    if (!has_a().Known()) return false;
    if (has_a().ValueOrDefault() && !a().Ok()) return false;

    if (!has_b().Known()) return false;
    if (has_b().ValueOrDefault() && !b().Ok()) return false;

    if (!has_c().Known()) return false;
    if (has_c().ValueOrDefault() && !c().Ok()) return false;

    if (!has_filtered_a().Known()) return false;
    if (has_filtered_a().ValueOrDefault() && !filtered_a().Ok()) return false;

    if (!has_alias_of_a().Known()) return false;
    if (has_alias_of_a().ValueOrDefault() && !alias_of_a().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;


    if (!(::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>((a().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(a().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>()), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0))), ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>((b().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(b().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>()), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0))))).ValueOr(false))
      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(
      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_a().Known()) return false;
    if (!emboss_reserved_local_other.has_a().Known()) return false;

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

    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
        has_a().ValueOrDefault() &&
        !a().Equals(emboss_reserved_local_other.a()))
      return false;



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

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

    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
        has_b().ValueOrDefault() &&
        !b().Equals(emboss_reserved_local_other.b()))
      return false;



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

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

    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
        has_c().ValueOrDefault() &&
        !c().Equals(emboss_reserved_local_other.c()))
      return false;

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

    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
        has_a().ValueOr(false) &&
        !a().UncheckedEquals(emboss_reserved_local_other.a()))
      return false;



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

    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
        has_b().ValueOr(false) &&
        !b().UncheckedEquals(emboss_reserved_local_other.b()))
      return false;



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

    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
        has_c().ValueOr(false) &&
        !c().UncheckedEquals(emboss_reserved_local_other.c()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericRequiresEnumsView<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 == "a") {
        if (!a().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

      if (emboss_reserved_local_name == "alias_of_a") {
        if (!alias_of_a().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_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          a().IsAggregate() || a().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("a: ");
        a().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() &&
                 !a().IsAggregate() && !a().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("# a: UNREADABLE\n");
      }
    }

    if (has_b().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b().IsAggregate() || b().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("b: ");
        b().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() &&
                 !b().IsAggregate() && !b().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("# b: UNREADABLE\n");
      }
    }

    if (has_c().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          c().IsAggregate() || c().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("c: ");
        c().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() &&
                 !c().IsAggregate() && !c().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("# c: UNREADABLE\n");
      }
    }

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

    if (has_alias_of_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          alias_of_a().IsAggregate() || alias_of_a().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("alias_of_a: ");
        alias_of_a().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() &&
                 !alias_of_a().IsAggregate() && !alias_of_a().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("# alias_of_a: 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::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 a() const;
  ::emboss::support::Maybe<bool> has_a() const;

 public:
  typename ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 b() const;
  ::emboss::support::Maybe<bool> has_b() const;

 public:
  typename ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

 c() const;
  ::emboss::support::Maybe<bool> has_c() const;

 public:
  class EmbossReservedVirtualFilteredAView final {
   public:
    using ValueType = ::emboss::test::RequiresEnums::Enum;

    explicit EmbossReservedVirtualFilteredAView(
        const GenericRequiresEnumsView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualFilteredAView() = delete;
    EmbossReservedVirtualFilteredAView(const EmbossReservedVirtualFilteredAView &) = default;
    EmbossReservedVirtualFilteredAView(EmbossReservedVirtualFilteredAView &&) = default;
    EmbossReservedVirtualFilteredAView &operator=(const EmbossReservedVirtualFilteredAView &) =
        default;
    EmbossReservedVirtualFilteredAView &operator=(EmbossReservedVirtualFilteredAView &&) =
        default;
    ~EmbossReservedVirtualFilteredAView() = default;

    ::emboss::test::RequiresEnums::Enum Read() const {
      EMBOSS_CHECK(view_.has_filtered_a().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ::emboss::test::RequiresEnums::Enum UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    template <class Stream>
    void WriteToTextStream(Stream *emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions
                               &emboss_reserved_local_options) const {
      ::emboss::support::WriteEnumViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }



   private:
    ::emboss::support::Maybe</**/ ::emboss::test::RequiresEnums::Enum> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.a();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1)), emboss_reserved_local_subexpr_2);

      return emboss_reserved_local_subexpr_4;
    }

    static constexpr bool ValueIsOk(
        ::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1))).ValueOr(false);
    }

    const GenericRequiresEnumsView view_;
  };
  EmbossReservedVirtualFilteredAView filtered_a() const;
  ::emboss::support::Maybe<bool> has_filtered_a() const;

 public:
  class EmbossReservedVirtualAliasOfAView final {
   public:
    using ValueType = ::emboss::test::RequiresEnums::Enum;

    explicit EmbossReservedVirtualAliasOfAView(
        const GenericRequiresEnumsView &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAliasOfAView() = delete;
    EmbossReservedVirtualAliasOfAView(const EmbossReservedVirtualAliasOfAView &) = default;
    EmbossReservedVirtualAliasOfAView(EmbossReservedVirtualAliasOfAView &&) = default;
    EmbossReservedVirtualAliasOfAView &operator=(const EmbossReservedVirtualAliasOfAView &) =
        default;
    EmbossReservedVirtualAliasOfAView &operator=(EmbossReservedVirtualAliasOfAView &&) =
        default;
    ~EmbossReservedVirtualAliasOfAView() = default;

    ::emboss::test::RequiresEnums::Enum Read() const {
      EMBOSS_CHECK(view_.has_alias_of_a().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ::emboss::test::RequiresEnums::Enum UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    template <class Stream>
    void WriteToTextStream(Stream *emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions
                               &emboss_reserved_local_options) const {
      ::emboss::support::WriteEnumViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

    bool TryToWrite(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
      return view_.a().TryToWrite(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    void Write(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
      const bool result = TryToWrite(emboss_reserved_local_value);
      (void)result;
      EMBOSS_CHECK(result);
    }
    void UncheckedWrite(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
      view_.a().UncheckedWrite((::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value)).ValueOrDefault());
    }
    bool CouldWriteValue(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
      if (!ValueIsOk(emboss_reserved_local_value)) return false;
      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
      return view_.a().CouldWriteValue(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    template <class Stream>
    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
      return ::emboss::support::ReadIntegerFromTextStream(
          this, emboss_reserved_local_stream);
    }



   private:
    ::emboss::support::Maybe</**/ ::emboss::test::RequiresEnums::Enum> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.a();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>());

      return emboss_reserved_local_subexpr_2;
    }

    static constexpr bool ValueIsOk(
        ::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1))).ValueOr(false);
    }

    const GenericRequiresEnumsView view_;
  };
  EmbossReservedVirtualAliasOfAView alias_of_a() const;
  ::emboss::support::Maybe<bool> has_alias_of_a() 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 GenericRequiresEnumsView;
};
using RequiresEnumsView =
    GenericRequiresEnumsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using RequiresEnumsWriter =
    GenericRequiresEnumsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericRequiresEnumsView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeRequiresEnumsView( T &&emboss_reserved_local_arg) {
  return GenericRequiresEnumsView<
      /**/ ::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 GenericRequiresEnumsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeRequiresEnumsView( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericRequiresEnumsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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







namespace RequiresWithOptionalFields {



namespace EmbossReservedAnonymousField1 {
struct EmbossReservedValidatorForBTrue {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::Maybe</**/bool>(emboss_reserved_local_value)).ValueOrDefault();
  }
};


}  // namespace EmbossReservedAnonymousField1





namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1


template <class View>
struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericEmbossReservedAnonymousField1View(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericEmbossReservedAnonymousField1View(
       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>
  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_a().Known()) return false;
    if (has_a().ValueOrDefault() && !a().Ok()) return false;

    if (!has_b_exists().Known()) return false;
    if (has_b_exists().ValueOrDefault() && !b_exists().Ok()) return false;

    if (!has_IntrinsicSizeInBits().Known()) return false;
    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;

    if (!has_MaxSizeInBits().Known()) return false;
    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;

    if (!has_MinSizeInBits().Known()) return false;
    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;

    if (!has_b().Known()) return false;
    if (has_b().ValueOrDefault() && !b().Ok()) return false;

    if (!has_b_true().Known()) return false;
    if (has_b_true().ValueOrDefault() && !b_true().Ok()) return false;



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



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

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

    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
        has_a().ValueOrDefault() &&
        !a().Equals(emboss_reserved_local_other.a()))
      return false;



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

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

    if (emboss_reserved_local_other.has_b_exists().ValueOrDefault() &&
        has_b_exists().ValueOrDefault() &&
        !b_exists().Equals(emboss_reserved_local_other.b_exists()))
      return false;



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

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

    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
        has_b().ValueOrDefault() &&
        !b().Equals(emboss_reserved_local_other.b()))
      return false;



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

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

    if (emboss_reserved_local_other.has_b_true().ValueOrDefault() &&
        has_b_true().ValueOrDefault() &&
        !b_true().Equals(emboss_reserved_local_other.b_true()))
      return false;

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

    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
        has_a().ValueOr(false) &&
        !a().UncheckedEquals(emboss_reserved_local_other.a()))
      return false;



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

    if (emboss_reserved_local_other.has_b_exists().ValueOr(false) &&
        has_b_exists().ValueOr(false) &&
        !b_exists().UncheckedEquals(emboss_reserved_local_other.b_exists()))
      return false;



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

    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
        has_b().ValueOr(false) &&
        !b().UncheckedEquals(emboss_reserved_local_other.b()))
      return false;



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

    if (emboss_reserved_local_other.has_b_true().ValueOr(false) &&
        has_b_true().ValueOr(false) &&
        !b_true().UncheckedEquals(emboss_reserved_local_other.b_true()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBits().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 == "a") {
        if (!a().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

      if (emboss_reserved_local_name == "b_true") {
        if (!b_true().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_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          a().IsAggregate() || a().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("a: ");
        a().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() &&
                 !a().IsAggregate() && !a().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("# a: UNREADABLE\n");
      }
    }

    if (has_b_exists().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b_exists().IsAggregate() || b_exists().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("b_exists: ");
        b_exists().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() &&
                 !b_exists().IsAggregate() && !b_exists().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("# b_exists: UNREADABLE\n");
      }
    }

    if (has_b().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b().IsAggregate() || b().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("b: ");
        b().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() &&
                 !b().IsAggregate() && !b().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("# b: UNREADABLE\n");
      }
    }

    if (has_b_true().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b_true().IsAggregate() || b_true().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("b_true: ");
        b_true().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() &&
                 !b_true().IsAggregate() && !b_true().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("# b_true: 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::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

 a() const;
  ::emboss::support::Maybe<bool> has_a() const;

 public:
  typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 1>>

 b_exists() const;
  ::emboss::support::Maybe<bool> has_b_exists() const;

 public:
  typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 2>>

 b() const;
  ::emboss::support::Maybe<bool> has_b() const;

 public:
  typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

 b_true() const;
  ::emboss::support::Maybe<bool> has_b_true() const;

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

    explicit EmbossReservedDollarVirtualIntrinsicSizeInBitsView(
        const GenericEmbossReservedAnonymousField1View &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = delete;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
        default;
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
        default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBits().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    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; }



   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.b_exists();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_3);

      return emboss_reserved_local_subexpr_4;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericEmbossReservedAnonymousField1View view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() const;

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

    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
        default;
    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
        default;
    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = 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 EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
    return EmbossReservedDollarVirtualMaxSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

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

    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
        default;
    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
        default;
    ~EmbossReservedDollarVirtualMinSizeInBitsView() = 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 EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
    return EmbossReservedDollarVirtualMinSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }



 private:
  Storage backing_;
  
  

  template <class OtherStorage>
  friend class GenericEmbossReservedAnonymousField1View;
};
using EmbossReservedAnonymousField1View =
    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using EmbossReservedAnonymousField1Writer =
    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericEmbossReservedAnonymousField1View<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
  return GenericEmbossReservedAnonymousField1View<
      /**/ ::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 GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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

}  // namespace RequiresWithOptionalFields


template <class View>
struct EmbossReservedInternalIsGenericRequiresWithOptionalFieldsView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericRequiresWithOptionalFieldsView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericRequiresWithOptionalFieldsView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericRequiresWithOptionalFieldsView(
       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>
  GenericRequiresWithOptionalFieldsView<Storage> &operator=(
      const GenericRequiresWithOptionalFieldsView<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().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;

    if (!has_a().Known()) return false;
    if (has_a().ValueOrDefault() && !a().Ok()) return false;

    if (!has_b_exists().Known()) return false;
    if (has_b_exists().ValueOrDefault() && !b_exists().Ok()) return false;

    if (!has_b().Known()) return false;
    if (has_b().ValueOrDefault() && !b().Ok()) return false;

    if (!has_b_true().Known()) return false;
    if (has_b_true().ValueOrDefault() && !b_true().Ok()) return false;


    if (!(::emboss::support::Or</**/bool, bool, bool, bool>((a().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(a().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()), (b().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()))).ValueOr(false))
      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(
      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;

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

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
      return false;

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

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericRequiresWithOptionalFieldsView<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 == "a") {
        if (!a().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

      if (emboss_reserved_local_name == "b_true") {
        if (!b_true().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_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          a().IsAggregate() || a().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("a: ");
        a().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() &&
                 !a().IsAggregate() && !a().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("# a: UNREADABLE\n");
      }
    }

    if (has_b_exists().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b_exists().IsAggregate() || b_exists().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("b_exists: ");
        b_exists().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() &&
                 !b_exists().IsAggregate() && !b_exists().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("# b_exists: UNREADABLE\n");
      }
    }

    if (has_b().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b().IsAggregate() || b().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("b: ");
        b().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() &&
                 !b().IsAggregate() && !b().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("# b: UNREADABLE\n");
      }
    }

    if (has_b_true().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          b_true().IsAggregate() || b_true().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("b_true: ");
        b_true().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() &&
                 !b_true().IsAggregate() && !b_true().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("# b_true: 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; }

 private:
  typename ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 emboss_reserved_anonymous_field_1() const;
  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;

 public:
  auto a() const -> decltype(this->emboss_reserved_anonymous_field_1().a()) {
   return has_a().ValueOrDefault() ? emboss_reserved_anonymous_field_1().a()
                                          : decltype(this->emboss_reserved_anonymous_field_1().a())();
  }
  ::emboss::support::Maybe<bool> has_a() const;

 public:
  auto b_exists() const -> decltype(this->emboss_reserved_anonymous_field_1().b_exists()) {
   return has_b_exists().ValueOrDefault() ? emboss_reserved_anonymous_field_1().b_exists()
                                          : decltype(this->emboss_reserved_anonymous_field_1().b_exists())();
  }
  ::emboss::support::Maybe<bool> has_b_exists() const;

 public:
  auto b() const -> decltype(this->emboss_reserved_anonymous_field_1().b()) {
   return has_b().ValueOrDefault() ? emboss_reserved_anonymous_field_1().b()
                                          : decltype(this->emboss_reserved_anonymous_field_1().b())();
  }
  ::emboss::support::Maybe<bool> has_b() const;

 public:
  auto b_true() const -> decltype(this->emboss_reserved_anonymous_field_1().b_true()) {
   return has_b_true().ValueOrDefault() ? emboss_reserved_anonymous_field_1().b_true()
                                          : decltype(this->emboss_reserved_anonymous_field_1().b_true())();
  }
  ::emboss::support::Maybe<bool> has_b_true() 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 GenericRequiresWithOptionalFieldsView;
};
using RequiresWithOptionalFieldsView =
    GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using RequiresWithOptionalFieldsWriter =
    GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericRequiresWithOptionalFieldsView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeRequiresWithOptionalFieldsView( T &&emboss_reserved_local_arg) {
  return GenericRequiresWithOptionalFieldsView<
      /**/ ::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 GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeRequiresWithOptionalFieldsView( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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



namespace RequiresInArrayElements {
namespace Element {
struct EmbossReservedValidatorForX {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))))).ValueOrDefault();
  }
};


}  // namespace Element





namespace Element {

}  // namespace Element


template <class View>
struct EmbossReservedInternalIsGenericElementView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericElementView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericElementView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericElementView(
       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>
  GenericElementView<Storage> &operator=(
      const GenericElementView<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().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(
      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

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

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

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

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericElementView<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 == "x") {
        if (!x().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_x().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          x().IsAggregate() || x().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("x: ");
        x().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() &&
                 !x().IsAggregate() && !x().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("# x: 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<8, Element::EmbossReservedValidatorForX>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 x() const;
  ::emboss::support::Maybe<bool> has_x() 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 GenericElementView;
};
using ElementView =
    GenericElementView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ElementWriter =
    GenericElementView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericElementView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeElementView( T &&emboss_reserved_local_arg) {
  return GenericElementView<
      /**/ ::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 GenericElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeElementView( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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

}  // namespace RequiresInArrayElements


template <class View>
struct EmbossReservedInternalIsGenericRequiresInArrayElementsView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericRequiresInArrayElementsView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericRequiresInArrayElementsView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericRequiresInArrayElementsView(
       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>
  GenericRequiresInArrayElementsView<Storage> &operator=(
      const GenericRequiresInArrayElementsView<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  

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


    if (!has_xs().Known()) return false;
    if (has_xs().ValueOrDefault() && !xs().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(
      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_xs().Known()) return false;
    if (!emboss_reserved_local_other.has_xs().Known()) return false;

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

    if (emboss_reserved_local_other.has_xs().ValueOrDefault() &&
        has_xs().ValueOrDefault() &&
        !xs().Equals(emboss_reserved_local_other.xs()))
      return false;

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

    if (emboss_reserved_local_other.has_xs().ValueOr(false) &&
        has_xs().ValueOr(false) &&
        !xs().UncheckedEquals(emboss_reserved_local_other.xs()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericRequiresInArrayElementsView<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 == "xs") {
        if (!xs().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_xs().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          xs().IsAggregate() || xs().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("xs: ");
        xs().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() &&
                 !xs().IsAggregate() && !xs().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("# xs: 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::support::GenericArrayView<
    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>

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

 xs() const;
  ::emboss::support::Maybe<bool> has_xs() 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 GenericRequiresInArrayElementsView;
};
using RequiresInArrayElementsView =
    GenericRequiresInArrayElementsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using RequiresInArrayElementsWriter =
    GenericRequiresInArrayElementsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

template <typename T>
inline GenericRequiresInArrayElementsView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeRequiresInArrayElementsView( T &&emboss_reserved_local_arg) {
  return GenericRequiresInArrayElementsView<
      /**/ ::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 GenericRequiresInArrayElementsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeRequiresInArrayElementsView( T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericRequiresInArrayElementsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}

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

namespace RequiresIntegers {

}  // namespace RequiresIntegers


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericRequiresIntegersView<Storage>::zero_through_nine()
    const {

  if ( has_zero_through_nine().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

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

();
}

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


template <class Storage>
inline typename ::emboss::prelude::IntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericRequiresIntegersView<Storage>::ten_through_twenty()
    const {

  if ( has_ten_through_twenty().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::IntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   1>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::IntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

();
}

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


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

 GenericRequiresIntegersView<Storage>::disjoint()
    const {

  if ( has_disjoint().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   2>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

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


template <class Storage>
inline typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZtnPlusTttView
GenericRequiresIntegersView<Storage>::ztn_plus_ttt() const {
  return
      typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZtnPlusTttView(
          *this);
}

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


template <class Storage>
inline typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualAliasOfZeroThroughNineView
GenericRequiresIntegersView<Storage>::alias_of_zero_through_nine() const {
  return
      typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualAliasOfZeroThroughNineView(
          *this);
}

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


template <class Storage>
inline typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZeroThroughNinePlusFiveView
GenericRequiresIntegersView<Storage>::zero_through_nine_plus_five() const {
  return
      typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZeroThroughNinePlusFiveView(
          *this);
}

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


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericRequiresIntegersView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return RequiresIntegers::MinSizeInBytes();
}
namespace RequiresBools {
namespace EmbossReservedAnonymousField2 {

}  // namespace EmbossReservedAnonymousField2


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

 GenericEmbossReservedAnonymousField2View<Storage>::a()
    const {

  if ( has_a().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

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

();
}

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


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 1>>

 GenericEmbossReservedAnonymousField2View<Storage>::b()
    const {

  if ( has_b().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 1>>

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

();
}

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


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

 GenericEmbossReservedAnonymousField2View<Storage>::must_be_true()
    const {

  if ( has_must_be_true().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   2>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

();
}

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


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
    typename Storage::template OffsetStorageType</**/0, 3>>

 GenericEmbossReservedAnonymousField2View<Storage>::must_be_false()
    const {

  if ( has_must_be_false().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
    typename Storage::template OffsetStorageType</**/0, 3>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   3>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
    typename Storage::template OffsetStorageType</**/0, 3>>

();
}

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


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

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField2View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
}

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

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
  return EmbossReservedAnonymousField2::MaxSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField2View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField2::MaxSizeInBits();
}

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

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
  return EmbossReservedAnonymousField2::MinSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField2View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField2::MinSizeInBits();
}

}  // namespace RequiresBools


template <class Storage>
inline typename ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericRequiresBoolsView<Storage>::emboss_reserved_anonymous_field_2()
    const {

  if ( has_emboss_reserved_anonymous_field_2().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   0>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

();
}

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


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresBoolsView<Storage>::has_a() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresBoolsView<Storage>::has_b() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresBoolsView<Storage>::has_must_be_true() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresBoolsView<Storage>::has_must_be_false() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualBMustBeFalseView
GenericRequiresBoolsView<Storage>::b_must_be_false() const {
  return
      typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualBMustBeFalseView(
          *this);
}

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


template <class Storage>
inline typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualAliasOfAMustBeTrueView
GenericRequiresBoolsView<Storage>::alias_of_a_must_be_true() const {
  return
      typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualAliasOfAMustBeTrueView(
          *this);
}

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


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericRequiresBoolsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return RequiresBools::MinSizeInBytes();
}
namespace RequiresEnums {

}  // namespace RequiresEnums


template <class Storage>
inline typename ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericRequiresEnumsView<Storage>::a()
    const {

  if ( has_a().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   0>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

();
}

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


template <class Storage>
inline typename ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericRequiresEnumsView<Storage>::b()
    const {

  if ( has_b().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   1>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

();
}

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


template <class Storage>
inline typename ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

 GenericRequiresEnumsView<Storage>::c()
    const {

  if ( has_c().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   2>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::EnumView<
    /**/ ::emboss::test::RequiresEnums::Enum,
    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

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


template <class Storage>
inline typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualFilteredAView
GenericRequiresEnumsView<Storage>::filtered_a() const {
  return
      typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualFilteredAView(
          *this);
}

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


template <class Storage>
inline typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualAliasOfAView
GenericRequiresEnumsView<Storage>::alias_of_a() const {
  return
      typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualAliasOfAView(
          *this);
}

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


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericRequiresEnumsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return RequiresEnums::MinSizeInBytes();
}
namespace RequiresWithOptionalFields {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

 GenericEmbossReservedAnonymousField1View<Storage>::a()
    const {

  if ( has_a().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

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

();
}

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


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 1>>

 GenericEmbossReservedAnonymousField1View<Storage>::b_exists()
    const {

  if ( has_b_exists().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 1>>

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

();
}

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


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 2>>

 GenericEmbossReservedAnonymousField1View<Storage>::b()
    const {

  if ( has_b().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 2>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   2>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 2>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField1View<Storage>::has_b() const {
  return (b_exists().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b_exists().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
}


template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

 GenericEmbossReservedAnonymousField1View<Storage>::b_true()
    const {

  if ( has_b_true().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   2>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
    typename Storage::template OffsetStorageType</**/0, 2>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField1View<Storage>::has_b_true() const {
  return (b_exists().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b_exists().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
}


template <class Storage>
inline typename GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView
GenericEmbossReservedAnonymousField1View<Storage>::IntrinsicSizeInBits() const {
  return
      typename GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView(
          *this);
}

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


namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t MaxSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
  return EmbossReservedAnonymousField1::MaxSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField1::MaxSizeInBits();
}

namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t MinSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
  return EmbossReservedAnonymousField1::MinSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField1::MinSizeInBits();
}

}  // namespace RequiresWithOptionalFields


template <class Storage>
inline typename ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericRequiresWithOptionalFieldsView<Storage>::emboss_reserved_anonymous_field_1()
    const {

  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   0>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

();
}

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


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresWithOptionalFieldsView<Storage>::has_a() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresWithOptionalFieldsView<Storage>::has_b_exists() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresWithOptionalFieldsView<Storage>::has_b() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_anonymous_field_1().has_b());
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRequiresWithOptionalFieldsView<Storage>::has_b_true() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_anonymous_field_1().has_b_true());
}


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericRequiresWithOptionalFieldsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return RequiresWithOptionalFields::MinSizeInBytes();
}
namespace RequiresInArrayElements {
namespace Element {

}  // namespace Element


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, Element::EmbossReservedValidatorForX>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericElementView<Storage>::x()
    const {

  if ( has_x().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
    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<8, Element::EmbossReservedValidatorForX>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

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

();
}

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


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

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

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

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

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

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

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

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

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

}  // namespace RequiresInArrayElements


template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>

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

 GenericRequiresInArrayElementsView<Storage>::xs()
    const {

  if ( has_xs().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::support::GenericArrayView<
    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>

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

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

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

();
}

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


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

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

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

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

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

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

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

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

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



}  // namespace test



}  // namespace emboss



/* NOLINTEND */

#endif  // TESTDATA_REQUIRES_EMB_H_

