Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(specialization)]
- use ::std::*;
- type Str = borrow::Cow<'static, str>;
- trait Point {
- fn magnitude (self: &'_ Self) -> f64;
- fn name (self: &'_ Self) -> &'_ str;
- }
- #[derive(Debug, Clone, Copy)]
- struct BasePoint {
- x: f64,
- y: f64,
- }
- impl Point for BasePoint {
- fn magnitude (self: &'_ Self) -> f64
- {
- let &BasePoint { x, y } = self;
- f64::sqrt(x * x + y * y)
- }
- #[inline]
- fn name (self: &'_ Self) -> &'_ str {
- "Point"
- }
- }
- trait SubPoint {
- type Super : Point;
- #[allow(non_snake_case)]
- fn upcast_Point (self: &'_ Self) -> &'_ Self::Super;
- }
- impl<P : SubPoint> Point for P {
- #[inline]
- default
- fn magnitude (self: &'_ Self) -> f64
- {
- self.upcast_Point().magnitude()
- }
- #[inline]
- default
- fn name (self: &'_ Self) -> &'_ str
- {
- self.upcast_Point().name()
- }
- }
- #[derive(Debug, Clone)]
- struct NamedPoint {
- point: BasePoint,
- name: Str,
- }
- /// derives non-overriden methods
- impl SubPoint for NamedPoint {
- type Super = BasePoint;
- #[inline]
- fn upcast_Point (self: &'_ Self) -> &'_ Self::Super { &self.point }
- }
- /// overriden methods
- impl Point for NamedPoint {
- #[inline]
- fn name (self: &'_ Self) -> &'_ str { &*self.name }
- }
- fn handle_point (point: &'_ impl Point)
- {
- println!("{} has a magnitude of {}", point.name(), point.magnitude());
- }
- fn main ()
- {
- let point = &NamedPoint {
- point: BasePoint { x: 3., y: 4. },
- name: "Foo".into(),
- };
- handle_point(point);
- handle_point(point.upcast_Point());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement