1
1
// SPDX-License-Identifier: Apache-2.0
2
2
3
3
use super :: * ;
4
- use core:: fmt:: { self , Formatter } ;
5
4
use core:: marker:: PhantomData ;
6
- use core:: mem:: align_of;
5
+ use core:: mem:: { align_of, size_of } ;
7
6
use core:: ops:: * ;
8
7
9
8
/// An address
@@ -18,10 +17,54 @@ use core::ops::*;
18
17
/// Unlike the naked underlying types, you can infallibly convert between,
19
18
/// for example, an `Address<usize, ()>` and an `Address<u64, ()>` wherever
20
19
/// such a conversion is lossless given the target CPU architecture.
21
- #[ derive( Copy , Clone , Debug , Default , PartialEq , Eq , PartialOrd , Ord ) ]
20
+ #[ derive( Copy , Clone , Default , PartialEq , Eq , PartialOrd , Ord ) ]
22
21
#[ repr( transparent) ]
23
22
pub struct Address < T , U > ( T , PhantomData < U > ) ;
24
23
24
+ impl < T : core:: fmt:: Binary , U > core:: fmt:: Binary for Address < T , U > {
25
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
26
+ core:: fmt:: Binary :: fmt ( & self . 0 , f)
27
+ }
28
+ }
29
+
30
+ impl < T : core:: fmt:: LowerHex , U > core:: fmt:: Debug for Address < T , U > {
31
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
32
+ f. write_fmt ( format_args ! (
33
+ "Address(0x{:01$x})" ,
34
+ self . 0 ,
35
+ size_of:: <T >( ) * 2
36
+ ) )
37
+ }
38
+ }
39
+
40
+ impl < T : core:: fmt:: Display , U > core:: fmt:: Display for Address < T , U > {
41
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
42
+ core:: fmt:: Display :: fmt ( & self . 0 , f)
43
+ }
44
+ }
45
+
46
+ impl < T : core:: fmt:: LowerHex , U > core:: fmt:: LowerHex for Address < T , U > {
47
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
48
+ core:: fmt:: LowerHex :: fmt ( & self . 0 , f)
49
+ }
50
+ }
51
+
52
+ impl < T , U > core:: fmt:: Pointer for Address < T , U >
53
+ where
54
+ Self : Into < Address < usize , U > > ,
55
+ Self : Copy ,
56
+ {
57
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
58
+ core:: fmt:: Pointer :: fmt ( & self . as_ptr ( ) , f)
59
+ }
60
+ }
61
+
62
+ impl < T : core:: fmt:: UpperHex , U > core:: fmt:: UpperHex for Address < T , U > {
63
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
64
+ core:: fmt:: UpperHex :: fmt ( & self . 0 , f)
65
+ }
66
+ }
67
+
25
68
#[ cfg( feature = "const-default" ) ]
26
69
impl < T : Zero , U > const_default:: ConstDefault for Address < T , U > {
27
70
const DEFAULT : Self = Self :: NULL ;
@@ -56,57 +99,48 @@ impl<T, U> Address<T, U> {
56
99
57
100
impl < T , U > Address < T , U >
58
101
where
59
- Address < usize , U > : From < Address < T , U > > ,
60
- Address < T , U > : Copy ,
102
+ Self : Into < Address < usize , U > > ,
61
103
{
62
104
/// Returns a raw pointer to its inner type
63
105
///
64
106
/// # Safety
65
107
/// Behavior is undefined, if the pointer is used and
66
108
/// is not aligned or points to uninitialized memory.
67
- pub fn as_ptr ( & self ) -> * const U {
68
- Address :: < usize , U > :: from ( * self ) . 0 as * const U
109
+ #[ inline]
110
+ pub fn as_ptr ( self ) -> * const U {
111
+ self . into ( ) . 0 as * const U
69
112
}
70
113
71
114
/// Returns a raw pointer to its inner type
72
115
///
73
116
/// # Safety
74
117
/// Behavior is undefined, if the pointer is used and
75
118
/// is not aligned or points to uninitialized memory.
76
- pub fn as_mut_ptr ( & self ) -> * mut U {
77
- Address :: < usize , U > :: from ( * self ) . 0 as * mut U
78
- }
79
- }
80
-
81
- impl < T : Copy , U > fmt:: Pointer for Address < T , U >
82
- where
83
- Address < usize , U > : From < Address < T , U > > ,
84
- Address < T , U > : Copy ,
85
- {
86
- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
87
- write ! ( f, "{:p}" , self . as_ptr( ) )
119
+ #[ inline]
120
+ pub fn as_mut_ptr ( self ) -> * mut U {
121
+ self . into ( ) . 0 as * mut U
88
122
}
89
123
}
90
124
91
125
pub struct AlignmentError ;
92
126
93
127
impl < T , U > Address < T , U >
94
128
where
95
- Offset < usize , ( ) > : Into < Offset < T , ( ) > > ,
96
- T : Rem < T , Output = T > ,
97
- T : Zero ,
98
- T : PartialEq ,
129
+ Self : Into < Address < usize , U > > ,
130
+ Self : From < Address < usize , U > > ,
99
131
{
100
132
/// Try casting an existing `Address` into an `Address` of a different type
101
133
///
102
- /// Succeeds only, if they have the same alignment
134
+ /// Succeeds only, if they have compatible alignment
103
135
#[ inline]
104
136
pub fn try_cast < V > ( self ) -> Result < Address < T , V > , AlignmentError > {
105
- let align: T = Offset :: from_items ( align_of :: < V > ( ) ) . into ( ) . items ( ) ;
106
- if self . 0 % align != T :: ZERO {
137
+ let addr = self . into ( ) ;
138
+
139
+ if addr. 0 % align_of :: < V > ( ) != 0 {
107
140
return Err ( AlignmentError ) ;
108
141
}
109
- Ok ( Address ( self . 0 , PhantomData ) )
142
+
143
+ Ok ( Address ( Self :: from ( addr) . 0 , PhantomData ) )
110
144
}
111
145
}
112
146
0 commit comments