polars_core/series/arithmetic/
bitops.rs1use std::borrow::Cow;
2
3use polars_error::PolarsResult;
4
5use super::{BooleanChunked, ChunkedArray, DataType, IntoSeries, Series, polars_bail};
6
7macro_rules! impl_bitop {
8 ($(($trait:ident, $f:ident))+) => {
9 $(
10 impl std::ops::$trait for &Series {
11 type Output = PolarsResult<Series>;
12 #[inline(never)]
13 fn $f(self, rhs: Self) -> Self::Output {
14 use DataType as DT;
15 match self.dtype() {
16 DT::Boolean => {
17 let lhs: &BooleanChunked = self.as_ref().as_ref().as_ref();
18 let rhs = lhs.unpack_series_matching_type(rhs)?;
19 Ok(lhs.$f(rhs).into_series())
20 },
21 dt if dt.is_integer() => {
22 let rhs = if rhs.len() == 1 {
23 Cow::Owned(rhs.cast(self.dtype())?)
24 } else {
25 Cow::Borrowed(rhs)
26 };
27
28 with_match_physical_integer_polars_type!(dt, |$T| {
29 let lhs: &ChunkedArray<$T> = self.as_ref().as_ref().as_ref();
30 let rhs = lhs.unpack_series_matching_type(&rhs)?;
31 Ok(lhs.$f(&rhs).into_series())
32 })
33 },
34 _ => polars_bail!(opq = $f, self.dtype()),
35 }
36 }
37 }
38 impl std::ops::$trait for Series {
39 type Output = PolarsResult<Series>;
40 #[inline(always)]
41 fn $f(self, rhs: Self) -> Self::Output {
42 <&Series as std::ops::$trait>::$f(&self, &rhs)
43 }
44 }
45 impl std::ops::$trait<&Series> for Series {
46 type Output = PolarsResult<Series>;
47 #[inline(always)]
48 fn $f(self, rhs: &Series) -> Self::Output {
49 <&Series as std::ops::$trait>::$f(&self, rhs)
50 }
51 }
52 impl std::ops::$trait<Series> for &Series {
53 type Output = PolarsResult<Series>;
54 #[inline(always)]
55 fn $f(self, rhs: Series) -> Self::Output {
56 <&Series as std::ops::$trait>::$f(self, &rhs)
57 }
58 }
59 )+
60 };
61}
62
63impl_bitop! {
64 (BitAnd, bitand)
65 (BitOr, bitor)
66 (BitXor, bitxor)
67}