@@ -15,6 +15,7 @@ Miscellaneous helpers for common patterns.
15
15
*/
16
16
17
17
use prelude:: * ;
18
+ use unstable:: intrinsics;
18
19
19
20
/// The identity function.
20
21
#[ inline( always) ]
@@ -49,18 +50,75 @@ pub fn with<T,R>(
49
50
*/
50
51
#[ inline( always) ]
51
52
pub fn swap < T > ( x : & mut T , y : & mut T ) {
52
- * x <-> * y;
53
+ unsafe {
54
+ swap_ptr ( ptr:: to_mut_unsafe_ptr ( x) , ptr:: to_mut_unsafe_ptr ( y) ) ;
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Swap the values at two mutable locations of the same type, without
60
+ * deinitialising or copying either one.
61
+ */
62
+ #[ inline]
63
+ #[ cfg( not( stage0) ) ]
64
+ pub unsafe fn swap_ptr < T > ( x : * mut T , y : * mut T ) {
65
+ if x == y { return }
66
+
67
+ // Give ourselves some scratch space to work with
68
+ let mut tmp: T = intrinsics:: uninit ( ) ;
69
+ let t = ptr:: to_mut_unsafe_ptr ( & mut tmp) ;
70
+
71
+ // Perform the swap
72
+ ptr:: copy_memory ( t, x, 1 ) ;
73
+ ptr:: copy_memory ( x, y, 1 ) ;
74
+ ptr:: copy_memory ( y, t, 1 ) ;
75
+
76
+ // y and t now point to the same thing, but we need to completely forget t
77
+ // because it's no longer relevant.
78
+ cast:: forget ( tmp) ;
79
+ }
80
+
81
+ /**
82
+ * Swap the values at two mutable locations of the same type, without
83
+ * deinitialising or copying either one.
84
+ */
85
+ #[ inline]
86
+ #[ cfg( stage0) ]
87
+ pub unsafe fn swap_ptr < T > ( x : * mut T , y : * mut T ) {
88
+ if x == y { return }
89
+
90
+ // Give ourselves some scratch space to work with
91
+ let mut tmp: T = intrinsics:: init ( ) ;
92
+ let t = ptr:: to_mut_unsafe_ptr ( & mut tmp) ;
93
+
94
+ // Perform the swap
95
+ ptr:: copy_memory ( t, x, 1 ) ;
96
+ ptr:: copy_memory ( x, y, 1 ) ;
97
+ ptr:: copy_memory ( y, t, 1 ) ;
98
+
99
+ // y and t now point to the same thing, but we need to completely forget t
100
+ // because it's no longer relevant.
101
+ cast:: forget ( tmp) ;
102
+ }
103
+
104
+ /**
105
+ * Replace the value at a mutable location with a new one, returning the old
106
+ * value, without deinitialising or copying either one.
107
+ */
108
+ #[ inline( always) ]
109
+ pub fn replace < T > ( dest : & mut T , mut src : T ) -> T {
110
+ swap ( dest, & mut src) ;
111
+ src
53
112
}
54
113
55
114
/**
56
115
* Replace the value at a mutable location with a new one, returning the old
57
116
* value, without deinitialising or copying either one.
58
117
*/
59
118
#[ inline( always) ]
60
- pub fn replace < T > ( dest : & mut T , src : T ) -> T {
61
- let mut tmp = src;
62
- swap ( dest, & mut tmp) ;
63
- tmp
119
+ pub unsafe fn replace_ptr < T > ( dest : * mut T , mut src : T ) -> T {
120
+ swap_ptr ( dest, ptr:: to_mut_unsafe_ptr ( & mut src) ) ;
121
+ src
64
122
}
65
123
66
124
/// A non-copyable dummy type.
0 commit comments