xtensor
xtensor copied to clipboard
Error with xt::axis_slice_xxxx iterators for const arrays with std algorithms
Consider a simple example: we want to take a slice iterator over a sorted array and apply std::lower_bound function to it.
#include <xtensor/xarray.hpp>
#include <xtensor/xaxis_slice_iterator.hpp>
#include <xtensor/xio.hpp>
xarray<int> a = {{{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}},
{{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}}};
auto iter = axis_slice_begin(a, 0);
auto end = axis_slice_end(a, 0);
auto it = std::lower_bound(iter, end,
8,
(auto cont & elementIt, int p)
{
return elementIt[0] < p;
});
std::cout << *it << std::endl; // PRINTS: {13, 17, 21}
Now if we use a const ref to our array and pass it to the same function, the code does not compile anymore:
auto const & b = a; // const ref to the same array
auto iter = axis_slice_begin(b, 0);
auto end = axis_slice_end(b, 0);
Compiler output: (it is approximately the same for gcc on linux and clang on macos)
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/algorithm:670:
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/copy.h:35:19: error: cannot assign to return value because function 'operator*' returns a const value
*__result = *__first;
~~~~~~~~~ ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/copy.h:69:23: note: in instantiation of function template specialization 'std::__copy_constexpr<xt::xiterator<xt::xstepper<const xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>, xt::xiterator<xt::xstepper<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>>' requested here
return _VSTD::__copy_constexpr(__first, __last, __result);
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xstrided_view.hpp:416:18: note: in instantiation of function template specialization 'std::copy<xt::xiterator<xt::xstepper<const xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>, xt::xiterator<xt::xstepper<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>>' requested here
std::copy(t.cbegin(), t.cend(), v.begin());
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xstrided_view.hpp:424:31: note: in instantiation of function template specialization 'xt::xstrided_view_detail::run_assign_temporary_impl<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>, xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>' requested here
xstrided_view_detail::run_assign_temporary_impl(*this, tmp, std::integral_constant<bool, fast_assign>{});
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xsemantic.hpp:662:30: note: in instantiation of member function 'xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>::assign_temporary_impl' requested here
this->derived_cast().assign_temporary_impl(std::move(tmp));
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xstrided_view.hpp:379:22: note: in instantiation of member function 'xt::xview_semantic<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>::assign_temporary' requested here
return this->assign_temporary(std::move(tmp));
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xaxis_slice_iterator.hpp:28:11: note: in instantiation of member function 'xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>::operator=' requested here
class xaxis_slice_iterator
^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/lower_bound.h:55:19: note: in instantiation of function template specialization 'std::__lower_bound<(lambda at /Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1209:31) &, xt::xaxis_slice_iterator<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>, double>' requested here
return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
^
/Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1207:19: note: in instantiation of function template specialization 'std::lower_bound<xt::xaxis_slice_iterator<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>, double, (lambda at /Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1209:31)>' requested here
auto iit = std::lower_bound(beginIt, endIt,
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xiterator.hpp:337:9: note: function 'operator*' which returns const-qualified type 'xt::xiterator<xt::xstepper<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>::reference' (aka 'const double &') declared here
reference operator*() const;
^~~~~~~~~
In file included from /Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1:
In file included from /Users/dmitry/projects/gamma/client/logview/CurveObject.hpp:3:
In file included from /Users/dmitry/projects/gamma/client/logview/LogViewObject.hpp:3:
In file included from /opt/homebrew/lib/QtWidgets.framework/Headers/QGraphicsItem:1:
In file included from /opt/homebrew/lib/QtWidgets.framework/Headers/qgraphicsitem.h:8:
In file included from /opt/homebrew/lib/QtCore.framework/Headers/qobject.h:11:
In file included from /opt/homebrew/lib/QtCore.framework/Headers/qstring.h:14:
In file included from /opt/homebrew/include/QtCore/qchar.h:651:
In file included from /opt/homebrew/include/QtCore/qstringview.h:8:
In file included from /opt/homebrew/include/QtCore/qbytearray.h:11:
In file included from /opt/homebrew/include/QtCore/qarraydatapointer.h:7:
In file included from /opt/homebrew/include/QtCore/qarraydataops.h:9:
In file included from /opt/homebrew/include/QtCore/qcontainertools_impl.h:20:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/algorithm:670:
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/copy.h:44:12: error: no matching function for call to '__copy_constexpr'
return _VSTD::__copy_constexpr(__first, __last, __result);
^~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__config:858:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_ABI_NAMESPACE
^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/copy.h:72:20: note: in instantiation of function template specialization 'std::__copy<xt::xiterator<xt::xstepper<const xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>, xt::xiterator<xt::xstepper<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>>' requested here
_VSTD::__copy(_VSTD::__unwrap_iter(__first),
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xstrided_view.hpp:416:18: note: in instantiation of function template specialization 'std::copy<xt::xiterator<xt::xstepper<const xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>, xt::xiterator<xt::xstepper<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>>' requested here
std::copy(t.cbegin(), t.cend(), v.begin());
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xstrided_view.hpp:424:31: note: in instantiation of function template specialization 'xt::xstrided_view_detail::run_assign_temporary_impl<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>, xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>' requested here
xstrided_view_detail::run_assign_temporary_impl(*this, tmp, std::integral_constant<bool, fast_assign>{});
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xsemantic.hpp:662:30: note: in instantiation of member function 'xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>::assign_temporary_impl' requested here
this->derived_cast().assign_temporary_impl(std::move(tmp));
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xstrided_view.hpp:379:22: note: in instantiation of member function 'xt::xview_semantic<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>::assign_temporary' requested here
return this->assign_temporary(std::move(tmp));
^
/Users/dmitry/projects/gamma/client/libraries/xtensor/include/xtensor/xaxis_slice_iterator.hpp:28:11: note: in instantiation of member function 'xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>::operator=' requested here
class xaxis_slice_iterator
^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/lower_bound.h:55:19: note: in instantiation of function template specialization 'std::__lower_bound<(lambda at /Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1209:31) &, xt::xaxis_slice_iterator<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>, double>' requested here
return _VSTD::__lower_bound<_Comp_ref>(__first, __last, __value_, __comp);
^
/Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1207:19: note: in instantiation of function template specialization 'std::lower_bound<xt::xaxis_slice_iterator<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>, double, (lambda at /Users/dmitry/projects/gamma/client/logview/CurveObject.cpp:1209:31)>' requested here
auto iit = std::lower_bound(beginIt, endIt,
^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__algorithm/copy.h:32:1: note: candidate template ignored: substitution failure [with _InputIterator = xt::xiterator<xt::xstepper<const xt::xarray_container<xt::uvector<double>, xt::layout_type::dynamic, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>, _OutputIterator = xt::xiterator<xt::xstepper<xt::xstrided_view<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>, xt::layout_type::dynamic, xt::detail::inner_storage_getter<const xt::xarray_container<xt::uvector<double>, xt::layout_type::row_major, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true>> &>>>, xt::svector<unsigned long, 4, std::allocator<unsigned long>, true> *, xt::layout_type::row_major>]
__copy_constexpr(_InputIterator __first, _InputIterator __last, _OutputIterator __result)
^
3 errors generated.
I believe, const ref arrays should be "iterable" the same way as non-const variables.
Thanks