mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2024-11-23 23:29:50 +00:00
Support derive(Hash)
This commit is contained in:
parent
a05f9402db
commit
7da38209bf
@ -134,6 +134,8 @@ fn write_functions<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
write_std_specializations(out, apis);
|
||||
}
|
||||
|
||||
for api in apis {
|
||||
@ -148,6 +150,36 @@ fn write_functions<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) {
|
||||
}
|
||||
}
|
||||
|
||||
fn write_std_specializations(out: &mut OutFile, apis: &[Api]) {
|
||||
out.set_namespace(Default::default());
|
||||
out.begin_block(Block::Namespace("std"));
|
||||
|
||||
for api in apis {
|
||||
if let Api::Struct(strct) = api {
|
||||
if derive::contains(&strct.derives, Trait::Hash) {
|
||||
out.next_section();
|
||||
let qualified = strct.name.to_fully_qualified();
|
||||
writeln!(out, "template <> struct hash<{}> {{", qualified);
|
||||
writeln!(
|
||||
out,
|
||||
" size_t operator()(const {} &self) const noexcept {{",
|
||||
qualified,
|
||||
);
|
||||
let link_name = mangle::operator(&strct.name, "hash");
|
||||
write!(out, " return ::");
|
||||
for name in &strct.name.namespace {
|
||||
write!(out, "{}::", name);
|
||||
}
|
||||
writeln!(out, "{}(self);", link_name);
|
||||
writeln!(out, " }}");
|
||||
writeln!(out, "}};");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.end_block(Block::Namespace("std"));
|
||||
}
|
||||
|
||||
fn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) {
|
||||
for api in apis {
|
||||
if let Api::Include(include) = api {
|
||||
@ -432,6 +464,15 @@ fn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
|
||||
}
|
||||
}
|
||||
|
||||
if derive::contains(&strct.derives, Trait::Hash) {
|
||||
let link_name = mangle::operator(&strct.name, "hash");
|
||||
writeln!(
|
||||
out,
|
||||
"size_t {}(const {} &) noexcept;",
|
||||
link_name, strct.name.cxx,
|
||||
);
|
||||
}
|
||||
|
||||
out.end_block(Block::ExternC);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ pub fn expand_struct(strct: &Struct, actual_derives: &mut Option<TokenStream>) -
|
||||
Trait::Debug => expanded.extend(struct_debug(strct, span)),
|
||||
Trait::Default => expanded.extend(struct_default(strct, span)),
|
||||
Trait::Eq => traits.push(quote_spanned!(span=> ::std::cmp::Eq)),
|
||||
Trait::Hash => expanded.extend(struct_hash(strct, span)),
|
||||
Trait::Ord => expanded.extend(struct_ord(strct, span)),
|
||||
Trait::PartialEq => traits.push(quote_spanned!(span=> ::std::cmp::PartialEq)),
|
||||
Trait::PartialOrd => expanded.extend(struct_partial_ord(strct, span)),
|
||||
@ -56,6 +57,7 @@ pub fn expand_enum(enm: &Enum, actual_derives: &mut Option<TokenStream>) -> Toke
|
||||
traits.push(quote_spanned!(span=> ::std::cmp::Eq));
|
||||
has_eq = true;
|
||||
}
|
||||
Trait::Hash => expanded.extend(enum_hash(enm, span)),
|
||||
Trait::Ord => expanded.extend(enum_ord(enm, span)),
|
||||
Trait::PartialEq => {
|
||||
traits.push(quote_spanned!(span=> ::std::cmp::PartialEq));
|
||||
@ -155,6 +157,21 @@ fn struct_default(strct: &Struct, span: Span) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_hash(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let fields = strct.fields.iter().map(|field| &field.ident);
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::std::hash::Hash for #ident {
|
||||
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
|
||||
#(
|
||||
::std::hash::Hash::hash(&self.#fields, state);
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_ord(strct: &Struct, span: Span) -> TokenStream {
|
||||
let ident = &strct.name.rust;
|
||||
let fields = strct.fields.iter().map(|field| &field.ident);
|
||||
@ -246,6 +263,18 @@ fn enum_debug(enm: &Enum, span: Span) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_hash(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
|
||||
quote_spanned! {span=>
|
||||
impl ::std::hash::Hash for #ident {
|
||||
fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
|
||||
::std::hash::Hash::hash(&self.repr, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enum_ord(enm: &Enum, span: Span) -> TokenStream {
|
||||
let ident = &enm.name.rust;
|
||||
|
||||
|
@ -230,6 +230,19 @@ fn expand_struct_operators(strct: &Struct) -> TokenStream {
|
||||
});
|
||||
}
|
||||
}
|
||||
Trait::Hash => {
|
||||
let link_name = mangle::operator(&strct.name, "hash");
|
||||
let local_name = format_ident!("__operator_hash_{}", strct.name.rust);
|
||||
operators.extend(quote_spanned! {span=>
|
||||
#[doc(hidden)]
|
||||
#[export_name = #link_name]
|
||||
extern "C" fn #local_name(this: &#ident) -> usize {
|
||||
let mut hasher = ::std::collections::hash_map::DefaultHasher::new();
|
||||
::std::hash::Hash::hash(this, &mut hasher);
|
||||
::std::hash::Hasher::finish(&hasher) as usize
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ pub enum Trait {
|
||||
Debug,
|
||||
Default,
|
||||
Eq,
|
||||
Hash,
|
||||
Ord,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
@ -26,6 +27,7 @@ impl Derive {
|
||||
"Debug" => Trait::Debug,
|
||||
"Default" => Trait::Default,
|
||||
"Eq" => Trait::Eq,
|
||||
"Hash" => Trait::Hash,
|
||||
"Ord" => Trait::Ord,
|
||||
"PartialEq" => Trait::PartialEq,
|
||||
"PartialOrd" => Trait::PartialOrd,
|
||||
@ -50,6 +52,7 @@ impl AsRef<str> for Trait {
|
||||
Trait::Debug => "Debug",
|
||||
Trait::Default => "Default",
|
||||
Trait::Eq => "Eq",
|
||||
Trait::Hash => "Hash",
|
||||
Trait::Ord => "Ord",
|
||||
Trait::PartialEq => "PartialEq",
|
||||
Trait::PartialOrd => "PartialOrd",
|
||||
|
@ -26,7 +26,13 @@ pub fn extern_fn(efn: &ExternFn, types: &Types) -> Symbol {
|
||||
}
|
||||
|
||||
pub fn operator(receiver: &Pair, operator: &'static str) -> Symbol {
|
||||
join!(receiver.namespace, CXXBRIDGE, receiver.cxx, "operator", operator)
|
||||
join!(
|
||||
receiver.namespace,
|
||||
CXXBRIDGE,
|
||||
receiver.cxx,
|
||||
"operator",
|
||||
operator,
|
||||
)
|
||||
}
|
||||
|
||||
// The C half of a function pointer trampoline.
|
||||
|
@ -25,7 +25,7 @@ pub mod ffi {
|
||||
msg: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Hash)]
|
||||
enum Enum {
|
||||
AVal,
|
||||
BVal = 2020,
|
||||
@ -64,6 +64,7 @@ pub mod ffi {
|
||||
}
|
||||
|
||||
#[namespace = "second"]
|
||||
#[derive(Hash)]
|
||||
struct Second {
|
||||
i: i32,
|
||||
e: COwnedEnum,
|
||||
@ -184,6 +185,7 @@ pub mod ffi {
|
||||
}
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Hash)]
|
||||
enum COwnedEnum {
|
||||
CVal1,
|
||||
CVal2,
|
||||
|
Loading…
Reference in New Issue
Block a user