From d64ff983110fed10a7a3351ad156091cfaf3203b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 6 Jun 2012 11:40:04 -0700 Subject: [PATCH] Revert "core: Remove swappable. Unused" due to test failures This reverts commit ec5cbb4f5e951fcc51362c557b1968a57be36afc. --- src/libcore/core.rc | 2 + src/libcore/swappable.rs | 98 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/libcore/swappable.rs diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 6b4c7ad7d3c..84cebcceccd 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -43,6 +43,7 @@ export comm, task, future; export extfmt; export tuple; export to_str; +export swappable; export dvec, dvec_iter; // NDM seems to be necessary for resolve to work @@ -163,6 +164,7 @@ mod option_iter { } mod result; mod to_str; +mod swappable; mod dvec; #[path="iter-trait"] mod dvec_iter { diff --git a/src/libcore/swappable.rs b/src/libcore/swappable.rs new file mode 100644 index 00000000000..5df9b2c4846 --- /dev/null +++ b/src/libcore/swappable.rs @@ -0,0 +1,98 @@ +export swappable; +export unwrap; +export methods; + +#[doc = " +A value that may be swapped out temporarily while it is being processed +and then replaced. Swappables are most useful when working with unique +values, which often cannot be mutated unless they are stored in the local +stack frame to ensure memory safety. + +The type guarantees the invariant that the value is always \"swapped in\" +except during the execution of the `swap()` and `with()` methods. +"] +type swappable = { + mut o_t: option +}; + +#[doc = "Create a swappable swapped in with a given initial value"] +fn swappable(+t: A) -> swappable { + {mut o_t: some(t)} +} + +#[doc = "Consumes a swappable and returns its contents without copying"] +fn unwrap(-s: swappable) -> A { + let {o_t: o_t} <- s; + option::unwrap(o_t) +} + +impl methods for swappable { + #[doc = " + Overwrites the contents of the swappable + "] + fn set(+a: A) { + self.o_t <- some(a); + } + + #[doc = " + Invokes `f()` with the current value but replaces the + current value when complete. Returns the result of `f()`. + + Attempts to read or access the receiver while `f()` is executing + will fail dynamically. + "] + fn with(f: fn(A) -> B) -> B { + let mut o_u = none; + self.swap { |t| o_u <- some(f(t)); t } + option::unwrap(o_u) + } + + #[doc = " + Invokes `f()` with the current value and then replaces the + current value with the result of `f()`. + + Attempts to read or access the receiver while `f()` is executing + will fail dynamically. + "] + fn swap(f: fn(-A) -> A) { + alt self.o_t { + none { fail "no value present---already swapped?"; } + some(_) {} + } + + let mut o_t = none; + o_t <-> self.o_t; + self.o_t <- some(f(option::unwrap(o_t))); + } + + #[doc = "True if there is a value present in this swappable"] + fn is_present() -> bool { + alt self.o_t { + none {false} + some(_) {true} + } + } + + #[doc = " + Removes the value from the swappable. Any further attempts + to use the swapabble without first invoking `set()` will fail. + "] + fn take() -> A { + alt self.o_t { + none { fail "swapped out"; } + some(_) {} + } + + let mut o_t = none; + option::unwrap(o_t) + } +} + +impl methods for swappable { + #[doc = " + Copies out the contents of the swappable + "] + fn get() -> A { + self.o_t.get() + } +} \ No newline at end of file