Skip to content

Commit e7a4932

Browse files
committed
Merge branch 'fix-cont-iter' into 'master'
fix cbegin and begin for cont layout See merge request correaa/boost-multi!1332
2 parents 27d42ff + fa95f42 commit e7a4932

File tree

7 files changed

+157
-145
lines changed

7 files changed

+157
-145
lines changed

include/boost/multi/adaptors/fftw/test/so_shift.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace multi = boost::multi;
1414

15-
auto main() -> int {
15+
auto main() -> int { // NOLINT(bugprone-exception-escape)
1616
using complex = std::complex<double>;
1717

1818
// input array

include/boost/multi/array_ref.hpp

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
#ifndef BOOST_MULTI_ARRAY_REF_HPP_
66
#define BOOST_MULTI_ARRAY_REF_HPP_
77
#include "detail/layout.hpp"
8+
#include <stdexcept>
89
#pragma once
910

1011
#include <boost/multi/detail/tuple_zip.hpp>
1112
#include <boost/multi/utility.hpp> // IWYU pragma: export
1213

14+
#include <string> // for to_string
15+
1316
namespace boost::multi {
1417

1518
template<class Element>
@@ -2234,7 +2237,7 @@ template<class Element, typename Ptr> struct array_iterator<Element, 0, Ptr>{};
22342237
template<class Element, typename Ptr, bool IsConst, bool IsMove, typename Stride>
22352238
struct array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride> // NOLINT(fuchsia-multiple-inheritance,cppcoreguidelines-pro-type-member-init,hicpp-member-init) stride_ is not initialized in some constructors
22362239
: boost::multi::iterator_facade<
2237-
array_iterator<Element, 1, Ptr, IsConst, IsMove>,
2240+
array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride>,
22382241
Element, std::random_access_iterator_tag,
22392242
std::conditional_t<
22402243
IsConst,
@@ -2247,11 +2250,11 @@ struct array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride> // NOLINT(fuchs
22472250
>,
22482251
multi::difference_type
22492252
>
2250-
, multi::affine <array_iterator<Element, 1, Ptr, IsConst>, multi::difference_type>
2251-
, multi::decrementable <array_iterator<Element, 1, Ptr, IsConst>>
2252-
, multi::incrementable <array_iterator<Element, 1, Ptr, IsConst>>
2253-
, multi::totally_ordered2 <array_iterator<Element, 1, Ptr, IsConst>, void> {
2254-
using affine = multi::affine<array_iterator<Element, 1, Ptr, IsConst>, multi::difference_type>;
2253+
, multi::affine <array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride>, multi::difference_type>
2254+
, multi::decrementable <array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride> >
2255+
, multi::incrementable <array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride> >
2256+
, multi::totally_ordered2 <array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride>, void> {
2257+
using affine = multi::affine<array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride>, multi::difference_type>;
22552258

22562259
using pointer = std::conditional_t<
22572260
IsConst,
@@ -2330,7 +2333,10 @@ struct array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride> // NOLINT(fuchs
23302333
static constexpr dimensionality_type rank_v = 1;
23312334
using rank = std::integral_constant<dimensionality_type, rank_v>;
23322335

2333-
BOOST_MULTI_HD explicit constexpr array_iterator(Ptr ptr, typename const_subarray<Element, 1, Ptr>::index stride)
2336+
// BOOST_MULTI_HD explicit constexpr array_iterator(Ptr ptr, typename const_subarray<Element, 1, Ptr>::index stride)
2337+
// : ptr_{ptr}, stride_{stride} {}
2338+
2339+
BOOST_MULTI_HD explicit constexpr array_iterator(Ptr ptr, Stride stride)
23342340
: ptr_{ptr}, stride_{stride} {}
23352341

23362342
private:
@@ -2376,8 +2382,12 @@ struct array_iterator<Element, 1, Ptr, IsConst, IsMove, Stride> // NOLINT(fuchs
23762382
#endif
23772383

23782384
constexpr auto operator-(array_iterator const& other) const -> difference_type {
2379-
assert(stride_==other.stride_ && (ptr_ - other.ptr_)%stride_ == 0);
2380-
return (ptr_ - other.ptr_)/stride_; // with struct-overflow=3 error: assuming signed overflow does not occur when simplifying `X - Y > 0` to `X > Y` [-Werror=strict-overflow]
2385+
assert(stride() != 0);
2386+
if(stride() != other.stride()) { throw std::runtime_error(std::to_string(stride()) + " // " + std::to_string(other.stride())); }
2387+
assert(stride() == other.stride());
2388+
// if((ptr_ - other.ptr_)%stride() != 0) { throw std::runtime_error(std::string{__PRETTY_FUNCTION__} + " --> " + std::to_string(ptr_ - other.ptr_) + " % " + std::to_string(stride())); }
2389+
// assert((ptr_ - other.ptr_)%stride() == 0);
2390+
return (ptr_ - other.ptr_)/stride(); // with struct-overflow=3 error: assuming signed overflow does not occur when simplifying `X - Y > 0` to `X > Y` [-Werror=strict-overflow]
23812391
// return -distance_to_(other);
23822392
}
23832393

@@ -3001,7 +3011,7 @@ struct const_subarray<T, 1, ElementPtr, Layout> // NOLINT(fuchsia-multiple-inhe
30013011
auto transposed() const& = delete;
30023012
auto flatted() const& = delete;
30033013

3004-
using iterator = typename multi::array_iterator<element_type, 1, typename types::element_ptr, false, false>;
3014+
using iterator = typename multi::array_iterator<element_type, 1, typename types::element_ptr, false, false, typename layout_type::stride_type>;
30053015
using const_iterator = typename multi::array_iterator<element_type, 1, typename types::element_ptr, true , false, typename layout_type::stride_type>;
30063016
using move_iterator = typename multi::array_iterator<element_type, 1, typename types::element_ptr, false, true >;
30073017

@@ -3042,42 +3052,36 @@ struct const_subarray<T, 1, ElementPtr, Layout> // NOLINT(fuchsia-multiple-inhe
30423052
#endif
30433053

30443054
constexpr BOOST_MULTI_HD auto begin_aux_() const {return iterator{this->base_ , this->stride()};}
3045-
constexpr auto end_aux_ () const {return iterator{this->base_ + types::nelems(), this->stride()};}
3055+
constexpr BOOST_MULTI_HD auto end_aux_ () const {return iterator{this->base_ + types::nelems(), this->stride()};}
30463056

30473057
#if defined(__clang__)
30483058
#pragma clang diagnostic pop
30493059
#endif
30503060

30513061
public:
3052-
BOOST_MULTI_HD constexpr auto begin() const& -> const_iterator {return begin_aux_();}
3053-
constexpr auto begin() & -> iterator {return begin_aux_();}
3054-
constexpr auto begin() && -> iterator {return begin_aux_();}
3055-
3056-
// constexpr auto mbegin() & {return move_iterator{begin()};}
3057-
// constexpr auto mend () & {return move_iterator{end ()};}
3058-
3059-
// constexpr auto mbegin() && {return move_iterator{begin()};}
3060-
// constexpr auto mend () && {return move_iterator{end ()};}
3062+
BOOST_MULTI_HD constexpr auto begin() const& -> const_iterator { return begin_aux_(); }
3063+
constexpr auto begin() & -> iterator { return begin_aux_(); }
3064+
constexpr auto begin() && -> iterator { return begin_aux_(); }
30613065

3062-
constexpr auto end () const& -> const_iterator {return end_aux_();}
3063-
constexpr auto end () & -> iterator {return end_aux_();}
3064-
constexpr auto end () && -> iterator {return end_aux_();}
3066+
constexpr auto end () const& -> const_iterator { return end_aux_(); }
3067+
constexpr auto end () & -> iterator { return end_aux_(); }
3068+
constexpr auto end () && -> iterator { return end_aux_(); }
30653069

3066-
[[deprecated("implement as negative stride")]] constexpr auto rbegin() const& {return const_reverse_iterator(end ());} // TODO(correaa) implement as negative stride?
3067-
[[deprecated("implement as negative stride")]] constexpr auto rend () const& {return const_reverse_iterator(begin());} // TODO(correaa) implement as negative stride?
3070+
[[deprecated("implement as negative stride")]] constexpr auto rbegin() const& { return const_reverse_iterator(end ()); } // TODO(correaa) implement as negative stride?
3071+
[[deprecated("implement as negative stride")]] constexpr auto rend () const& { return const_reverse_iterator(begin()); } // TODO(correaa) implement as negative stride?
30683072

3069-
BOOST_MULTI_FRIEND_CONSTEXPR auto begin(const_subarray const& self) -> const_iterator {return self .begin();}
3070-
BOOST_MULTI_FRIEND_CONSTEXPR auto begin(const_subarray & self) -> iterator {return self .begin();}
3071-
BOOST_MULTI_FRIEND_CONSTEXPR auto begin(const_subarray && self) -> iterator {return std::move(self).begin();}
3073+
BOOST_MULTI_FRIEND_CONSTEXPR auto begin(const_subarray const& self) -> const_iterator { return self .begin(); }
3074+
BOOST_MULTI_FRIEND_CONSTEXPR auto begin(const_subarray & self) -> iterator { return self .begin(); }
3075+
BOOST_MULTI_FRIEND_CONSTEXPR auto begin(const_subarray && self) -> iterator { return std::move(self).begin(); }
30723076

3073-
BOOST_MULTI_FRIEND_CONSTEXPR auto end (const_subarray const& self) -> const_iterator {return self .end() ;}
3074-
BOOST_MULTI_FRIEND_CONSTEXPR auto end (const_subarray & self) -> iterator {return self .end() ;}
3075-
BOOST_MULTI_FRIEND_CONSTEXPR auto end (const_subarray && self) -> iterator {return std::move(self).end() ;}
3077+
BOOST_MULTI_FRIEND_CONSTEXPR auto end (const_subarray const& self) -> const_iterator { return self .end() ; }
3078+
BOOST_MULTI_FRIEND_CONSTEXPR auto end (const_subarray & self) -> iterator { return self .end() ; }
3079+
BOOST_MULTI_FRIEND_CONSTEXPR auto end (const_subarray && self) -> iterator { return std::move(self).end() ; }
30763080

3077-
BOOST_MULTI_HD constexpr auto cbegin() const& -> const_iterator {return begin();}
3078-
constexpr auto cend () const& -> const_iterator {return end() ;}
3081+
BOOST_MULTI_HD constexpr auto cbegin() const& -> const_iterator { return begin(); }
3082+
BOOST_MULTI_HD constexpr auto cend () const& -> const_iterator { return end() ; }
30793083

3080-
friend BOOST_MULTI_HD /*constexpr*/ auto cbegin(const_subarray const& self) {return self.cbegin();}
3084+
BOOST_MULTI_FRIEND_CONSTEXPR auto cbegin(const_subarray const& self) {return self.cbegin();}
30813085
BOOST_MULTI_FRIEND_CONSTEXPR auto cend (const_subarray const& self) {return self.cend() ;}
30823086

30833087
// // fix mutation

include/boost/multi/detail/layout.hpp

Lines changed: 10 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ struct stride_traits<std::ptrdiff_t> {
4747
using category = std::random_access_iterator_tag;
4848
};
4949

50-
template<>
51-
struct stride_traits<std::integral_constant<std::ptrdiff_t, 1> > {
50+
template<typename Integer>
51+
struct stride_traits<std::integral_constant<Integer, 1> > {
5252
#if (__cplusplus >= 202002L)
5353
using category = std::contiguous_iterator_tag;
5454
#else
@@ -524,7 +524,7 @@ struct monostate : equality_comparable<monostate> {
524524
friend BOOST_MULTI_HD constexpr auto operator==(monostate const& /*self*/, monostate const& /*other*/) {return true;}
525525
};
526526

527-
template<typename SSize = multi::size_t>
527+
template<typename SSize = multi::index>
528528
class stride_t {
529529
difference_type stride_;
530530

@@ -539,95 +539,23 @@ class stride_t {
539539
using category = std::random_access_iterator_tag;
540540
};
541541

542-
template<typename SSize = multi::size_t>
542+
template<typename SSize = multi::index>
543543
class contiguous_stride_t {
544544
public:
545545
// using difference_type = SSize;
546546

547547
constexpr auto operator()() const -> SSize { return 1; }
548548

549549
template<class Ptr>
550-
constexpr auto operator()(Ptr ptr) const -> Ptr { return ptr + 1; }
550+
constexpr auto operator()(Ptr const& ptr) const -> Ptr { return ptr + 1; }
551551

552552
#if(__cplusplus >= 202002L)
553-
using category = std::contiguous_iterator_tag;
553+
using category = std::random_access_iterator_tag; // std::contiguous_iterator_tag;
554554
#else
555555
using category = std::random_access_iterator_tag;
556556
#endif
557557
};
558558

559-
// template<multi::dimensionality_t D, typename SSsize = multi::size_t>
560-
// class contiguous_layout;
561-
562-
// template<typename SSize>
563-
// class contiguous_layout<1, SSize> {
564-
// public:
565-
// contiguous_layout() = default;
566-
567-
// using dimensionality_type = multi::dimensionality_t;
568-
// using rank = std::integral_constant<dimensionality_type, 1>;
569-
// static constexpr dimensionality_type rank_v = rank::value;
570-
// static constexpr dimensionality_type dimensionality = rank_v; // TODO(correaa) : consider deprecation
571-
572-
// using difference_type = SSize;
573-
// using size_type = difference_type;
574-
575-
// using index = difference_type;
576-
// using index_range = multi::range<index>;
577-
// using index_extension = multi::extension_t<index>;
578-
// using extension_type = index_extension;
579-
580-
// constexpr auto extension() const { return extension_type{offset_, offset_ + nelems_}; }
581-
582-
// using extensions_type = multi::index_extensions<1>;
583-
// auto extensions() const -> extensions_type { return extensions_type{extension()}; }
584-
585-
// constexpr auto is_empty() const -> bool { return false; }
586-
// constexpr auto empty() const -> bool { return is_empty(); }
587-
588-
// auto is_compact() const = delete;
589-
590-
// auto sub() const { return layout_t<0, SSize>{}; }
591-
592-
// using stride_type = std::integral_constant<difference_type, 1>;
593-
// auto stride() const -> stride_type { return {}; }
594-
595-
// using num_elements_type = size_type;
596-
// auto num_elements() const -> num_elements_type { return nelems_; }
597-
598-
// using offset_type = difference_type;
599-
// auto offset() const -> offset_type { return offset_; }
600-
601-
// using offsets_type = void;
602-
// auto offsets() const -> offsets_type;
603-
604-
// using strides_type = multi::tuple<std::integral_constant<difference_type, 1> >;
605-
// auto strides() const -> stride_type;
606-
607-
// constexpr auto size() const -> size_type { return nelems_; }
608-
609-
// using nelems_type = size_type;
610-
// constexpr auto nelems() const -> nelems_type { return nelems_; }
611-
612-
// using sizes_type = void;
613-
// auto sizes() const -> sizes_type = delete;
614-
615-
// constexpr auto operator()(index const& idx) const -> difference_type { return idx - offset_; }
616-
617-
// private:
618-
// // BOOST_MULTI_NO_UNIQUE_ADDRESS sub_type sub_ ;
619-
// // BOOST_MULTI_NO_UNIQUE_ADDRESS stride_type stride_; // = {};
620-
// offset_type offset_;
621-
// nelems_type nelems_;
622-
623-
// public:
624-
// constexpr explicit contiguous_layout(extensions_type const& xs)
625-
// : offset_{xs.get<0>().front()},
626-
// nelems_{xs.get<0>().size()} {}
627-
628-
// constexpr auto reindex(index idx) -> auto& { offset_ = idx * stride(); return *this; }
629-
// };
630-
631559
template<typename SSize>
632560
struct layout_t<0, SSize>
633561
: multi::equality_comparable<layout_t<0, SSize> >
@@ -744,7 +672,7 @@ struct layout_t<0, SSize>
744672
constexpr auto hull_size() const -> size_type {return num_elements();} // not in bytes
745673
};
746674

747-
template<typename SSize = multi::size_t>
675+
template<typename SSize = multi::index>
748676
class contiguous_layout {
749677

750678
public:
@@ -765,7 +693,7 @@ class contiguous_layout {
765693
using extension_type = multi::extension_t<index>;
766694
using extensions_type = multi::extensions_t<1>;
767695

768-
using stride_type = std::integral_constant<size_type, 1>;
696+
using stride_type = std::integral_constant<int, 1>;
769697
using strides_type = typename boost::multi::detail::tuple<stride_type>;
770698

771699

@@ -780,8 +708,8 @@ class contiguous_layout {
780708
public:
781709
constexpr explicit contiguous_layout(multi::extensions_t<1> xs) : nelems_{get_<0>(xs).size()} {}
782710

783-
constexpr auto stride() const { return std::integral_constant<dimensionality_type, 1>{}; }
784-
constexpr auto offset() const { return std::integral_constant<dimensionality_type, 0>{}; }
711+
constexpr auto stride() const { return std::integral_constant<int, 1>{}; }
712+
constexpr auto offset() const { return std::integral_constant<int, 0>{}; }
785713
constexpr auto extension() const { return extension_type{0, nelems_}; }
786714

787715
constexpr auto num_elements() const { return nelems_; }

include/boost/multi/detail/operators.hpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,18 @@ template<class Self> struct selfable {
2727

2828
public:
2929
using self_type = Self;
30-
constexpr auto self() const -> self_type const& { return static_cast<self_type const&>(*this); }
31-
constexpr auto self() -> self_type& { return static_cast<self_type&>(*this); }
32-
friend constexpr auto self(selfable const& self) -> self_type const& { return self.self(); }
30+
constexpr auto self() const -> self_type const& {
31+
static_assert(std::is_base_of_v<selfable<Self>, Self>);
32+
return static_cast<self_type const&>(*this);
33+
}
34+
constexpr auto self() -> self_type& {
35+
static_assert(std::is_base_of_v<selfable<Self>, Self>);
36+
return static_cast<self_type&>(*this);
37+
}
38+
friend constexpr auto self(selfable const& self) -> self_type const& {
39+
static_assert(std::is_base_of_v<selfable<Self>, Self>);
40+
return self.self();
41+
}
3342
};
3443

3544
template<class Self, class U> struct equality_comparable2;
@@ -99,6 +108,7 @@ struct incrementable : totally_ordered<Self> {
99108

100109
public:
101110
friend constexpr auto operator++(incrementable& self, int) -> Self {
111+
static_assert(std::is_base_of_v<incrementable<Self>, Self>);
102112
Self tmp{self.self()};
103113
++self.self();
104114
assert(self.self() > tmp);

pre-push

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ else
6666
#(mkdir -p .build.g++-14 && cd .build.g++-14 && CXX=g++-14 cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_STANDARD=23 && cmake --build . && ctest -j 12 --output-on-failure) || exit 666
6767
(mkdir -p .build.c++.std23 && cd .build.c++.std23 && CXX=c++ CXXFLAGS="-fexperimental-library" cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 && cmake --build . && ctest -j 12 --output-on-failure) || exit 666
6868
#(mkdir -p .build.mull && cd .build.mull && CXX=c++ CXXFLAGS="-O1 -fpass-plugin=~/bin/mull-ir-frontend-16 -g -grecord-command-line -fprofile-instr-generate -fcoverage-mapping" cmake .. && cmake --build . && (ls *.x | xargs -n 1 sh -c 'echo $0 && ((~/bin/mull-runner-16 $0 -test-program=ctest -- -j2 --stop-on-failure) || exit 255)')) || exit 666
69-
(mkdir -p .build.c++.asan && cd .build.c++.asan && CXX=c++ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-D_LIBCPP_DEBUG=1 -fsanitize=undefined -fsanitize=pointer-overflow -fsanitize-trap=pointer-overflow -fsanitize=address -fno-omit-frame-pointer -fsanitize=signed-integer-overflow" && cmake --build . && ASAN_OPTIONS="new_delete_type_mismatch=1" ctest -j 12 --output-on-failure) || exit 666
69+
(mkdir -p .build.c++.asan && cd .build.c++.asan && CXX=c++ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_STANDARD=20 -DCMAKE_CXX_FLAGS="-D_LIBCPP_DEBUG=1 -fsanitize=undefined -fsanitize=pointer-overflow -fsanitize-trap=pointer-overflow -fsanitize=address -fno-omit-frame-pointer -fsanitize=signed-integer-overflow" && cmake --build . && ASAN_OPTIONS="new_delete_type_mismatch=1" ctest -j 12 --output-on-failure) || exit 666
7070
(mkdir -p .build.c++.m32 && cd .build.c++.m32 && CXX=c++ cmake .. -DCMAKE_BUILD_TYPE=Debug && cmake --build . && ctest -j 12 --output-on-failure) || exit 666
7171
(mkdir -p .build.c++.tidy && cd .build.c++.tidy && CXX=c++ cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_CLANG_TIDY=clang-tidy -DCMAKE_CXX_CPPLINT="cpplint;--quiet" -DCMAKE_CXX_CPPCHECK="cppcheck;--enable=all;--suppress=missingIncludeSystem;--checkers-report=cppcheck.report;--suppress=checkersReport;--inline-suppr;--std=c++17;--error-exitcode=1" -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE="include-what-you-use;-Xiwyu;--mapping_file=/Users/correatedesco1/boost-multi/.iwyu-test.imp;-Xiwyu;--no_fwd_decls;-Xiwyu;--error" && cmake --build . --verbose --parallel && ctest -j 12 --output-on-failure) || exit 666
7272

test/array_ref.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ inline auto trace_separate_sub(multi::subarray<int, 2> const& arr) -> int {
136136
} // end unnamed namespace
137137

138138
auto main() -> int { // NOLINT(readability-function-cognitive-complexity,bugprone-exception-escape)
139-
140139
{
141140
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) for test
142141
int icarr[5] = {};

0 commit comments

Comments
 (0)