|
21 | 21 | //! custom operators are required, you should look toward macros or compiler
|
22 | 22 | //! plugins to extend Rust's syntax.
|
23 | 23 | //!
|
| 24 | +//! Note that the `&&` and `||` operators short-circuit, i.e. they only |
| 25 | +//! evaluate their second operand if it contributes to the result. Since this |
| 26 | +//! behavior is not enforceable by traits, `&&` and `||` are not supported as |
| 27 | +//! overloadable operators. |
| 28 | +//! |
24 | 29 | //! Many of the operators take their operands by value. In non-generic
|
25 | 30 | //! contexts involving built-in types, this is usually not a problem.
|
26 | 31 | //! However, using these operators in generic code, requires some
|
@@ -813,41 +818,56 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
813 | 818 | ///
|
814 | 819 | /// # Examples
|
815 | 820 | ///
|
816 |
| -/// In this example, the `BitAnd` trait is implemented for a `BooleanVector` |
817 |
| -/// struct. |
| 821 | +/// In this example, the `&` operator is lifted to a trivial `Scalar` type. |
818 | 822 | ///
|
819 | 823 | /// ```
|
820 | 824 | /// use std::ops::BitAnd;
|
821 | 825 | ///
|
822 |
| -/// #[derive(Debug)] |
823 |
| -/// struct BooleanVector { |
824 |
| -/// value: Vec<bool>, |
825 |
| -/// }; |
| 826 | +/// #[derive(Debug, PartialEq)] |
| 827 | +/// struct Scalar(bool); |
826 | 828 | ///
|
827 |
| -/// impl BitAnd for BooleanVector { |
| 829 | +/// impl BitAnd for Scalar { |
828 | 830 | /// type Output = Self;
|
829 | 831 | ///
|
| 832 | +/// // rhs is the "right-hand side" of the expression `a & b` |
830 | 833 | /// fn bitand(self, rhs: Self) -> Self {
|
831 |
| -/// BooleanVector { |
832 |
| -/// value: self.value |
833 |
| -/// .iter() |
834 |
| -/// .zip(rhs.value.iter()) |
835 |
| -/// .map(|(x, y)| *x && *y) |
836 |
| -/// .collect(), |
837 |
| -/// } |
| 834 | +/// Scalar(self.0 & rhs.0) |
838 | 835 | /// }
|
839 | 836 | /// }
|
840 | 837 | ///
|
841 |
| -/// impl PartialEq for BooleanVector { |
842 |
| -/// fn eq(&self, other: &Self) -> bool { |
843 |
| -/// self.value == other.value |
| 838 | +/// fn main() { |
| 839 | +/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true)); |
| 840 | +/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false)); |
| 841 | +/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false)); |
| 842 | +/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false)); |
| 843 | +/// } |
| 844 | +/// ``` |
| 845 | +/// |
| 846 | +/// In this example, the `BitAnd` trait is implemented for a `BooleanVector` |
| 847 | +/// struct. |
| 848 | +/// |
| 849 | +/// ``` |
| 850 | +/// use std::ops::BitAnd; |
| 851 | +/// |
| 852 | +/// #[derive(Debug, PartialEq)] |
| 853 | +/// struct BooleanVector(Vec<bool>); |
| 854 | +/// |
| 855 | +/// impl BitAnd for BooleanVector { |
| 856 | +/// type Output = Self; |
| 857 | +/// |
| 858 | +/// fn bitand(self, BooleanVector(rhs): Self) -> Self { |
| 859 | +/// let BooleanVector(lhs) = self; |
| 860 | +/// assert_eq!(lhs.len(), rhs.len()); |
| 861 | +/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect()) |
844 | 862 | /// }
|
845 | 863 | /// }
|
846 | 864 | ///
|
847 |
| -/// let bv1 = BooleanVector { value: vec![true, true, false, false] }; |
848 |
| -/// let bv2 = BooleanVector { value: vec![true, false, true, false] }; |
849 |
| -/// let expected = BooleanVector { value: vec![true, false, false, false] }; |
850 |
| -/// assert_eq!(bv1 & bv2, expected); |
| 865 | +/// fn main() { |
| 866 | +/// let bv1 = BooleanVector(vec![true, true, false, false]); |
| 867 | +/// let bv2 = BooleanVector(vec![true, false, true, false]); |
| 868 | +/// let expected = BooleanVector(vec![true, false, false, false]); |
| 869 | +/// assert_eq!(bv1 & bv2, expected); |
| 870 | +/// } |
851 | 871 | /// ```
|
852 | 872 | #[lang = "bitand"]
|
853 | 873 | #[stable(feature = "rust1", since = "1.0.0")]
|
|
0 commit comments