1{#--- 2 Macro for enum definition, and the declaration of associated functions. 3---#} 4 5{%- macro enum_decl(enum) %} 6{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %} 7enum class {{enum_name}} : int32_t { 8{%- for field in enum.fields %} 9{%- if field.value %} 10 {{field.name}} = {{field.value|expression_to_text}}, 11{%- else %} 12 {{field.name}}, 13{%- endif %} 14{%- endfor %} 15{%- if enum.min_value is not none %} 16 kMinValue = {{enum.min_value}}, 17{%- endif %} 18{%- if enum.max_value is not none %} 19 kMaxValue = {{enum.max_value}}, 20{%- endif %} 21}; 22 23inline std::ostream& operator<<(std::ostream& os, {{enum_name}} value) { 24{%- if enum.fields %} 25 switch(value) { 26{%- for _, values in enum.fields|groupby('numeric_value') %} 27 case {{enum_name}}::{{values[0].name}}: 28 return os << "{{enum_name}}:: 29{%- if values|length > 1 -%} 30 {{'{'}} 31{%- endif -%} 32 {{values|map(attribute='name')|join(', ')}} 33{%- if values|length > 1 -%} 34 {{'}'}} 35{%- endif -%} 36 "; 37{%- endfor %} 38 default: 39 return os << "Unknown {{enum_name}} value: " << static_cast<int32_t>(value); 40 } 41{%- else %} 42 return os << "Unknown {{enum_name}} value: " << static_cast<int32_t>(value); 43{%- endif %} 44} 45 46{#- Returns true if the given enum value exists in this version of enum. #} 47inline bool IsKnownEnumValue({{enum_name}} value) { 48 return {{enum|get_name_for_kind(internal=True, 49 flatten_nested_kind=True)}}::IsKnownValue( 50 static_cast<int32_t>(value)); 51} 52{%- endmacro %} 53 54{%- macro enum_data_decl(enum) %} 55{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %} 56struct {{enum_name}}_Data { 57 public: 58 static bool constexpr kIsExtensible = {% if enum.extensible %}true{% else %}false{% endif %}; 59 60 static bool IsKnownValue(int32_t value) { 61{%- if enum.fields %} 62 switch (value) { 63{%- for enum_field in enum.fields|groupby('numeric_value') %} 64 case {{enum_field[0]}}: 65{%- endfor %} 66 return true; 67 } 68{%- endif %} 69 return false; 70 } 71 72 static bool Validate(int32_t value, 73 mojo::internal::ValidationContext* validation_context) { 74 if (kIsExtensible || IsKnownValue(value)) 75 return true; 76 77 ReportValidationError(validation_context, 78 mojo::internal::VALIDATION_ERROR_UNKNOWN_ENUM_VALUE); 79 return false; 80 } 81}; 82{%- endmacro %} 83 84{%- macro enum_hash(enum) %} 85{%- set enum_name = enum|get_qualified_name_for_kind( 86 flatten_nested_kind=True) %} 87template <> 88struct hash<{{enum_name}}> 89 : public mojo::internal::EnumHashImpl<{{enum_name}}> {}; 90{%- endmacro %} 91 92{%- macro enum_hash_blink(enum) %} 93{%- set enum_name = enum|get_qualified_name_for_kind( 94 flatten_nested_kind=True, include_variant=False) %} 95{%- set hash_fn_name = enum|wtf_hash_fn_name_for_enum %} 96{# We need two unused enum values: #} 97{%- set empty_value = -1000000 %} 98{%- set deleted_value = -1000001 %} 99{%- set empty_value_unused = "false" if empty_value in enum|all_enum_values else "true" %} 100{%- set deleted_value_unused = "false" if empty_value in enum|all_enum_values else "true" %} 101namespace WTF { 102struct {{hash_fn_name}} { 103 static unsigned GetHash(const {{enum_name}}& value) { 104 using utype = std::underlying_type<{{enum_name}}>::type; 105 return DefaultHash<utype>::Hash().GetHash(static_cast<utype>(value)); 106 } 107 static bool Equal(const {{enum_name}}& left, const {{enum_name}}& right) { 108 return left == right; 109 } 110 static const bool safe_to_compare_to_empty_or_deleted = true; 111}; 112 113template <> 114struct DefaultHash<{{enum_name}}> { 115 using Hash = {{hash_fn_name}}; 116}; 117 118template <> 119struct HashTraits<{{enum_name}}> 120 : public GenericHashTraits<{{enum_name}}> { 121 static_assert({{empty_value_unused}}, 122 "{{empty_value}} is a reserved enum value"); 123 static_assert({{deleted_value_unused}}, 124 "{{deleted_value}} is a reserved enum value"); 125 static const bool hasIsEmptyValueFunction = true; 126 static bool IsEmptyValue(const {{enum_name}}& value) { 127 return value == static_cast<{{enum_name}}>({{empty_value}}); 128 } 129 static void ConstructDeletedValue({{enum_name}}& slot, bool) { 130 slot = static_cast<{{enum_name}}>({{deleted_value}}); 131 } 132 static bool IsDeletedValue(const {{enum_name}}& value) { 133 return value == static_cast<{{enum_name}}>({{deleted_value}}); 134 } 135}; 136} // namespace WTF 137{%- endmacro %} 138