Skip to content

Commit 7b27315

Browse files
committed
xor fexpr
1 parent 26a07c0 commit 7b27315

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

src/core/expr/fbinary/bimaker.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ bimaker_ptr resolve_op(Op opcode, SType stype1, SType stype2) {
4747
switch (opcode) {
4848
//case Op::AND: return resolve_op_and(stype1, stype2);
4949
//case Op::OR: return resolve_op_or(stype1, stype2);
50-
case Op::XOR: return resolve_op_xor(stype1, stype2);
50+
//case Op::XOR: return resolve_op_xor(stype1, stype2);
5151
case Op::LSHIFT: return resolve_op_lshift(stype1, stype2);
5252
case Op::RSHIFT: return resolve_op_rshift(stype1, stype2);
5353

src/core/expr/fbinary/bimaker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ bimaker_ptr resolve_op(Op, SType, SType);
7979

8080
//bimaker_ptr resolve_op_and(SType, SType);
8181
//bimaker_ptr resolve_op_or(SType, SType);
82-
bimaker_ptr resolve_op_xor(SType, SType);
82+
//bimaker_ptr resolve_op_xor(SType, SType);
8383
bimaker_ptr resolve_op_lshift(SType, SType);
8484
bimaker_ptr resolve_op_rshift(SType, SType);
8585

src/core/expr/fbinary/bitwise_and.cc renamed to src/core/expr/fbinary/bitwise_and_or.cc

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ inline static T op_or(T x, T y) {
6868
return (x | y);
6969
}
7070

71+
template <typename T>
72+
inline static T op_xor(T x, T y) {
73+
return (x ^ y);
74+
}
75+
7176
template<bool AND>
7277
class FExpr__andor__ : public FExpr_BinaryOp {
7378
public:
@@ -110,7 +115,8 @@ class FExpr__andor__ : public FExpr_BinaryOp {
110115
case SType::INT32: return make<int32_t, AND>(std::move(lcol), std::move(rcol), stype0);
111116
case SType::INT64: return make<int64_t, AND>(std::move(lcol), std::move(rcol), stype0);
112117
default:
113-
throw TypeError() << "Operator `&` cannot be applied to columns of "
118+
char op = AND?'&':'|';
119+
throw TypeError() << "Operator " << op << " cannot be applied to columns of "
114120
"types `" << stype1 << "` and `" << stype2 << "`";
115121
}
116122
}
@@ -138,6 +144,50 @@ class FExpr__andor__ : public FExpr_BinaryOp {
138144
};
139145

140146

147+
class FExpr__xor__ : public FExpr_BinaryOp {
148+
public:
149+
using FExpr_BinaryOp::FExpr_BinaryOp;
150+
using FExpr_BinaryOp::lhs_;
151+
using FExpr_BinaryOp::rhs_;
152+
153+
154+
std::string name() const override { return "^"; }
155+
int precedence() const noexcept override { return 8; }
156+
157+
158+
Column evaluate1(Column&& lcol, Column&& rcol) const override {
159+
xassert(lcol.nrows() == rcol.nrows());
160+
auto stype1 = lcol.stype();
161+
auto stype2 = rcol.stype();
162+
auto stype0 = common_stype(stype1, stype2);
163+
164+
switch (stype0) {
165+
case SType::BOOL: return make<int8_t>(std::move(lcol), std::move(rcol), stype0);
166+
case SType::INT8: return make<int8_t>(std::move(lcol), std::move(rcol), stype0);
167+
case SType::INT16: return make<int16_t>(std::move(lcol), std::move(rcol), stype0);
168+
case SType::INT32: return make<int32_t>(std::move(lcol), std::move(rcol), stype0);
169+
case SType::INT64: return make<int64_t>(std::move(lcol), std::move(rcol), stype0);
170+
default:
171+
throw TypeError() << "Operator `^` cannot be applied to columns of "
172+
"types `" << stype1 << "` and `" << stype2 << "`";
173+
}
174+
}
175+
176+
private:
177+
template <typename T>
178+
static Column make(Column&& a, Column&& b, SType stype) {
179+
xassert(compatible_type<T>(stype));
180+
size_t nrows = a.nrows();
181+
a.cast_inplace(stype);
182+
b.cast_inplace(stype);
183+
return Column(new FuncBinary1_ColumnImpl<T, T, T>(
184+
std::move(a), std::move(b),
185+
op_xor<T>,
186+
nrows, stype
187+
));
188+
}
189+
};
190+
141191

142192
py::oobj PyFExpr::nb__and__(py::robj lhs, py::robj rhs) {
143193
return PyFExpr::make(
@@ -149,6 +199,13 @@ py::oobj PyFExpr::nb__or__(py::robj lhs, py::robj rhs) {
149199
new FExpr__andor__<false>(as_fexpr(lhs), as_fexpr(rhs)));
150200
}
151201

202+
py::oobj PyFExpr::nb__xor__(py::robj lhs, py::robj rhs) {
203+
return PyFExpr::make(
204+
new FExpr__xor__(as_fexpr(lhs), as_fexpr(rhs)));
205+
}
206+
152207

153208

154209
}} // namespace dt::expr
210+
211+

src/core/expr/fexpr.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ static oobj make_binexpr(dt::expr::Op op, robj lhs, robj rhs) {
186186

187187

188188
//oobj PyFExpr::nb__and__(robj lhs, robj rhs) { return make_binexpr(dt::expr::Op::AND, lhs, rhs); }
189-
oobj PyFExpr::nb__xor__(robj lhs, robj rhs) { return make_binexpr(dt::expr::Op::XOR, lhs, rhs); }
189+
//oobj PyFExpr::nb__xor__(robj lhs, robj rhs) { return make_binexpr(dt::expr::Op::XOR, lhs, rhs); }
190190
//oobj PyFExpr::nb__or__(robj lhs, robj rhs) { return make_binexpr(dt::expr::Op::OR, lhs, rhs); }
191191
oobj PyFExpr::nb__lshift__(robj lhs, robj rhs) { return make_binexpr(dt::expr::Op::LSHIFT, lhs, rhs); }
192192
oobj PyFExpr::nb__rshift__(robj lhs, robj rhs) { return make_binexpr(dt::expr::Op::RSHIFT, lhs, rhs); }

0 commit comments

Comments
 (0)