|
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
|
@@ -860,41 +865,56 @@ not_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
860 | 865 | ///
|
861 | 866 | /// # Examples
|
862 | 867 | ///
|
863 |
| -/// In this example, the `BitAnd` trait is implemented for a `BooleanVector` |
864 |
| -/// struct. |
| 868 | +/// In this example, the `&` operator is lifted to a trivial `Scalar` type. |
865 | 869 | ///
|
866 | 870 | /// ```
|
867 | 871 | /// use std::ops::BitAnd;
|
868 | 872 | ///
|
869 |
| -/// #[derive(Debug)] |
870 |
| -/// struct BooleanVector { |
871 |
| -/// value: Vec<bool>, |
872 |
| -/// }; |
| 873 | +/// #[derive(Debug, PartialEq)] |
| 874 | +/// struct Scalar(bool); |
873 | 875 | ///
|
874 |
| -/// impl BitAnd for BooleanVector { |
| 876 | +/// impl BitAnd for Scalar { |
875 | 877 | /// type Output = Self;
|
876 | 878 | ///
|
| 879 | +/// // rhs is the "right-hand side" of the expression `a & b` |
877 | 880 | /// fn bitand(self, rhs: Self) -> Self {
|
878 |
| -/// BooleanVector { |
879 |
| -/// value: self.value |
880 |
| -/// .iter() |
881 |
| -/// .zip(rhs.value.iter()) |
882 |
| -/// .map(|(x, y)| *x && *y) |
883 |
| -/// .collect(), |
884 |
| -/// } |
| 881 | +/// Scalar(self.0 & rhs.0) |
885 | 882 | /// }
|
886 | 883 | /// }
|
887 | 884 | ///
|
888 |
| -/// impl PartialEq for BooleanVector { |
889 |
| -/// fn eq(&self, other: &Self) -> bool { |
890 |
| -/// self.value == other.value |
| 885 | +/// fn main() { |
| 886 | +/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true)); |
| 887 | +/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false)); |
| 888 | +/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false)); |
| 889 | +/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false)); |
| 890 | +/// } |
| 891 | +/// ``` |
| 892 | +/// |
| 893 | +/// In this example, the `BitAnd` trait is implemented for a `BooleanVector` |
| 894 | +/// struct. |
| 895 | +/// |
| 896 | +/// ``` |
| 897 | +/// use std::ops::BitAnd; |
| 898 | +/// |
| 899 | +/// #[derive(Debug, PartialEq)] |
| 900 | +/// struct BooleanVector(Vec<bool>); |
| 901 | +/// |
| 902 | +/// impl BitAnd for BooleanVector { |
| 903 | +/// type Output = Self; |
| 904 | +/// |
| 905 | +/// fn bitand(self, BooleanVector(rhs): Self) -> Self { |
| 906 | +/// let BooleanVector(lhs) = self; |
| 907 | +/// assert_eq!(lhs.len(), rhs.len()); |
| 908 | +/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect()) |
891 | 909 | /// }
|
892 | 910 | /// }
|
893 | 911 | ///
|
894 |
| -/// let bv1 = BooleanVector { value: vec![true, true, false, false] }; |
895 |
| -/// let bv2 = BooleanVector { value: vec![true, false, true, false] }; |
896 |
| -/// let expected = BooleanVector { value: vec![true, false, false, false] }; |
897 |
| -/// assert_eq!(bv1 & bv2, expected); |
| 912 | +/// fn main() { |
| 913 | +/// let bv1 = BooleanVector(vec![true, true, false, false]); |
| 914 | +/// let bv2 = BooleanVector(vec![true, false, true, false]); |
| 915 | +/// let expected = BooleanVector(vec![true, false, false, false]); |
| 916 | +/// assert_eq!(bv1 & bv2, expected); |
| 917 | +/// } |
898 | 918 | /// ```
|
899 | 919 | #[lang = "bitand"]
|
900 | 920 | #[stable(feature = "rust1", since = "1.0.0")]
|
|
0 commit comments