@@ -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