diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-10-01 05:00:50 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-10-09 17:19:53 -0400 |
| commit | 6340c1a3739de1519f7416ac52263b4234965739 (patch) | |
| tree | 3a532bebe3c14438f035caf45bd3724ba750f045 | |
| parent | 389ef6601d18112a7a449eac2e190e4eb061bdf8 (diff) | |
| download | rust-6340c1a3739de1519f7416ac52263b4234965739.tar.gz rust-6340c1a3739de1519f7416ac52263b4234965739.zip | |
Add a model for how conditional trait impls might be used to implement
the Fn-FnMut-FnOnce hierarchy.
| -rw-r--r-- | src/test/run-pass/traits-conditional-model-fn.rs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/test/run-pass/traits-conditional-model-fn.rs b/src/test/run-pass/traits-conditional-model-fn.rs new file mode 100644 index 00000000000..11e144e7dfe --- /dev/null +++ b/src/test/run-pass/traits-conditional-model-fn.rs @@ -0,0 +1,101 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// A model for how the `Fn` traits could work. You can implement at +// most one of `Go`, `GoMut`, or `GoOnce`, and then the others follow +// automatically. + +use std::rc::Rc; +use std::cell::Cell; + +trait Go { + fn go(&self, arg: int); +} + +fn go<G:Go>(this: &G, arg: int) { + this.go(arg) +} + +trait GoMut { + fn go_mut(&mut self, arg: int); +} + +fn go_mut<G:GoMut>(this: &mut G, arg: int) { + this.go_mut(arg) +} + +trait GoOnce { + fn go_once(self, arg: int); +} + +fn go_once<G:GoOnce>(this: G, arg: int) { + this.go_once(arg) +} + +impl<G> GoMut for G + where G : Go +{ + fn go_mut(&mut self, arg: int) { + go(&*self, arg) + } +} + +impl<G> GoOnce for G + where G : GoMut +{ + fn go_once(mut self, arg: int) { + go_mut(&mut self, arg) + } +} + +/////////////////////////////////////////////////////////////////////////// + +struct SomeGoableThing { + counter: Rc<Cell<int>> +} + +impl Go for SomeGoableThing { + fn go(&self, arg: int) { + self.counter.set(self.counter.get() + arg); + } +} + +/////////////////////////////////////////////////////////////////////////// + +struct SomeGoOnceableThing { + counter: Rc<Cell<int>> +} + +impl GoOnce for SomeGoOnceableThing { + fn go_once(self, arg: int) { + self.counter.set(self.counter.get() + arg); + } +} + +/////////////////////////////////////////////////////////////////////////// + +fn main() { + let counter = Rc::new(Cell::new(0)); + let mut x = SomeGoableThing { counter: counter.clone() }; + + go(&x, 10); + assert_eq!(counter.get(), 10); + + go_mut(&mut x, 100); + assert_eq!(counter.get(), 110); + + go_once(x, 1_000); + assert_eq!(counter.get(), 1_110); + + let x = SomeGoOnceableThing { counter: counter.clone() }; + + go_once(x, 10_000); + assert_eq!(counter.get(), 11_110); +} |
