Skip to content

Commit

Permalink
replacing is_array, tuple_size with has_fixed_size, get_fixed_size.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mykola Vankovych committed Aug 8, 2022
1 parent 3084585 commit 22a30c9
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 61 deletions.
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

0 comments on commit 22a30c9

Please sign in to comment.