Skip to content

Commit c31da9d

Browse files
committed
Fix non-portable swap for Vector<bool>
1 parent fe65094 commit c31da9d

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

binding-generator/src/writer/rust_native/tpl/vector/cpp.tpl.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern "C" {
3232
}
3333

3434
void cv_{{rust_localalias}}_swap({{cpp_full}}* instance, size_t index1, size_t index2) {
35-
std::swap((*instance)[index1], (*instance)[index2]);
35+
{{swap_func}}((*instance)[index1], (*instance)[index2]);
3636
}
3737

3838
void cv_{{rust_localalias}}_clear({{cpp_full}}* instance) {

binding-generator/src/writer/rust_native/vector.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ impl RustNativeGeneratedElement for Vector<'_> {
9696

9797
let vec_type = self.type_ref();
9898
let element_type = self.element_type();
99+
let element_is_bool = element_type.is_bool();
100+
// https://stackoverflow.com/questions/58660207/why-doesnt-stdswap-work-on-vectorbool-elements-under-clang-win
101+
let swap_func = if element_is_bool {
102+
"instance->swap"
103+
} else {
104+
"std::swap"
105+
};
99106
let mut inter_vars = hashmap! {
100107
"rust_localalias" => self.rust_localalias(),
101108
"cpp_full" => vec_type.cpp_full(),
@@ -105,6 +112,7 @@ impl RustNativeGeneratedElement for Vector<'_> {
105112
"inner_cpp_func_call" => element_type.cpp_arg_func_call("val"),
106113
"inner_cpp_extern_return" => element_type.cpp_extern_return(),
107114
"inner_cpp_extern_return_wrapper" => element_type.cpp_extern_return_wrapper_full(),
115+
"swap_func" => swap_func.into(),
108116
};
109117

110118
let mut prefix = Cow::Borrowed("");
@@ -119,7 +127,7 @@ impl RustNativeGeneratedElement for Vector<'_> {
119127
inter_vars.insert("prefix", prefix);
120128
inter_vars.insert("suffix", suffix);
121129
let mut exports = String::new();
122-
if element_type.is_copy() && !element_type.is_bool() {
130+
if element_type.is_copy() && !element_is_bool {
123131
exports += &METHODS_COPY_NON_BOOL_TPL.interpolate(&inter_vars);
124132
}
125133
if self.is_data_type(&element_type) {

tests/vector.rs

+12
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,18 @@ fn swap() -> Result<()> {
305305
assert_eq!("123", vec.get(2)?);
306306
}
307307

308+
{
309+
let mut vec = VectorOfbool::new();
310+
vec.push(true);
311+
vec.push(false);
312+
vec.push(true);
313+
vec.swap(0, 1)?;
314+
assert_eq!(false, vec.get(0)?);
315+
assert_eq!(true, vec.get(1)?);
316+
vec.swap(1, 2)?;
317+
assert_eq!(true, vec.get(2)?);
318+
}
319+
308320
Ok(())
309321
}
310322

0 commit comments

Comments
 (0)