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
return result;
}
auto CartesianIndices::dims() const -> index_t { return as<index_t>(idxrange_.size()); }
auto CartesianIndices::size() const -> index_t
template <std::size_t N, typename Fn>
auto map(std::array<IndexRange, N> v, index_t size, Fn fn)
{
// TODO: Once the coverage CI image is updated, change this to:
// clang-format off
// std::transform_reduce(idxrange_.begin(), idxrange_.end(), 1, std::multiplies<>{},
// [](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<>{});
IndexVector_t result(size);
std::transform(v.begin(), v.begin() + size, result.begin(), std::move(fn));
return result;
}
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
{
return map(idxrange_, [](auto range) { return range.second; });
}
auto CartesianIndices::dims() const -> index_t { return size_; }
auto CartesianIndices::last() const -> IndexVector_t
{
return map(idxrange_, [](auto range) { return range.second; });
}
auto CartesianIndices::size() const -> index_t { return (last_ - first_).prod(); }
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()); }
......@@ -70,14 +67,18 @@ namespace elsa
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)
{
}
auto CartesianIndices::iterator::operator*() const -> IndexVector_t { return cur_; }
auto CartesianIndices::iterator::operator*() const -> const IndexVector_t& { return cur_; }
auto CartesianIndices::iterator::operator++() -> iterator&
{
......
......@@ -55,7 +55,9 @@ namespace elsa
class CartesianIndices
{
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++
// 20, remove this and let `end()` return a proper sentinel type
......@@ -69,36 +71,26 @@ namespace elsa
CartesianIndices(std::vector<IndexRange> ranges);
/// Create an index space ranging from `0`, to `to` with the dimension of `to`
CartesianIndices(const IndexVector_t& to);
template <typename Vector>
// requires ForwardRange + Sized
CartesianIndices(Vector to)
CartesianIndices(const Vector& to)
: size_(to.size()), first_(IndexVector_t::Zero(size_)), last_(to.size())
{
idxrange_.reserve(to.size());
using std::begin;
using std::end;
std::transform(begin(to), end(to), std::back_inserter(idxrange_), [](auto idx) {
return std::pair{0, idx};
});
std::copy_n(begin(to), size_, last_.begin());
}
/// 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>
// requires ForwardRange + Sized
CartesianIndices(Vector from, Vector to)
CartesianIndices(const Vector& from, const 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::end;
std::transform(begin(from), end(from), begin(to), std::back_inserter(idxrange_),
[](auto start, auto end) {
return std::pair{start, end};
});
std::copy_n(begin(from), size_, first_.begin());
std::copy_n(begin(to), size_, last_.begin());
}
/// Return the dimension of index space
......@@ -111,21 +103,21 @@ namespace elsa
auto range(index_t i) const -> IndexRange;
/// Return the lower bound of the index space
auto first() -> IndexVector_t;
auto first() -> IndexVector_t&;
/// @overload
auto first() const -> IndexVector_t;
auto first() const -> const IndexVector_t&;
/// Return the upper bound of the index space
auto last() -> IndexVector_t;
auto last() -> IndexVector_t&;
/// @overload
auto last() const -> IndexVector_t;
auto last() const -> const IndexVector_t&;
/// Random Access Iterator for index space
struct iterator {
private:
IndexVector_t cur_;
IndexVector_t begins_;
IndexVector_t ends_;
const IndexVector_t& begins_;
const IndexVector_t& ends_;
public:
using value_type = IndexVector_t;
......@@ -136,12 +128,13 @@ namespace elsa
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
IndexVector_t operator*() const;
const IndexVector_t& operator*() const;
// Increment
iterator& operator++();
......
Markdown is supported
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