Skip to content

Commit 36c583c

Browse files
committed
added << and >> bitwise operator
1 parent ed227dc commit 36c583c

1 file changed

Lines changed: 57 additions & 0 deletions

File tree

include/pythonic/pythonicVars.hpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4143,6 +4143,63 @@ namespace pythonic
41434143
}
41444144
throw pythonic::PythonicTypeError("operator^ requires integral types or sets/lists. Cannot perform '" + type() + " ^ " + other.type() + "'.");
41454145
}
4146+
4147+
// Bitwise shift helpers
4148+
template <typename T, typename U>
4149+
static auto shift_left(T lhs, U rhs)
4150+
{
4151+
static_assert(std::is_integral_v<T> && std::is_integral_v<U>,
4152+
"Bitwise shift requires integral types");
4153+
using ResultType = std::common_type_t<T, U>;
4154+
return static_cast<ResultType>(lhs) << static_cast<ResultType>(rhs);
4155+
}
4156+
4157+
template <typename T, typename U>
4158+
static auto shift_right(T lhs, U rhs)
4159+
{
4160+
static_assert(std::is_integral_v<T> && std::is_integral_v<U>,
4161+
"Bitwise shift requires integral types");
4162+
using ResultType = std::common_type_t<T, U>;
4163+
return static_cast<ResultType>(lhs) >> static_cast<ResultType>(rhs);
4164+
}
4165+
4166+
template <typename Int = long long>
4167+
Int get_integral() const
4168+
{
4169+
switch (tag_)
4170+
{
4171+
case TypeTag::INT:
4172+
return static_cast<Int>(var_get<int>());
4173+
case TypeTag::LONG:
4174+
return static_cast<Int>(var_get<long>());
4175+
case TypeTag::LONG_LONG:
4176+
return static_cast<Int>(var_get<long long>());
4177+
case TypeTag::UINT:
4178+
return static_cast<Int>(var_get<unsigned int>());
4179+
case TypeTag::ULONG:
4180+
return static_cast<Int>(var_get<unsigned long>());
4181+
case TypeTag::ULONG_LONG:
4182+
return static_cast<Int>(var_get<unsigned long long>());
4183+
default:
4184+
throw pythonic::PythonicTypeError("Value is not an integral type: '" + type() + "'.");
4185+
}
4186+
}
4187+
4188+
var operator<<(const var &other) const
4189+
{
4190+
if (!isIntegral() || !other.isIntegral())
4191+
throw pythonic::PythonicTypeError(
4192+
"operator<< requires integral types. Cannot perform '" + type() + " << " + other.type() + "'.");
4193+
return var(shift_left(get_integral(), other.get_integral()));
4194+
}
4195+
4196+
var operator>>(const var &other) const
4197+
{
4198+
if (!isIntegral() || !other.isIntegral())
4199+
throw pythonic::PythonicTypeError(
4200+
"operator>> requires integral types. Cannot perform '" + type() + " >> " + other.type() + "'.");
4201+
return var(shift_right(get_integral(), other.get_integral()));
4202+
}
41464203
// In-place bitwise AND
41474204
var &operator&=(const var &other)
41484205
{

0 commit comments

Comments
 (0)