Skip to content

Commit 38cd7ec

Browse files
authored
Partial elimination of TMP from xutils.hpp and patches for dependencies (#2923)
# Checklist - [X] The title and commit message(s) are descriptive. - [ ] Small commits made to fix your PR have been squashed to avoid history pollution. - [X] Tests have been added for new features or bug fixes. - [X] API of new functions and classes are documented. # Description With concepts and constexpr the library can be more readable and less reliant on recursion. This PR is the first of hopefully many that will flatten the template structure in xtensor logic without changing public interfaces or functionality. The goal is to make additional optimizations and functionality easier to reason about and implement moving forward. Additionally, eliminating recursion should help compile times!
1 parent 2f59efe commit 38cd7ec

21 files changed

Lines changed: 240 additions & 351 deletions

include/xtensor/core/xassign.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ namespace xt
214214
template <class E1, class E2>
215215
inline void assign_xexpression(xexpression<E1>& e1, const xexpression<E2>& e2)
216216
{
217-
if constexpr (has_assign_to<E1, E2>::value)
217+
if constexpr (assignable_to_expression<E1, E2>)
218218
{
219219
e2.derived_cast().assign_to(e1);
220220
}
@@ -267,14 +267,14 @@ namespace xt
267267

268268
template <class E1, class E2>
269269
inline auto is_linear_assign(const E1& e1, const E2& e2)
270-
-> std::enable_if_t<has_strides<E1>::value, bool>
270+
-> std::enable_if_t<strided_expression<E1>, bool>
271271
{
272272
return (E1::contiguous_layout && E2::contiguous_layout && linear_static_layout<E1, E2>())
273273
|| (e1.is_contiguous() && e2.has_linear_assign(e1.strides()));
274274
}
275275

276276
template <class E1, class E2>
277-
inline auto is_linear_assign(const E1&, const E2&) -> std::enable_if_t<!has_strides<E1>::value, bool>
277+
inline auto is_linear_assign(const E1&, const E2&) -> std::enable_if_t<!strided_expression<E1>, bool>
278278
{
279279
return false;
280280
}
@@ -304,7 +304,7 @@ namespace xt
304304
return std::is_reference<typename T::stepper::reference>::value;
305305
}
306306

307-
static constexpr bool value = has_strides<T>::value
307+
static constexpr bool value = strided_expression<T>
308308
&& has_step_leading<typename T::stepper>::value && stepper_deref();
309309
};
310310

@@ -1002,13 +1002,13 @@ namespace xt
10021002
const strides_type& m_strides;
10031003
};
10041004

1005-
template <bool possible = true, class E1, class E2, std::enable_if_t<!has_strides<E1>::value || !possible, bool> = true>
1005+
template <bool possible = true, class E1, class E2, std::enable_if_t<!strided_expression<E1> || !possible, bool> = true>
10061006
loop_sizes_t get_loop_sizes(const E1& e1, const E2&)
10071007
{
10081008
return {false, true, 1, e1.size(), e1.dimension(), e1.dimension()};
10091009
}
10101010

1011-
template <bool possible = true, class E1, class E2, std::enable_if_t<has_strides<E1>::value && possible, bool> = true>
1011+
template <bool possible = true, class E1, class E2, std::enable_if_t<strided_expression<E1> && possible, bool> = true>
10121012
loop_sizes_t get_loop_sizes(const E1& e1, const E2& e2)
10131013
{
10141014
using shape_value_type = typename E1::shape_type::value_type;

include/xtensor/core/xeval.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,15 +147,15 @@ namespace xt
147147
*/
148148
template <layout_type L = layout_type::any, class E>
149149
inline auto as_strided(E&& e)
150-
-> std::enable_if_t<has_data_interface<std::decay_t<E>>::value && detail::has_same_layout<L, E>(), E&&>
150+
-> std::enable_if_t<data_interface_expression<std::decay_t<E>> && detail::has_same_layout<L, E>(), E&&>
151151
{
152152
return std::forward<E>(e);
153153
}
154154

155155
/// @cond DOXYGEN_INCLUDE_SFINAE
156156
template <layout_type L = layout_type::any, class E>
157157
inline auto as_strided(E&& e) -> std::enable_if_t<
158-
(!(has_data_interface<std::decay_t<E>>::value && detail::has_same_layout<L, E>()))
158+
(!(data_interface_expression<std::decay_t<E>> && detail::has_same_layout<L, E>()))
159159
&& detail::has_fixed_dims<E>(),
160160
detail::as_xtensor_container_t<E, L>>
161161
{
@@ -164,7 +164,7 @@ namespace xt
164164

165165
template <layout_type L = layout_type::any, class E>
166166
inline auto as_strided(E&& e) -> std::enable_if_t<
167-
(!(has_data_interface<std::decay_t<E>>::value && detail::has_same_layout<L, E>()))
167+
(!(data_interface_expression<std::decay_t<E>> && detail::has_same_layout<L, E>()))
168168
&& (!detail::has_fixed_dims<E>()),
169169
detail::as_xarray_container_t<E, L>>
170170
{

include/xtensor/core/xexpression.hpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -525,15 +525,18 @@ namespace xt
525525
using inner_shape_type = typename E::inner_shape_type;
526526
using shape_type = typename E::shape_type;
527527

528-
using strides_type = xtl::mpl::
529-
eval_if_t<has_strides<E>, detail::expr_strides_type<E>, get_strides_type<shape_type>>;
530-
using backstrides_type = xtl::mpl::
531-
eval_if_t<has_strides<E>, detail::expr_backstrides_type<E>, get_strides_type<shape_type>>;
532-
using inner_strides_type = xtl::mpl::
533-
eval_if_t<has_strides<E>, detail::expr_inner_strides_type<E>, get_strides_type<shape_type>>;
534-
using inner_backstrides_type = xtl::mpl::
535-
eval_if_t<has_strides<E>, detail::expr_inner_backstrides_type<E>, get_strides_type<shape_type>>;
536-
using storage_type = xtl::mpl::eval_if_t<has_storage_type<E>, detail::expr_storage_type<E>, make_invalid_type<>>;
528+
using strides_type = typename std::
529+
conditional_t<strided_expression<E>, detail::expr_strides_type<E>, get_strides_type<shape_type>>::type;
530+
using backstrides_type = typename std::
531+
conditional_t<strided_expression<E>, detail::expr_backstrides_type<E>, get_strides_type<shape_type>>::type;
532+
using inner_strides_type = typename std::
533+
conditional_t<strided_expression<E>, detail::expr_inner_strides_type<E>, get_strides_type<shape_type>>::type;
534+
using inner_backstrides_type = typename std::conditional_t<
535+
strided_expression<E>,
536+
detail::expr_inner_backstrides_type<E>,
537+
get_strides_type<shape_type>>::type;
538+
using storage_type = typename std::
539+
conditional_t<container_expression<E>, detail::expr_storage_type<E>, make_invalid_type<>>::type;
537540

538541
using stepper = typename E::stepper;
539542
using const_stepper = typename E::const_stepper;
@@ -638,43 +641,43 @@ namespace xt
638641
}
639642

640643
template <class T = E>
641-
std::enable_if_t<has_strides<T>::value, const inner_strides_type&> strides() const
644+
std::enable_if_t<strided_expression<T>, const inner_strides_type&> strides() const
642645
{
643646
return m_ptr->strides();
644647
}
645648

646649
template <class T = E>
647-
std::enable_if_t<has_strides<T>::value, const inner_strides_type&> backstrides() const
650+
std::enable_if_t<strided_expression<T>, const inner_strides_type&> backstrides() const
648651
{
649652
return m_ptr->backstrides();
650653
}
651654

652655
template <class T = E>
653-
std::enable_if_t<has_data_interface<T>::value, pointer> data() noexcept
656+
std::enable_if_t<data_interface_expression<T>, pointer> data() noexcept
654657
{
655658
return m_ptr->data();
656659
}
657660

658661
template <class T = E>
659-
std::enable_if_t<has_data_interface<T>::value, pointer> data() const noexcept
662+
std::enable_if_t<data_interface_expression<T>, pointer> data() const noexcept
660663
{
661664
return m_ptr->data();
662665
}
663666

664667
template <class T = E>
665-
std::enable_if_t<has_data_interface<T>::value, size_type> data_offset() const noexcept
668+
std::enable_if_t<data_interface_expression<T>, size_type> data_offset() const noexcept
666669
{
667670
return m_ptr->data_offset();
668671
}
669672

670673
template <class T = E>
671-
std::enable_if_t<has_data_interface<T>::value, typename T::storage_type&> storage() noexcept
674+
std::enable_if_t<data_interface_expression<T>, typename T::storage_type&> storage() noexcept
672675
{
673676
return m_ptr->storage();
674677
}
675678

676679
template <class T = E>
677-
std::enable_if_t<has_data_interface<T>::value, const typename T::storage_type&> storage() const noexcept
680+
std::enable_if_t<data_interface_expression<T>, const typename T::storage_type&> storage() const noexcept
678681
{
679682
return m_ptr->storage();
680683
}

include/xtensor/core/xfunction.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ namespace xt
133133
struct xcontainer_inner_types<xfunction<F, CT...>>
134134
{
135135
// Added indirection for MSVC 2017 bug with the operator value_type()
136-
using func_return_type = typename meta_identity<
136+
using func_return_type = typename std::type_identity<
137137
decltype(std::declval<F>()(std::declval<xvalue_type_t<std::decay_t<CT>>>()...))>::type;
138138
using value_type = std::decay_t<func_return_type>;
139139
using reference = func_return_type;
@@ -156,7 +156,7 @@ namespace xt
156156
template <class E>
157157
struct overlapping_memory_checker_traits<
158158
E,
159-
std::enable_if_t<!has_memory_address<E>::value && is_specialization_of<xfunction, E>::value>>
159+
std::enable_if_t<!addressable_to_expression<E> && is_specialization_of<xfunction, E>::value>>
160160
{
161161
template <std::size_t I = 0, class... T, std::enable_if_t<(I == sizeof...(T)), int> = 0>
162162
static bool check_tuple(const std::tuple<T...>&, const memory_range&)

include/xtensor/core/xiterable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ namespace xt
293293
};
294294

295295
template <class D>
296-
using linear_iterator_traits = linear_iterator_traits_impl<D, has_storage_type<D>::value>;
296+
using linear_iterator_traits = linear_iterator_traits_impl<D, container_expression<D>>;
297297
}
298298

299299
/**

include/xtensor/core/xmath.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,13 @@ namespace xt
350350
namespace detail
351351
{
352352
template <class R, class T>
353-
std::enable_if_t<!has_iterator_interface<R>::value, R> fill_init(T init)
353+
std::enable_if_t<!iterable_expression<R>, R> fill_init(T init)
354354
{
355355
return R(init);
356356
}
357357

358358
template <class R, class T>
359-
std::enable_if_t<has_iterator_interface<R>::value, R> fill_init(T init)
359+
std::enable_if_t<iterable_expression<R>, R> fill_init(T init)
360360
{
361361
R result;
362362
std::fill(std::begin(result), std::end(result), init);

include/xtensor/core/xsemantic.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ namespace xt
224224
template <class E>
225225
struct overlapping_memory_checker_traits<
226226
E,
227-
std::enable_if_t<!has_memory_address<E>::value && is_crtp_base_of<xview_semantic, E>::value>>
227+
std::enable_if_t<!addressable_to_expression<E> && is_crtp_base_of<xview_semantic, E>::value>>
228228
{
229229
static bool check_overlap(const E& expr, const memory_range& dst_range)
230230
{

include/xtensor/core/xshape.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ namespace xt
138138
* @param shape the shape to test
139139
* @return bool
140140
*/
141-
template <class E, class S, class = typename std::enable_if_t<has_iterator_interface<S>::value>>
141+
template <class E, class S, class = typename std::enable_if_t<iterable_expression<S>>>
142142
inline bool has_shape(const E& e, const S& shape)
143143
{
144144
return e.shape().size() == shape.size()

include/xtensor/generators/xgenerator.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ namespace xt
8282
*************************************/
8383

8484
template <xgenerator_concept E>
85-
requires(without_memory_address_concept<E>)
85+
requires(!addressable_to_expression<std::decay_t<E>>)
8686
struct overlapping_memory_checker_traits<E>
8787
{
8888
static bool check_overlap(const E&, const memory_range&)
@@ -167,7 +167,7 @@ namespace xt
167167

168168
template <class E, class FE = F>
169169
void assign_to(xexpression<E>& e) const noexcept
170-
requires(has_assign_to_v<E, FE>);
170+
requires(assignable_to_expression<E, FE>);
171171

172172
const functor_type& functor() const noexcept;
173173

@@ -374,7 +374,7 @@ namespace xt
374374
template <class F, class R, class S>
375375
template <class E, class FE>
376376
inline void xgenerator<F, R, S>::assign_to(xexpression<E>& e) const noexcept
377-
requires(has_assign_to_v<E, FE>)
377+
requires(assignable_to_expression<E, FE>)
378378
{
379379
e.derived_cast().resize(m_shape);
380380
m_f.assign_to(e);

include/xtensor/misc/xmanipulation.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ namespace xt
214214
template <class E, class S, class X>
215215
inline void compute_transposed_strides(E&& e, const S& shape, X& strides)
216216
{
217-
if constexpr (has_data_interface<std::decay_t<E>>::value)
217+
if constexpr (data_interface_expression<std::decay_t<E>>)
218218
{
219219
std::copy(e.strides().crbegin(), e.strides().crend(), strides.begin());
220220
}

0 commit comments

Comments
 (0)