@@ -10,7 +10,7 @@ A safe version of ManuallyDrop with various features and options to track undefi
1010
1111### 1. easy
1212
13- ``` rust
13+ ``` should_panic
1414use SafeManuallyDrop::ManuallyDrop;
1515use std::ops::Deref;
1616
@@ -53,7 +53,90 @@ fn main() {
5353}
5454```
5555
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
57140
58141``` rust
59142use std :: ops :: Deref ;
@@ -93,7 +176,7 @@ fn main() {
93176}
94177```
95178
96- ### 3 . counter
179+ ### 4 . counter
97180
98181``` rust
99182// Let me remind you that CounterManuallyDrop by behavior allows undefined
@@ -155,12 +238,56 @@ fn main() {
155238}
156239```
157240
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+ ```
159270
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+ ]
160284```
285+
286+ # cargo.toml -> features
287+
288+ ``` rust,ignore
161289// Flags:
162290//
163-
164291// ManuallyDrop and AutoManuallyDrop are always type safe and are automatically
165292// checked on use if the debug_assertions flag is enabled (the flag is automatically
166293// enabled if test build, debug build, or env: CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS=true).
@@ -172,7 +299,7 @@ fn main() {
172299// regardless of external flags.
173300//
174301// (Also, AlwaysSafeManuallyDrop is always checked for safety when it is used, regardless of the flags.)
175- // "always_safe_manuallydrop",
302+ //"always_safe_manuallydrop",
176303
177304// Enable additional internal checks of the SafeManuallyDrop library when
178305// the debug_assertions flag is enabled (does not depend on the always_check_in_case_debug_assertions
@@ -181,8 +308,8 @@ fn main() {
181308//
182309// "allow_fullinternal_debug_assertions",
183310
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)
186313"always_compatible_stdapi",
187314
188315// Always create a modular table of library flags used in the build.
@@ -191,13 +318,16 @@ fn main() {
191318
192319// Trigs:
193320//
194-
195321// Ability to determine if an empty loop trigger has been executed.
196322"support_istrig_loop",
197323
198324// 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",
201331
202332// HookManuallyDrop support, in case of undefined HookManuallyDrop behavior,
203333// the hook function will be called.
@@ -211,9 +341,13 @@ fn main() {
211341// cause a panic in case of undefined behavior.
212342//"always_deftrig_panic",
213343
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+
214348// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always
215349// call the hook function in case of undefined behavior.
216- // "always_deftrig_hookfn",
350+ "always_deftrig_hookfn",
217351
218352// The behavior for the simple AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop type will always call
219353// the +1 counter function in case of undefined behavior.
@@ -222,21 +356,6 @@ fn main() {
222356// The behavior for the simple type AutoSafeManuallyDrop/AlwaysSafeManuallyDrop/ManuallyDrop will always call
223357// the eternal loop function in case of undefined behavior.
224358//"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- //
240359```
241360
242361# License
0 commit comments