@@ -299,26 +299,63 @@ sub_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
299
299
///
300
300
/// # Examples
301
301
///
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:
304
303
///
305
304
/// ```
306
305
/// use std::ops::Mul;
307
306
///
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
+ /// }
309
315
///
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
+ /// }
312
321
///
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
+ /// }
316
329
/// }
317
330
/// }
318
331
///
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
321
354
/// }
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));
322
359
/// ```
323
360
///
324
361
/// Note that `RHS = Self` by default, but this is not mandatory. Here is an
@@ -486,26 +523,34 @@ div_impl_float! { f32 f64 }
486
523
///
487
524
/// # Examples
488
525
///
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.
491
530
///
492
531
/// ```
493
532
/// use std::ops::Rem;
494
533
///
495
- /// struct Foo;
534
+ /// #[derive(PartialEq, Debug)]
535
+ /// struct SplitSlice<'a, T: 'a> {
536
+ /// slice: &'a [T],
537
+ /// }
496
538
///
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> ;
499
541
///
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..]}
503
547
/// }
504
548
/// }
505
549
///
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] });
509
554
/// ```
510
555
#[ lang = "rem" ]
511
556
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -694,26 +739,41 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
694
739
///
695
740
/// # Examples
696
741
///
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 .
699
744
///
700
745
/// ```
701
746
/// use std::ops::BitAnd;
702
747
///
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
+ /// }
711
764
/// }
712
765
/// }
713
766
///
714
- /// fn main() {
715
- /// Foo & Foo;
767
+ /// impl PartialEq for BooleanVector {
768
+ /// fn eq(&self, other: &Self) -> bool {
769
+ /// self.value == other.value
770
+ /// }
716
771
/// }
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);
717
777
/// ```
718
778
#[ lang = "bitand" ]
719
779
#[ 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 }
1490
1550
///
1491
1551
/// # Examples
1492
1552
///
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 .
1495
1555
///
1496
1556
/// ```
1497
1557
/// use std::ops::Index;
1498
1558
///
1499
- /// #[derive(Copy, Clone)]
1500
- /// struct Foo;
1501
- /// struct Bar;
1559
+ /// enum Nucleotide {
1560
+ /// A,
1561
+ /// C,
1562
+ /// G,
1563
+ /// T,
1564
+ /// }
1502
1565
///
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
+ /// }
1505
1572
///
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
+ /// }
1509
1583
/// }
1510
1584
/// }
1511
1585
///
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);
1515
1591
/// ```
1516
1592
#[ lang = "index" ]
1517
1593
#[ rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`" ]
0 commit comments