@@ -10,7 +10,7 @@ A safe version of ManuallyDrop with various features and options to track undefi
10
10
11
11
### 1. easy
12
12
13
- ``` rust
13
+ ``` should_panic
14
14
use SafeManuallyDrop::ManuallyDrop;
15
15
use std::ops::Deref;
16
16
@@ -53,7 +53,90 @@ fn main() {
53
53
}
54
54
```
55
55
56
- ### 2. hook
56
+ ### 2. EasyStruct
57
+
58
+ ``` rust
59
+ // 1. In production code, it is recommended to use AutoSafe instead of AlwaysSafe,
60
+ // this will eliminate unnecessary checks in the release build, but leave
61
+ // them in the test build.
62
+ //
63
+ // 2. It is generally recommended to use Panic or Abort as a trigger for undefined behavior.
64
+ //
65
+ use SafeManuallyDrop :: AlwaysSafePanicManuallyDrop as ManuallyDrop ;
66
+
67
+ #[derive(Default , Debug )]
68
+ struct ControlDrop (usize );
69
+
70
+ // Properly created and validated MyLogicData structure.
71
+ #[derive(Default )]
72
+ struct MyLogicData {
73
+ data : ManuallyDrop <ControlDrop >
74
+ }
75
+
76
+ impl MyLogicData {
77
+ /// Exceptional logic. As a result, the original value will always be returned.
78
+ pub fn ignore_mylogic_and_getdata (mut self ) -> ControlDrop {
79
+ // Note that you can only `take` once, any further operation with
80
+ // ManuallyDrop will cause a panic.
81
+ let data = unsafe {
82
+ ManuallyDrop :: take (& mut self . data)
83
+ };
84
+
85
+ // ManuallyDrop::forget analog forget(self).
86
+ ManuallyDrop :: forget (self );
87
+
88
+ /*
89
+ data logic
90
+ */
91
+
92
+ data
93
+ }
94
+ }
95
+
96
+ impl Drop for MyLogicData {
97
+ fn drop (& mut self ) {
98
+ /*
99
+ def logic
100
+ */
101
+ println! (" MyLogicData, indata: {:?}" , self . data);
102
+
103
+ /*
104
+ Notification
105
+ 1. `ManuallyDrop` always requires it to be freed when it is no longer needed.
106
+ 2. Once `ManuallyDrop` is freed, you will not be able to read data from it
107
+ 3. You cannot drop `ManuallyDrop` twice.
108
+ ...
109
+
110
+ You can remove the `unsafe` flags if you don't use the `always_compatible_stdapi` flag.
111
+ */
112
+ unsafe {
113
+ ManuallyDrop :: drop (& mut self . data);
114
+ }
115
+ }
116
+ }
117
+
118
+ fn main () {
119
+ {
120
+ // run my logic
121
+ let indata = MyLogicData :: default ();
122
+ drop (indata );
123
+
124
+ // This case will just make the logic default by executing the code in drop.
125
+ }
126
+ {
127
+ // ignore_mylogic
128
+ let indata = MyLogicData :: default ();
129
+ let cd_data = indata . ignore_mylogic_and_getdata ();
130
+
131
+ println! (" ignore_mylogic: {:?}" , cd_data );
132
+
133
+ // In this case, the standard reset logic is eliminated and another
134
+ // specific principle is used, which is embedded in the function with data return.
135
+ }
136
+ }
137
+ ```
138
+
139
+ ### 3. hook
57
140
58
141
``` rust
59
142
use std :: ops :: Deref ;
@@ -93,7 +176,7 @@ fn main() {
93
176
}
94
177
```
95
178
96
- ### 3 . counter
179
+ ### 4 . counter
97
180
98
181
``` rust
99
182
// Let me remind you that CounterManuallyDrop by behavior allows undefined
@@ -155,12 +238,56 @@ fn main() {
155
238
}
156
239
```
157
240
158
- # cargo.toml -> features
241
+ ### 1. PlugAndPlay (Minimal, Panic)
242
+ ``` rust,ignore
243
+ [dependencies.SafeManuallyDrop]
244
+ version = "1.0.3"
245
+ default-features = false
246
+ features = [
247
+ "always_check_in_case_debug_assertions",
248
+
249
+ #"always_compatible_stdapi",
250
+
251
+ "support_panic_trig",
252
+ "always_deftrig_panic"
253
+ ]
254
+ ```
255
+
256
+ ### 2. PlugAndPlay (Minimal, Abort)
257
+ ``` rust,ignore
258
+ [dependencies.SafeManuallyDrop]
259
+ version = "1.0.3"
260
+ default-features = false
261
+ features = [
262
+ "always_check_in_case_debug_assertions",
263
+
264
+ #"always_compatible_stdapi",
265
+
266
+ "support_abort_trig",
267
+ "always_deftrig_abort"
268
+ ]
269
+ ```
159
270
271
+ ### 3. PlugAndPlay (Minimal, Hook)
272
+ ``` rust,ignore
273
+ [dependencies.SafeManuallyDrop]
274
+ version = "1.0.3"
275
+ default-features = false
276
+ features = [
277
+ "always_check_in_case_debug_assertions",
278
+
279
+ #"always_compatible_stdapi",
280
+
281
+ "support_hookfn_trig",
282
+ "always_deftrig_hookfn"
283
+ ]
160
284
```
285
+
286
+ # cargo.toml -> features
287
+
288
+ ``` rust,ignore
161
289
// Flags:
162
290
//
163
-
164
291
// ManuallyDrop and AutoManuallyDrop are always type safe and are automatically
165
292
// checked on use if the debug_assertions flag is enabled (the flag is automatically
166
293
// enabled if test build, debug build, or env: CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS=true).
@@ -172,7 +299,7 @@ fn main() {
172
299
// regardless of external flags.
173
300
//
174
301
// (Also, AlwaysSafeManuallyDrop is always checked for safety when it is used, regardless of the flags.)
175
- // "always_safe_manuallydrop",
302
+ //"always_safe_manuallydrop",
176
303
177
304
// Enable additional internal checks of the SafeManuallyDrop library when
178
305
// the debug_assertions flag is enabled (does not depend on the always_check_in_case_debug_assertions
@@ -181,8 +308,8 @@ fn main() {
181
308
//
182
309
// "allow_fullinternal_debug_assertions",
183
310
184
- // Preserve unsafe fn flags even if functions are safe
185
- // (may be required for additional compatibility with the standard API)
311
+ # Preserve unsafe fn flags even if functions are safe
312
+ # (may be required for additional compatibility with the standard API)
186
313
"always_compatible_stdapi",
187
314
188
315
// Always create a modular table of library flags used in the build.
@@ -191,13 +318,16 @@ fn main() {
191
318
192
319
// Trigs:
193
320
//
194
-
195
321
// Ability to determine if an empty loop trigger has been executed.
196
322
"support_istrig_loop",
197
323
198
324
// Support for PanicManuallyDrop, in case of undefined behavior
199
- // of PanicManuallyDrop there will be a panic.
200
- "support_panic_trig",
325
+ // of ManuallyDrop there will be a panic.
326
+ "support_panic_trig",
327
+
328
+ // Support for AbortManuallyDrop, in case of undefined behavior
329
+ // of ManuallyDrop there will be a abort. (Note that this feature requires std.)
330
+ //"support_abort_trig",
201
331
202
332
// HookManuallyDrop support, in case of undefined HookManuallyDrop behavior,
203
333
// the hook function will be called.
@@ -211,9 +341,13 @@ fn main() {
211
341
// cause a panic in case of undefined behavior.
212
342
//"always_deftrig_panic",
213
343
344
+ // The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always
345
+ // cause a abort in case of undefined behavior.
346
+ //"always_deftrig_abort",
347
+
214
348
// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always
215
349
// call the hook function in case of undefined behavior.
216
- // "always_deftrig_hookfn",
350
+ "always_deftrig_hookfn",
217
351
218
352
// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always call
219
353
// the +1 counter function in case of undefined behavior.
@@ -222,21 +356,6 @@ fn main() {
222
356
// The behavior for the simple type AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop will always call
223
357
// the eternal loop function in case of undefined behavior.
224
358
//"always_deftrig_loop"
225
-
226
- // INFO:
227
- // If the behavior for the general AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop is not fixed,
228
- // the behavior will be determined according to the following scheme:
229
- //
230
- // always_deftrig_panic not exists AND
231
- // always_deftrig_hookfn not exists AND
232
- // always_deftrig_count not exists AND
233
- // always_deftrig_loop not exists THEN
234
- //
235
- // support_hookfn_trig -> Hook, else:
236
- // support_panic_trig -> Panic, else:
237
- // support_count_trig -> Count, else:
238
- // Loop
239
- //
240
359
```
241
360
242
361
# License
0 commit comments