mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40:18 +00:00
348 lines
11 KiB
C++
348 lines
11 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_ACCESSIBLE_HPP
|
|
#define XTENSOR_ACCESSIBLE_HPP
|
|
|
|
#include "xexception.hpp"
|
|
#include "xstrides.hpp"
|
|
#include "xtensor_forward.hpp"
|
|
|
|
namespace xt
|
|
{
|
|
/**
|
|
* @class xconst_accessible
|
|
* @brief Base class for implementation of common expression constant access methods.
|
|
*
|
|
* The xaccessible class implements constant access methods common to all expressions.
|
|
*
|
|
* @tparam D The derived type, i.e. the inheriting class for which xconst_accessible
|
|
* provides the interface.
|
|
*/
|
|
template <class D>
|
|
class xconst_accessible
|
|
{
|
|
public:
|
|
|
|
using derived_type = D;
|
|
using inner_types = xcontainer_inner_types<D>;
|
|
using reference = typename inner_types::reference;
|
|
using const_reference = typename inner_types::const_reference;
|
|
using size_type = typename inner_types::size_type;
|
|
|
|
size_type size() const noexcept;
|
|
size_type dimension() const noexcept;
|
|
size_type shape(size_type index) const;
|
|
|
|
template <class... Args>
|
|
const_reference at(Args... args) const;
|
|
|
|
template <class S>
|
|
disable_integral_t<S, const_reference> operator[](const S& index) const;
|
|
template <class I>
|
|
const_reference operator[](std::initializer_list<I> index) const;
|
|
const_reference operator[](size_type i) const;
|
|
|
|
template <class... Args>
|
|
const_reference periodic(Args... args) const;
|
|
|
|
template <class... Args>
|
|
bool in_bounds(Args... args) const;
|
|
|
|
const_reference front() const;
|
|
const_reference back() const;
|
|
|
|
protected:
|
|
|
|
xconst_accessible() = default;
|
|
~xconst_accessible() = default;
|
|
|
|
xconst_accessible(const xconst_accessible&) = default;
|
|
xconst_accessible& operator=(const xconst_accessible&) = default;
|
|
|
|
xconst_accessible(xconst_accessible&&) = default;
|
|
xconst_accessible& operator=(xconst_accessible&&) = default;
|
|
|
|
private:
|
|
|
|
const derived_type& derived_cast() const noexcept;
|
|
};
|
|
|
|
/**
|
|
* @class xaccessible
|
|
* @brief Base class for implementation of common expression access methods.
|
|
*
|
|
* The xaccessible class implements access methods common to all expressions.
|
|
*
|
|
* @tparam D The derived type, i.e. the inheriting class for which xaccessible
|
|
* provides the interface.
|
|
*/
|
|
template <class D>
|
|
class xaccessible : public xconst_accessible<D>
|
|
{
|
|
public:
|
|
|
|
using base_type = xconst_accessible<D>;
|
|
using derived_type = typename base_type::derived_type;
|
|
using reference = typename base_type::reference;
|
|
using size_type = typename base_type::size_type;
|
|
|
|
template <class... Args>
|
|
reference at(Args... args);
|
|
|
|
template <class S>
|
|
disable_integral_t<S, reference> operator[](const S& index);
|
|
template <class I>
|
|
reference operator[](std::initializer_list<I> index);
|
|
reference operator[](size_type i);
|
|
|
|
template <class... Args>
|
|
reference periodic(Args... args);
|
|
|
|
reference front();
|
|
reference back();
|
|
|
|
using base_type::at;
|
|
using base_type::operator[];
|
|
using base_type::back;
|
|
using base_type::front;
|
|
using base_type::periodic;
|
|
|
|
protected:
|
|
|
|
xaccessible() = default;
|
|
~xaccessible() = default;
|
|
|
|
xaccessible(const xaccessible&) = default;
|
|
xaccessible& operator=(const xaccessible&) = default;
|
|
|
|
xaccessible(xaccessible&&) = default;
|
|
xaccessible& operator=(xaccessible&&) = default;
|
|
|
|
private:
|
|
|
|
derived_type& derived_cast() noexcept;
|
|
};
|
|
|
|
/************************************
|
|
* xconst_accessible implementation *
|
|
************************************/
|
|
|
|
/**
|
|
* Returns the size of the expression.
|
|
*/
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::size() const noexcept -> size_type
|
|
{
|
|
return compute_size(derived_cast().shape());
|
|
}
|
|
|
|
/**
|
|
* Returns the number of dimensions of the expression.
|
|
*/
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::dimension() const noexcept -> size_type
|
|
{
|
|
return derived_cast().shape().size();
|
|
}
|
|
|
|
/**
|
|
* Returns the i-th dimension of the expression.
|
|
*/
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::shape(size_type index) const -> size_type
|
|
{
|
|
return derived_cast().shape()[index];
|
|
}
|
|
|
|
/**
|
|
* Returns a constant reference to the element at the specified position in the expression,
|
|
* after dimension and bounds checking.
|
|
* @param args a list of indices specifying the position in the expression. Indices
|
|
* must be unsigned integers, the number of indices should be equal to the number of dimensions
|
|
* of the expression.
|
|
* @exception std::out_of_range if the number of argument is greater than the number of dimensions
|
|
* or if indices are out of bounds.
|
|
*/
|
|
template <class D>
|
|
template <class... Args>
|
|
inline auto xconst_accessible<D>::at(Args... args) const -> const_reference
|
|
{
|
|
check_access(derived_cast().shape(), args...);
|
|
return derived_cast().operator()(args...);
|
|
}
|
|
|
|
/**
|
|
* Returns a constant reference to the element at the specified position in the expression.
|
|
* @param index a sequence of indices specifying the position in the expression. Indices
|
|
* must be unsigned integers, the number of indices in the list should be equal or greater
|
|
* than the number of dimensions of the expression.
|
|
*/
|
|
template <class D>
|
|
template <class S>
|
|
inline auto xconst_accessible<D>::operator[](const S& index) const
|
|
-> disable_integral_t<S, const_reference>
|
|
{
|
|
return derived_cast().element(index.cbegin(), index.cend());
|
|
}
|
|
|
|
template <class D>
|
|
template <class I>
|
|
inline auto xconst_accessible<D>::operator[](std::initializer_list<I> index) const -> const_reference
|
|
{
|
|
return derived_cast().element(index.begin(), index.end());
|
|
}
|
|
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::operator[](size_type i) const -> const_reference
|
|
{
|
|
return derived_cast().operator()(i);
|
|
}
|
|
|
|
/**
|
|
* Returns a constant reference to the element at the specified position in the expression,
|
|
* after applying periodicity to the indices (negative and 'overflowing' indices are changed).
|
|
* @param args a list of indices specifying the position in the expression. Indices
|
|
* must be integers, the number of indices should be equal to the number of dimensions
|
|
* of the expression.
|
|
*/
|
|
template <class D>
|
|
template <class... Args>
|
|
inline auto xconst_accessible<D>::periodic(Args... args) const -> const_reference
|
|
{
|
|
normalize_periodic(derived_cast().shape(), args...);
|
|
return derived_cast()(static_cast<size_type>(args)...);
|
|
}
|
|
|
|
/**
|
|
* Returns a constant reference to first the element of the expression
|
|
*/
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::front() const -> const_reference
|
|
{
|
|
return *derived_cast().begin();
|
|
}
|
|
|
|
/**
|
|
* Returns a constant reference to last the element of the expression
|
|
*/
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::back() const -> const_reference
|
|
{
|
|
return *std::prev(derived_cast().end());
|
|
}
|
|
|
|
/**
|
|
* Returns ``true`` only if the the specified position is a valid entry in the expression.
|
|
* @param args a list of indices specifying the position in the expression.
|
|
* @return bool
|
|
*/
|
|
template <class D>
|
|
template <class... Args>
|
|
inline bool xconst_accessible<D>::in_bounds(Args... args) const
|
|
{
|
|
return check_in_bounds(derived_cast().shape(), args...);
|
|
}
|
|
|
|
template <class D>
|
|
inline auto xconst_accessible<D>::derived_cast() const noexcept -> const derived_type&
|
|
{
|
|
return *static_cast<const derived_type*>(this);
|
|
}
|
|
|
|
/******************************
|
|
* xaccessible implementation *
|
|
******************************/
|
|
|
|
/**
|
|
* Returns a reference to the element at the specified position in the expression,
|
|
* after dimension and bounds checking.
|
|
* @param args a list of indices specifying the position in the expression. Indices
|
|
* must be unsigned integers, the number of indices should be equal to the number of dimensions
|
|
* of the expression.
|
|
* @exception std::out_of_range if the number of argument is greater than the number of dimensions
|
|
* or if indices are out of bounds.
|
|
*/
|
|
template <class D>
|
|
template <class... Args>
|
|
inline auto xaccessible<D>::at(Args... args) -> reference
|
|
{
|
|
check_access(derived_cast().shape(), args...);
|
|
return derived_cast().operator()(args...);
|
|
}
|
|
|
|
/**
|
|
* Returns a reference to the element at the specified position in the expression.
|
|
* @param index a sequence of indices specifying the position in the expression. Indices
|
|
* must be unsigned integers, the number of indices in the list should be equal or greater
|
|
* than the number of dimensions of the expression.
|
|
*/
|
|
template <class D>
|
|
template <class S>
|
|
inline auto xaccessible<D>::operator[](const S& index) -> disable_integral_t<S, reference>
|
|
{
|
|
return derived_cast().element(index.cbegin(), index.cend());
|
|
}
|
|
|
|
template <class D>
|
|
template <class I>
|
|
inline auto xaccessible<D>::operator[](std::initializer_list<I> index) -> reference
|
|
{
|
|
return derived_cast().element(index.begin(), index.end());
|
|
}
|
|
|
|
template <class D>
|
|
inline auto xaccessible<D>::operator[](size_type i) -> reference
|
|
{
|
|
return derived_cast().operator()(i);
|
|
}
|
|
|
|
/**
|
|
* Returns a reference to the element at the specified position in the expression,
|
|
* after applying periodicity to the indices (negative and 'overflowing' indices are changed).
|
|
* @param args a list of indices specifying the position in the expression. Indices
|
|
* must be integers, the number of indices should be equal to the number of dimensions
|
|
* of the expression.
|
|
*/
|
|
template <class D>
|
|
template <class... Args>
|
|
inline auto xaccessible<D>::periodic(Args... args) -> reference
|
|
{
|
|
normalize_periodic(derived_cast().shape(), args...);
|
|
return derived_cast()(args...);
|
|
}
|
|
|
|
/**
|
|
* Returns a reference to the first element of the expression.
|
|
*/
|
|
template <class D>
|
|
inline auto xaccessible<D>::front() -> reference
|
|
{
|
|
return *derived_cast().begin();
|
|
}
|
|
|
|
/**
|
|
* Returns a reference to the last element of the expression.
|
|
*/
|
|
template <class D>
|
|
inline auto xaccessible<D>::back() -> reference
|
|
{
|
|
return *std::prev(derived_cast().end());
|
|
}
|
|
|
|
template <class D>
|
|
inline auto xaccessible<D>::derived_cast() noexcept -> derived_type&
|
|
{
|
|
return *static_cast<derived_type*>(this);
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|