• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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