/**
 * Generated by the Emboss compiler.  DO NOT EDIT!
 */
#ifndef TESTDATA_CONDITION_EMB_H_
#define TESTDATA_CONDITION_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 BasicConditional {

}  // namespace BasicConditional


template <class Storage>
class GenericBasicConditionalView;

namespace NegativeConditional {

}  // namespace NegativeConditional


template <class Storage>
class GenericNegativeConditionalView;

namespace ConditionalAndUnconditionalOverlappingFinalField {

}  // namespace ConditionalAndUnconditionalOverlappingFinalField


template <class Storage>
class GenericConditionalAndUnconditionalOverlappingFinalFieldView;

namespace ConditionalBasicConditionalFieldFirst {

}  // namespace ConditionalBasicConditionalFieldFirst


template <class Storage>
class GenericConditionalBasicConditionalFieldFirstView;

namespace ConditionalAndDynamicLocation {

}  // namespace ConditionalAndDynamicLocation


template <class Storage>
class GenericConditionalAndDynamicLocationView;

namespace ConditionUsesMinInt {

}  // namespace ConditionUsesMinInt


template <class Storage>
class GenericConditionUsesMinIntView;

namespace NestedConditional {

}  // namespace NestedConditional


template <class Storage>
class GenericNestedConditionalView;

namespace CorrectNestedConditional {

}  // namespace CorrectNestedConditional


template <class Storage>
class GenericCorrectNestedConditionalView;

namespace AlwaysFalseCondition {

}  // namespace AlwaysFalseCondition


template <class Storage>
class GenericAlwaysFalseConditionView;

namespace OnlyAlwaysFalseCondition {

}  // namespace OnlyAlwaysFalseCondition


template <class Storage>
class GenericOnlyAlwaysFalseConditionView;

namespace EmptyStruct {

}  // namespace EmptyStruct


template <class Storage>
class GenericEmptyStructView;

namespace AlwaysFalseConditionDynamicSize {

}  // namespace AlwaysFalseConditionDynamicSize


template <class Storage>
class GenericAlwaysFalseConditionDynamicSizeView;

namespace ConditionDoesNotContributeToSize {

}  // namespace ConditionDoesNotContributeToSize


template <class Storage>
class GenericConditionDoesNotContributeToSizeView;

enum class OnOff : ::std::uint64_t;

namespace EnumCondition {

}  // namespace EnumCondition


template <class Storage>
class GenericEnumConditionView;

namespace NegativeEnumCondition {

}  // namespace NegativeEnumCondition


template <class Storage>
class GenericNegativeEnumConditionView;

namespace LessThanCondition {

}  // namespace LessThanCondition


template <class Storage>
class GenericLessThanConditionView;

namespace LessThanOrEqualCondition {

}  // namespace LessThanOrEqualCondition


template <class Storage>
class GenericLessThanOrEqualConditionView;

namespace GreaterThanOrEqualCondition {

}  // namespace GreaterThanOrEqualCondition


template <class Storage>
class GenericGreaterThanOrEqualConditionView;

namespace GreaterThanCondition {

}  // namespace GreaterThanCondition


template <class Storage>
class GenericGreaterThanConditionView;

namespace RangeCondition {

}  // namespace RangeCondition


template <class Storage>
class GenericRangeConditionView;

namespace ReverseRangeCondition {

}  // namespace ReverseRangeCondition


template <class Storage>
class GenericReverseRangeConditionView;

namespace AndCondition {

}  // namespace AndCondition


template <class Storage>
class GenericAndConditionView;

namespace OrCondition {

}  // namespace OrCondition


template <class Storage>
class GenericOrConditionView;

namespace ChoiceCondition {
enum class Field : ::std::uint64_t;


}  // namespace ChoiceCondition


template <class Storage>
class GenericChoiceConditionView;

namespace ContainsBits {
namespace EmbossReservedAnonymousField3 {

}  // namespace EmbossReservedAnonymousField3


template <class Storage>
class GenericEmbossReservedAnonymousField3View;


}  // namespace ContainsBits


template <class Storage>
class GenericContainsBitsView;

namespace ContainsContainsBits {

}  // namespace ContainsContainsBits


template <class Storage>
class GenericContainsContainsBitsView;

namespace ConditionalInline {
namespace Type0 {

}  // namespace Type0


template <class Storage>
class GenericType0View;


namespace Type1 {

}  // namespace Type1


template <class Storage>
class GenericType1View;


}  // namespace ConditionalInline


template <class Storage>
class GenericConditionalInlineView;

namespace ConditionalAnonymous {
namespace EmbossReservedAnonymousField2 {

}  // namespace EmbossReservedAnonymousField2


template <class Storage>
class GenericEmbossReservedAnonymousField2View;


}  // namespace ConditionalAnonymous


template <class Storage>
class GenericConditionalAnonymousView;

namespace ConditionalOnFlag {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1


template <class Storage>
class GenericEmbossReservedAnonymousField1View;


}  // namespace ConditionalOnFlag


template <class Storage>
class GenericConditionalOnFlagView;






namespace BasicConditional {

}  // namespace BasicConditional


template <class View>
struct EmbossReservedInternalIsGenericBasicConditionalView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    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;

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



  template <typename OtherStorage>
  bool Equals(
      GenericBasicConditionalView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericBasicConditionalView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericBasicConditionalView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericBasicConditionalView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Equal</**/::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>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericBasicConditionalView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericBasicConditionalView;
};
using BasicConditionalView =
    GenericBasicConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using BasicConditionalWriter =
    GenericBasicConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace NegativeConditional {

}  // namespace NegativeConditional


template <class View>
struct EmbossReservedInternalIsGenericNegativeConditionalView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericNegativeConditionalView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericNegativeConditionalView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericNegativeConditionalView(
       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>
  GenericNegativeConditionalView<Storage> &operator=(
      const GenericNegativeConditionalView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericNegativeConditionalView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericNegativeConditionalView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericNegativeConditionalView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericNegativeConditionalView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::NotEqual</**/::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>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericNegativeConditionalView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericNegativeConditionalView;
};
using NegativeConditionalView =
    GenericNegativeConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using NegativeConditionalWriter =
    GenericNegativeConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ConditionalAndUnconditionalOverlappingFinalField {

}  // namespace ConditionalAndUnconditionalOverlappingFinalField


template <class View>
struct EmbossReservedInternalIsGenericConditionalAndUnconditionalOverlappingFinalFieldView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }



    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(
      GenericConditionalAndUnconditionalOverlappingFinalFieldView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;



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

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

    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
        has_z().ValueOrDefault() &&
        !z().Equals(emboss_reserved_local_other.z()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConditionalAndUnconditionalOverlappingFinalFieldView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;



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

    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
        has_z().ValueOr(false) &&
        !z().UncheckedEquals(emboss_reserved_local_other.z()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConditionalAndUnconditionalOverlappingFinalFieldView<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;
      }

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

      if (emboss_reserved_local_name == "z") {
        if (!z().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

 z() const;
  ::emboss::support::Maybe<bool> has_z() 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 GenericConditionalAndUnconditionalOverlappingFinalFieldView;
};
using ConditionalAndUnconditionalOverlappingFinalFieldView =
    GenericConditionalAndUnconditionalOverlappingFinalFieldView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionalAndUnconditionalOverlappingFinalFieldWriter =
    GenericConditionalAndUnconditionalOverlappingFinalFieldView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace ConditionalBasicConditionalFieldFirst {

}  // namespace ConditionalBasicConditionalFieldFirst


template <class View>
struct EmbossReservedInternalIsGenericConditionalBasicConditionalFieldFirstView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    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;

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }



    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(
      GenericConditionalBasicConditionalFieldFirstView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConditionalBasicConditionalFieldFirstView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericConditionalBasicConditionalFieldFirstView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConditionalBasicConditionalFieldFirstView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() 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 GenericConditionalBasicConditionalFieldFirstView;
};
using ConditionalBasicConditionalFieldFirstView =
    GenericConditionalBasicConditionalFieldFirstView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionalBasicConditionalFieldFirstWriter =
    GenericConditionalBasicConditionalFieldFirstView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ConditionalAndDynamicLocation {

}  // namespace ConditionalAndDynamicLocation


template <class View>
struct EmbossReservedInternalIsGenericConditionalAndDynamicLocationView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



  template <typename OtherStorage>
  bool Equals(
      GenericConditionalAndDynamicLocationView<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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConditionalAndDynamicLocationView<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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericConditionalAndDynamicLocationView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConditionalAndDynamicLocationView<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;
      }

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

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Equal</**/::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>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = view_.y();
      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Maximum</**/::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>(3LL)), emboss_reserved_local_subexpr_7);

      return emboss_reserved_local_subexpr_8;
    }

    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 GenericConditionalAndDynamicLocationView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericConditionalAndDynamicLocationView;
};
using ConditionalAndDynamicLocationView =
    GenericConditionalAndDynamicLocationView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionalAndDynamicLocationWriter =
    GenericConditionalAndDynamicLocationView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace ConditionUsesMinInt {

}  // namespace ConditionUsesMinInt


template <class View>
struct EmbossReservedInternalIsGenericConditionUsesMinIntView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_ok_subexpr_3 = ::emboss::support::Difference</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>(emboss_reserved_local_ok_subexpr_2, ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(9223372036854775680LL)));

    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;

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_3;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int64_t>(-9223372036854775807LL - 1):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



  template <typename OtherStorage>
  bool Equals(
      GenericConditionUsesMinIntView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConditionUsesMinIntView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericConditionUsesMinIntView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConditionUsesMinIntView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Difference</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(9223372036854775680LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Equal</**/::std::int64_t, bool, ::std::int64_t, ::std::int64_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(-9223372036854775807LL - 1)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::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_reserved_local_subexpr_5);

      return emboss_reserved_local_subexpr_6;
    }

    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 GenericConditionUsesMinIntView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericConditionUsesMinIntView;
};
using ConditionUsesMinIntView =
    GenericConditionUsesMinIntView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionUsesMinIntWriter =
    GenericConditionUsesMinIntView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace NestedConditional {

}  // namespace NestedConditional


template <class View>
struct EmbossReservedInternalIsGenericNestedConditionalView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_ok_subexpr_3 = xc();
      const auto emboss_reserved_local_ok_subexpr_4 = (emboss_reserved_local_ok_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    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;

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_4;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xcc().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



  template <typename OtherStorage>
  bool Equals(
      GenericNestedConditionalView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xcc().ValueOrDefault() &&
        has_xcc().ValueOrDefault() &&
        !xcc().Equals(emboss_reserved_local_other.xcc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericNestedConditionalView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;



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

    if (emboss_reserved_local_other.has_xcc().ValueOr(false) &&
        has_xcc().ValueOr(false) &&
        !xcc().UncheckedEquals(emboss_reserved_local_other.xcc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericNestedConditionalView<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;
      }

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

      if (emboss_reserved_local_name == "xcc") {
        if (!xcc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

 xcc() const;
  ::emboss::support::Maybe<bool> has_xcc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Equal</**/::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>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = view_.xc();
      const auto emboss_reserved_local_subexpr_6 = (emboss_reserved_local_subexpr_5.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_5.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::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_9 = ::emboss::support::Maximum</**/::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_reserved_local_subexpr_4, emboss_reserved_local_subexpr_8);

      return emboss_reserved_local_subexpr_9;
    }

    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 GenericNestedConditionalView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericNestedConditionalView;
};
using NestedConditionalView =
    GenericNestedConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using NestedConditionalWriter =
    GenericNestedConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace CorrectNestedConditional {

}  // namespace CorrectNestedConditional


template <class View>
struct EmbossReservedInternalIsGenericCorrectNestedConditionalView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    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;

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }

    if (!has_xcc().Known()) return false;
    if (has_xcc().ValueOrDefault() && !xcc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericCorrectNestedConditionalView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xcc().ValueOrDefault() &&
        has_xcc().ValueOrDefault() &&
        !xcc().Equals(emboss_reserved_local_other.xcc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericCorrectNestedConditionalView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;



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

    if (emboss_reserved_local_other.has_xcc().ValueOr(false) &&
        has_xcc().ValueOr(false) &&
        !xcc().UncheckedEquals(emboss_reserved_local_other.xcc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericCorrectNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericCorrectNestedConditionalView<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;
      }

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

      if (emboss_reserved_local_name == "xcc") {
        if (!xcc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

 xcc() const;
  ::emboss::support::Maybe<bool> has_xcc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Equal</**/::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>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = view_.xc();
      const auto emboss_reserved_local_subexpr_6 = (emboss_reserved_local_subexpr_5.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_5.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_7);
      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::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_10 = ::emboss::support::Maximum</**/::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_reserved_local_subexpr_4, emboss_reserved_local_subexpr_9);

      return emboss_reserved_local_subexpr_10;
    }

    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 GenericCorrectNestedConditionalView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericCorrectNestedConditionalView;
};
using CorrectNestedConditionalView =
    GenericCorrectNestedConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using CorrectNestedConditionalWriter =
    GenericCorrectNestedConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace AlwaysFalseCondition {

}  // namespace AlwaysFalseCondition


template <class View>
struct EmbossReservedInternalIsGenericAlwaysFalseConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericAlwaysFalseConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericAlwaysFalseConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAlwaysFalseConditionView(
       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>
  GenericAlwaysFalseConditionView<Storage> &operator=(
      const GenericAlwaysFalseConditionView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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(
      GenericAlwaysFalseConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAlwaysFalseConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAlwaysFalseConditionView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() 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 GenericAlwaysFalseConditionView;
};
using AlwaysFalseConditionView =
    GenericAlwaysFalseConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AlwaysFalseConditionWriter =
    GenericAlwaysFalseConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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



namespace OnlyAlwaysFalseCondition {

}  // namespace OnlyAlwaysFalseCondition


template <class View>
struct EmbossReservedInternalIsGenericOnlyAlwaysFalseConditionView;

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

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

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

  

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


    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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(
      GenericOnlyAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_xc().Known()) return false;
    if (!emboss_reserved_local_other.has_xc().Known()) return false;

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() 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 GenericOnlyAlwaysFalseConditionView;
};
using OnlyAlwaysFalseConditionView =
    GenericOnlyAlwaysFalseConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using OnlyAlwaysFalseConditionWriter =
    GenericOnlyAlwaysFalseConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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


namespace EmptyStruct {

}  // namespace EmptyStruct


template <class View>
struct EmbossReservedInternalIsGenericEmptyStructView;

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

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

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

  

  bool Ok() const {
    if (!IsComplete()) 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(
      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
     return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
     return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericEmptyStructView<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;

      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;

    (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:
  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 GenericEmptyStructView;
};
using EmptyStructView =
    GenericEmptyStructView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using EmptyStructWriter =
    GenericEmptyStructView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace AlwaysFalseConditionDynamicSize {

}  // namespace AlwaysFalseConditionDynamicSize


template <class View>
struct EmbossReservedInternalIsGenericAlwaysFalseConditionDynamicSizeView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericAlwaysFalseConditionDynamicSizeView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericAlwaysFalseConditionDynamicSizeView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAlwaysFalseConditionDynamicSizeView(
       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>
  GenericAlwaysFalseConditionDynamicSizeView<Storage> &operator=(
      const GenericAlwaysFalseConditionDynamicSizeView<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_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().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_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericAlwaysFalseConditionDynamicSizeView<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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAlwaysFalseConditionDynamicSizeView<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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAlwaysFalseConditionDynamicSizeView<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;
      }

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

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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>(1LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));

      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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAlwaysFalseConditionDynamicSizeView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericAlwaysFalseConditionDynamicSizeView;
};
using AlwaysFalseConditionDynamicSizeView =
    GenericAlwaysFalseConditionDynamicSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AlwaysFalseConditionDynamicSizeWriter =
    GenericAlwaysFalseConditionDynamicSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ConditionDoesNotContributeToSize {

}  // namespace ConditionDoesNotContributeToSize


template <class View>
struct EmbossReservedInternalIsGenericConditionDoesNotContributeToSizeView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }



    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(
      GenericConditionDoesNotContributeToSizeView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConditionDoesNotContributeToSizeView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericConditionDoesNotContributeToSizeView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConditionDoesNotContributeToSizeView<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;
      }

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

      if (emboss_reserved_local_name == "y") {
        if (!y().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() 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 GenericConditionDoesNotContributeToSizeView;
};
using ConditionDoesNotContributeToSizeView =
    GenericConditionDoesNotContributeToSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionDoesNotContributeToSizeWriter =
    GenericConditionDoesNotContributeToSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

template <typename T, ::std::size_t kAlignment>
inline GenericConditionDoesNotContributeToSizeView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedConditionDoesNotContributeToSizeView(
     T *emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return GenericConditionDoesNotContributeToSizeView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}
enum class OnOff : ::std::uint64_t {
  OFF = static_cast</**/::std::int32_t>(0LL),
  ON = static_cast</**/::std::int32_t>(1LL),

};
template <class Enum>
class EnumTraits;

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      OnOff emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case OnOff::OFF: return "OFF";

      case OnOff::ON: return "ON";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(OnOff emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case OnOff::OFF: return true;

      case OnOff::ON: return true;

      default:
        return false;
    }
  }

  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
                                       OnOff 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<OnOff>::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,
    OnOff *emboss_reserved_local_result) {
  return EnumTraits<OnOff>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

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

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

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





namespace EnumCondition {

}  // namespace EnumCondition


template <class View>
struct EmbossReservedInternalIsGenericEnumConditionView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = x();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>());

    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;

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::emboss::test::OnOff>(1):
          if (!xc().Ok()) return false;
          break;




        
        default: break;
      }
    }

    if (!has_xc2().Known()) return false;
    if (has_xc2().ValueOrDefault() && !xc2().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericEnumConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc2().ValueOrDefault() &&
        has_xc2().ValueOrDefault() &&
        !xc2().Equals(emboss_reserved_local_other.xc2()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericEnumConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;



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

    if (emboss_reserved_local_other.has_xc2().ValueOr(false) &&
        has_xc2().ValueOr(false) &&
        !xc2().UncheckedEquals(emboss_reserved_local_other.xc2()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericEnumConditionView<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;
      }

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

      if (emboss_reserved_local_name == "xc2") {
        if (!xc2().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

 xc2() const;
  ::emboss::support::Maybe<bool> has_xc2() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::GreaterThan</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(0)));
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Maximum</**/::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_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6);

      return emboss_reserved_local_subexpr_7;
    }

    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 GenericEnumConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericEnumConditionView;
};
using EnumConditionView =
    GenericEnumConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using EnumConditionWriter =
    GenericEnumConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace NegativeEnumCondition {

}  // namespace NegativeEnumCondition


template <class View>
struct EmbossReservedInternalIsGenericNegativeEnumConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericNegativeEnumConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericNegativeEnumConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericNegativeEnumConditionView(
       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>
  GenericNegativeEnumConditionView<Storage> &operator=(
      const GenericNegativeEnumConditionView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericNegativeEnumConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericNegativeEnumConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericNegativeEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericNegativeEnumConditionView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::NotEqual</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericNegativeEnumConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericNegativeEnumConditionView;
};
using NegativeEnumConditionView =
    GenericNegativeEnumConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using NegativeEnumConditionWriter =
    GenericNegativeEnumConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace LessThanCondition {

}  // namespace LessThanCondition


template <class View>
struct EmbossReservedInternalIsGenericLessThanConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericLessThanConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericLessThanConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericLessThanConditionView(
       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>
  GenericLessThanConditionView<Storage> &operator=(
      const GenericLessThanConditionView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericLessThanConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericLessThanConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericLessThanConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericLessThanConditionView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::LessThan</**/::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>(5LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericLessThanConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericLessThanConditionView;
};
using LessThanConditionView =
    GenericLessThanConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using LessThanConditionWriter =
    GenericLessThanConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace LessThanOrEqualCondition {

}  // namespace LessThanOrEqualCondition


template <class View>
struct EmbossReservedInternalIsGenericLessThanOrEqualConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericLessThanOrEqualConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericLessThanOrEqualConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericLessThanOrEqualConditionView(
       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>
  GenericLessThanOrEqualConditionView<Storage> &operator=(
      const GenericLessThanOrEqualConditionView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericLessThanOrEqualConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericLessThanOrEqualConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericLessThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericLessThanOrEqualConditionView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::LessThanOrEqual</**/::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>(5LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericLessThanOrEqualConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericLessThanOrEqualConditionView;
};
using LessThanOrEqualConditionView =
    GenericLessThanOrEqualConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using LessThanOrEqualConditionWriter =
    GenericLessThanOrEqualConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace GreaterThanOrEqualCondition {

}  // namespace GreaterThanOrEqualCondition


template <class View>
struct EmbossReservedInternalIsGenericGreaterThanOrEqualConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericGreaterThanOrEqualConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericGreaterThanOrEqualConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericGreaterThanOrEqualConditionView(
       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>
  GenericGreaterThanOrEqualConditionView<Storage> &operator=(
      const GenericGreaterThanOrEqualConditionView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericGreaterThanOrEqualConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericGreaterThanOrEqualConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericGreaterThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericGreaterThanOrEqualConditionView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::GreaterThanOrEqual</**/::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>(5LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericGreaterThanOrEqualConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericGreaterThanOrEqualConditionView;
};
using GreaterThanOrEqualConditionView =
    GenericGreaterThanOrEqualConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using GreaterThanOrEqualConditionWriter =
    GenericGreaterThanOrEqualConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace GreaterThanCondition {

}  // namespace GreaterThanCondition


template <class View>
struct EmbossReservedInternalIsGenericGreaterThanConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericGreaterThanConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericGreaterThanConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericGreaterThanConditionView(
       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>
  GenericGreaterThanConditionView<Storage> &operator=(
      const GenericGreaterThanConditionView<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;

    if (!has_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericGreaterThanConditionView<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;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericGreaterThanConditionView<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;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericGreaterThanConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericGreaterThanConditionView<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;
      }

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::GreaterThan</**/::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>(5LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericGreaterThanConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericGreaterThanConditionView;
};
using GreaterThanConditionView =
    GenericGreaterThanConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using GreaterThanConditionWriter =
    GenericGreaterThanConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace RangeCondition {

}  // namespace RangeCondition


template <class View>
struct EmbossReservedInternalIsGenericRangeConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericRangeConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericRangeConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericRangeConditionView(
       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>
  GenericRangeConditionView<Storage> &operator=(
      const GenericRangeConditionView<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_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().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_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericRangeConditionView<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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericRangeConditionView<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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericRangeConditionView<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;
      }

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

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), emboss_reserved_local_subexpr_2);
      const auto emboss_reserved_local_subexpr_4 = view_.y();
      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_5);
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_7, emboss_reserved_local_subexpr_8);
      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_9, ::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_11 = ::emboss::support::Maximum</**/::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_10);

      return emboss_reserved_local_subexpr_11;
    }

    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 GenericRangeConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericRangeConditionView;
};
using RangeConditionView =
    GenericRangeConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using RangeConditionWriter =
    GenericRangeConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ReverseRangeCondition {

}  // namespace ReverseRangeCondition


template <class View>
struct EmbossReservedInternalIsGenericReverseRangeConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericReverseRangeConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericReverseRangeConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericReverseRangeConditionView(
       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>
  GenericReverseRangeConditionView<Storage> &operator=(
      const GenericReverseRangeConditionView<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_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().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_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericReverseRangeConditionView<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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericReverseRangeConditionView<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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericReverseRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericReverseRangeConditionView<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;
      }

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

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.y();
      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::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
      const auto emboss_reserved_local_subexpr_4 = view_.x();
      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_5);
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_7, emboss_reserved_local_subexpr_8);
      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_9, ::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_11 = ::emboss::support::Maximum</**/::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_10);

      return emboss_reserved_local_subexpr_11;
    }

    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 GenericReverseRangeConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericReverseRangeConditionView;
};
using ReverseRangeConditionView =
    GenericReverseRangeConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ReverseRangeConditionWriter =
    GenericReverseRangeConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace AndCondition {

}  // namespace AndCondition


template <class View>
struct EmbossReservedInternalIsGenericAndConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericAndConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericAndConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAndConditionView(
       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>
  GenericAndConditionView<Storage> &operator=(
      const GenericAndConditionView<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_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().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_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericAndConditionView<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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAndConditionView<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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericAndConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAndConditionView<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;
      }

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

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Equal</**/::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>(5LL)));
      const auto emboss_reserved_local_subexpr_4 = view_.y();
      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::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_9 = ::emboss::support::Maximum</**/::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_8);

      return emboss_reserved_local_subexpr_9;
    }

    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 GenericAndConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericAndConditionView;
};
using AndConditionView =
    GenericAndConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AndConditionWriter =
    GenericAndConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace OrCondition {

}  // namespace OrCondition


template <class View>
struct EmbossReservedInternalIsGenericOrConditionView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericOrConditionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericOrConditionView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericOrConditionView(
       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>
  GenericOrConditionView<Storage> &operator=(
      const GenericOrConditionView<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_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().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_xc().Known()) return false;
    if (has_xc().ValueOrDefault() && !xc().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericOrConditionView<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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
        has_xc().ValueOrDefault() &&
        !xc().Equals(emboss_reserved_local_other.xc()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericOrConditionView<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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
        has_xc().ValueOr(false) &&
        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericOrConditionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericOrConditionView<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;
      }

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

      if (emboss_reserved_local_name == "xc") {
        if (!xc().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");
      }
    }

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xc() const;
  ::emboss::support::Maybe<bool> has_xc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::Equal</**/::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>(5LL)));
      const auto emboss_reserved_local_subexpr_4 = view_.y();
      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Or</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::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_9 = ::emboss::support::Maximum</**/::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_8);

      return emboss_reserved_local_subexpr_9;
    }

    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 GenericOrConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericOrConditionView;
};
using OrConditionView =
    GenericOrConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using OrConditionWriter =
    GenericOrConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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






namespace ChoiceCondition {
enum class Field : ::std::uint64_t {
  USE_X = static_cast</**/::std::int32_t>(1LL),
  USE_Y = static_cast</**/::std::int32_t>(2LL),

};
template <class Enum>
class EnumTraits;

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      Field emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Field::USE_X: return "USE_X";

      case Field::USE_Y: return "USE_Y";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(Field emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Field::USE_X: return true;

      case Field::USE_Y: return true;

      default:
        return false;
    }
  }

  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
                                       Field 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<Field>::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,
    Field *emboss_reserved_local_result) {
  return EnumTraits<Field>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

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

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

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

}  // namespace ChoiceCondition


template <class View>
struct EmbossReservedInternalIsGenericChoiceConditionView;

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

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

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

    using Field = ::emboss::test::ChoiceCondition::Field;

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

      const auto emboss_reserved_local_ok_subexpr_1 = field();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>());
      const auto emboss_reserved_local_ok_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::ChoiceCondition::Field, bool, ::emboss::test::ChoiceCondition::Field, ::emboss::test::ChoiceCondition::Field>(emboss_reserved_local_ok_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(1)));
      const auto emboss_reserved_local_ok_subexpr_4 = x();
      const auto emboss_reserved_local_ok_subexpr_5 = (emboss_reserved_local_ok_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_ok_subexpr_6 = y();
      const auto emboss_reserved_local_ok_subexpr_7 = (emboss_reserved_local_ok_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_ok_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_ok_subexpr_3, emboss_reserved_local_ok_subexpr_5, emboss_reserved_local_ok_subexpr_7);

    if (!has_field().Known()) return false;
    if (has_field().ValueOrDefault() && !field().Ok()) return false;

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_8;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(5LL):
          if (!xyc().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



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

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

    if (emboss_reserved_local_other.has_field().ValueOrDefault() &&
        has_field().ValueOrDefault() &&
        !field().Equals(emboss_reserved_local_other.field()))
      return false;



    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;



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

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

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;



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

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

    if (emboss_reserved_local_other.has_xyc().ValueOrDefault() &&
        has_xyc().ValueOrDefault() &&
        !xyc().Equals(emboss_reserved_local_other.xyc()))
      return false;

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

    if (emboss_reserved_local_other.has_field().ValueOr(false) &&
        has_field().ValueOr(false) &&
        !field().UncheckedEquals(emboss_reserved_local_other.field()))
      return false;



    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;



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

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;



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

    if (emboss_reserved_local_other.has_xyc().ValueOr(false) &&
        has_xyc().ValueOr(false) &&
        !xyc().UncheckedEquals(emboss_reserved_local_other.xyc()))
      return false;

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

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

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

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

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

    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");
      }
    }

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

    if (has_xyc().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          xyc().IsAggregate() || xyc().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("xyc: ");
        xyc().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() &&
                 !xyc().IsAggregate() && !xyc().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("# xyc: 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::ChoiceCondition::Field,
    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 field() const;
  ::emboss::support::Maybe<bool> has_field() const;

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

 y() const;
  ::emboss::support::Maybe<bool> has_y() const;

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

 xyc() const;
  ::emboss::support::Maybe<bool> has_xyc() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.field();
      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>());
      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::ChoiceCondition::Field, bool, ::emboss::test::ChoiceCondition::Field, ::emboss::test::ChoiceCondition::Field>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(1)));
      const auto emboss_reserved_local_subexpr_4 = view_.x();
      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_6 = view_.y();
      const auto emboss_reserved_local_subexpr_7 = (emboss_reserved_local_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_7);
      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_9, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_11 = ::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::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_10);

      return emboss_reserved_local_subexpr_11;
    }

    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 GenericChoiceConditionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericChoiceConditionView;
};
using ChoiceConditionView =
    GenericChoiceConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ChoiceConditionWriter =
    GenericChoiceConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ContainsBits {




namespace EmbossReservedAnonymousField3 {

}  // namespace EmbossReservedAnonymousField3


template <class View>
struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField3View;

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

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

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

  

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


    if (!has_has_top().Known()) return false;
    if (has_has_top().ValueOrDefault() && !has_top().Ok()) return false;

    if (!has_has_bottom().Known()) return false;
    if (has_has_bottom().ValueOrDefault() && !has_bottom().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(
      GenericEmbossReservedAnonymousField3View<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_has_top().Known()) return false;
    if (!emboss_reserved_local_other.has_has_top().Known()) return false;

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

    if (emboss_reserved_local_other.has_has_top().ValueOrDefault() &&
        has_has_top().ValueOrDefault() &&
        !has_top().Equals(emboss_reserved_local_other.has_top()))
      return false;



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

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

    if (emboss_reserved_local_other.has_has_bottom().ValueOrDefault() &&
        has_has_bottom().ValueOrDefault() &&
        !has_bottom().Equals(emboss_reserved_local_other.has_bottom()))
      return false;

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

    if (emboss_reserved_local_other.has_has_top().ValueOr(false) &&
        has_has_top().ValueOr(false) &&
        !has_top().UncheckedEquals(emboss_reserved_local_other.has_top()))
      return false;



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

    if (emboss_reserved_local_other.has_has_bottom().ValueOr(false) &&
        has_has_bottom().ValueOr(false) &&
        !has_bottom().UncheckedEquals(emboss_reserved_local_other.has_bottom()))
      return false;

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

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

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

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

 has_top() const;
  ::emboss::support::Maybe<bool> has_has_top() const;

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

 has_bottom() const;
  ::emboss::support::Maybe<bool> has_has_bottom() 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 GenericEmbossReservedAnonymousField3View;
};
using EmbossReservedAnonymousField3View =
    GenericEmbossReservedAnonymousField3View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using EmbossReservedAnonymousField3Writer =
    GenericEmbossReservedAnonymousField3View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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

}  // namespace ContainsBits


template <class View>
struct EmbossReservedInternalIsGenericContainsBitsView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericContainsBitsView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericContainsBitsView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericContainsBitsView(
       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>
  GenericContainsBitsView<Storage> &operator=(
      const GenericContainsBitsView<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_3().Known()) return false;
    if (has_emboss_reserved_anonymous_field_3().ValueOrDefault() && !emboss_reserved_anonymous_field_3().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_has_top().Known()) return false;
    if (has_has_top().ValueOrDefault() && !has_top().Ok()) return false;

    if (!has_has_bottom().Known()) return false;
    if (has_has_bottom().ValueOrDefault() && !has_bottom().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(
      GenericContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_emboss_reserved_anonymous_field_3().Known()) return false;
    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().Known()) return false;

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

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOrDefault() &&
        has_emboss_reserved_anonymous_field_3().ValueOrDefault() &&
        !emboss_reserved_anonymous_field_3().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_3()))
      return false;

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

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOr(false) &&
        has_emboss_reserved_anonymous_field_3().ValueOr(false) &&
        !emboss_reserved_anonymous_field_3().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_3()))
      return false;

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

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

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

    if (has_has_bottom().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          has_bottom().IsAggregate() || has_bottom().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("has_bottom: ");
        has_bottom().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() &&
                 !has_bottom().IsAggregate() && !has_bottom().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("# has_bottom: 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::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 emboss_reserved_anonymous_field_3() const;
  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_3() const;

 public:
  auto has_top() const -> decltype(this->emboss_reserved_anonymous_field_3().has_top()) {
   return has_has_top().ValueOrDefault() ? emboss_reserved_anonymous_field_3().has_top()
                                          : decltype(this->emboss_reserved_anonymous_field_3().has_top())();
  }
  ::emboss::support::Maybe<bool> has_has_top() const;

 public:
  auto has_bottom() const -> decltype(this->emboss_reserved_anonymous_field_3().has_bottom()) {
   return has_has_bottom().ValueOrDefault() ? emboss_reserved_anonymous_field_3().has_bottom()
                                          : decltype(this->emboss_reserved_anonymous_field_3().has_bottom())();
  }
  ::emboss::support::Maybe<bool> has_has_bottom() 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 GenericContainsBitsView;
};
using ContainsBitsView =
    GenericContainsBitsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ContainsBitsWriter =
    GenericContainsBitsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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




namespace ContainsContainsBits {

}  // namespace ContainsContainsBits


template <class View>
struct EmbossReservedInternalIsGenericContainsContainsBitsView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = condition().has_top();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(1LL):
          if (!top().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



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

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

    if (emboss_reserved_local_other.has_condition().ValueOrDefault() &&
        has_condition().ValueOrDefault() &&
        !condition().Equals(emboss_reserved_local_other.condition()))
      return false;



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

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

    if (emboss_reserved_local_other.has_top().ValueOrDefault() &&
        has_top().ValueOrDefault() &&
        !top().Equals(emboss_reserved_local_other.top()))
      return false;

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

    if (emboss_reserved_local_other.has_condition().ValueOr(false) &&
        has_condition().ValueOr(false) &&
        !condition().UncheckedEquals(emboss_reserved_local_other.condition()))
      return false;



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

    if (emboss_reserved_local_other.has_top().ValueOr(false) &&
        has_top().ValueOr(false) &&
        !top().UncheckedEquals(emboss_reserved_local_other.top()))
      return false;

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

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

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

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

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



  static constexpr bool IsAggregate() { return true; }

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

 condition() const;
  ::emboss::support::Maybe<bool> has_condition() const;

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

 top() const;
  ::emboss::support::Maybe<bool> has_top() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.condition().has_top();
      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::Equal</**/::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>(1LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericContainsContainsBitsView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericContainsContainsBitsView;
};
using ContainsContainsBitsView =
    GenericContainsContainsBitsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ContainsContainsBitsWriter =
    GenericContainsContainsBitsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ConditionalInline {





namespace Type0 {

}  // namespace Type0


template <class View>
struct EmbossReservedInternalIsGenericType0View;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericType0View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericType0View(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericType0View(
       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>
  GenericType0View<Storage> &operator=(
      const GenericType0View<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_c().Known()) return false;
    if (has_c().ValueOrDefault() && !c().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(
      GenericType0View<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(
      GenericType0View<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(
      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericType0View<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;
      }

      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");
      }
    }

    (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, ::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::prelude::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    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 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 GenericType0View;
};
using Type0View =
    GenericType0View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using Type0Writer =
    GenericType0View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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






namespace Type1 {

}  // namespace Type1


template <class View>
struct EmbossReservedInternalIsGenericType1View;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericType1View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericType1View(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericType1View(
       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>
  GenericType1View<Storage> &operator=(
      const GenericType1View<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_c().Known()) return false;
    if (has_c().ValueOrDefault() && !c().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(
      GenericType1View<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(
      GenericType1View<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(
      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericType1View<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;
      }

      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");
      }
    }

    (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, ::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::prelude::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    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 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 GenericType1View;
};
using Type1View =
    GenericType1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using Type1Writer =
    GenericType1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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

}  // namespace ConditionalInline


template <class View>
struct EmbossReservedInternalIsGenericConditionalInlineView;

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

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

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

  

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

      const auto emboss_reserved_local_ok_subexpr_1 = payload_id();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(0LL):
          if (!type_0().Ok()) return false;
          break;



        case static_cast</**/::std::int32_t>(1LL):
          if (!type_1().Ok()) return false;
          break;




        
        default: break;
      }
    }



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



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

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

    if (emboss_reserved_local_other.has_payload_id().ValueOrDefault() &&
        has_payload_id().ValueOrDefault() &&
        !payload_id().Equals(emboss_reserved_local_other.payload_id()))
      return false;



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

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

    if (emboss_reserved_local_other.has_type_0().ValueOrDefault() &&
        has_type_0().ValueOrDefault() &&
        !type_0().Equals(emboss_reserved_local_other.type_0()))
      return false;



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

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

    if (emboss_reserved_local_other.has_type_1().ValueOrDefault() &&
        has_type_1().ValueOrDefault() &&
        !type_1().Equals(emboss_reserved_local_other.type_1()))
      return false;

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

    if (emboss_reserved_local_other.has_payload_id().ValueOr(false) &&
        has_payload_id().ValueOr(false) &&
        !payload_id().UncheckedEquals(emboss_reserved_local_other.payload_id()))
      return false;



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

    if (emboss_reserved_local_other.has_type_0().ValueOr(false) &&
        has_type_0().ValueOr(false) &&
        !type_0().UncheckedEquals(emboss_reserved_local_other.type_0()))
      return false;



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

    if (emboss_reserved_local_other.has_type_1().ValueOr(false) &&
        has_type_1().ValueOr(false) &&
        !type_1().UncheckedEquals(emboss_reserved_local_other.type_1()))
      return false;

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

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

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

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

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

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

 payload_id() const;
  ::emboss::support::Maybe<bool> has_payload_id() const;

 public:
  typename ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>

 type_0() const;
  ::emboss::support::Maybe<bool> has_type_0() const;

 public:
  typename ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>

 type_1() const;
  ::emboss::support::Maybe<bool> has_type_1() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.payload_id();
      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::Equal</**/::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>(0LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Equal</**/::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>(1LL)));
      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Maximum</**/::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_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6);

      return emboss_reserved_local_subexpr_7;
    }

    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 GenericConditionalInlineView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericConditionalInlineView;
};
using ConditionalInlineView =
    GenericConditionalInlineView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionalInlineWriter =
    GenericConditionalInlineView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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







namespace ConditionalAnonymous {





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;

      const auto emboss_reserved_local_ok_subexpr_1 = low();
      const auto emboss_reserved_local_ok_subexpr_2 = (emboss_reserved_local_ok_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_ok_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());

    if (!has_low().Known()) return false;
    if (has_low().ValueOrDefault() && !low().Ok()) return false;

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

    {

      const auto emboss_reserved_switch_discrim = emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/::std::int32_t>(1LL):
          if (!mid().Ok()) return false;
          break;




        
        default: break;
      }
    }



    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_low().Known()) return false;
    if (!emboss_reserved_local_other.has_low().Known()) return false;

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

    if (emboss_reserved_local_other.has_low().ValueOrDefault() &&
        has_low().ValueOrDefault() &&
        !low().Equals(emboss_reserved_local_other.low()))
      return false;



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

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

    if (emboss_reserved_local_other.has_mid().ValueOrDefault() &&
        has_mid().ValueOrDefault() &&
        !mid().Equals(emboss_reserved_local_other.mid()))
      return false;



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

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

    if (emboss_reserved_local_other.has_high().ValueOrDefault() &&
        has_high().ValueOrDefault() &&
        !high().Equals(emboss_reserved_local_other.high()))
      return false;

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

    if (emboss_reserved_local_other.has_low().ValueOr(false) &&
        has_low().ValueOr(false) &&
        !low().UncheckedEquals(emboss_reserved_local_other.low()))
      return false;



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

    if (emboss_reserved_local_other.has_mid().ValueOr(false) &&
        has_mid().ValueOr(false) &&
        !mid().UncheckedEquals(emboss_reserved_local_other.mid()))
      return false;



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

    if (emboss_reserved_local_other.has_high().ValueOr(false) &&
        has_high().ValueOr(false) &&
        !high().UncheckedEquals(emboss_reserved_local_other.high()))
      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 == "low") {
        if (!low().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

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

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

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

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

 low() const;
  ::emboss::support::Maybe<bool> has_low() const;

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

 mid() const;
  ::emboss::support::Maybe<bool> has_mid() const;

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

 high() const;
  ::emboss::support::Maybe<bool> has_high() 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 ConditionalAnonymous


template <class View>
struct EmbossReservedInternalIsGenericConditionalAnonymousView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericConditionalAnonymousView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericConditionalAnonymousView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericConditionalAnonymousView(
       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>
  GenericConditionalAnonymousView<Storage> &operator=(
      const GenericConditionalAnonymousView<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;

    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_low().Known()) return false;
    if (has_low().ValueOrDefault() && !low().Ok()) return false;

    if (!has_high().Known()) return false;
    if (has_high().ValueOrDefault() && !high().Ok()) return false;

    if (!has_mid().Known()) return false;
    if (has_mid().ValueOrDefault() && !mid().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericConditionalAnonymousView<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;



    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(
      GenericConditionalAnonymousView<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;



    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(
      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConditionalAnonymousView<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;
      }

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

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

      if (emboss_reserved_local_name == "high") {
        if (!high().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");
      }
    }

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

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

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

 x() const;
  ::emboss::support::Maybe<bool> has_x() const;

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

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

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

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

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

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.x();
      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::GreaterThan</**/::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>(10LL)));
      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::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_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::Maybe<bool>(true).ValueOr(false);
    }

    const GenericConditionalAnonymousView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericConditionalAnonymousView;
};
using ConditionalAnonymousView =
    GenericConditionalAnonymousView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionalAnonymousWriter =
    GenericConditionalAnonymousView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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





namespace ConditionalOnFlag {



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_enabled().Known()) return false;
    if (has_enabled().ValueOrDefault() && !enabled().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(
      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_enabled().Known()) return false;
    if (!emboss_reserved_local_other.has_enabled().Known()) return false;

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

    if (emboss_reserved_local_other.has_enabled().ValueOrDefault() &&
        has_enabled().ValueOrDefault() &&
        !enabled().Equals(emboss_reserved_local_other.enabled()))
      return false;

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

    if (emboss_reserved_local_other.has_enabled().ValueOr(false) &&
        has_enabled().ValueOr(false) &&
        !enabled().UncheckedEquals(emboss_reserved_local_other.enabled()))
      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 == "enabled") {
        if (!enabled().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_enabled().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          enabled().IsAggregate() || enabled().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("enabled: ");
        enabled().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() &&
                 !enabled().IsAggregate() && !enabled().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("# enabled: 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>>

 enabled() const;
  ::emboss::support::Maybe<bool> has_enabled() 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 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 ConditionalOnFlag


template <class View>
struct EmbossReservedInternalIsGenericConditionalOnFlagView;

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

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

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericConditionalOnFlagView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericConditionalOnFlagView(
       Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) 
         {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericConditionalOnFlagView(
       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>
  GenericConditionalOnFlagView<Storage> &operator=(
      const GenericConditionalOnFlagView<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_enabled().Known()) return false;
    if (has_enabled().ValueOrDefault() && !enabled().Ok()) return false;

    if (!has_value().Known()) return false;
    if (has_value().ValueOrDefault() && !value().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());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }



  template <typename OtherStorage>
  bool Equals(
      GenericConditionalOnFlagView<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;



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

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

    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
        has_value().ValueOrDefault() &&
        !value().Equals(emboss_reserved_local_other.value()))
      return false;

 return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConditionalOnFlagView<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;



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

    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
        has_value().ValueOr(false) &&
        !value().UncheckedEquals(emboss_reserved_local_other.value()))
      return false;

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

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

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

    if (has_value().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          value().IsAggregate() || value().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("value: ");
        value().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() &&
                 !value().IsAggregate() && !value().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("# value: 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::ConditionalOnFlag::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 enabled() const -> decltype(this->emboss_reserved_anonymous_field_1().enabled()) {
   return has_enabled().ValueOrDefault() ? emboss_reserved_anonymous_field_1().enabled()
                                          : decltype(this->emboss_reserved_anonymous_field_1().enabled())();
  }
  ::emboss::support::Maybe<bool> has_enabled() const;

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

 value() const;
  ::emboss::support::Maybe<bool> has_value() const;

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

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

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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_.enabled();
      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>(2LL)), ::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>(::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_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 GenericConditionalOnFlagView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 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 GenericConditionalOnFlagView;
};
using ConditionalOnFlagView =
    GenericConditionalOnFlagView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConditionalOnFlagWriter =
    GenericConditionalOnFlagView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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

namespace BasicConditional {

}  // namespace BasicConditional


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

 GenericBasicConditionalView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericBasicConditionalView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericBasicConditionalView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericBasicConditionalView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


template <class Storage>
inline typename GenericBasicConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericBasicConditionalView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericBasicConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericBasicConditionalView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return BasicConditional::MinSizeInBytes();
}
namespace NegativeConditional {

}  // namespace NegativeConditional


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

 GenericNegativeConditionalView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericNegativeConditionalView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericNegativeConditionalView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericNegativeConditionalView<Storage>::has_xc() const {
  return ::emboss::support::NotEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


template <class Storage>
inline typename GenericNegativeConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericNegativeConditionalView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericNegativeConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericNegativeConditionalView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return NegativeConditional::MinSizeInBytes();
}
namespace ConditionalAndUnconditionalOverlappingFinalField {

}  // namespace ConditionalAndUnconditionalOverlappingFinalField


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

 GenericConditionalAndUnconditionalOverlappingFinalFieldView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


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

 GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::z()
    const {

  if ( has_z().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::has_z() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalAndUnconditionalOverlappingFinalFieldView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionalAndUnconditionalOverlappingFinalField::MinSizeInBytes();
}
namespace ConditionalBasicConditionalFieldFirst {

}  // namespace ConditionalBasicConditionalFieldFirst


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

 GenericConditionalBasicConditionalFieldFirstView<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>(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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalBasicConditionalFieldFirstView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericConditionalBasicConditionalFieldFirstView<Storage>::xc()
    const {

  if ( has_xc().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, ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalBasicConditionalFieldFirstView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalBasicConditionalFieldFirstView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionalBasicConditionalFieldFirst::MinSizeInBytes();
}
namespace ConditionalAndDynamicLocation {

}  // namespace ConditionalAndDynamicLocation


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

 GenericConditionalAndDynamicLocationView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalAndDynamicLocationView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericConditionalAndDynamicLocationView<Storage>::y()
    const {

  if ( has_y().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

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


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

 GenericConditionalAndDynamicLocationView<Storage>::xc()
    const {

  if ( has_xc().ValueOr(false)) {
    const auto emboss_reserved_local_subexpr_1 = y();
    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>());

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

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

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalAndDynamicLocationView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


template <class Storage>
inline typename GenericConditionalAndDynamicLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericConditionalAndDynamicLocationView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericConditionalAndDynamicLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalAndDynamicLocationView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionalAndDynamicLocation::MinSizeInBytes();
}
namespace ConditionUsesMinInt {

}  // namespace ConditionUsesMinInt


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

 GenericConditionUsesMinIntView<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::IntView<
    /**/ ::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::prelude::IntView<
    /**/ ::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>
GenericConditionUsesMinIntView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericConditionUsesMinIntView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionUsesMinIntView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int64_t, bool, ::std::int64_t, ::std::int64_t>(::emboss::support::Difference</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(9223372036854775680LL))), ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(-9223372036854775807LL - 1)));
}


template <class Storage>
inline typename GenericConditionUsesMinIntView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericConditionUsesMinIntView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericConditionUsesMinIntView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionUsesMinIntView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionUsesMinInt::MinSizeInBytes();
}
namespace NestedConditional {

}  // namespace NestedConditional


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

 GenericNestedConditionalView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericNestedConditionalView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericNestedConditionalView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericNestedConditionalView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


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

 GenericNestedConditionalView<Storage>::xcc()
    const {

  if ( has_xcc().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericNestedConditionalView<Storage>::has_xcc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((xc().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(xc().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


template <class Storage>
inline typename GenericNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericNestedConditionalView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericNestedConditionalView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return NestedConditional::MinSizeInBytes();
}
namespace CorrectNestedConditional {

}  // namespace CorrectNestedConditional


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

 GenericCorrectNestedConditionalView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericCorrectNestedConditionalView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericCorrectNestedConditionalView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericCorrectNestedConditionalView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


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

 GenericCorrectNestedConditionalView<Storage>::xcc()
    const {

  if ( has_xcc().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericCorrectNestedConditionalView<Storage>::has_xcc() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL))), ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((xc().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(xc().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL))));
}


template <class Storage>
inline typename GenericCorrectNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericCorrectNestedConditionalView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericCorrectNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericCorrectNestedConditionalView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return CorrectNestedConditional::MinSizeInBytes();
}
namespace AlwaysFalseCondition {

}  // namespace AlwaysFalseCondition


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

 GenericAlwaysFalseConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericAlwaysFalseConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericAlwaysFalseConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericAlwaysFalseConditionView<Storage>::has_xc() const {
  return ::emboss::support::Maybe</**/bool>(false);
}


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericAlwaysFalseConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return AlwaysFalseCondition::MinSizeInBytes();
}
namespace OnlyAlwaysFalseCondition {

}  // namespace OnlyAlwaysFalseCondition


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

 GenericOnlyAlwaysFalseConditionView<Storage>::xc()
    const {

  if ( has_xc().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, ::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::prelude::UIntView<
    /**/ ::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>
GenericOnlyAlwaysFalseConditionView<Storage>::has_xc() const {
  return ::emboss::support::Maybe</**/bool>(false);
}


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericOnlyAlwaysFalseConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return OnlyAlwaysFalseCondition::MinSizeInBytes();
}
namespace EmptyStruct {

}  // namespace EmptyStruct


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericEmptyStructView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return EmptyStruct::MinSizeInBytes();
}
namespace AlwaysFalseConditionDynamicSize {

}  // namespace AlwaysFalseConditionDynamicSize


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

 GenericAlwaysFalseConditionDynamicSizeView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericAlwaysFalseConditionDynamicSizeView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericAlwaysFalseConditionDynamicSizeView<Storage>::y()
    const {

  if ( has_y().ValueOr(false)) {
    const auto emboss_reserved_local_subexpr_1 = x();
    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>());

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

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

();
}

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


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

 GenericAlwaysFalseConditionDynamicSizeView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericAlwaysFalseConditionDynamicSizeView<Storage>::has_xc() const {
  return ::emboss::support::Maybe</**/bool>(false);
}


template <class Storage>
inline typename GenericAlwaysFalseConditionDynamicSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericAlwaysFalseConditionDynamicSizeView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericAlwaysFalseConditionDynamicSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericAlwaysFalseConditionDynamicSizeView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return AlwaysFalseConditionDynamicSize::MinSizeInBytes();
}
namespace ConditionDoesNotContributeToSize {

}  // namespace ConditionDoesNotContributeToSize


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

 GenericConditionDoesNotContributeToSizeView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionDoesNotContributeToSizeView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericConditionDoesNotContributeToSizeView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionDoesNotContributeToSizeView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


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

 GenericConditionDoesNotContributeToSizeView<Storage>::y()
    const {

  if ( has_y().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

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


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionDoesNotContributeToSizeView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionDoesNotContributeToSize::MinSizeInBytes();
}
namespace EnumCondition {

}  // namespace EnumCondition


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

 GenericEnumConditionView<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::support::EnumView<
    /**/ ::emboss::test::OnOff,
    ::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::OnOff,
    ::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>
GenericEnumConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericEnumConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericEnumConditionView<Storage>::has_xc() const {
  return ::emboss::support::Equal</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>((x().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>()), ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
}


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

 GenericEnumConditionView<Storage>::xc2()
    const {

  if ( has_xc2().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericEnumConditionView<Storage>::has_xc2() const {
  return ::emboss::support::GreaterThan</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>((x().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>()), ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(0)));
}


template <class Storage>
inline typename GenericEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericEnumConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericEnumConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return EnumCondition::MinSizeInBytes();
}
namespace NegativeEnumCondition {

}  // namespace NegativeEnumCondition


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

 GenericNegativeEnumConditionView<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::support::EnumView<
    /**/ ::emboss::test::OnOff,
    ::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::OnOff,
    ::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>
GenericNegativeEnumConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericNegativeEnumConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericNegativeEnumConditionView<Storage>::has_xc() const {
  return ::emboss::support::NotEqual</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>((x().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>()), ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
}


template <class Storage>
inline typename GenericNegativeEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericNegativeEnumConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericNegativeEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericNegativeEnumConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return NegativeEnumCondition::MinSizeInBytes();
}
namespace LessThanCondition {

}  // namespace LessThanCondition


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

 GenericLessThanConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericLessThanConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericLessThanConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericLessThanConditionView<Storage>::has_xc() const {
  return ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
}


template <class Storage>
inline typename GenericLessThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericLessThanConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericLessThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericLessThanConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return LessThanCondition::MinSizeInBytes();
}
namespace LessThanOrEqualCondition {

}  // namespace LessThanOrEqualCondition


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

 GenericLessThanOrEqualConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericLessThanOrEqualConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericLessThanOrEqualConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericLessThanOrEqualConditionView<Storage>::has_xc() const {
  return ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
}


template <class Storage>
inline typename GenericLessThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericLessThanOrEqualConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericLessThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericLessThanOrEqualConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return LessThanOrEqualCondition::MinSizeInBytes();
}
namespace GreaterThanOrEqualCondition {

}  // namespace GreaterThanOrEqualCondition


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

 GenericGreaterThanOrEqualConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericGreaterThanOrEqualConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericGreaterThanOrEqualConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericGreaterThanOrEqualConditionView<Storage>::has_xc() const {
  return ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
}


template <class Storage>
inline typename GenericGreaterThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericGreaterThanOrEqualConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericGreaterThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericGreaterThanOrEqualConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return GreaterThanOrEqualCondition::MinSizeInBytes();
}
namespace GreaterThanCondition {

}  // namespace GreaterThanCondition


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

 GenericGreaterThanConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericGreaterThanConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericGreaterThanConditionView<Storage>::xc()
    const {

  if ( has_xc().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericGreaterThanConditionView<Storage>::has_xc() const {
  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
}


template <class Storage>
inline typename GenericGreaterThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericGreaterThanConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericGreaterThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericGreaterThanConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return GreaterThanCondition::MinSizeInBytes();
}
namespace RangeCondition {

}  // namespace RangeCondition


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

 GenericRangeConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericRangeConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericRangeConditionView<Storage>::y()
    const {

  if ( has_y().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericRangeConditionView<Storage>::has_y() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericRangeConditionView<Storage>::xc()
    const {

  if ( has_xc().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericRangeConditionView<Storage>::has_xc() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), (x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>())), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), (y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()))), ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))));
}


template <class Storage>
inline typename GenericRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericRangeConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericRangeConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return RangeCondition::MinSizeInBytes();
}
namespace ReverseRangeCondition {

}  // namespace ReverseRangeCondition


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

 GenericReverseRangeConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericReverseRangeConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericReverseRangeConditionView<Storage>::y()
    const {

  if ( has_y().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericReverseRangeConditionView<Storage>::has_y() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericReverseRangeConditionView<Storage>::xc()
    const {

  if ( has_xc().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericReverseRangeConditionView<Storage>::has_xc() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), (y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>())), ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), (x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()))), ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))));
}


template <class Storage>
inline typename GenericReverseRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericReverseRangeConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericReverseRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericReverseRangeConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ReverseRangeCondition::MinSizeInBytes();
}
namespace AndCondition {

}  // namespace AndCondition


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

 GenericAndConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericAndConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericAndConditionView<Storage>::y()
    const {

  if ( has_y().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericAndConditionView<Storage>::has_y() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericAndConditionView<Storage>::xc()
    const {

  if ( has_xc().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAndConditionView<Storage>::has_xc() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))), ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))));
}


template <class Storage>
inline typename GenericAndConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericAndConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericAndConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericAndConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return AndCondition::MinSizeInBytes();
}
namespace OrCondition {

}  // namespace OrCondition


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

 GenericOrConditionView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericOrConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericOrConditionView<Storage>::y()
    const {

  if ( has_y().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericOrConditionView<Storage>::has_y() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericOrConditionView<Storage>::xc()
    const {

  if ( has_xc().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericOrConditionView<Storage>::has_xc() const {
  return ::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))), ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))));
}


template <class Storage>
inline typename GenericOrConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericOrConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericOrConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericOrConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return OrCondition::MinSizeInBytes();
}
namespace ChoiceCondition {

}  // namespace ChoiceCondition


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

 GenericChoiceConditionView<Storage>::field()
    const {

  if ( has_field().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::ChoiceCondition::Field,
    ::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::ChoiceCondition::Field,
    ::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>
GenericChoiceConditionView<Storage>::has_field() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericChoiceConditionView<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>(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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericChoiceConditionView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericChoiceConditionView<Storage>::y()
    const {

  if ( has_y().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, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

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


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

 GenericChoiceConditionView<Storage>::xyc()
    const {

  if ( has_xyc().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::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>

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

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericChoiceConditionView<Storage>::has_xyc() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Equal</**/::emboss::test::ChoiceCondition::Field, bool, ::emboss::test::ChoiceCondition::Field, ::emboss::test::ChoiceCondition::Field>((field().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(field().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>()), ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(1))), (x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), (y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>())), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
}


template <class Storage>
inline typename GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericChoiceConditionView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

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


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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ChoiceCondition::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericChoiceConditionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ChoiceCondition::MinSizeInBytes();
}
namespace ContainsBits {
namespace EmbossReservedAnonymousField3 {

}  // namespace EmbossReservedAnonymousField3


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 7>>

 GenericEmbossReservedAnonymousField3View<Storage>::has_top()
    const {

  if ( has_has_top().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>(7LL));
    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<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 7>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   7>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 7>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField3View<Storage>::has_has_top() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

 GenericEmbossReservedAnonymousField3View<Storage>::has_bottom()
    const {

  if ( has_has_bottom().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<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::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField3View<Storage>::has_has_bottom() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace EmbossReservedAnonymousField3 {
inline constexpr ::std::int32_t IntrinsicSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField3

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField3View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
  return EmbossReservedAnonymousField3::IntrinsicSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField3View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField3::IntrinsicSizeInBits();
}

namespace EmbossReservedAnonymousField3 {
inline constexpr ::std::int32_t MaxSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField3

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField3View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
  return EmbossReservedAnonymousField3::MaxSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField3View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField3::MaxSizeInBits();
}

namespace EmbossReservedAnonymousField3 {
inline constexpr ::std::int32_t MinSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField3

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField3View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
  return EmbossReservedAnonymousField3::MinSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField3View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField3::MinSizeInBits();
}

}  // namespace ContainsBits


template <class Storage>
inline typename ::emboss::test::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericContainsBitsView<Storage>::emboss_reserved_anonymous_field_3()
    const {

  if ( has_emboss_reserved_anonymous_field_3().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::ContainsBits::GenericEmbossReservedAnonymousField3View<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::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericContainsBitsView<Storage>::has_emboss_reserved_anonymous_field_3() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericContainsBitsView<Storage>::has_has_top() 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>
GenericContainsBitsView<Storage>::has_has_bottom() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


namespace ContainsBits {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ContainsBits

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return ContainsBits::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsBitsView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return ContainsBits::IntrinsicSizeInBytes();
}

namespace ContainsBits {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ContainsBits

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsBitsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ContainsBits::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsBitsView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ContainsBits::MaxSizeInBytes();
}

namespace ContainsBits {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ContainsBits

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsBitsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ContainsBits::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsBitsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ContainsBits::MinSizeInBytes();
}
namespace ContainsContainsBits {

}  // namespace ContainsContainsBits


template <class Storage>
inline typename ::emboss::test::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>

 GenericContainsContainsBitsView<Storage>::condition()
    const {

  if ( has_condition().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::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   0>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericContainsContainsBitsView<Storage>::has_condition() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericContainsContainsBitsView<Storage>::top()
    const {

  if ( has_top().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericContainsContainsBitsView<Storage>::has_top() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((condition().has_top().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(condition().has_top().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
}


template <class Storage>
inline typename GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericContainsContainsBitsView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericContainsContainsBitsView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace ContainsContainsBits {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
}
}  // namespace ContainsContainsBits

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ContainsContainsBits::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsContainsBitsView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ContainsContainsBits::MaxSizeInBytes();
}

namespace ContainsContainsBits {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ContainsContainsBits

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ContainsContainsBits::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericContainsContainsBitsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ContainsContainsBits::MinSizeInBytes();
}
namespace ConditionalInline {
namespace Type0 {

}  // namespace Type0


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericType0View<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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericType0View<Storage>::has_a() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericType0View<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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericType0View<Storage>::has_b() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

 GenericType0View<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::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericType0View<Storage>::has_c() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace Type0 {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace Type0

template <class Storage>
inline constexpr ::std::int32_t
GenericType0View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return Type0::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericType0View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return Type0::IntrinsicSizeInBytes();
}

namespace Type0 {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace Type0

template <class Storage>
inline constexpr ::std::int32_t
GenericType0View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Type0::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericType0View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Type0::MaxSizeInBytes();
}

namespace Type0 {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace Type0

template <class Storage>
inline constexpr ::std::int32_t
GenericType0View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Type0::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericType0View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Type0::MinSizeInBytes();
}

namespace Type1 {

}  // namespace Type1


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericType1View<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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericType1View<Storage>::has_a() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericType1View<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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericType1View<Storage>::has_b() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

 GenericType1View<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::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    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, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericType1View<Storage>::has_c() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace Type1 {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace Type1

template <class Storage>
inline constexpr ::std::int32_t
GenericType1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return Type1::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericType1View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return Type1::IntrinsicSizeInBytes();
}

namespace Type1 {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace Type1

template <class Storage>
inline constexpr ::std::int32_t
GenericType1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Type1::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericType1View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Type1::MaxSizeInBytes();
}

namespace Type1 {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
}
}  // namespace Type1

template <class Storage>
inline constexpr ::std::int32_t
GenericType1View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Type1::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericType1View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Type1::MinSizeInBytes();
}

}  // namespace ConditionalInline


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericConditionalInlineView<Storage>::payload_id()
    const {

  if ( has_payload_id().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, ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalInlineView<Storage>::has_payload_id() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>

 GenericConditionalInlineView<Storage>::type_0()
    const {

  if ( has_type_0().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
    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::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   1>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalInlineView<Storage>::has_type_0() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((payload_id().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(payload_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
}


template <class Storage>
inline typename ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>

 GenericConditionalInlineView<Storage>::type_1()
    const {

  if ( has_type_1().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
    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::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   1>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalInlineView<Storage>::has_type_1() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((payload_id().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(payload_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
}


template <class Storage>
inline typename GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericConditionalInlineView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalInlineView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace ConditionalInline {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
}
}  // namespace ConditionalInline

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ConditionalInline::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalInlineView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ConditionalInline::MaxSizeInBytes();
}

namespace ConditionalInline {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ConditionalInline

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ConditionalInline::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalInlineView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionalInline::MinSizeInBytes();
}
namespace ConditionalAnonymous {
namespace EmbossReservedAnonymousField2 {

}  // namespace EmbossReservedAnonymousField2


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

 GenericEmbossReservedAnonymousField2View<Storage>::low()
    const {

  if ( has_low().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<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::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 0>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField2View<Storage>::has_low() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 3>>

 GenericEmbossReservedAnonymousField2View<Storage>::mid()
    const {

  if ( has_mid().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
    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::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 3>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   3>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 3>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField2View<Storage>::has_mid() const {
  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((low().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(low().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 7>>

 GenericEmbossReservedAnonymousField2View<Storage>::high()
    const {

  if ( has_high().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>(7LL));
    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<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 7>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   7>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 7>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField2View<Storage>::has_high() 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>(8LL)).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>(8LL)).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>(8LL)).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 ConditionalAnonymous


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericConditionalAnonymousView<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, ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalAnonymousView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline typename ::emboss::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericConditionalAnonymousView<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>(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::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<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::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalAnonymousView<Storage>::has_emboss_reserved_anonymous_field_2() const {
  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalAnonymousView<Storage>::has_low() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(has_emboss_reserved_anonymous_field_2(), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalAnonymousView<Storage>::has_mid() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(has_emboss_reserved_anonymous_field_2(), emboss_reserved_anonymous_field_2().has_mid());
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalAnonymousView<Storage>::has_high() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(has_emboss_reserved_anonymous_field_2(), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline typename GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericConditionalAnonymousView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalAnonymousView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace ConditionalAnonymous {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
}
}  // namespace ConditionalAnonymous

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ConditionalAnonymous::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalAnonymousView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ConditionalAnonymous::MaxSizeInBytes();
}

namespace ConditionalAnonymous {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ConditionalAnonymous

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ConditionalAnonymous::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalAnonymousView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionalAnonymous::MinSizeInBytes();
}
namespace ConditionalOnFlag {
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>::enabled()
    const {

  if ( has_enabled().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_enabled() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t IntrinsicSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
}

namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t MaxSizeInBits() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).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>(1LL)).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 ConditionalOnFlag


template <class Storage>
inline typename ::emboss::test::ConditionalOnFlag::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

 GenericConditionalOnFlagView<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::ConditionalOnFlag::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::ConditionalOnFlag::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalOnFlagView<Storage>::has_emboss_reserved_anonymous_field_1() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalOnFlagView<Storage>::has_enabled() const {
  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
}


template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>

 GenericConditionalOnFlagView<Storage>::value()
    const {

  if ( has_value().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::UIntView<
    /**/ ::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::prelude::UIntView<
    /**/ ::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>
GenericConditionalOnFlagView<Storage>::has_value() const {
  return (enabled().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(enabled().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
}


template <class Storage>
inline typename GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericConditionalOnFlagView<Storage>::IntrinsicSizeInBytes() const {
  return
      typename GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConditionalOnFlagView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


namespace ConditionalOnFlag {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
}
}  // namespace ConditionalOnFlag

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ConditionalOnFlag::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalOnFlagView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ConditionalOnFlag::MaxSizeInBytes();
}

namespace ConditionalOnFlag {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
}
}  // namespace ConditionalOnFlag

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ConditionalOnFlag::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConditionalOnFlagView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConditionalOnFlag::MinSizeInBytes();
}



}  // namespace test



}  // namespace emboss



/* NOLINTEND */

#endif  // TESTDATA_CONDITION_EMB_H_

