Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding xt::detail::has_fixed_size and replacing is_array to expand supported types. #2556

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 28 additions & 28 deletions include/xtensor/xadapt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace xt
using default_allocator_for_ptr_t = typename default_allocator_for_ptr<P>::type;

template <class T>
using not_an_array = xtl::negation<is_array<T>>;
using has_dynamic_size = xtl::negation<has_fixed_size<T>>;

template <class T>
using not_a_pointer = xtl::negation<std::is_pointer<T>>;
Expand All @@ -71,8 +71,8 @@ namespace xt
* @param l the layout_type of the xarray_adaptor
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class C, class SC,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>,
detail::not_a_pointer<C>)>
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>,
detail::not_a_pointer<std::remove_reference_t<C>>)>
inline xarray_adaptor<xtl::closure_type_t<C>, L, std::decay_t<SC>>
adapt(C&& container, const SC& shape, layout_type l = L)
{
Expand All @@ -88,7 +88,7 @@ namespace xt
* @param l the layout_type of the xarray_adaptor
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class C, class SC,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>,
std::is_pointer<std::remove_reference_t<C>>)>
inline auto adapt(C&& pointer, const SC& shape, layout_type l = L)
{
Expand All @@ -107,7 +107,7 @@ namespace xt
* @param strides the strides of the xarray_adaptor
*/
template <class C, class SC, class SS,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<SS>>)>
inline xarray_adaptor<xtl::closure_type_t<C>, layout_type::dynamic, std::decay_t<SC>>
adapt(C&& container, SC&& shape, SS&& strides)
Expand All @@ -131,7 +131,7 @@ namespace xt
* @param alloc the allocator used for allocating / deallocating the dynamic array
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class P, class O, class SC, class A = detail::default_allocator_for_ptr_t<P>,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>)>
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>)>
inline xarray_adaptor<xbuffer_adaptor<xtl::closure_type_t<P>, O, A>, L, SC>
adapt(P&& pointer, typename A::size_type size, O ownership, const SC& shape, layout_type l = L, const A& alloc = A())
{
Expand All @@ -155,7 +155,7 @@ namespace xt
* @param alloc the allocator used for allocating / deallocating the dynamic array
*/
template <class P, class O, class SC, class SS, class A = detail::default_allocator_for_ptr_t<P>,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<SS>>)>
inline xarray_adaptor<xbuffer_adaptor<xtl::closure_type_t<P>, O, A>, layout_type::dynamic, std::decay_t<SC>>
adapt(P&& pointer, typename A::size_type size, O ownership, SC&& shape, SS&& strides, const A& alloc = A())
Expand All @@ -178,7 +178,7 @@ namespace xt
* @param l the layout_type of the xarray_adaptor
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class T, std::size_t N, class SC,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>)>
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>)>
inline auto adapt(T (&c_array)[N], const SC& shape, layout_type l = L)
{
return adapt(&c_array[0], N, xt::no_ownership(), shape, l);
Expand All @@ -192,7 +192,7 @@ namespace xt
* @param strides the strides of the xarray_adaptor
*/
template <class T, std::size_t N, class SC, class SS,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<SS>>)>
inline auto adapt(T (&c_array)[N], SC&& shape, SS&& strides)
{
Expand Down Expand Up @@ -228,13 +228,13 @@ namespace xt
* @param l the layout_type of the xtensor_adaptor
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class C, class SC,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>,
detail::not_a_pointer<C>)>
inline xtensor_adaptor<C, detail::array_size<SC>::value, L>
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>,
detail::not_a_pointer<std::remove_reference_t<C>>)>
inline xtensor_adaptor<C, detail::get_fixed_size<std::decay_t<SC>>::value, L>
adapt(C&& container, const SC& shape, layout_type l = L)
{
static_assert(!xtl::is_integral<SC>::value, "shape cannot be a integer");
constexpr std::size_t N = detail::array_size<SC>::value;
constexpr std::size_t N = detail::get_fixed_size<std::decay_t<SC>>::value;
using return_type = xtensor_adaptor<xtl::closure_type_t<C>, N, L>;
return return_type(std::forward<C>(container), shape, l);
}
Expand All @@ -246,13 +246,13 @@ namespace xt
* @param l the layout_type of the xtensor_adaptor
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class C, class SC,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>,
std::is_pointer<std::remove_reference_t<C>>)>
inline auto adapt(C&& pointer, const SC& shape, layout_type l = L)
{
static_assert(!xtl::is_integral<SC>::value, "shape cannot be a integer");
using buffer_type = xbuffer_adaptor<C, xt::no_ownership, detail::default_allocator_for_ptr_t<C>>;
constexpr std::size_t N = detail::array_size<SC>::value;
constexpr std::size_t N = detail::get_fixed_size<std::decay_t<SC>>::value;
using return_type = xtensor_adaptor<buffer_type, N, L>;
return return_type(buffer_type(pointer, compute_size(shape)), shape, l);
}
Expand All @@ -265,13 +265,13 @@ namespace xt
* @param strides the strides of the xtensor_adaptor
*/
template <class C, class SC, class SS,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<SS>>)>
inline xtensor_adaptor<C, detail::array_size<SC>::value, layout_type::dynamic>
inline xtensor_adaptor<C, detail::get_fixed_size<std::decay_t<SC>>::value, layout_type::dynamic>
adapt(C&& container, SC&& shape, SS&& strides)
{
static_assert(!xtl::is_integral<std::decay_t<SC>>::value, "shape cannot be a integer");
constexpr std::size_t N = detail::array_size<SC>::value;
constexpr std::size_t N = detail::get_fixed_size<std::decay_t<SC>>::value;
using return_type = xtensor_adaptor<xtl::closure_type_t<C>, N, layout_type::dynamic>;
return return_type(std::forward<C>(container),
xtl::forward_sequence<typename return_type::inner_shape_type, SC>(shape),
Expand Down Expand Up @@ -312,14 +312,14 @@ namespace xt
* @param alloc the allocator used for allocating / deallocating the dynamic array
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class P, class O, class SC, class A = detail::default_allocator_for_ptr_t<P>,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>)>
inline xtensor_adaptor<xbuffer_adaptor<xtl::closure_type_t<P>, O, A>, detail::array_size<SC>::value, L>
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>)>
inline xtensor_adaptor<xbuffer_adaptor<xtl::closure_type_t<P>, O, A>, detail::get_fixed_size<std::decay_t<SC>>::value, L>
adapt(P&& pointer, typename A::size_type size, O ownership, const SC& shape, layout_type l = L, const A& alloc = A())
{
static_assert(!xtl::is_integral<SC>::value, "shape cannot be a integer");
(void)ownership;
using buffer_type = xbuffer_adaptor<xtl::closure_type_t<P>, O, A>;
constexpr std::size_t N = detail::array_size<SC>::value;
constexpr std::size_t N = detail::get_fixed_size<std::decay_t<SC>>::value;
using return_type = xtensor_adaptor<buffer_type, N, L>;
buffer_type buf(std::forward<P>(pointer), size, alloc);
return return_type(std::move(buf), shape, l);
Expand All @@ -337,15 +337,15 @@ namespace xt
* @param alloc the allocator used for allocating / deallocating the dynamic array
*/
template <class P, class O, class SC, class SS, class A = detail::default_allocator_for_ptr_t<P>,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<SS>>)>
inline xtensor_adaptor<xbuffer_adaptor<xtl::closure_type_t<P>, O, A>, detail::array_size<SC>::value, layout_type::dynamic>
inline xtensor_adaptor<xbuffer_adaptor<xtl::closure_type_t<P>, O, A>, detail::get_fixed_size<std::decay_t<SC>>::value, layout_type::dynamic>
adapt(P&& pointer, typename A::size_type size, O ownership, SC&& shape, SS&& strides, const A& alloc = A())
{
static_assert(!xtl::is_integral<std::decay_t<SC>>::value, "shape cannot be a integer");
(void)ownership;
using buffer_type = xbuffer_adaptor<xtl::closure_type_t<P>, O, A>;
constexpr std::size_t N = detail::array_size<SC>::value;
constexpr std::size_t N = detail::get_fixed_size<std::decay_t<SC>>::value;
using return_type = xtensor_adaptor<buffer_type, N, layout_type::dynamic>;
buffer_type buf(std::forward<P>(pointer), size, alloc);
return return_type(std::move(buf),
Expand All @@ -361,7 +361,7 @@ namespace xt
* @param l the layout_type of the xarray_adaptor
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class T, std::size_t N, class SC,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>)>
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>)>
inline auto adapt(T (&c_array)[N], const SC& shape, layout_type l = L)
{
return adapt(&c_array[0], N, xt::no_ownership(), shape, l);
Expand All @@ -375,7 +375,7 @@ namespace xt
* @param strides the strides of the xarray_adaptor
*/
template <class T, std::size_t N, class SC, class SS,
XTL_REQUIRES(detail::is_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_fixed_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<SS>>)>
inline auto adapt(T (&c_array)[N], SC&& shape, SS&& strides)
{
Expand Down Expand Up @@ -557,7 +557,7 @@ namespace xt
* @return xarray_adaptor for memory
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class P, class SC,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>)>
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>)>
auto adapt_smart_ptr(P&& smart_ptr, const SC& shape, layout_type l = L)
{
using buffer_adaptor = xbuffer_adaptor<decltype(smart_ptr.get()), smart_ownership,
Expand Down Expand Up @@ -619,7 +619,7 @@ namespace xt
* @return xarray_adaptor on the memory
*/
template <layout_type L = XTENSOR_DEFAULT_LAYOUT, class P, class SC, class D,
XTL_REQUIRES(detail::not_an_array<std::decay_t<SC>>,
XTL_REQUIRES(detail::has_dynamic_size<std::decay_t<SC>>,
detail::not_a_layout<std::decay_t<D>>)>
auto adapt_smart_ptr(P&& data_ptr, const SC& shape, D&& smart_ptr, layout_type l = L)
{
Expand Down
4 changes: 2 additions & 2 deletions include/xtensor/xeval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace xt
template <class E>
constexpr bool has_fixed_dims()
{
return detail::is_array<typename std::decay_t<E>::shape_type>::value;
return detail::has_fixed_size<typename std::decay_t<E>::shape_type>::value;
}

template <class E>
Expand All @@ -102,7 +102,7 @@ namespace xt

template <class E, layout_type L>
using as_xtensor_container_t = xtensor<typename std::decay_t<E>::value_type,
std::tuple_size<typename std::decay_t<E>::shape_type>::value,
detail::get_fixed_size<typename std::decay_t<E>::shape_type>::value,
layout_remove_any(L)>;
}

Expand Down
29 changes: 27 additions & 2 deletions include/xtensor/xfixed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ namespace xt
constexpr T get_backstrides(const S& shape, const T& strides) noexcept
{
return detail::get_backstrides_impl(shape, strides,
std::make_index_sequence<std::tuple_size<T>::value>{});
std::make_index_sequence<detail::get_fixed_size<T>::value>{});
}

template <class V, class S>
Expand Down Expand Up @@ -314,7 +314,7 @@ namespace xt
using temporary_type = typename semantic_base::temporary_type;
using expression_tag = Tag;

constexpr static std::size_t N = std::tuple_size<shape_type>::value;
constexpr static std::size_t N = detail::get_fixed_size<shape_type>::value;
constexpr static std::size_t rank = N;

xfixed_container() = default;
Expand Down Expand Up @@ -950,4 +950,29 @@ namespace xt
}
}

/******************************
* std::tuple_size extensions *
******************************/

#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wmismatched-tags"
#endif

template <class ET, class S, xt::layout_type L, bool SH, class Tag>
class std::tuple_size<xt::xfixed_container<ET, S, L, SH, Tag>> :
public std::integral_constant<std::size_t, xt::detail::fixed_compute_size<S>::value>
{
};

template <class ET, class S, xt::layout_type L, bool SH, class Tag>
class std::tuple_size<xt::xfixed_adaptor<ET, S, L, SH, Tag>> :
public std::integral_constant<std::size_t, xt::detail::fixed_compute_size<S>::value>
{
};

#if defined(__clang__)
# pragma clang diagnostic pop
#endif

#endif
20 changes: 18 additions & 2 deletions include/xtensor/xfunction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <xtl/xtype_traits.hpp>

#include "xaccessible.hpp"
#include "xaccumulator.hpp"
#include "xexpression_traits.hpp"
#include "xiterable.hpp"
#include "xlayout.hpp"
Expand Down Expand Up @@ -913,7 +914,7 @@ namespace xt
// Optimization: no need to compare each subiterator since they all
// are incremented decremented together.
constexpr std::size_t temp = xtl::mpl::find_if<is_not_xdummy_iterator, data_type>::value;
constexpr std::size_t index = (temp == std::tuple_size<data_type>::value) ? 0 : temp;
constexpr std::size_t index = (temp == detail::get_fixed_size<data_type>::value) ? 0 : temp;
return std::get<index>(m_it) == std::get<index>(rhs.m_it);
}

Expand All @@ -923,7 +924,7 @@ namespace xt
// Optimization: no need to compare each subiterator since they all
// are incremented decremented together.
constexpr std::size_t temp = xtl::mpl::find_if<is_not_xdummy_iterator, data_type>::value;
constexpr std::size_t index = (temp == std::tuple_size<data_type>::value) ? 0 : temp;
constexpr std::size_t index = (temp == detail::get_fixed_size<data_type>::value) ? 0 : temp;
return std::get<index>(m_it) < std::get<index>(rhs.m_it);
}

Expand Down Expand Up @@ -1059,6 +1060,21 @@ namespace xt
auto step_leading_lambda = [](auto&& st) { st.step_leading(); };
for_each(step_leading_lambda, m_st);
}

namespace detail
{
template<class F, class... CT>
struct has_fixed_size<xfunction<F, CT...>, std::enable_if_t<is_fixed<typename xfunction<F, CT...>::shape_type>::value>>
: std::true_type
{
};

template<class F, class... CT>
struct get_fixed_size<xfunction<F, CT...>, std::enable_if_t<has_fixed_size<xfunction<F, CT...>>::value>>
: std::integral_constant<std::size_t, fixed_compute_size<typename xfunction<F, CT...>::shape_type>::value>
{
};
}
}

#endif
6 changes: 3 additions & 3 deletions include/xtensor/xreducer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ namespace xt

reducer_options(const T& tpl)
{
xtl::mpl::static_if<initial_val_idx != std::tuple_size<T>::value>([this, &tpl](auto no_compile) {
xtl::mpl::static_if<initial_val_idx != detail::get_fixed_size<T>::value>([this, &tpl](auto no_compile) {
// use no_compile to prevent compilation if initial_val_idx is out of bounds!
this->initial_value = no_compile(std::get<initial_val_idx != std::tuple_size<T>::value ? initial_val_idx : 0>(tpl)).value();
this->initial_value = no_compile(std::get<initial_val_idx != detail::get_fixed_size<T>::value ? initial_val_idx : 0>(tpl)).value();
},
[](auto /*np_compile*/){}
);
Expand All @@ -133,7 +133,7 @@ namespace xt
std::true_type,
std::false_type>;

constexpr static bool has_initial_value = initial_val_idx != std::tuple_size<d_t>::value;
constexpr static bool has_initial_value = initial_val_idx != detail::get_fixed_size<d_t>::value;

R initial_value;

Expand Down
33 changes: 29 additions & 4 deletions include/xtensor/xshape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@

namespace xt
{
namespace detail
{
template <class E, class Enable = void>
struct get_fixed_size;
}

template <class T>
using dynamic_shape = svector<T, 4>;

Expand Down Expand Up @@ -231,9 +237,9 @@ namespace xt
};

template <class T>
struct static_dimension_impl<T, void_t<decltype(std::tuple_size<T>::value)>>
struct static_dimension_impl<T, void_t<decltype(detail::get_fixed_size<T>::value)>>
{
static constexpr std::ptrdiff_t value = static_cast<std::ptrdiff_t>(std::tuple_size<T>::value);
static constexpr std::ptrdiff_t value = static_cast<std::ptrdiff_t>(detail::get_fixed_size<T>::value);
};
}

Expand Down Expand Up @@ -281,7 +287,7 @@ namespace xt
};

template <class T, class... Ts>
struct max_array_size<T, Ts...> : std::integral_constant<std::size_t, imax(std::tuple_size<T>::value, max_array_size<Ts...>::value)>
struct max_array_size<T, Ts...> : std::integral_constant<std::size_t, imax(detail::get_fixed_size<T>::value, max_array_size<Ts...>::value)>
{
};

Expand Down Expand Up @@ -375,8 +381,27 @@ namespace xt
static constexpr bool value = true;
};

template <class E, class Enable = void>
struct has_fixed_size : std::false_type
{
};

template <class E>
struct has_fixed_size<E, void_t<decltype(std::tuple_size<E>::value)>>
: std::true_type
{
};

template <class E, class Enable>
struct get_fixed_size;

template <class E>
struct get_fixed_size<E, void_t<decltype(std::tuple_size<E>::value)>> : std::integral_constant<std::size_t, std::tuple_size<E>::value>
{
};

template <class... S>
using only_array = xtl::conjunction<xtl::disjunction<is_array<S>, is_fixed<S>>...>;
using only_array = xtl::conjunction<xtl::disjunction<is_array<S>, is_fixed<S>, has_fixed_size<S>>...>;

// test that at least one argument is a fixed shape. If yes, then either argument has to be fixed or scalar
template <class... S>
Expand Down
Loading