From c70044c89f1ee5368ee9686d6e05dea78684be00 Mon Sep 17 00:00:00 2001 From: kadiwa Date: Wed, 27 Sep 2023 15:24:16 +0200 Subject: [PATCH 1/2] implement some useful traits --- Changelog.md | 2 ++ src/volatile_ptr/mod.rs | 51 ++++++++++++++++++++++++++++++++++++-- src/volatile_ref.rs | 54 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 0d7515f..2a1db12 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,7 @@ # Unreleased +- Add implementations for `fmt::Pointer`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`. + # 0.5.1 – 2023-06-24 - Fix: Add missing documentation of the `map` macro diff --git a/src/volatile_ptr/mod.rs b/src/volatile_ptr/mod.rs index 32e8012..245aff8 100644 --- a/src/volatile_ptr/mod.rs +++ b/src/volatile_ptr/mod.rs @@ -1,4 +1,4 @@ -use core::{fmt, marker::PhantomData, ptr::NonNull}; +use core::{cmp::Ordering, fmt, hash, marker::PhantomData, ptr::NonNull}; use crate::access::ReadWrite; @@ -47,7 +47,7 @@ where impl fmt::Debug for VolatilePtr<'_, T, A> where - T: Copy + fmt::Debug + ?Sized, + T: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("VolatilePtr") @@ -56,3 +56,50 @@ where .finish() } } + +impl fmt::Pointer for VolatilePtr<'_, T, A> +where + T: ?Sized, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&self.pointer.as_ptr(), f) + } +} + +impl PartialEq for VolatilePtr<'_, T, A> +where + T: ?Sized, +{ + fn eq(&self, other: &Self) -> bool { + core::ptr::eq(self.pointer.as_ptr(), other.pointer.as_ptr()) + } +} + +impl Eq for VolatilePtr<'_, T, A> where T: ?Sized {} + +impl PartialOrd for VolatilePtr<'_, T, A> +where + T: ?Sized, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(&self.pointer.as_ptr(), &other.pointer.as_ptr())) + } +} + +impl Ord for VolatilePtr<'_, T, A> +where + T: ?Sized, +{ + fn cmp(&self, other: &Self) -> Ordering { + Ord::cmp(&self.pointer.as_ptr(), &other.pointer.as_ptr()) + } +} + +impl hash::Hash for VolatilePtr<'_, T, A> +where + T: ?Sized, +{ + fn hash(&self, state: &mut H) { + self.pointer.as_ptr().hash(state); + } +} diff --git a/src/volatile_ref.rs b/src/volatile_ref.rs index 0dbe697..a09fe12 100644 --- a/src/volatile_ref.rs +++ b/src/volatile_ref.rs @@ -2,7 +2,7 @@ use crate::{ access::{Access, Copyable, ReadOnly, ReadWrite, WriteOnly}, volatile_ptr::VolatilePtr, }; -use core::{fmt, marker::PhantomData, ptr::NonNull}; +use core::{cmp::Ordering, fmt, hash, marker::PhantomData, ptr::NonNull}; /// Volatile pointer type that respects Rust's aliasing rules. /// @@ -12,6 +12,9 @@ use core::{fmt, marker::PhantomData, ptr::NonNull}; /// - only read-only types implement [`Clone`] and [`Copy`] /// - [`Send`] and [`Sync`] are implemented if `T: Sync` /// +/// However, trait implementations like [`fmt::Debug`] and [`Eq`] behave like they do on pointer +/// types and don't access the referenced value. +/// /// To perform volatile operations on `VolatileRef` types, use the [`as_ptr`][Self::as_ptr] /// or [`as_mut_ptr`](Self::as_mut_ptr) methods to create a temporary /// [`VolatilePtr`][crate::VolatilePtr] instance. @@ -239,7 +242,7 @@ unsafe impl Sync for VolatileRef<'_, T, A> where T: Sync {} impl fmt::Debug for VolatileRef<'_, T, A> where - T: Copy + fmt::Debug + ?Sized, + T: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("VolatileRef") @@ -248,3 +251,50 @@ where .finish() } } + +impl fmt::Pointer for VolatileRef<'_, T, A> +where + T: ?Sized, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&self.pointer.as_ptr(), f) + } +} + +impl PartialEq for VolatileRef<'_, T, A> +where + T: ?Sized, +{ + fn eq(&self, other: &Self) -> bool { + core::ptr::eq(self.pointer.as_ptr(), other.pointer.as_ptr()) + } +} + +impl Eq for VolatileRef<'_, T, A> where T: ?Sized {} + +impl PartialOrd for VolatileRef<'_, T, A> +where + T: ?Sized, +{ + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(&self.pointer.as_ptr(), &other.pointer.as_ptr())) + } +} + +impl Ord for VolatileRef<'_, T, A> +where + T: ?Sized, +{ + fn cmp(&self, other: &Self) -> Ordering { + Ord::cmp(&self.pointer.as_ptr(), &other.pointer.as_ptr()) + } +} + +impl hash::Hash for VolatileRef<'_, T, A> +where + T: ?Sized, +{ + fn hash(&self, state: &mut H) { + self.pointer.as_ptr().hash(state); + } +} From 56dc7f9be1e2019d141bebb203fc8179d04ac409 Mon Sep 17 00:00:00 2001 From: kadiwa Date: Wed, 27 Sep 2023 15:25:37 +0200 Subject: [PATCH 2/2] shorten `Debug` output --- src/volatile_ptr/mod.rs | 5 +---- src/volatile_ref.rs | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/volatile_ptr/mod.rs b/src/volatile_ptr/mod.rs index 245aff8..0f1cbad 100644 --- a/src/volatile_ptr/mod.rs +++ b/src/volatile_ptr/mod.rs @@ -50,10 +50,7 @@ where T: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("VolatilePtr") - .field("pointer", &self.pointer) - .field("access", &self.access) - .finish() + fmt::Pointer::fmt(&self.pointer.as_ptr(), f) } } diff --git a/src/volatile_ref.rs b/src/volatile_ref.rs index a09fe12..2880628 100644 --- a/src/volatile_ref.rs +++ b/src/volatile_ref.rs @@ -245,10 +245,7 @@ where T: ?Sized, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("VolatileRef") - .field("pointer", &self.pointer) - .field("access", &self.access) - .finish() + fmt::Pointer::fmt(&self.pointer.as_ptr(), f) } }