| Server IP : 217.160.0.135 / Your IP : 216.73.217.85 Web Server : Apache System : Linux www 6.18.52-i1-ampere #1203 SMP Mon Sep 14 18:29:59 CEST 2026 aarch64 User : sws1074145052 ( 1074145052) PHP Version : 8.3.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /usr/lib/python3/dist-packages/pythran/pythonic/include/types/ |
Upload File : |
#ifndef PYTHONIC_INCLUDE_TYPES_NUMPY_VEXPR_HPP
#define PYTHONIC_INCLUDE_TYPES_NUMPY_VEXPR_HPP
#include "pythonic/include/types/nditerator.hpp"
PYTHONIC_NS_BEGIN
namespace types
{
template <class T, class F>
struct numpy_vexpr {
static constexpr size_t value = T::value;
static const bool is_vectorizable = false;
using dtype = typename dtype_of<T>::type;
using value_type = T;
static constexpr bool is_strided = T::is_strided;
using iterator = nditerator<numpy_vexpr>;
using const_iterator = const_nditerator<numpy_vexpr>;
T data_;
F view_;
numpy_vexpr() = default;
numpy_vexpr(T const &data, F const &view) : data_(data), view_(view)
{
}
long flat_size() const
{
return sutils::prod_tail(data_) * view_.template shape<0>();
}
long size() const
{
return view_.size();
}
template <class E>
typename std::enable_if<is_iterable<E>::value, numpy_vexpr &>::type
operator=(E const &);
template <class E>
typename std::enable_if<!is_iterable<E>::value, numpy_vexpr &>::type
operator=(E const &expr);
numpy_vexpr &operator=(numpy_vexpr const &);
using shape_t = array<long, value>;
template <size_t I>
long shape() const
{
if (I == 0)
return view_.template shape<0>();
else
return data_.template shape<I>();
}
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
#ifdef USE_XSIMD
using simd_iterator = const_simd_nditerator<numpy_vexpr>;
using simd_iterator_nobroadcast = simd_iterator;
template <class vectorizer>
simd_iterator vbegin(vectorizer) const;
template <class vectorizer>
simd_iterator vend(vectorizer) const;
#endif
template <class... Indices>
dtype load(long i, Indices... indices) const
{
return data_.load(view_.fast(i), indices...);
}
template <class Elt, class... Indices>
void store(Elt elt, long i, Indices... indices) const
{
data_.store(elt, view_.fast(i), indices...);
}
template <class Op, class Elt, class... Indices>
void update(Elt elt, long i, Indices... indices) const
{
data_.template update<Op>(elt, view_.fast(i), indices...);
}
auto fast(long i) -> decltype(data_.fast(i))
{
return data_.fast(view_.fast(i));
}
auto fast(long i) const -> decltype(data_.fast(i))
{
return data_.fast(view_.fast(i));
}
template <class... S>
auto operator()(S const &... slices) const
-> decltype(ndarray<dtype, array<long, value>>{*this}(slices...));
auto operator[](long i) const -> decltype(data_[i])
{
return data_.fast(view_[i]);
}
template <class S>
typename std::enable_if<
is_slice<S>::value,
numpy_gexpr<numpy_vexpr, decltype(std::declval<S>().normalize(1))>>
operator[](S s) const
{
return {*this, s.normalize(size())};
}
/* element filtering */
template <class E> // indexing through an array of boolean -- a mask
typename std::enable_if<
is_numexpr_arg<E>::value &&
std::is_same<bool, typename E::dtype>::value &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_vexpr, ndarray<long, pshape<long>>>>::type
fast(E const &filter) const;
template <class E> // indexing through an array of boolean -- a mask
typename std::enable_if<
!is_slice<E>::value && is_numexpr_arg<E>::value &&
std::is_same<bool, typename E::dtype>::value &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_vexpr, ndarray<long, pshape<long>>>>::type
operator[](E const &filter) const;
template <class E> // indexing through an array of indices -- a view
typename std::enable_if<is_numexpr_arg<E>::value &&
!is_array_index<E>::value &&
!std::is_same<bool, typename E::dtype>::value &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_vexpr, E>>::type
operator[](E const &filter) const;
template <class E> // indexing through an array of indices -- a view
typename std::enable_if<is_numexpr_arg<E>::value &&
!is_array_index<E>::value &&
!std::is_same<bool, typename E::dtype>::value &&
!is_pod_array<F>::value,
numpy_vexpr<numpy_vexpr, E>>::type
fast(E const &filter) const;
template <class Op, class Expr>
numpy_vexpr &update_(Expr const &expr);
template <class E>
numpy_vexpr &operator+=(E const &expr);
template <class E>
numpy_vexpr &operator-=(E const &expr);
template <class E>
numpy_vexpr &operator*=(E const &expr);
template <class E>
numpy_vexpr &operator/=(E const &expr);
template <class E>
numpy_vexpr &operator&=(E const &expr);
template <class E>
numpy_vexpr &operator|=(E const &expr);
template <class E>
numpy_vexpr &operator^=(E const &expr);
};
}
template <class T, class F>
struct assignable<types::numpy_vexpr<T, F>> {
using type = types::ndarray<typename types::dtype_of<T>::type,
typename types::numpy_vexpr<T, F>::shape_t>;
};
template <class T, class F>
struct lazy<types::numpy_vexpr<T, F>> {
using type =
types::numpy_vexpr<typename lazy<T>::type, typename lazy<F>::type>;
};
PYTHONIC_NS_END
/* combined are sorted such that the assigned type comes first */
template <class E, class F, class T, class pS>
struct __combined<pythonic::types::numpy_vexpr<E, F>,
pythonic::types::ndarray<T, pS>> {
using type = pythonic::types::ndarray<T, pS>;
};
template <class E, class F, class T, class pS>
struct __combined<pythonic::types::ndarray<T, pS>,
pythonic::types::numpy_vexpr<E, F>> {
using type = pythonic::types::ndarray<T, pS>;
};
#endif