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

}  // namespace Constants


template <class Storage>
class GenericConstantsView;

enum class Kind : ::std::uint64_t;

enum class Signed : ::std::int64_t;

enum class OnlyShortValues : ::std::uint64_t;

enum class OnlyShortSignedValues : ::std::int64_t;

enum class ExplicitlySigned : ::std::int64_t;

enum class ExplicitlySized64 : ::std::uint64_t;

enum class ExplicitlySized32 : ::std::uint32_t;

enum class ExplicitlySized16 : ::std::uint16_t;

enum class ExplicitlySized8 : ::std::uint8_t;

enum class ExplicitlySized12 : ::std::uint16_t;

enum class ExplicitlySizedAndSigned : ::std::int32_t;

namespace ManifestEntry {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1


template <class Storage>
class GenericEmbossReservedAnonymousField1View;


}  // namespace ManifestEntry


template <class Storage>
class GenericManifestEntryView;

namespace StructContainingEnum {
enum class Status : ::std::uint64_t;


}  // namespace StructContainingEnum


template <class Storage>
class GenericStructContainingEnumView;






namespace Constants {

}  // namespace Constants


template <class View>
struct EmbossReservedInternalIsGenericConstantsView;

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

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

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

  

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

    if (!sprocket().Ok()) return false;


    if (!geegaw().Ok()) return false;


    if (!IntrinsicSizeInBytes().Ok()) return false;


    if (!MaxSizeInBytes().Ok()) return false;


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

  template <typename OtherStorage>
  void CopyFrom(
      GenericConstantsView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConstantsView<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;
    if (has_sprocket().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          sprocket().IsAggregate() || sprocket().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# sprocket: ");
        sprocket().WriteToTextStream(emboss_reserved_local_stream,
                                           emboss_reserved_local_field_options);
        emboss_reserved_local_stream->Write("\n");
      } else {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# sprocket: UNREADABLE\n");
      }
    }

    if (has_geegaw().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          geegaw().IsAggregate() || geegaw().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# geegaw: ");
        geegaw().WriteToTextStream(emboss_reserved_local_stream,
                                           emboss_reserved_local_field_options);
        emboss_reserved_local_stream->Write("\n");
      } else {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# geegaw: 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:
  class EmbossReservedVirtualSprocketView final {
   public:
    using ValueType = ::std::int32_t;

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

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

    constexpr EmbossReservedVirtualGeegawView() {}
    EmbossReservedVirtualGeegawView(const EmbossReservedVirtualGeegawView &) = default;
    EmbossReservedVirtualGeegawView(EmbossReservedVirtualGeegawView &&) = default;
    EmbossReservedVirtualGeegawView &operator=(const EmbossReservedVirtualGeegawView &) =
        default;
    EmbossReservedVirtualGeegawView &operator=(EmbossReservedVirtualGeegawView &&) =
        default;
    ~EmbossReservedVirtualGeegawView() = 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 EmbossReservedVirtualGeegawView geegaw() {
    return EmbossReservedVirtualGeegawView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_geegaw() {
    return ::emboss::support::Maybe<bool>(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 GenericConstantsView;
};
using ConstantsView =
    GenericConstantsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConstantsWriter =
    GenericConstantsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

template <typename T, ::std::size_t kAlignment>
inline GenericConstantsView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedConstantsView(
     T *emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return GenericConstantsView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
       emboss_reserved_local_data,
      emboss_reserved_local_size);
}
enum class Kind : ::std::uint64_t {
  WIDGET = static_cast</**/::std::int32_t>(0LL),
  SPROCKET = static_cast</**/::std::int32_t>(1LL),
  GEEGAW = static_cast</**/::std::int32_t>(2LL),
  COMPUTED = static_cast</**/::std::int32_t>(3LL),
  LARGE_VALUE = static_cast</**/::std::int32_t>(2000LL),
  DUPLICATE_LARGE_VALUE = static_cast</**/::std::int32_t>(2000LL),
  MAX32BIT = static_cast</**/::std::uint32_t>(4294967295ULL),
  MAX64BIT = static_cast</**/::std::uint64_t>(18446744073709551615ULL),

};
template <class Enum>
class EnumTraits;

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

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

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

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

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

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

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      Kind emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Kind::WIDGET: return "WIDGET";

      case Kind::SPROCKET: return "SPROCKET";

      case Kind::GEEGAW: return "GEEGAW";

      case Kind::COMPUTED: return "COMPUTED";

      case Kind::LARGE_VALUE: return "LARGE_VALUE";

      case Kind::MAX32BIT: return "MAX32BIT";

      case Kind::MAX64BIT: return "MAX64BIT";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(Kind emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Kind::WIDGET: return true;

      case Kind::SPROCKET: return true;

      case Kind::GEEGAW: return true;

      case Kind::COMPUTED: return true;

      case Kind::LARGE_VALUE: return true;

      case Kind::MAX32BIT: return true;

      case Kind::MAX64BIT: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    Kind emboss_reserved_local_value) {
  return EnumTraits<Kind>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class Signed : ::std::int64_t {
  MIN64BIT = static_cast</**/::std::int64_t>(-9223372036854775807LL - 1),
  MAX64BIT = static_cast</**/::std::int64_t>(9223372036854775807LL),

};
template <class Enum>
class EnumTraits;

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      Signed emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Signed::MIN64BIT: return "MIN64BIT";

      case Signed::MAX64BIT: return "MAX64BIT";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(Signed emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Signed::MIN64BIT: return true;

      case Signed::MAX64BIT: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    Signed emboss_reserved_local_value) {
  return EnumTraits<Signed>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class OnlyShortValues : ::std::uint64_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),
  ONE = static_cast</**/::std::int32_t>(1LL),

};
template <class Enum>
class EnumTraits;

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      OnlyShortValues emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case OnlyShortValues::ZERO: return "ZERO";

      case OnlyShortValues::ONE: return "ONE";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(OnlyShortValues emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case OnlyShortValues::ZERO: return true;

      case OnlyShortValues::ONE: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    OnlyShortValues emboss_reserved_local_value) {
  return EnumTraits<OnlyShortValues>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class OnlyShortSignedValues : ::std::int64_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),
  NEGATIVE_ONE = static_cast</**/::std::int32_t>(-1LL),

};
template <class Enum>
class EnumTraits;

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      OnlyShortSignedValues emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case OnlyShortSignedValues::ZERO: return "ZERO";

      case OnlyShortSignedValues::NEGATIVE_ONE: return "NEGATIVE_ONE";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(OnlyShortSignedValues emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case OnlyShortSignedValues::ZERO: return true;

      case OnlyShortSignedValues::NEGATIVE_ONE: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    OnlyShortSignedValues emboss_reserved_local_value) {
  return EnumTraits<OnlyShortSignedValues>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySigned : ::std::int64_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySigned emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySigned::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySigned emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySigned::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ExplicitlySigned emboss_reserved_local_value) {
  return EnumTraits<ExplicitlySigned>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySized64 : ::std::uint64_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySized64 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized64::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySized64 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized64::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ExplicitlySized64 emboss_reserved_local_value) {
  return EnumTraits<ExplicitlySized64>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySized32 : ::std::uint32_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySized32 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized32::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySized32 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized32::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ExplicitlySized32 emboss_reserved_local_value) {
  return EnumTraits<ExplicitlySized32>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySized16 : ::std::uint16_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySized16 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized16::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySized16 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized16::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ExplicitlySized16 emboss_reserved_local_value) {
  return EnumTraits<ExplicitlySized16>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySized8 : ::std::uint8_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySized8 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized8::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySized8 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized8::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ExplicitlySized8 emboss_reserved_local_value) {
  return EnumTraits<ExplicitlySized8>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySized12 : ::std::uint16_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySized12 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized12::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySized12 emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySized12::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ExplicitlySized12 emboss_reserved_local_value) {
  return EnumTraits<ExplicitlySized12>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}
enum class ExplicitlySizedAndSigned : ::std::int32_t {
  ZERO = static_cast</**/::std::int32_t>(0LL),

};
template <class Enum>
class EnumTraits;

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      ExplicitlySizedAndSigned emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySizedAndSigned::ZERO: return "ZERO";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(ExplicitlySizedAndSigned emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case ExplicitlySizedAndSigned::ZERO: return true;

      default:
        return false;
    }
  }

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

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

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

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







namespace ManifestEntry {



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 (!wide_kind_in_bits().Ok()) return false;


    if (!IntrinsicSizeInBits().Ok()) return false;


    if (!MaxSizeInBits().Ok()) return false;


    if (!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_wide_kind_in_bits().Known()) return false;
    if (!emboss_reserved_local_other.has_wide_kind_in_bits().Known()) return false;

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

    if (emboss_reserved_local_other.has_wide_kind_in_bits().ValueOrDefault() &&
        has_wide_kind_in_bits().ValueOrDefault() &&
        !wide_kind_in_bits().Equals(emboss_reserved_local_other.wide_kind_in_bits()))
      return false;

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

    if (emboss_reserved_local_other.has_wide_kind_in_bits().ValueOr(false) &&
        has_wide_kind_in_bits().ValueOr(false) &&
        !wide_kind_in_bits().UncheckedEquals(emboss_reserved_local_other.wide_kind_in_bits()))
      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 == "wide_kind_in_bits") {
        if (!wide_kind_in_bits().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_wide_kind_in_bits().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          wide_kind_in_bits().IsAggregate() || wide_kind_in_bits().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("wide_kind_in_bits: ");
        wide_kind_in_bits().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() &&
                 !wide_kind_in_bits().IsAggregate() && !wide_kind_in_bits().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("# wide_kind_in_bits: 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::Kind,
    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 4>>

 wide_kind_in_bits() const;
  ::emboss::support::Maybe<bool> has_wide_kind_in_bits() 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 ManifestEntry


template <class View>
struct EmbossReservedInternalIsGenericManifestEntryView;

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

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

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

  

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

    if (!kind().Ok()) return false;


    if (!count().Ok()) return false;


    if (!wide_kind().Ok()) return false;


    if (!emboss_reserved_anonymous_field_1().Ok()) return false;


    if (!has_wide_kind_in_bits().Known()) return false;
    if (has_wide_kind_in_bits().ValueOrDefault() && !wide_kind_in_bits().Ok()) return false;


    if (!IntrinsicSizeInBytes().Ok()) return false;


    if (!MaxSizeInBytes().Ok()) return false;


    if (!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(
      GenericManifestEntryView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_kind().Known()) return false;
    if (!emboss_reserved_local_other.has_kind().Known()) return false;

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

    if (emboss_reserved_local_other.has_kind().ValueOrDefault() &&
        has_kind().ValueOrDefault() &&
        !kind().Equals(emboss_reserved_local_other.kind()))
      return false;



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

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

    if (emboss_reserved_local_other.has_count().ValueOrDefault() &&
        has_count().ValueOrDefault() &&
        !count().Equals(emboss_reserved_local_other.count()))
      return false;



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

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

    if (emboss_reserved_local_other.has_wide_kind().ValueOrDefault() &&
        has_wide_kind().ValueOrDefault() &&
        !wide_kind().Equals(emboss_reserved_local_other.wide_kind()))
      return false;



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

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

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

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

    if (emboss_reserved_local_other.has_kind().ValueOr(false) &&
        has_kind().ValueOr(false) &&
        !kind().UncheckedEquals(emboss_reserved_local_other.kind()))
      return false;



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

    if (emboss_reserved_local_other.has_count().ValueOr(false) &&
        has_count().ValueOr(false) &&
        !count().UncheckedEquals(emboss_reserved_local_other.count()))
      return false;



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

    if (emboss_reserved_local_other.has_wide_kind().ValueOr(false) &&
        has_wide_kind().ValueOr(false) &&
        !wide_kind().UncheckedEquals(emboss_reserved_local_other.wide_kind()))
      return false;



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

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

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

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

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

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

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

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

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

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

 kind() const;
  ::emboss::support::Maybe<bool> has_kind() const;

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

 count() const;
  ::emboss::support::Maybe<bool> has_count() const;

 public:
  typename ::emboss::support::EnumView<
    /**/ ::emboss::test::Kind,
    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 32>>

 wide_kind() const;
  ::emboss::support::Maybe<bool> has_wide_kind() const;

 private:
  typename ::emboss::test::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>

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

 public:
  auto wide_kind_in_bits() const -> decltype(this->emboss_reserved_anonymous_field_1().wide_kind_in_bits()) {
   return has_wide_kind_in_bits().ValueOrDefault() ? emboss_reserved_anonymous_field_1().wide_kind_in_bits()
                                          : decltype(this->emboss_reserved_anonymous_field_1().wide_kind_in_bits())();
  }
  ::emboss::support::Maybe<bool> has_wide_kind_in_bits() 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 GenericManifestEntryView;
};
using ManifestEntryView =
    GenericManifestEntryView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ManifestEntryWriter =
    GenericManifestEntryView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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



namespace StructContainingEnum {
enum class Status : ::std::uint64_t {
  OK = static_cast</**/::std::int32_t>(0LL),
  FAILURE = static_cast</**/::std::int32_t>(1LL),

};
template <class Enum>
class EnumTraits;

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

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

    return false;
  }

  static const char *TryToGetNameFromEnum(
      Status emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Status::OK: return "OK";

      case Status::FAILURE: return "FAILURE";

      default: return nullptr;
    }
  }

  static bool EnumIsKnown(Status emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Status::OK: return true;

      case Status::FAILURE: return true;

      default:
        return false;
    }
  }

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

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

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

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

}  // namespace StructContainingEnum


template <class View>
struct EmbossReservedInternalIsGenericStructContainingEnumView;

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

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

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

    using Status = ::emboss::test::StructContainingEnum::Status;

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

    if (!bar().Ok()) return false;


    if (!IntrinsicSizeInBytes().Ok()) return false;


    if (!MaxSizeInBytes().Ok()) return false;


    if (!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(
      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
    
    if (!has_bar().Known()) return false;
    if (!emboss_reserved_local_other.has_bar().Known()) return false;

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

    if (emboss_reserved_local_other.has_bar().ValueOrDefault() &&
        has_bar().ValueOrDefault() &&
        !bar().Equals(emboss_reserved_local_other.bar()))
      return false;

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

    if (emboss_reserved_local_other.has_bar().ValueOr(false) &&
        has_bar().ValueOr(false) &&
        !bar().UncheckedEquals(emboss_reserved_local_other.bar()))
      return false;

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

  template <typename OtherStorage>
  void CopyFrom(
      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericStructContainingEnumView<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 == "bar") {
        if (!bar().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_bar().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          bar().IsAggregate() || bar().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("bar: ");
        bar().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() &&
                 !bar().IsAggregate() && !bar().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("# bar: 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>>

 bar() const;
  ::emboss::support::Maybe<bool> has_bar() 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 GenericStructContainingEnumView;
};
using StructContainingEnumView =
    GenericStructContainingEnumView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using StructContainingEnumWriter =
    GenericStructContainingEnumView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

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

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

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

namespace Constants {

}  // namespace Constants


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

template <class Storage>
inline constexpr ::std::int32_t
GenericConstantsView<Storage>::EmbossReservedVirtualSprocketView::Read() {
  return Constants::sprocket();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConstantsView<
    Storage>::EmbossReservedVirtualSprocketView::UncheckedRead() {
  return Constants::sprocket();
}

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConstantsView<Storage>::EmbossReservedVirtualGeegawView::Read() {
  return Constants::geegaw();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConstantsView<
    Storage>::EmbossReservedVirtualGeegawView::UncheckedRead() {
  return Constants::geegaw();
}

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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericConstantsView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Constants::MinSizeInBytes();
}
namespace ManifestEntry {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1


template <class Storage>
inline typename ::emboss::support::EnumView<
    /**/ ::emboss::test::Kind,
    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 4>>

 GenericEmbossReservedAnonymousField1View<Storage>::wide_kind_in_bits()
    const {

  if ( has_wide_kind_in_bits().ValueOr(false)) {

    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL));
    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
        return ::emboss::support::EnumView<
    /**/ ::emboss::test::Kind,
    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 4>>

(
                 backing_
                        .template GetOffsetStorage<0,
                                                   4>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::EnumView<
    /**/ ::emboss::test::Kind,
    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/0, 4>>

();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField1View<Storage>::has_wide_kind_in_bits() 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>(36LL)).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>(36LL)).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>(36LL)).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 ManifestEntry


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

 GenericManifestEntryView<Storage>::kind()
    const {

  if ( has_kind().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::Kind,
    ::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::Kind,
    ::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>
GenericManifestEntryView<Storage>::has_kind() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

 GenericManifestEntryView<Storage>::count()
    const {

  if ( has_count().ValueOr(false)) {

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

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

();
}

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


template <class Storage>
inline typename ::emboss::support::EnumView<
    /**/ ::emboss::test::Kind,
    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 32>>

 GenericManifestEntryView<Storage>::wide_kind()
    const {

  if ( has_wide_kind().ValueOr(false)) {

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

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

();
}

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


template <class Storage>
inline typename ::emboss::test::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>

 GenericManifestEntryView<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>(5LL));
    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL));
    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::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>

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

();
}

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


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


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

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

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

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

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

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

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

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

template <class Storage>
inline constexpr ::std::int32_t
GenericManifestEntryView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ManifestEntry::MinSizeInBytes();
}
namespace StructContainingEnum {

}  // namespace StructContainingEnum


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>>

 GenericStructContainingEnumView<Storage>::bar()
    const {

  if ( has_bar().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>
GenericStructContainingEnumView<Storage>::has_bar() const {
  return ::emboss::support::Maybe</**/bool>(true);
}


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

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

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

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

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

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

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

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

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



}  // namespace test



}  // namespace emboss



/* NOLINTEND */

#endif  // TESTDATA_ENUM_EMB_H_

