pocketpy/3rd/numpy/include/xtensor/xiterable.hpp
Anurag Bhat 86b4fc623c
Merge numpy to pocketpy (#303)
* Merge numpy to pocketpy

* Add CI

* Fix CI
2024-09-02 16:22:41 +08:00

1370 lines
51 KiB
C++

/***************************************************************************
* 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_ITERABLE_HPP
#define XTENSOR_ITERABLE_HPP
#include "xiterator.hpp"
namespace xt
{
/*******************
* xconst_iterable *
*******************/
template <class D>
struct xiterable_inner_types;
/**
* @class xconst_iterable
* @brief Base class for multidimensional iterable constant expressions
*
* The xconst_iterable class defines the interface for multidimensional
* constant expressions that can be iterated.
*
* @tparam D The derived type, i.e. the inheriting class for which xconst_iterable
* provides the interface.
*/
template <class D>
class xconst_iterable
{
public:
using derived_type = D;
using iterable_types = xiterable_inner_types<D>;
using inner_shape_type = typename iterable_types::inner_shape_type;
using stepper = typename iterable_types::stepper;
using const_stepper = typename iterable_types::const_stepper;
template <layout_type L>
using layout_iterator = xiterator<stepper, inner_shape_type*, L>;
template <layout_type L>
using const_layout_iterator = xiterator<const_stepper, inner_shape_type*, L>;
template <layout_type L>
using reverse_layout_iterator = std::reverse_iterator<layout_iterator<L>>;
template <layout_type L>
using const_reverse_layout_iterator = std::reverse_iterator<const_layout_iterator<L>>;
using linear_iterator = layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using const_linear_iterator = const_layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using reverse_linear_iterator = reverse_layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using const_reverse_linear_iterator = const_reverse_layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
template <class S, layout_type L>
using broadcast_iterator = xiterator<stepper, S, L>;
template <class S, layout_type L>
using const_broadcast_iterator = xiterator<const_stepper, S, L>;
template <class S, layout_type L>
using reverse_broadcast_iterator = std::reverse_iterator<broadcast_iterator<S, L>>;
template <class S, layout_type L>
using const_reverse_broadcast_iterator = std::reverse_iterator<const_broadcast_iterator<S, L>>;
using iterator = layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using const_iterator = const_layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using reverse_iterator = reverse_layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using const_reverse_iterator = const_reverse_layout_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_layout_iterator<L> begin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_layout_iterator<L> end() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_layout_iterator<L> cbegin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_layout_iterator<L> cend() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_reverse_layout_iterator<L> rbegin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_reverse_layout_iterator<L> rend() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_reverse_layout_iterator<L> crbegin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
const_reverse_layout_iterator<L> crend() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> begin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> end(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> cbegin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> cend(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> rbegin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> rend(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> crbegin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> crend(const S& shape) const noexcept;
protected:
const inner_shape_type& get_shape() const;
private:
template <layout_type L>
const_layout_iterator<L> get_cbegin(bool end_index) const noexcept;
template <layout_type L>
const_layout_iterator<L> get_cend(bool end_index) const noexcept;
template <layout_type L, class S>
const_broadcast_iterator<S, L> get_cbegin(const S& shape, bool end_index) const noexcept;
template <layout_type L, class S>
const_broadcast_iterator<S, L> get_cend(const S& shape, bool end_index) const noexcept;
template <class S>
const_stepper get_stepper_begin(const S& shape) const noexcept;
template <class S>
const_stepper get_stepper_end(const S& shape, layout_type l) const noexcept;
const derived_type& derived_cast() const;
};
/*************
* xiterable *
*************/
/**
* @class xiterable
* @brief Base class for multidimensional iterable expressions
*
* The xiterable class defines the interface for multidimensional
* expressions that can be iterated.
*
* @tparam D The derived type, i.e. the inheriting class for which xiterable
* provides the interface.
*/
template <class D>
class xiterable : public xconst_iterable<D>
{
public:
using derived_type = D;
using base_type = xconst_iterable<D>;
using inner_shape_type = typename base_type::inner_shape_type;
using stepper = typename base_type::stepper;
using const_stepper = typename base_type::const_stepper;
using linear_iterator = typename base_type::linear_iterator;
using reverse_linear_iterator = typename base_type::reverse_linear_iterator;
template <layout_type L>
using layout_iterator = typename base_type::template layout_iterator<L>;
template <layout_type L>
using const_layout_iterator = typename base_type::template const_layout_iterator<L>;
template <layout_type L>
using reverse_layout_iterator = typename base_type::template reverse_layout_iterator<L>;
template <layout_type L>
using const_reverse_layout_iterator = typename base_type::template const_reverse_layout_iterator<L>;
template <class S, layout_type L>
using broadcast_iterator = typename base_type::template broadcast_iterator<S, L>;
template <class S, layout_type L>
using const_broadcast_iterator = typename base_type::template const_broadcast_iterator<S, L>;
template <class S, layout_type L>
using reverse_broadcast_iterator = typename base_type::template reverse_broadcast_iterator<S, L>;
template <class S, layout_type L>
using const_reverse_broadcast_iterator = typename base_type::template const_reverse_broadcast_iterator<S, L>;
using iterator = typename base_type::iterator;
using const_iterator = typename base_type::const_iterator;
using reverse_iterator = typename base_type::reverse_iterator;
using const_reverse_iterator = typename base_type::const_reverse_iterator;
using base_type::begin;
using base_type::end;
using base_type::rbegin;
using base_type::rend;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
layout_iterator<L> begin() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
layout_iterator<L> end() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
reverse_layout_iterator<L> rbegin() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
reverse_layout_iterator<L> rend() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
broadcast_iterator<S, L> begin(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
broadcast_iterator<S, L> end(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
reverse_broadcast_iterator<S, L> rbegin(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
reverse_broadcast_iterator<S, L> rend(const S& shape) noexcept;
private:
template <layout_type L>
layout_iterator<L> get_begin(bool end_index) noexcept;
template <layout_type L>
layout_iterator<L> get_end(bool end_index) noexcept;
template <layout_type L, class S>
broadcast_iterator<S, L> get_begin(const S& shape, bool end_index) noexcept;
template <layout_type L, class S>
broadcast_iterator<S, L> get_end(const S& shape, bool end_index) noexcept;
template <class S>
stepper get_stepper_begin(const S& shape) noexcept;
template <class S>
stepper get_stepper_end(const S& shape, layout_type l) noexcept;
template <class S>
const_stepper get_stepper_begin(const S& shape) const noexcept;
template <class S>
const_stepper get_stepper_end(const S& shape, layout_type l) const noexcept;
derived_type& derived_cast();
};
/************************
* xcontiguous_iterable *
************************/
template <class D>
struct xcontainer_inner_types;
namespace detail
{
template <class T, bool is_const>
struct get_storage_iterator;
template <class T>
struct get_storage_iterator<T, true>
{
using iterator = typename T::const_iterator;
using const_iterator = typename T::const_iterator;
using reverse_iterator = typename T::const_reverse_iterator;
using const_reverse_iterator = typename T::const_reverse_iterator;
};
template <class T>
struct get_storage_iterator<T, false>
{
using iterator = typename T::iterator;
using const_iterator = typename T::const_iterator;
using reverse_iterator = typename T::reverse_iterator;
using const_reverse_iterator = typename T::const_reverse_iterator;
};
template <class D, bool has_storage_type>
struct linear_iterator_traits_impl;
template <class D>
struct linear_iterator_traits_impl<D, true>
{
using inner_types = xcontainer_inner_types<D>;
using storage_type = typename inner_types::storage_type;
using iterator_type = get_storage_iterator<storage_type, std::is_const<storage_type>::value>;
using linear_iterator = typename iterator_type::iterator;
using const_linear_iterator = typename iterator_type::const_iterator;
using reverse_linear_iterator = typename iterator_type::reverse_iterator;
using const_reverse_linear_iterator = typename iterator_type::const_reverse_iterator;
};
template <class D>
struct linear_iterator_traits_impl<D, false>
{
using inner_types = xcontainer_inner_types<D>;
using xexpression_type = typename inner_types::xexpression_type;
using linear_iterator = typename xexpression_type::linear_iterator;
using const_linear_iterator = typename xexpression_type::const_linear_iterator;
using reverse_linear_iterator = typename xexpression_type::reverse_linear_iterator;
using const_reverse_linear_iterator = typename xexpression_type::const_reverse_linear_iterator;
};
template <class D>
using linear_iterator_traits = linear_iterator_traits_impl<D, has_storage_type<D>::value>;
}
/**
* @class xcontiguous_iterable
* @brief Base class for multidimensional iterable expressions with
* contiguous storage
*
* The xcontiguous_iterable class defines the interface for multidimensional
* expressions with contiguous that can be iterated.
*
* @tparam D The derived type, i.e. the inheriting class for which xcontiguous_iterable
* provides the interface.
*/
template <class D>
class xcontiguous_iterable : private xiterable<D>
{
public:
using derived_type = D;
using inner_types = xcontainer_inner_types<D>;
using iterable_base = xiterable<D>;
using stepper = typename iterable_base::stepper;
using const_stepper = typename iterable_base::const_stepper;
static constexpr layout_type static_layout = inner_types::layout;
#if defined(_MSC_VER) && _MSC_VER >= 1910
// Workaround for compiler bug in Visual Studio 2017 with respect to alias templates with non-type
// parameters.
template <layout_type L>
using layout_iterator = xiterator<typename iterable_base::stepper, typename iterable_base::inner_shape_type*, L>;
template <layout_type L>
using const_layout_iterator = xiterator<
typename iterable_base::const_stepper,
typename iterable_base::inner_shape_type*,
L>;
template <layout_type L>
using reverse_layout_iterator = std::reverse_iterator<layout_iterator<L>>;
template <layout_type L>
using const_reverse_layout_iterator = std::reverse_iterator<const_layout_iterator<L>>;
#else
template <layout_type L>
using layout_iterator = typename iterable_base::template layout_iterator<L>;
template <layout_type L>
using const_layout_iterator = typename iterable_base::template const_layout_iterator<L>;
template <layout_type L>
using reverse_layout_iterator = typename iterable_base::template reverse_layout_iterator<L>;
template <layout_type L>
using const_reverse_layout_iterator = typename iterable_base::template const_reverse_layout_iterator<L>;
#endif
template <class S, layout_type L>
using broadcast_iterator = typename iterable_base::template broadcast_iterator<S, L>;
template <class S, layout_type L>
using const_broadcast_iterator = typename iterable_base::template const_broadcast_iterator<S, L>;
template <class S, layout_type L>
using reverse_broadcast_iterator = typename iterable_base::template reverse_broadcast_iterator<S, L>;
template <class S, layout_type L>
using const_reverse_broadcast_iterator = typename iterable_base::template const_reverse_broadcast_iterator<S, L>;
using linear_traits = detail::linear_iterator_traits<D>;
using linear_iterator = typename linear_traits::linear_iterator;
using const_linear_iterator = typename linear_traits::const_linear_iterator;
using reverse_linear_iterator = typename linear_traits::reverse_linear_iterator;
using const_reverse_linear_iterator = typename linear_traits::const_reverse_linear_iterator;
template <layout_type L, class It1, class It2>
using select_iterator_impl = std::conditional_t<L == static_layout, It1, It2>;
template <layout_type L>
using select_iterator = select_iterator_impl<L, linear_iterator, layout_iterator<L>>;
template <layout_type L>
using select_const_iterator = select_iterator_impl<L, const_linear_iterator, const_layout_iterator<L>>;
template <layout_type L>
using select_reverse_iterator = select_iterator_impl<L, reverse_linear_iterator, reverse_layout_iterator<L>>;
template <layout_type L>
using select_const_reverse_iterator = select_iterator_impl<
L,
const_reverse_linear_iterator,
const_reverse_layout_iterator<L>>;
using iterator = select_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using const_iterator = select_const_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using reverse_iterator = select_reverse_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
using const_reverse_iterator = select_const_reverse_iterator<XTENSOR_DEFAULT_TRAVERSAL>;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_iterator<L> begin() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_iterator<L> end() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_iterator<L> begin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_iterator<L> end() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_iterator<L> cbegin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_iterator<L> cend() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_reverse_iterator<L> rbegin() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_reverse_iterator<L> rend() noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_reverse_iterator<L> rbegin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_reverse_iterator<L> rend() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_reverse_iterator<L> crbegin() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL>
select_const_reverse_iterator<L> crend() const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
broadcast_iterator<S, L> begin(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
broadcast_iterator<S, L> end(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> begin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> end(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> cbegin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_broadcast_iterator<S, L> cend(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
reverse_broadcast_iterator<S, L> rbegin(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
reverse_broadcast_iterator<S, L> rend(const S& shape) noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> rbegin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> rend(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> crbegin(const S& shape) const noexcept;
template <layout_type L = XTENSOR_DEFAULT_TRAVERSAL, class S>
const_reverse_broadcast_iterator<S, L> crend(const S& shape) const noexcept;
private:
derived_type& derived_cast();
const derived_type& derived_cast() const;
friend class xiterable<D>;
friend class xconst_iterable<D>;
};
/**********************************
* xconst_iterable implementation *
**********************************/
/**
* @name Constant iterators
*/
//@{
/**
* Returns a constant iterator to the first element of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::begin() const noexcept -> const_layout_iterator<L>
{
return this->template cbegin<L>();
}
/**
* Returns a constant iterator to the element following the last element
* of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::end() const noexcept -> const_layout_iterator<L>
{
return this->template cend<L>();
}
/**
* Returns a constant iterator to the first element of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::cbegin() const noexcept -> const_layout_iterator<L>
{
return this->template get_cbegin<L>(false);
}
/**
* Returns a constant iterator to the element following the last element
* of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::cend() const noexcept -> const_layout_iterator<L>
{
return this->template get_cend<L>(true);
}
//@}
/**
* @name Constant reverse iterators
*/
//@{
/**
* Returns a constant iterator to the first element of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::rbegin() const noexcept -> const_reverse_layout_iterator<L>
{
return this->template crbegin<L>();
}
/**
* Returns a constant iterator to the element following the last element
* of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::rend() const noexcept -> const_reverse_layout_iterator<L>
{
return this->template crend<L>();
}
/**
* Returns a constant iterator to the first element of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::crbegin() const noexcept -> const_reverse_layout_iterator<L>
{
return const_reverse_layout_iterator<L>(get_cend<L>(true));
}
/**
* Returns a constant iterator to the element following the last element
* of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::crend() const noexcept -> const_reverse_layout_iterator<L>
{
return const_reverse_layout_iterator<L>(get_cbegin<L>(false));
}
//@}
/**
* @name Constant broadcast iterators
*/
//@{
/**
* Returns a constant iterator to the first element of the expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::begin(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return cbegin<L>(shape);
}
/**
* Returns a constant iterator to the element following the last element of the
* expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::end(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return cend<L>(shape);
}
/**
* Returns a constant iterator to the first element of the expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::cbegin(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return get_cbegin<L, S>(shape, false);
}
/**
* Returns a constant iterator to the element following the last element of the
* expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::cend(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return get_cend<L, S>(shape, true);
}
//@}
/**
* @name Constant reverse broadcast iterators
*/
//@{
/**
* Returns a constant iterator to the first element of the reversed expression.
* The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::rbegin(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return crbegin<L, S>(shape);
}
/**
* Returns a constant iterator to the element following the last element of the
* reversed expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::rend(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return crend<L, S>(shape);
}
/**
* Returns a constant iterator to the first element of the reversed expression.
* The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::crbegin(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return const_reverse_broadcast_iterator<S, L>(get_cend<L, S>(shape, true));
}
/**
* Returns a constant iterator to the element following the last element of the
* reversed expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::crend(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return const_reverse_broadcast_iterator<S, L>(get_cbegin<L, S>(shape, false));
}
//@}
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::get_cbegin(bool end_index) const noexcept -> const_layout_iterator<L>
{
return const_layout_iterator<L>(get_stepper_begin(get_shape()), &get_shape(), end_index);
}
template <class D>
template <layout_type L>
inline auto xconst_iterable<D>::get_cend(bool end_index) const noexcept -> const_layout_iterator<L>
{
return const_layout_iterator<L>(get_stepper_end(get_shape(), L), &get_shape(), end_index);
}
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::get_cbegin(const S& shape, bool end_index) const noexcept
-> const_broadcast_iterator<S, L>
{
return const_broadcast_iterator<S, L>(get_stepper_begin(shape), shape, end_index);
}
template <class D>
template <layout_type L, class S>
inline auto xconst_iterable<D>::get_cend(const S& shape, bool end_index) const noexcept
-> const_broadcast_iterator<S, L>
{
return const_broadcast_iterator<S, L>(get_stepper_end(shape, L), shape, end_index);
}
template <class D>
template <class S>
inline auto xconst_iterable<D>::get_stepper_begin(const S& shape) const noexcept -> const_stepper
{
return derived_cast().stepper_begin(shape);
}
template <class D>
template <class S>
inline auto xconst_iterable<D>::get_stepper_end(const S& shape, layout_type l) const noexcept
-> const_stepper
{
return derived_cast().stepper_end(shape, l);
}
template <class D>
inline auto xconst_iterable<D>::get_shape() const -> const inner_shape_type&
{
return derived_cast().shape();
}
template <class D>
inline auto xconst_iterable<D>::derived_cast() const -> const derived_type&
{
return *static_cast<const derived_type*>(this);
}
/****************************
* xiterable implementation *
****************************/
/**
* @name Iterators
*/
//@{
/**
* Returns an iterator to the first element of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xiterable<D>::begin() noexcept -> layout_iterator<L>
{
return get_begin<L>(false);
}
/**
* Returns an iterator to the element following the last element
* of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xiterable<D>::end() noexcept -> layout_iterator<L>
{
return get_end<L>(true);
}
//@}
/**
* @name Reverse iterators
*/
//@{
/**
* Returns an iterator to the first element of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xiterable<D>::rbegin() noexcept -> reverse_layout_iterator<L>
{
return reverse_layout_iterator<L>(get_end<L>(true));
}
/**
* Returns an iterator to the element following the last element
* of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xiterable<D>::rend() noexcept -> reverse_layout_iterator<L>
{
return reverse_layout_iterator<L>(get_begin<L>(false));
}
//@}
/**
* @name Broadcast iterators
*/
//@{
/**
* Returns an iterator to the first element of the expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xiterable<D>::begin(const S& shape) noexcept -> broadcast_iterator<S, L>
{
return get_begin<L, S>(shape, false);
}
/**
* Returns an iterator to the element following the last element of the
* expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xiterable<D>::end(const S& shape) noexcept -> broadcast_iterator<S, L>
{
return get_end<L, S>(shape, true);
}
//@}
/**
* @name Reverse broadcast iterators
*/
//@{
/**
* Returns an iterator to the first element of the reversed expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xiterable<D>::rbegin(const S& shape) noexcept -> reverse_broadcast_iterator<S, L>
{
return reverse_broadcast_iterator<S, L>(get_end<L, S>(shape, true));
}
/**
* Returns an iterator to the element following the last element of the
* reversed expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xiterable<D>::rend(const S& shape) noexcept -> reverse_broadcast_iterator<S, L>
{
return reverse_broadcast_iterator<S, L>(get_begin<L, S>(shape, false));
}
//@}
template <class D>
template <layout_type L>
inline auto xiterable<D>::get_begin(bool end_index) noexcept -> layout_iterator<L>
{
return layout_iterator<L>(get_stepper_begin(this->get_shape()), &(this->get_shape()), end_index);
}
template <class D>
template <layout_type L>
inline auto xiterable<D>::get_end(bool end_index) noexcept -> layout_iterator<L>
{
return layout_iterator<L>(get_stepper_end(this->get_shape(), L), &(this->get_shape()), end_index);
}
template <class D>
template <layout_type L, class S>
inline auto xiterable<D>::get_begin(const S& shape, bool end_index) noexcept -> broadcast_iterator<S, L>
{
return broadcast_iterator<S, L>(get_stepper_begin(shape), shape, end_index);
}
template <class D>
template <layout_type L, class S>
inline auto xiterable<D>::get_end(const S& shape, bool end_index) noexcept -> broadcast_iterator<S, L>
{
return broadcast_iterator<S, L>(get_stepper_end(shape, L), shape, end_index);
}
template <class D>
template <class S>
inline auto xiterable<D>::get_stepper_begin(const S& shape) noexcept -> stepper
{
return derived_cast().stepper_begin(shape);
}
template <class D>
template <class S>
inline auto xiterable<D>::get_stepper_end(const S& shape, layout_type l) noexcept -> stepper
{
return derived_cast().stepper_end(shape, l);
}
template <class D>
template <class S>
inline auto xiterable<D>::get_stepper_begin(const S& shape) const noexcept -> const_stepper
{
return derived_cast().stepper_begin(shape);
}
template <class D>
template <class S>
inline auto xiterable<D>::get_stepper_end(const S& shape, layout_type l) const noexcept -> const_stepper
{
return derived_cast().stepper_end(shape, l);
}
template <class D>
inline auto xiterable<D>::derived_cast() -> derived_type&
{
return *static_cast<derived_type*>(this);
}
/***************************************
* xcontiguous_iterable implementation *
***************************************/
/**
* @name Iterators
*/
//@{
/**
* Returns an iterator to the first element of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::begin() noexcept -> select_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_begin();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template begin<L>();
}
);
}
/**
* Returns an iterator to the element following the last element
* of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::end() noexcept -> select_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_end();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template end<L>();
}
);
}
/**
* Returns a constant iterator to the first element of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::begin() const noexcept -> select_const_iterator<L>
{
return this->template cbegin<L>();
}
/**
* Returns a constant iterator to the element following the last element
* of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::end() const noexcept -> select_const_iterator<L>
{
return this->template cend<L>();
}
/**
* Returns a constant iterator to the first element of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::cbegin() const noexcept -> select_const_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_cbegin();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template cbegin<L>();
}
);
}
/**
* Returns a constant iterator to the element following the last element
* of the expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::cend() const noexcept -> select_const_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_cend();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template cend<L>();
}
);
}
//@}
/**
* @name Reverse iterators
*/
//@{
/**
* Returns an iterator to the first element of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::rbegin() noexcept -> select_reverse_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_rbegin();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template rbegin<L>();
}
);
}
/**
* Returns an iterator to the element following the last element
* of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::rend() noexcept -> select_reverse_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_rend();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template rend<L>();
}
);
}
/**
* Returns a constant iterator to the first element of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::rbegin() const noexcept -> select_const_reverse_iterator<L>
{
return this->template crbegin<L>();
}
/**
* Returns a constant iterator to the element following the last element
* of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::rend() const noexcept -> select_const_reverse_iterator<L>
{
return this->template crend<L>();
}
/**
* Returns a constant iterator to the first element of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::crbegin() const noexcept -> select_const_reverse_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_crbegin();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template crbegin<L>();
}
);
}
/**
* Returns a constant iterator to the element following the last element
* of the reversed expression.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L>
inline auto xcontiguous_iterable<D>::crend() const noexcept -> select_const_reverse_iterator<L>
{
return xtl::mpl::static_if<L == static_layout>(
[&](auto self)
{
return self(*this).derived_cast().linear_crend();
},
/*else*/
[&](auto self)
{
return self(*this).iterable_base::template crend<L>();
}
);
}
//@}
/**
* @name Broadcast iterators
*/
/**
* Returns an iterator to the first element of the expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
//@{
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::begin(const S& shape) noexcept -> broadcast_iterator<S, L>
{
return iterable_base::template begin<L, S>(shape);
}
/**
* Returns an iterator to the element following the last element of the
* expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::end(const S& shape) noexcept -> broadcast_iterator<S, L>
{
return iterable_base::template end<L, S>(shape);
}
/**
* Returns a constant iterator to the first element of the expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::begin(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return iterable_base::template begin<L, S>(shape);
}
/**
* Returns a constant iterator to the element following the last element of the
* expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::end(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return iterable_base::template end<L, S>(shape);
}
/**
* Returns a constant iterator to the first element of the expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::cbegin(const S& shape) const noexcept
-> const_broadcast_iterator<S, L>
{
return iterable_base::template cbegin<L, S>(shape);
}
/**
* Returns a constant iterator to the element following the last element of the
* expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::cend(const S& shape) const noexcept -> const_broadcast_iterator<S, L>
{
return iterable_base::template cend<L, S>(shape);
}
//@}
/**
* @name Reverse broadcast iterators
*/
//@{
/**
* Returns an iterator to the first element of the reversed expression. The
* iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::rbegin(const S& shape) noexcept -> reverse_broadcast_iterator<S, L>
{
return iterable_base::template rbegin<L, S>(shape);
}
/**
* Returns an iterator to the element following the last element of the
* reversed expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::rend(const S& shape) noexcept -> reverse_broadcast_iterator<S, L>
{
return iterable_base::template rend<L, S>(shape);
}
/**
* Returns a constant iterator to the first element of the reversed expression.
* The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::rbegin(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return iterable_base::template rbegin<L, S>(shape);
}
/**
* Returns a constant iterator to the element following the last element of the
* reversed expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::rend(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return iterable_base::template rend<L, S>(shape);
}
/**
* Returns a constant iterator to the first element of the reversed expression.
* The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::crbegin(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return iterable_base::template crbegin<L, S>(shape);
}
/**
* Returns a constant iterator to the element following the last element of the
* reversed expression. The iteration is broadcasted to the specified shape.
* @param shape the shape used for broadcasting
* @tparam S type of the \c shape parameter.
* @tparam L order used for the traversal. Default value is \c XTENSOR_DEFAULT_TRAVERSAL.
*/
template <class D>
template <layout_type L, class S>
inline auto xcontiguous_iterable<D>::crend(const S& shape) const noexcept
-> const_reverse_broadcast_iterator<S, L>
{
return iterable_base::template crend<L, S>(shape);
}
//@}
template <class D>
inline auto xcontiguous_iterable<D>::derived_cast() -> derived_type&
{
return *static_cast<derived_type*>(this);
}
template <class D>
inline auto xcontiguous_iterable<D>::derived_cast() const -> const derived_type&
{
return *static_cast<const derived_type*>(this);
}
}
#endif