Commit fc3598f3 authored by David Frank's avatar David Frank
Browse files

Add missing declaration of CarteSianIndices constructor

parent bfaf64b0
...@@ -14,45 +14,42 @@ namespace elsa ...@@ -14,45 +14,42 @@ namespace elsa
return result; return result;
} }
auto CartesianIndices::dims() const -> index_t { return as<index_t>(idxrange_.size()); } template <std::size_t N, typename Fn>
auto map(std::array<IndexRange, N> v, index_t size, Fn fn)
auto CartesianIndices::size() const -> index_t
{ {
// TODO: Once the coverage CI image is updated, change this to: IndexVector_t result(size);
// clang-format off std::transform(v.begin(), v.begin() + size, result.begin(), std::move(fn));
// std::transform_reduce(idxrange_.begin(), idxrange_.end(), 1, std::multiplies<>{}, return result;
// [](auto p) { return p.second - p.first; }));
// clang-format on
std::vector<index_t> tmp;
tmp.reserve(idxrange_.size());
std::transform(idxrange_.begin(), idxrange_.end(), std::back_inserter(tmp),
[](auto p) { return p.second - p.first; });
return std::accumulate(tmp.begin(), tmp.end(), 1, std::multiplies<>{});
} }
auto CartesianIndices::range(index_t i) const -> IndexRange { return idxrange_[asUnsigned(i)]; } CartesianIndices::CartesianIndices(std::vector<IndexRange> ranges) : size_(ranges.size()) {}
auto CartesianIndices::first() -> IndexVector_t CartesianIndices::CartesianIndices(const IndexVector_t& to)
: size_(to.size()), first_(IndexVector_t::Zero(size_)), last_(to)
{ {
return map(idxrange_, [](auto range) { return range.first; });
} }
auto CartesianIndices::first() const -> IndexVector_t CartesianIndices::CartesianIndices(const IndexVector_t& from, const IndexVector_t& to)
: size_(to.size()), first_(from), last_(to)
{ {
return map(idxrange_, [](auto range) { return range.first; }); if (from.size() != to.size()) {
throw InvalidArgumentError("CartesianIndices: vectors must be of same size");
}
} }
auto CartesianIndices::last() -> IndexVector_t auto CartesianIndices::dims() const -> index_t { return size_; }
{
return map(idxrange_, [](auto range) { return range.second; });
}
auto CartesianIndices::last() const -> IndexVector_t auto CartesianIndices::size() const -> index_t { return (last_ - first_).prod(); }
{
return map(idxrange_, [](auto range) { return range.second; }); auto CartesianIndices::range(index_t i) const -> IndexRange { return {first_[i], last_[i]}; }
}
auto CartesianIndices::first() -> IndexVector_t& { return first_; }
auto CartesianIndices::first() const -> const IndexVector_t& { return first_; }
auto CartesianIndices::last() -> IndexVector_t& { return last_; }
auto CartesianIndices::last() const -> const IndexVector_t& { return last_; }
auto CartesianIndices::begin() -> iterator { return iterator(first(), first(), last()); } auto CartesianIndices::begin() -> iterator { return iterator(first(), first(), last()); }
...@@ -70,14 +67,18 @@ namespace elsa ...@@ -70,14 +67,18 @@ namespace elsa
cur_.tail(cur_.size() - 1) = begin.tail(cur_.size() - 1); cur_.tail(cur_.size() - 1) = begin.tail(cur_.size() - 1);
} }
CartesianIndices::iterator::iterator(IndexVector_t vec) : cur_(vec), begins_(vec), ends_(vec) {} CartesianIndices::iterator::iterator(const IndexVector_t& vec)
: cur_(vec), begins_(vec), ends_(vec)
{
}
CartesianIndices::iterator::iterator(IndexVector_t cur, IndexVector_t begin, IndexVector_t end) CartesianIndices::iterator::iterator(const IndexVector_t& cur, const IndexVector_t& begin,
const IndexVector_t& end)
: cur_(cur), begins_(begin), ends_(end) : cur_(cur), begins_(begin), ends_(end)
{ {
} }
auto CartesianIndices::iterator::operator*() const -> IndexVector_t { return cur_; } auto CartesianIndices::iterator::operator*() const -> const IndexVector_t& { return cur_; }
auto CartesianIndices::iterator::operator++() -> iterator& auto CartesianIndices::iterator::operator++() -> iterator&
{ {
......
...@@ -55,7 +55,9 @@ namespace elsa ...@@ -55,7 +55,9 @@ namespace elsa
class CartesianIndices class CartesianIndices
{ {
private: private:
std::vector<IndexRange> idxrange_{}; index_t size_;
IndexVector_t first_;
IndexVector_t last_;
// Tag struct, just to indicate the end iterator as sentinel. TODO: With a switch to C++ // Tag struct, just to indicate the end iterator as sentinel. TODO: With a switch to C++
// 20, remove this and let `end()` return a proper sentinel type // 20, remove this and let `end()` return a proper sentinel type
...@@ -69,36 +71,26 @@ namespace elsa ...@@ -69,36 +71,26 @@ namespace elsa
CartesianIndices(std::vector<IndexRange> ranges); CartesianIndices(std::vector<IndexRange> ranges);
/// Create an index space ranging from `0`, to `to` with the dimension of `to` /// Create an index space ranging from `0`, to `to` with the dimension of `to`
CartesianIndices(const IndexVector_t& to);
template <typename Vector> template <typename Vector>
// requires ForwardRange + Sized CartesianIndices(const Vector& to)
CartesianIndices(Vector to) : size_(to.size()), first_(IndexVector_t::Zero(size_)), last_(to.size())
{ {
idxrange_.reserve(to.size());
using std::begin; using std::begin;
using std::end; std::copy_n(begin(to), size_, last_.begin());
std::transform(begin(to), end(to), std::back_inserter(idxrange_), [](auto idx) {
return std::pair{0, idx};
});
} }
/// Create an index space ranging from `from`, to `to` with the dimension of `ranges` /// Create an index space ranging from `from`, to `to` with the dimension of `ranges`
CartesianIndices(const IndexVector_t& from, const IndexVector_t& to);
template <typename Vector> template <typename Vector>
// requires ForwardRange + Sized CartesianIndices(const Vector& from, const Vector& to)
CartesianIndices(Vector from, Vector to) : size_(to.size()), first_(from.size()), last_(to.size())
{ {
if (from.size() != to.size()) {
throw InvalidArgumentError("CartesianIndices: vectors must be of same size");
}
idxrange_.reserve(asUnsigned(from.size()));
using std::begin; using std::begin;
using std::end; std::copy_n(begin(from), size_, first_.begin());
std::transform(begin(from), end(from), begin(to), std::back_inserter(idxrange_), std::copy_n(begin(to), size_, last_.begin());
[](auto start, auto end) {
return std::pair{start, end};
});
} }
/// Return the dimension of index space /// Return the dimension of index space
...@@ -111,21 +103,21 @@ namespace elsa ...@@ -111,21 +103,21 @@ namespace elsa
auto range(index_t i) const -> IndexRange; auto range(index_t i) const -> IndexRange;
/// Return the lower bound of the index space /// Return the lower bound of the index space
auto first() -> IndexVector_t; auto first() -> IndexVector_t&;
/// @overload /// @overload
auto first() const -> IndexVector_t; auto first() const -> const IndexVector_t&;
/// Return the upper bound of the index space /// Return the upper bound of the index space
auto last() -> IndexVector_t; auto last() -> IndexVector_t&;
/// @overload /// @overload
auto last() const -> IndexVector_t; auto last() const -> const IndexVector_t&;
/// Random Access Iterator for index space /// Random Access Iterator for index space
struct iterator { struct iterator {
private: private:
IndexVector_t cur_; IndexVector_t cur_;
IndexVector_t begins_; const IndexVector_t& begins_;
IndexVector_t ends_; const IndexVector_t& ends_;
public: public:
using value_type = IndexVector_t; using value_type = IndexVector_t;
...@@ -136,12 +128,13 @@ namespace elsa ...@@ -136,12 +128,13 @@ namespace elsa
iterator(as_sentinel, const IndexVector_t& begin, const IndexVector_t& end); iterator(as_sentinel, const IndexVector_t& begin, const IndexVector_t& end);
explicit iterator(IndexVector_t vec); explicit iterator(const IndexVector_t& vec);
iterator(IndexVector_t cur, IndexVector_t begin, IndexVector_t end); iterator(const IndexVector_t& cur, const IndexVector_t& begin,
const IndexVector_t& end);
// Dereference // Dereference
IndexVector_t operator*() const; const IndexVector_t& operator*() const;
// Increment // Increment
iterator& operator++(); iterator& operator++();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment