/*************************************************************************** * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * * Copyright (c) QuantStack * * * * Distributed under the terms of the BSD 3-Clause License. * * * * The full license is in the file LICENSE, distributed with this software. * ****************************************************************************/ #ifndef XTENSOR_VIEW_UTILS_HPP #define XTENSOR_VIEW_UTILS_HPP #include #include "xlayout.hpp" #include "xslice.hpp" #include "xtensor_forward.hpp" namespace xt { /******************************** * helper functions declaration * ********************************/ // number of integral types in the specified sequence of types template constexpr std::size_t integral_count(); // number of integral types in the specified sequence of types before specified index template constexpr std::size_t integral_count_before(std::size_t i); // index in the specified sequence of types of the ith non-integral type template constexpr std::size_t integral_skip(std::size_t i); // number of newaxis types in the specified sequence of types template constexpr std::size_t newaxis_count(); // number of newaxis types in the specified sequence of types before specified index template constexpr std::size_t newaxis_count_before(std::size_t i); // index in the specified sequence of types of the ith non-newaxis type template constexpr std::size_t newaxis_skip(std::size_t i); template inline disable_xslice get_slice_value(const S& s, It&) noexcept { return static_cast(s); } template inline auto get_slice_value(const xslice& slice, It& it) noexcept { return slice.derived_cast()(typename S::size_type(*it)); } /*********************** * view_temporary_type * ***********************/ namespace detail { template struct view_temporary_type_impl { using type = xt::xarray; }; template struct view_temporary_type_impl, L, SL...> { using type = xt::xtensor() - integral_count(), L>; }; } template struct view_temporary_type { using type = typename detail::view_temporary_type_impl< std::decay_t, typename E::shape_type, E::static_layout, SL...>::type; }; template using view_temporary_type_t = typename view_temporary_type::type; /************************ * count integral types * ************************/ namespace detail { template struct integral_count_impl { static constexpr std::size_t count(std::size_t i) noexcept { return i ? (integral_count_impl::count(i - 1) + (xtl::is_integral>::value ? 1 : 0)) : 0; } }; template <> struct integral_count_impl { static constexpr std::size_t count(std::size_t /*i*/) noexcept { return 0; } }; } template constexpr std::size_t integral_count() { return detail::integral_count_impl::count(sizeof...(S)); } template constexpr std::size_t integral_count_before(std::size_t i) { return detail::integral_count_impl::count(i); } /*********************** * count newaxis types * ***********************/ namespace detail { template struct is_newaxis : std::false_type { }; template struct is_newaxis> : public std::true_type { }; template struct newaxis_count_impl { static constexpr std::size_t count(std::size_t i) noexcept { return i ? (newaxis_count_impl::count(i - 1) + (is_newaxis>::value ? 1 : 0)) : 0; } }; template <> struct newaxis_count_impl { static constexpr std::size_t count(std::size_t /*i*/) noexcept { return 0; } }; } template constexpr std::size_t newaxis_count() { return detail::newaxis_count_impl::count(sizeof...(S)); } template constexpr std::size_t newaxis_count_before(std::size_t i) { return detail::newaxis_count_impl::count(i); } /********************************** * index of ith non-integral type * **********************************/ namespace detail { template struct integral_skip_impl { static constexpr std::size_t count(std::size_t i) noexcept { return i == 0 ? count_impl() : count_impl(i); } private: static constexpr std::size_t count_impl(std::size_t i) noexcept { return 1 + (xtl::is_integral>::value ? integral_skip_impl::count(i) : integral_skip_impl::count(i - 1)); } static constexpr std::size_t count_impl() noexcept { return xtl::is_integral>::value ? 1 + integral_skip_impl::count(0) : 0; } }; template <> struct integral_skip_impl { static constexpr std::size_t count(std::size_t i) noexcept { return i; } }; } template constexpr std::size_t integral_skip(std::size_t i) { return detail::integral_skip_impl::count(i); } /********************************* * index of ith non-newaxis type * *********************************/ namespace detail { template struct newaxis_skip_impl { static constexpr std::size_t count(std::size_t i) noexcept { return i == 0 ? count_impl() : count_impl(i); } private: static constexpr std::size_t count_impl(std::size_t i) noexcept { return 1 + (is_newaxis>::value ? newaxis_skip_impl::count(i) : newaxis_skip_impl::count(i - 1)); } static constexpr std::size_t count_impl() noexcept { return is_newaxis>::value ? 1 + newaxis_skip_impl::count(0) : 0; } }; template <> struct newaxis_skip_impl { static constexpr std::size_t count(std::size_t i) noexcept { return i; } }; } template constexpr std::size_t newaxis_skip(std::size_t i) { return detail::newaxis_skip_impl::count(i); } } #endif