Skip to content

Commit 9ada80a

Browse files
committed
Implement Ord for Ptr
1 parent b5dd144 commit 9ada80a

7 files changed

Lines changed: 217 additions & 43 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2575,7 +2575,8 @@ bool Converter::VisitCXXRewrittenBinaryOperator(
25752575

25762576
bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) {
25772577
if (expr->getOpcode() == clang::BO_Cmp) {
2578-
StrCat(std::format("({}).cmp(&({}))", ConvertRValue(expr->getLHS()),
2578+
StrCat(std::format("std::cmp::Ord::cmp(&({}), &({}))",
2579+
ConvertRValue(expr->getLHS()),
25792580
ConvertRValue(expr->getRHS())));
25802581
computed_expr_type_ = ComputedExprType::FreshValue;
25812582
return false;

‎libcc2rs/src/rc.rs‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,21 @@ impl<T> PartialEq for Ptr<T> {
167167

168168
impl<T> Eq for Ptr<T> {}
169169

170-
impl<T> PartialOrd for Ptr<T> {
171-
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
170+
impl<T> Ord for Ptr<T> {
171+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
172172
match self.kind.partial_cmp(&other.kind) {
173-
Some(std::cmp::Ordering::Equal) => self.byte_offset().partial_cmp(&other.byte_offset()),
174-
ord => ord,
173+
Some(std::cmp::Ordering::Equal) | None => self.byte_offset().cmp(&other.byte_offset()),
174+
Some(ord) => ord,
175175
}
176176
}
177177
}
178178

179+
impl<T> PartialOrd for Ptr<T> {
180+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
181+
Some(self.cmp(other))
182+
}
183+
}
184+
179185
impl<T> Ptr<T> {
180186
#[inline]
181187
pub fn null() -> Self {

‎tests/unit/operator_comparison_defaulted.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ struct Secondary {
4848
bool operator>=(const Secondary &) const = default;
4949
};
5050

51+
struct PtrMember {
52+
int *p;
53+
auto operator<=>(const PtrMember &) const = default;
54+
};
55+
5156
int main() {
5257
Eq e1{1, 2}, e2{1, 2}, e3{1, 3};
5358
assert(e1 == e2);
@@ -72,5 +77,10 @@ int main() {
7277
assert(s1 < s2);
7378
assert(s2 >= s1);
7479
assert(!(s2 < s1));
80+
int arr[2] = {0, 0};
81+
PtrMember p1{arr}, p2{arr + 1}, p3{arr};
82+
assert(p1 < p2);
83+
assert(p1 == p3);
84+
assert((p2 <=> p1) == std::strong_ordering::greater);
7585
return 0;
7686
}

‎tests/unit/out/refcount/operator_comparison_defaulted.rs‎

Lines changed: 125 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,58 @@ impl ByteRepr for Secondary {
407407
}
408408
}
409409
}
410+
#[derive(Default)]
411+
pub struct PtrMember {
412+
pub p: Value<Ptr<i32>>,
413+
}
414+
impl std::cmp::Ord for PtrMember {
415+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
416+
{
417+
PtrMemberImpl::operator_cmp(
418+
&Rc::new(RefCell::new(PtrMember { p: self.p.clone() })).as_pointer(),
419+
Rc::new(RefCell::new(PtrMember { p: other.p.clone() })).as_pointer(),
420+
)
421+
}
422+
}
423+
}
424+
impl std::cmp::PartialOrd for PtrMember {
425+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
426+
Some(self.cmp(other))
427+
}
428+
}
429+
impl std::cmp::PartialEq for PtrMember {
430+
fn eq(&self, other: &Self) -> bool {
431+
{
432+
PtrMemberImpl::operator_cmp(
433+
&Rc::new(RefCell::new(PtrMember { p: self.p.clone() })).as_pointer(),
434+
Rc::new(RefCell::new(PtrMember { p: other.p.clone() })).as_pointer(),
435+
) == std::cmp::Ordering::Equal
436+
}
437+
}
438+
}
439+
impl std::cmp::Eq for PtrMember {}
440+
impl Clone for PtrMember {
441+
fn clone(&self) -> Self {
442+
let __this: Value<PtrMember> = Rc::new(RefCell::new(Self {
443+
p: Rc::new(RefCell::new((*self.p.borrow()).clone())),
444+
}));
445+
let this: Ptr<PtrMember> = __this.as_pointer();
446+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
447+
}
448+
}
449+
impl ByteRepr for PtrMember {
450+
fn byte_size() -> usize {
451+
8
452+
}
453+
fn to_bytes(&self, buf: &mut [u8]) {
454+
(*self.p.borrow()).to_bytes(&mut buf[0..8]);
455+
}
456+
fn from_bytes(buf: &[u8]) -> Self {
457+
Self {
458+
p: Rc::new(RefCell::new(<Ptr<i32>>::from_bytes(&buf[0..8]))),
459+
}
460+
}
461+
}
410462
pub fn main() {
411463
__cpp2rust_init_globals();
412464
std::process::exit(main_0());
@@ -525,6 +577,27 @@ fn main_0() -> i32 {
525577
assert!(({ SecondaryImpl::operator_lt(&s1.as_pointer(), s2.as_pointer(),) }));
526578
assert!(({ SecondaryImpl::operator_ge(&s2.as_pointer(), s1.as_pointer(),) }));
527579
assert!(!({ SecondaryImpl::operator_lt(&s2.as_pointer(), s1.as_pointer(),) }));
580+
let arr: Value<Box<[i32]>> = Rc::new(RefCell::new(Box::new([0, 0])));
581+
let p1: Value<PtrMember> = Rc::new(RefCell::new(PtrMember {
582+
p: Rc::new(RefCell::new((arr.as_pointer() as Ptr<i32>))),
583+
}));
584+
let p2: Value<PtrMember> = Rc::new(RefCell::new(PtrMember {
585+
p: Rc::new(RefCell::new(
586+
(arr.as_pointer() as Ptr<i32>).offset((1) as isize),
587+
)),
588+
}));
589+
let p3: Value<PtrMember> = Rc::new(RefCell::new(PtrMember {
590+
p: Rc::new(RefCell::new((arr.as_pointer() as Ptr<i32>))),
591+
}));
592+
assert!(
593+
({ PtrMemberImpl::operator_cmp(&p1.as_pointer(), p2.as_pointer(),) })
594+
== std::cmp::Ordering::Less
595+
);
596+
assert!(({ PtrMemberImpl::operator_eq(&p1.as_pointer(), p3.as_pointer(),) }));
597+
assert!(
598+
({ PtrMemberImpl::operator_cmp(&p2.as_pointer(), p1.as_pointer(),) })
599+
== std::cmp::Ordering::Greater
600+
);
528601
return 0;
529602
}
530603
pub trait BothImpl {
@@ -540,10 +613,10 @@ impl BothImpl for Ptr<Both> {
540613
}
541614
fn operator_cmp(&self, _a0: Ptr<Both>) -> std::cmp::Ordering {
542615
{
543-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
544-
(*(*(*self).upgrade().deref()).a.borrow())
545-
.cmp(&(*(*_a0.upgrade().deref()).a.borrow())),
546-
));
616+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
617+
&(*(*(*self).upgrade().deref()).a.borrow()),
618+
&(*(*_a0.upgrade().deref()).a.borrow()),
619+
)));
547620
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
548621
return (*cmp.borrow_mut()).clone();
549622
}
@@ -558,19 +631,19 @@ pub trait CmpImpl {
558631
impl CmpImpl for Ptr<Cmp> {
559632
fn operator_cmp(&self, _a0: Ptr<Cmp>) -> std::cmp::Ordering {
560633
{
561-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
562-
(*(*(*self).upgrade().deref()).a.borrow())
563-
.cmp(&(*(*_a0.upgrade().deref()).a.borrow())),
564-
));
634+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
635+
&(*(*(*self).upgrade().deref()).a.borrow()),
636+
&(*(*_a0.upgrade().deref()).a.borrow()),
637+
)));
565638
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
566639
return (*cmp.borrow_mut()).clone();
567640
}
568641
}
569642
{
570-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
571-
(*(*(*self).upgrade().deref()).b.borrow())
572-
.cmp(&(*(*_a0.upgrade().deref()).b.borrow())),
573-
));
643+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
644+
&(*(*(*self).upgrade().deref()).b.borrow()),
645+
&(*(*_a0.upgrade().deref()).b.borrow()),
646+
)));
574647
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
575648
return (*cmp.borrow_mut()).clone();
576649
}
@@ -608,10 +681,10 @@ pub trait InnerImpl {
608681
impl InnerImpl for Ptr<Inner> {
609682
fn operator_cmp(&self, _a0: Ptr<Inner>) -> std::cmp::Ordering {
610683
{
611-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
612-
(*(*(*self).upgrade().deref()).x.borrow())
613-
.cmp(&(*(*_a0.upgrade().deref()).x.borrow())),
614-
));
684+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
685+
&(*(*(*self).upgrade().deref()).x.borrow()),
686+
&(*(*_a0.upgrade().deref()).x.borrow()),
687+
)));
615688
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
616689
return (*cmp.borrow_mut()).clone();
617690
}
@@ -631,10 +704,10 @@ pub trait OrdOnlyImpl {
631704
impl OrdOnlyImpl for Ptr<OrdOnly> {
632705
fn operator_cmp(&self, _a0: Ptr<OrdOnly>) -> std::cmp::Ordering {
633706
{
634-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
635-
(*(*(*self).upgrade().deref()).a.borrow())
636-
.cmp(&(*(*_a0.upgrade().deref()).a.borrow())),
637-
));
707+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
708+
&(*(*(*self).upgrade().deref()).a.borrow()),
709+
&(*(*_a0.upgrade().deref()).a.borrow()),
710+
)));
638711
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
639712
return (*cmp.borrow_mut()).clone();
640713
}
@@ -660,10 +733,10 @@ impl OuterImpl for Ptr<Outer> {
660733
}
661734
}
662735
{
663-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
664-
(*(*(*self).upgrade().deref()).y.borrow())
665-
.cmp(&(*(*_a0.upgrade().deref()).y.borrow())),
666-
));
736+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
737+
&(*(*(*self).upgrade().deref()).y.borrow()),
738+
&(*(*_a0.upgrade().deref()).y.borrow()),
739+
)));
667740
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
668741
return (*cmp.borrow_mut()).clone();
669742
}
@@ -680,6 +753,30 @@ impl OuterImpl for Ptr<Outer> {
680753
});
681754
}
682755
}
756+
pub trait PtrMemberImpl {
757+
fn operator_cmp(&self, _a0: Ptr<PtrMember>) -> std::cmp::Ordering;
758+
fn operator_eq(&self, _a0: Ptr<PtrMember>) -> bool;
759+
}
760+
impl PtrMemberImpl for Ptr<PtrMember> {
761+
fn operator_cmp(&self, _a0: Ptr<PtrMember>) -> std::cmp::Ordering {
762+
{
763+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
764+
&(*(*(*self).upgrade().deref()).p.borrow()),
765+
&(*(*_a0.upgrade().deref()).p.borrow()),
766+
)));
767+
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
768+
return (*cmp.borrow_mut()).clone();
769+
}
770+
}
771+
return std::cmp::Ordering::Equal;
772+
}
773+
fn operator_eq(&self, _a0: Ptr<PtrMember>) -> bool {
774+
return {
775+
let _lhs = (*(*(*self).upgrade().deref()).p.borrow()).clone();
776+
_lhs == (*(*_a0.upgrade().deref()).p.borrow()).clone()
777+
};
778+
}
779+
}
683780
pub trait SecondaryImpl {
684781
fn operator_eq(&self, _a0: Ptr<Secondary>) -> bool;
685782
fn operator_ne(&self, _a0: Ptr<Secondary>) -> bool;
@@ -702,10 +799,10 @@ impl SecondaryImpl for Ptr<Secondary> {
702799
}
703800
fn operator_cmp(&self, _a0: Ptr<Secondary>) -> std::cmp::Ordering {
704801
{
705-
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(
706-
(*(*(*self).upgrade().deref()).a.borrow())
707-
.cmp(&(*(*_a0.upgrade().deref()).a.borrow())),
708-
));
802+
let cmp: Value<std::cmp::Ordering> = Rc::new(RefCell::new(std::cmp::Ord::cmp(
803+
&(*(*(*self).upgrade().deref()).a.borrow()),
804+
&(*(*_a0.upgrade().deref()).a.borrow()),
805+
)));
709806
if !((*cmp.borrow()) == std::cmp::Ordering::Equal) {
710807
return (*cmp.borrow_mut()).clone();
711808
}

‎tests/unit/out/refcount/operator_traits.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,10 @@ pub trait CmpImpl {
487487
}
488488
impl CmpImpl for Ptr<Cmp> {
489489
fn operator_cmp(&self, o: Ptr<Cmp>) -> std::cmp::Ordering {
490-
return (*(*(*self).upgrade().deref()).v.borrow())
491-
.cmp(&(*(*o.upgrade().deref()).v.borrow()));
490+
return std::cmp::Ord::cmp(
491+
&(*(*(*self).upgrade().deref()).v.borrow()),
492+
&(*(*o.upgrade().deref()).v.borrow()),
493+
);
492494
}
493495
fn operator_eq(&self, o: Ptr<Cmp>) -> bool {
494496
return {

0 commit comments

Comments
 (0)