22namespace stratax::core::bitwise_detail {
32template<Array A, Integral Count,
typename Op>
39 using value_type =
typename A::value_type;
41 validation::require_valid_shift_count<value_type>(rhs);
46 result_type result(lhs.shape());
48 auto out = result.begin();
50 for (
auto it = lhs.begin(); it != lhs.end(); ++it, ++out)
52 *out =
static_cast<value_type
>(
69template<Array L, Array R,
typename Op>
79 using value_type =
typename L::value_type;
87 const auto result_shape =
88 stratax::core::broadcast_detail::array_result_shape(lhs, rhs);
90 result_type result(result_shape);
92 for (std::size_t i = 0; i < result.size(); ++i)
94 const std::size_t lhs_index =
95 stratax::core::broadcast_detail::flat_operand_index(
100 const std::size_t rhs_index =
101 stratax::core::broadcast_detail::flat_operand_index(
106 const auto count = rhs[rhs_index];
108 validation::require_valid_shift_count<value_type>(count);
110 result[i] =
static_cast<value_type
>(
111 op(lhs[lhs_index], count));
125template<Integral Scalar, Array A,
typename Op>
132 using value_type = std::remove_cvref_t<Scalar>;
139 result_type result(rhs.shape());
141 auto out = result.begin();
143 for (
auto it = rhs.begin(); it != rhs.end(); ++it, ++out)
145 validation::require_valid_shift_count<value_type>(*it);
147 *out =
static_cast<value_type
>(
165template<Array L, Array R,
typename Op>
175 const auto result_shape =
176 stratax::core::broadcast_detail::array_result_shape(lhs, rhs);
178 if (result_shape != lhs.shape())
181 "In-place broadcasting cannot change the left operand's shape.");
184 constexpr bool stage = !compound_detail::owns_storage<L> ||
185 !compound_detail::owns_storage<R>;
186 return compound_detail::write_results<stage>(lhs, [&](std::size_t i)
188 const auto rhs_index = broadcast_detail::flat_operand_index(
189 i, lhs.shape(), rhs.shape());
190 return op(lhs[i], rhs[rhs_index]);
203template<Array A, Integral Scalar,
typename Op>
210 const Scalar scalar = rhs;
211 return compound_detail::write_results<
212 !compound_detail::owns_storage<A>>(lhs, [&](std::size_t i)
214 return op(lhs[i], scalar);
234template<Array L, Array R,
typename Op>
244 const auto result_shape =
245 stratax::core::broadcast_detail::array_result_shape(lhs, rhs);
247 if (result_shape != lhs.shape())
250 "In-place broadcasting cannot change the left operand's shape.");
253 using value_type =
typename L::value_type;
255 for (std::size_t i = 0; i < lhs.size(); ++i)
257 const std::size_t rhs_index =
258 stratax::core::broadcast_detail::flat_operand_index(
263 validation::require_valid_shift_count<value_type>(rhs[rhs_index]);
266 constexpr bool stage = !compound_detail::owns_storage<L> ||
267 !compound_detail::owns_storage<R>;
268 return compound_detail::write_results<stage>(lhs, [&](std::size_t i)
270 const auto rhs_index = broadcast_detail::flat_operand_index(
271 i, lhs.shape(), rhs.shape());
272 return op(lhs[i], rhs[rhs_index]);
294template<Array L, Array R,
typename Op>
304 using result_value_type =
306 typename L::value_type,
307 typename R::value_type>;
309 return stratax::core::broadcasted_op<result_value_type>(
328template<Array A, Integral Scalar,
typename Op>
331 const Scalar& scalar,
334 using result_value_type =
340 result_type result(arr.shape());
342 for (std::size_t i = 0; i < arr.size(); ++i)
344 result[i] =
static_cast<result_value_type
>(
364template<Integral Scalar, Array A,
typename Op>
366 const Scalar& scalar,
370 using result_value_type =
376 result_type result(arr.shape());
378 for (std::size_t i = 0; i < arr.size(); ++i)
380 result[i] =
static_cast<result_value_type
>(
395template<Array A, Integral Count,
typename Op>
402 const Count scalar = rhs;
403 validation::require_valid_shift_count<typename A::value_type>(scalar);
404 return compound_detail::write_results<
405 !compound_detail::owns_storage<A>>(lhs, [&](std::size_t i)
407 return op(lhs[i], scalar);
425 A result(value.shape());
427 auto out = result.begin();
428 for (
auto it = value.begin(); it != value.end(); ++it, ++out)
430 *out =
static_cast<typename A::value_type
>(std::bit_not<>{}(*it));
439template<Array L, Array R>
444auto operator&(
const L& lhs,
const R& rhs)
446 return stratax::core::bitwise_detail::binary_bitwise_op(
447 lhs, rhs, std::bit_and<>{});
451template<Array L, Array R>
456auto operator|(
const L& lhs,
const R& rhs)
458 return stratax::core::bitwise_detail::binary_bitwise_op(
459 lhs, rhs, std::bit_or<>{});
463template<Array L, Array R>
468auto operator^(
const L& lhs,
const R& rhs)
470 return stratax::core::bitwise_detail::binary_bitwise_op(
471 lhs, rhs, std::bit_xor<>{});
475template<Array L, Array R>
480auto operator<<(
const L& lhs,
const R& rhs)
482 return stratax::core::bitwise_detail::shift_array_op(
485 [](
auto value,
auto count)
487 return value << count;
492template<Array L, Array R>
497auto operator>>(
const L& lhs,
const R& rhs)
499 return stratax::core::bitwise_detail::shift_array_op(
502 [](
auto value,
auto count)
504 return value >> count;
511template<Array A, Integral Scalar>
515 return stratax::core::bitwise_detail::binary_scalar_bitwise_op(
516 lhs, rhs, std::bit_and<>{});
520template<Array A, Integral Scalar>
524 return stratax::core::bitwise_detail::binary_scalar_bitwise_op(
525 lhs, rhs, std::bit_or<>{});
529template<Array A, Integral Scalar>
533 return stratax::core::bitwise_detail::binary_scalar_bitwise_op(
534 lhs, rhs, std::bit_xor<>{});
538template<Array A, Integral Scalar>
542 return stratax::core::bitwise_detail::shift_scalar_op(
545 [](
auto value,
auto count)
547 return value << count;
552template<Array A, Integral Scalar>
556 return stratax::core::bitwise_detail::shift_scalar_op(
559 [](
auto value,
auto count)
561 return value >> count;
568template<Integral Scalar, Array A>
572 return stratax::core::bitwise_detail::binary_scalar_bitwise_op(
573 lhs, rhs, std::bit_and<>{});
577template<Integral Scalar, Array A>
581 return stratax::core::bitwise_detail::binary_scalar_bitwise_op(
582 lhs, rhs, std::bit_or<>{});
586template<Integral Scalar, Array A>
590 return stratax::core::bitwise_detail::binary_scalar_bitwise_op(
591 lhs, rhs, std::bit_xor<>{});
595template<Integral Scalar, Array A>
599 return stratax::core::bitwise_detail::scalar_shift_array_op(
602 [](
auto value,
auto count)
604 return value << count;
609template<Integral Scalar, Array A>
613 return stratax::core::bitwise_detail::scalar_shift_array_op(
616 [](
auto value,
auto count)
618 return value >> count;
625template<Array L, Array R>
630L&
operator&=(L& lhs,
const R& rhs)
632 return stratax::core::bitwise_detail::compound_bitwise_op(
633 lhs, rhs, std::bit_and<>{});
637template<Array L, Array R>
642L&
operator|=(L& lhs,
const R& rhs)
644 return stratax::core::bitwise_detail::compound_bitwise_op(
645 lhs, rhs, std::bit_or<>{});
649template<Array L, Array R>
654L&
operator^=(L& lhs,
const R& rhs)
656 return stratax::core::bitwise_detail::compound_bitwise_op(
657 lhs, rhs, std::bit_xor<>{});
661template<Array L, Array R>
666L&
operator<<=(L& lhs,
const R& rhs)
668 return stratax::core::bitwise_detail::compound_shift_op(
671 [](
auto value,
auto count) {
672 return value << count;
677template<Array L, Array R>
682L&
operator>>=(L& lhs,
const R& rhs)
684 return stratax::core::bitwise_detail::compound_shift_op(
687 [](
auto value,
auto count) {
688 return value >> count;
695template<Array A, Integral Scalar>
699 return stratax::core::bitwise_detail::compound_scalar_bitwise_op(
700 lhs, rhs, std::bit_and<>{});
704template<Array A, Integral Scalar>
708 return stratax::core::bitwise_detail::compound_scalar_bitwise_op(
709 lhs, rhs, std::bit_or<>{});
713template<Array A, Integral Scalar>
717 return stratax::core::bitwise_detail::compound_scalar_bitwise_op(
718 lhs, rhs, std::bit_xor<>{});
722template<Array A, Integral Scalar>
726 return stratax::core::bitwise_detail::compound_scalar_shift_op(
729 [](
auto value,
auto count)
731 return value << count;
736template<Array A, Integral Scalar>
740 return stratax::core::bitwise_detail::compound_scalar_shift_op(
743 [](
auto value,
auto count)
745 return value >> count;
typename PromoteArray< std::remove_cvref_t< L >, std::remove_cvref_t< R >, std::remove_cvref_t< T > >::type promote_array_t
Convenience alias for the promoted array container type.
typename RebindArray< std::remove_cvref_t< A >, std::remove_cvref_t< T > >::type rebind_array_t
Convenience alias for rebinding an array to a new value type.
auto operator<<(const L &lhs, const R &rhs)
Left-shifts broadcasted left values by corresponding right counts.
auto operator>>(const L &lhs, const R &rhs)
Right-shifts broadcasted left values by corresponding right counts.
L & operator>>=(L &lhs, const R &rhs)
Applies broadcasted right-shift assignment after validating every count.
auto operator^(const L &lhs, const R &rhs)
Computes the broadcasted element-wise bitwise XOR.
auto operator&(const L &lhs, const R &rhs)
Computes the broadcasted element-wise bitwise AND.
auto shift_scalar_op(const A &lhs, const Count &rhs, Op op)
Applies a validated scalar shift to every array element.
auto shift_array_op(const L &lhs, const R &rhs, Op op)
Applies broadcasted per-element shift counts to an array.
A & compound_scalar_bitwise_op(A &lhs, const Scalar &rhs, Op op)
Applies a scalar bitwise operation to lhs in place.
auto scalar_shift_array_op(const Scalar &lhs, const A &rhs, Op op)
Shifts a scalar by every count stored in an array.
L & operator|=(L &lhs, const R &rhs)
Applies broadcasted bitwise OR assignment.
L & compound_bitwise_op(L &lhs, const R &rhs, Op op)
Applies a broadcasted bitwise operation to lhs in place.
L & compound_shift_op(L &lhs, const R &rhs, Op op)
Applies validated broadcasted shift counts to lhs in place.
auto binary_bitwise_op(const L &lhs, const R &rhs, Op op)
Applies a bitwise callable to two broadcast-compatible integer arrays.
A operator~(const A &value)
Applies bitwise NOT to each element of an integer array.
L & operator&=(L &lhs, const R &rhs)
Applies broadcasted bitwise AND assignment.
L & operator^=(L &lhs, const R &rhs)
Applies broadcasted bitwise XOR assignment.
auto binary_scalar_bitwise_op(const A &arr, const Scalar &scalar, Op op)
Applies a callable to every integer array element and a right scalar.
L & operator<<=(L &lhs, const R &rhs)
Applies broadcasted left-shift assignment after validating every count.
auto operator|(const L &lhs, const R &rhs)
Computes the broadcasted element-wise bitwise OR.
A & compound_scalar_shift_op(A &lhs, const Count &rhs, Op op)
Applies a validated scalar shift to an array in place.
Trailing-axis shape compatibility and element projection.
Internal result staging for compound operations on aliased arrays.
Dtype and array interface concepts.
Shared validation for division operands and integral shift counts.
Operands cannot broadcast to the requested result.
Supported integer dtype, excluding bool.