Skip to content

Commit

Permalink
make mD iterator pointer-like for wrapping in a ref
Browse files Browse the repository at this point in the history
  • Loading branch information
alfC committed Feb 12, 2025
1 parent 834c131 commit 2aba019
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 19 deletions.
19 changes: 19 additions & 0 deletions include/boost/multi/array_ref.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ struct array_iterator // NOLINT(fuchsia-multiple-inheritance) for facades
using element_ptr = ElementPtr;
using element_const_ptr = typename std::pointer_traits<ElementPtr>::template rebind<element const>;
using value_type = typename subarray<element, D-1, element_ptr>::decay_type;
using element_type = value_type;

using pointer = subarray<element, D - 1, element_ptr>*;
using reference = std::conditional_t<
Expand Down Expand Up @@ -1640,6 +1641,15 @@ struct const_subarray : array_types<T, D, ElementPtr, Layout> {
class = decltype(Range(std::declval<typename const_subarray::const_iterator>(), std::declval<typename const_subarray::const_iterator>()))>
constexpr explicit operator Range() const { return Range(begin(), end()); } // NOLINT(fuchsia-default-arguments-calls) for example std::vector(it, ti, alloc = {})

template<class TT, dimensionality_type DD, class... As>
friend constexpr auto operator==(const_subarray const& self, const_subarray<TT, DD, As...> const& other) -> bool {
return (self.extension() == other.extension()) && adl_equal(self.begin(), self.end(), other.begin());
}
template<class TT, dimensionality_type DD, class... As>
friend constexpr auto operator!=(const_subarray const& self, const_subarray<TT, DD, As...> const& other) -> bool {
return (self.extension() != other.extension()) || adl_equal(self.begin(), self.end(), other.begin());
}

template<class TT, class... As>
friend constexpr auto operator==(const_subarray const& self, const_subarray<TT, D, As...> const& other) -> bool {
return (self.extension() == other.extension()) && (self.elements() == other.elements());
Expand Down Expand Up @@ -3131,6 +3141,15 @@ struct const_subarray<T, 1, ElementPtr, Layout> // NOLINT(fuchsia-multiple-inhe
->decltype(adl_copy_n(first, std::declval<size_type>(), std::declval<iterator>()), void()) {
return adl_copy_n(first, this-> size() , std::move(*this).begin()), void(); }

template<class TT, dimensionality_type DD, class... As>
friend constexpr auto operator==(const_subarray const& self, const_subarray<TT, DD, As...> const& other) -> bool {
return (self.extension() == other.extension()) && adl_equal(self.begin(), self.end(), other.begin());
}
template<class TT, dimensionality_type DD, class... As>
friend constexpr auto operator!=(const_subarray const& self, const_subarray<TT, DD, As...> const& other) -> bool {
return (self.extension() != other.extension()) || adl_equal(self.begin(), self.end(), other.begin());
}

friend constexpr auto operator==(const_subarray const& self, const_subarray const& other) -> bool {
return
self.extension() == other.extension()
Expand Down
19 changes: 13 additions & 6 deletions test/array_ref.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,19 @@ BOOST_AUTO_TEST_CASE(array_ref_test_no_ub) {

/*use iterator as pointer*/
{
// multi::array<int, 2> const arr = { {1, 2}, {3, 4}, {5, 6}, {7, 8}};
// multi::array_ref<int, 2, multi::array<int, 2>::const_iterator> const arr2({2, 2}, arr.begin());
// BOOST_TEST(( arr2 == multi::array{
// {1, 2, 3},
// {4, 5, 6}
// }));
multi::array<int, 2> const arr = { {1, 2}, {3, 4}, {5, 6}, {7, 8}};
// std::pointer_traits<multi::array<int, 2>::const_iterator>::difference_type dt;
multi::array_ref<int, 2, multi::array<int, 2>::const_iterator> const arr2({2, 2}, arr.begin());

BOOST_TEST(( arr2[0][0] == multi::array<int, 1>{1, 2} ));
BOOST_TEST(( arr2[0][1] == multi::array<int, 1>{3, 4} ));
BOOST_TEST(( arr2[1][0] == multi::array<int, 1>{5, 6} ));
BOOST_TEST(( arr2[1][1] == multi::array<int, 1>{7, 8} ));

BOOST_TEST(( arr2 == multi::array<int, 3>{
{{1, 2}, {3, 4}},
{{5, 6}, {7, 8}}
}));
}


Expand Down
26 changes: 13 additions & 13 deletions test/subarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
namespace multi = boost::multi;

namespace {
auto f_arr(multi::array<int, 1> arr) {
return arr[2];
}
auto f_arr(multi::array<int, 1> arr) {
return arr[2];
}

auto f_sub(multi::const_subarray<int, 1> const& arr) {
return arr[2];
}
auto f_sub(multi::const_subarray<int, 1> const& arr) {
return arr[2];
}
} // namespace

auto main() -> int { // NOLINT(readability-function-cognitive-complexity,bugprone-exception-escape)
Expand Down Expand Up @@ -182,17 +182,17 @@ auto main() -> int { // NOLINT(readability-function-cognitive-complexity,bugpro
// static_assert( std::is_nothrow_swappable_v <multi::array_ref<int, 4>>);
// static_assert( std::is_trivially_relocatable_v <multi::array_ref<int, 4>>); // <==========

static_assert( std::is_move_constructible_v <multi::subarray<int, 4>>); // mmm, something strange here
static_assert( std::is_nothrow_move_constructible_v<multi::subarray<int, 4>>); // mmm, something strange here
static_assert(! std::is_copy_constructible_v <multi::subarray<int, 4>>);
static_assert( std::is_move_constructible_v <multi::subarray<int, 4>>); // mmm, something strange here
static_assert( std::is_nothrow_move_constructible_v<multi::subarray<int, 4>>); // mmm, something strange here
static_assert(!std::is_copy_constructible_v <multi::subarray<int, 4>>);

#if !defined(__circle_build__)
static_assert(! std::is_trivially_copyable_v <multi::subarray<int, 4>>);
static_assert(!std::is_trivially_copyable_v <multi::subarray<int, 4>>);
#endif

static_assert( std::is_copy_assignable_v <multi::subarray<int, 4>>);
static_assert(! std::is_trivially_copy_assignable_v <multi::subarray<int, 4>>);
static_assert( std::is_swappable_v <multi::subarray<int, 4>>); // TODO(correaa) fix?
static_assert( std::is_copy_assignable_v <multi::subarray<int, 4>>);
static_assert(!std::is_trivially_copy_assignable_v <multi::subarray<int, 4>>);
static_assert( std::is_swappable_v <multi::subarray<int, 4>>); // TODO(correaa) fix?

// static_assert( std::is_nothrow_swappable_v <multi::subarray<int, 4>>);
// static_assert( std::is_trivially_relocatable_v <multi::subarray<int, 4>>); // <==========
Expand Down

0 comments on commit 2aba019

Please sign in to comment.