1{%- set union_prefix = "%s.%s"|format(module_prefix, union.name) %} 2 3{{ kythe_annotation(union_prefix) }} 4class {{export_attribute}} {{union.name}} { 5 public: 6 using DataView = {{union.name}}DataView; 7 using Data_ = internal::{{union.name}}_Data; 8 using Tag = Data_::{{union.name}}_Tag; 9 10 static {{union.name}}Ptr New() { 11 return {{union.name}}Ptr(base::in_place); 12 } 13 14{%- for field in union.fields %} 15 // Construct an instance holding |{{field.name}}|. 16 static {{union.name}}Ptr 17 New{{field.name|under_to_camel}}( 18 {{field.kind|cpp_wrapper_param_type_new}} {{field.name}}) { 19 auto result = {{union.name}}Ptr(base::in_place); 20 result->set_{{field.name}}(std::move({{field.name}})); 21 return result; 22 } 23{%- endfor %} 24 25 template <typename U> 26 static {{union.name}}Ptr From(const U& u) { 27 return mojo::TypeConverter<{{union.name}}Ptr, U>::Convert(u); 28 } 29 30 template <typename U> 31 U To() const { 32 return mojo::TypeConverter<U, {{union.name}}>::Convert(*this); 33 } 34 35 {{union.name}}(); 36 ~{{union.name}}(); 37 38 // Clone() is a template so it is only instantiated if it is used. Thus, the 39 // bindings generator does not need to know whether Clone() or copy 40 // constructor/assignment are available for members. 41 template <typename UnionPtrType = {{union.name}}Ptr> 42 {{union.name}}Ptr Clone() const; 43 44 // Equals() is a template so it is only instantiated if it is used. Thus, the 45 // bindings generator does not need to know whether Equals() or == operator 46 // are available for members. 47 template <typename T, 48 typename std::enable_if<std::is_same< 49 T, {{union.name}}>::value>::type* = nullptr> 50 bool Equals(const T& other) const; 51 52{%- if union|is_hashable %} 53 size_t Hash(size_t seed) const; 54{%- endif %} 55 56 Tag which() const { 57 return tag_; 58 } 59 60{% for field in union.fields %} 61 {{ kythe_annotation("%s.%s"|format(union_prefix, field.name)) }} 62 bool is_{{field.name}}() const { return tag_ == Tag::{{field.name|upper}}; } 63 64 {{ kythe_annotation("%s.%s"|format(union_prefix, field.name)) }} 65 {{field.kind|cpp_union_getter_return_type}} get_{{field.name}}() const { 66 DCHECK(tag_ == Tag::{{field.name|upper}}); 67{%- if field.kind|is_object_kind or 68 field.kind|is_any_handle_or_interface_kind %} 69 return *(data_.{{field.name}}); 70{%- else %} 71 return data_.{{field.name}}; 72{%- endif %} 73 } 74 75 {{ kythe_annotation("%s.%s"|format(union_prefix, field.name)) }} 76 void set_{{field.name}}( 77 {{field.kind|cpp_wrapper_param_type_new}} {{field.name}}); 78{%- endfor %} 79 80 template <typename UserType> 81 static mojo::Message SerializeAsMessage(UserType* input) { 82 return mojo::internal::SerializeAsMessageImpl< 83 {{union.name}}::DataView>(input); 84 } 85 86 template <typename UserType> 87 static bool DeserializeFromMessage(mojo::Message input, 88 UserType* output) { 89 return mojo::internal::DeserializeImpl<{{union.name}}::DataView>( 90 input.payload(), input.payload_num_bytes(), 91 std::move(*input.mutable_handles()), output, Validate); 92 } 93 94 private: 95 union Union_ { 96 Union_() {} 97 ~Union_() {} 98 99{%- for field in union.fields %} 100{%- if field.kind|is_object_kind or 101 field.kind|is_any_handle_or_interface_kind %} 102 {{field.kind|cpp_wrapper_type}}* {{field.name}}; 103{%- else %} 104 {{field.kind|cpp_wrapper_type}} {{field.name}}; 105{%- endif %} 106{%- endfor %} 107 }; 108 109 static bool Validate(const void* data, 110 mojo::internal::ValidationContext* validation_context); 111 112 void DestroyActive(); 113 Tag tag_; 114 Union_ data_; 115}; 116