|
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