@@ -299,26 +299,63 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
299299///
300300/// # Examples
301301///
302- /// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
303- /// calling `mul`, and therefore, `main` prints `Multiplying!`.
302+ /// Implementing a `Mul`tipliable rational number struct:
304303///
305304/// ```
306305/// use std::ops::Mul;
307306///
308- /// struct Foo;
307+ /// // The uniqueness of rational numbers in lowest terms is a consequence of
308+ /// // the fundamental theorem of arithmetic.
309+ /// #[derive(Eq)]
310+ /// #[derive(PartialEq, Debug)]
311+ /// struct Rational {
312+ /// nominator: usize,
313+ /// denominator: usize,
314+ /// }
309315///
310- /// impl Mul for Foo {
311- /// type Output = Foo;
316+ /// impl Rational {
317+ /// fn new(nominator: usize, denominator: usize) -> Self {
318+ /// if denominator == 0 {
319+ /// panic!("Zero is an invalid denominator!");
320+ /// }
312321///
313- /// fn mul(self, _rhs: Foo) -> Foo {
314- /// println!("Multiplying!");
315- /// self
322+ /// // Reduce to lowest terms by dividing by the greatest common
323+ /// // divisor.
324+ /// let gcd = gcd(nominator, denominator);
325+ /// Rational {
326+ /// nominator: nominator / gcd,
327+ /// denominator: denominator / gcd,
328+ /// }
316329/// }
317330/// }
318331///
319- /// fn main() {
320- /// Foo * Foo;
332+ /// impl Mul for Rational {
333+ /// // The multiplication of rational numbers is a closed operation.
334+ /// type Output = Self;
335+ ///
336+ /// fn mul(self, rhs: Self) -> Self {
337+ /// let nominator = self.nominator * rhs.nominator;
338+ /// let denominator = self.denominator * rhs.denominator;
339+ /// Rational::new(nominator, denominator)
340+ /// }
341+ /// }
342+ ///
343+ /// // Euclid's two-thousand-year-old algorithm for finding the greatest common
344+ /// // divisor.
345+ /// fn gcd(x: usize, y: usize) -> usize {
346+ /// let mut x = x;
347+ /// let mut y = y;
348+ /// while y != 0 {
349+ /// let t = y;
350+ /// y = x % y;
351+ /// x = t;
352+ /// }
353+ /// x
321354/// }
355+ ///
356+ /// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
357+ /// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
358+ /// Rational::new(1, 2));
322359/// ```
323360///
324361/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
@@ -486,26 +523,34 @@ div_impl_float! { f32 f64 }
486523///
487524/// # Examples
488525///
489- /// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
490- /// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
526+ /// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
527+ /// implemented, one can use the `%` operator to find out what the remaining
528+ /// elements of the slice would be after splitting it into equal slices of a
529+ /// given length.
491530///
492531/// ```
493532/// use std::ops::Rem;
494533///
495- /// struct Foo;
534+ /// #[derive(PartialEq, Debug)]
535+ /// struct SplitSlice<'a, T: 'a> {
536+ /// slice: &'a [T],
537+ /// }
496538///
497- /// impl Rem for Foo {
498- /// type Output = Foo ;
539+ /// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
540+ /// type Output = SplitSlice<'a, T> ;
499541///
500- /// fn rem(self, _rhs: Foo) -> Foo {
501- /// println!("Remainder-ing!");
502- /// self
542+ /// fn rem(self, modulus: usize) -> Self {
543+ /// let len = self.slice.len();
544+ /// let rem = len % modulus;
545+ /// let start = len - rem;
546+ /// SplitSlice {slice: &self.slice[start..]}
503547/// }
504548/// }
505549///
506- /// fn main() {
507- /// Foo % Foo;
508- /// }
550+ /// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
551+ /// // the remainder would be &[6, 7]
552+ /// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
553+ /// SplitSlice { slice: &[6, 7] });
509554/// ```
510555#[ lang = "rem" ]
511556#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -694,26 +739,41 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
694739///
695740/// # Examples
696741///
697- /// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
698- /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!` .
742+ /// In this example, the `BitAnd` trait is implemented for a `BooleanVector`
743+ /// struct .
699744///
700745/// ```
701746/// use std::ops::BitAnd;
702747///
703- /// struct Foo;
704- ///
705- /// impl BitAnd for Foo {
706- /// type Output = Foo;
707- ///
708- /// fn bitand(self, _rhs: Foo) -> Foo {
709- /// println!("Bitwise And-ing!");
710- /// self
748+ /// #[derive(Debug)]
749+ /// struct BooleanVector {
750+ /// value: Vec<bool>,
751+ /// };
752+ ///
753+ /// impl BitAnd for BooleanVector {
754+ /// type Output = Self;
755+ ///
756+ /// fn bitand(self, rhs: Self) -> Self {
757+ /// BooleanVector {
758+ /// value: self.value
759+ /// .iter()
760+ /// .zip(rhs.value.iter())
761+ /// .map(|(x, y)| *x && *y)
762+ /// .collect(),
763+ /// }
711764/// }
712765/// }
713766///
714- /// fn main() {
715- /// Foo & Foo;
767+ /// impl PartialEq for BooleanVector {
768+ /// fn eq(&self, other: &Self) -> bool {
769+ /// self.value == other.value
770+ /// }
716771/// }
772+ ///
773+ /// let bv1 = BooleanVector { value: vec![true, true, false, false] };
774+ /// let bv2 = BooleanVector { value: vec![true, false, true, false] };
775+ /// let expected = BooleanVector { value: vec![true, false, false, false] };
776+ /// assert_eq!(bv1 & bv2, expected);
717777/// ```
718778#[ lang = "bitand" ]
719779#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1490,28 +1550,44 @@ shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
14901550///
14911551/// # Examples
14921552///
1493- /// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
1494- /// calling `index`, and therefore, `main` prints `Indexing!` .
1553+ /// This example implements `Index` on a read-only `NucleotideCount` container,
1554+ /// enabling individual counts to be retrieved with index syntax .
14951555///
14961556/// ```
14971557/// use std::ops::Index;
14981558///
1499- /// #[derive(Copy, Clone)]
1500- /// struct Foo;
1501- /// struct Bar;
1559+ /// enum Nucleotide {
1560+ /// A,
1561+ /// C,
1562+ /// G,
1563+ /// T,
1564+ /// }
15021565///
1503- /// impl Index<Bar> for Foo {
1504- /// type Output = Foo;
1566+ /// struct NucleotideCount {
1567+ /// a: usize,
1568+ /// c: usize,
1569+ /// g: usize,
1570+ /// t: usize,
1571+ /// }
15051572///
1506- /// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
1507- /// println!("Indexing!");
1508- /// self
1573+ /// impl Index<Nucleotide> for NucleotideCount {
1574+ /// type Output = usize;
1575+ ///
1576+ /// fn index(&self, nucleotide: Nucleotide) -> &usize {
1577+ /// match nucleotide {
1578+ /// Nucleotide::A => &self.a,
1579+ /// Nucleotide::C => &self.c,
1580+ /// Nucleotide::G => &self.g,
1581+ /// Nucleotide::T => &self.t,
1582+ /// }
15091583/// }
15101584/// }
15111585///
1512- /// fn main() {
1513- /// Foo[Bar];
1514- /// }
1586+ /// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
1587+ /// assert_eq!(nucleotide_count[Nucleotide::A], 14);
1588+ /// assert_eq!(nucleotide_count[Nucleotide::C], 9);
1589+ /// assert_eq!(nucleotide_count[Nucleotide::G], 10);
1590+ /// assert_eq!(nucleotide_count[Nucleotide::T], 12);
15151591/// ```
15161592#[ lang = "index" ]
15171593#[ rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`" ]
0 commit comments