Skip to content
Snippets Groups Projects
Commit 53ed2f1d authored by patavirt's avatar patavirt
Browse files

array: use pointers, not offsets

parent 60c7d6f3
No related branches found
No related tags found
No related merge requests found
......@@ -90,19 +90,16 @@ namespace detail
class fixed_base
{
protected:
size_t offset_;
template <typename Storage>
void data_bounds_check(Storage& data) const
void data_bounds_check(size_t size) const
{
#ifndef NO_BOUNDS_CHECK
if (Shape::size > data.size())
if (Shape::size > size)
throw std::out_of_range("data array too small");
#endif
}
}
public:
fixed_base(size_t offset=0) : offset_(offset)
fixed_base()
{
static_assert(Shape::fixed, "array shape must be compile-time fixed");
}
......@@ -112,7 +109,6 @@ namespace detail
constexpr std::array<size_t, Shape::ndim> shape() const { return Shape::shape(); }
constexpr std::array<size_t, Shape::ndim> strides() const { return Shape::strides(); }
constexpr size_t offset() const { return offset_; }
constexpr size_t size() const { return Shape::size; }
};
......@@ -124,10 +120,8 @@ namespace detail
protected:
std::array<size_t, Shape::ndim> shape_;
std::array<size_t, Shape::ndim> strides_;
size_t offset_;
template <typename Storage>
void data_bounds_check(Storage& data) const
void data_bounds_check(size_t size) const
{
#ifndef NO_BOUNDS_CHECK
size_t total = 1;
......@@ -137,15 +131,14 @@ namespace detail
if (shape_[i] != dim(i))
throw std::out_of_range("mismatch with fixed shape");
}
total += offset_;
if (total > data.size())
if (total > size)
throw std::out_of_range("data array too small");
#endif
}
public:
dynamic_base(const std::array<size_t, Shape::ndim> shape, size_t offset)
: shape_(shape), offset_(offset)
dynamic_base(const std::array<size_t, Shape::ndim> shape)
: shape_(shape)
{
static_assert(!Shape::fixed, "array shape must not be compile-time fixed");
......@@ -181,7 +174,6 @@ namespace detail
const std::array<size_t, Shape::ndim>& shape() const { return shape_; }
const std::array<size_t, Shape::ndim>& strides() const { return strides_; }
size_t offset() const { return offset_; }
size_t size() const
{
size_t size = 1;
......@@ -194,13 +186,13 @@ namespace detail
/*! Simple data-by-reference strided array class a la Fortran
*/
template <typename Scalar, typename Shape, typename Storage = std::vector<Scalar> >
template <typename Scalar, typename Shape>
class Array : public std::conditional_t<Shape::fixed, detail::fixed_base<Shape>, detail::dynamic_base<Shape> >
{
private:
typedef std::conditional_t<Shape::fixed, detail::fixed_base<Shape>, detail::dynamic_base<Shape> > Base;
Storage& data_;
Scalar *data_;
template <size_t axis>
static constexpr Eigen::Index eigen_shape()
......@@ -210,16 +202,16 @@ private:
}
public:
Array(Storage& data, const std::array<size_t, Shape::ndim> shape, const size_t offset=0)
: Base(shape, offset), data_(data)
Array(Scalar *data, size_t size, const std::array<size_t, Shape::ndim> shape)
: Base(shape), data_(data)
{
Base::data_bounds_check(data);
Base::data_bounds_check(size);
}
Array(Storage& data, const size_t offset=0)
: Base(offset), data_(data)
Array(Scalar *data, size_t size)
: Base(), data_(data)
{
Base::data_bounds_check(data);
Base::data_bounds_check(size);
}
template <typename... Idx>
......@@ -238,7 +230,7 @@ public:
return data_[index(idxs...)];
}
Storage& data() { return data_; }
Scalar* data() { return data_; }
template <typename... Idx>
size_t index(Idx... idxs) const
......@@ -247,7 +239,7 @@ public:
"number of indices must be smaller than the number of dimensions");
const std::array<size_t, Shape::ndim> m{idxs...};
size_t idx = Base::offset();
size_t idx = 0;
for (size_t i = 0; i < sizeof...(idxs); ++i) {
idx += Base::stride(i) * m[i];
......@@ -257,10 +249,6 @@ public:
#endif
}
#ifndef NO_BOUNDS_CHECK
if (idx >= data_.size())
throw std::out_of_range("total index out of bounds");
#endif
return idx;
}
......@@ -275,7 +263,7 @@ public:
"number of indices must be small than the number of dimensions");
size_t offset = index(idxs...);
return {data_, offset};
return {data_ + offset, Base::size() - offset};
}
/*! Extract partial matrix (compile-time dynamic size) */
......@@ -292,7 +280,7 @@ public:
std::array<size_t, Shape::ndim - nidxs> shape;
for (size_t i = nidxs; i < Shape::ndim; ++i)
shape[i - nidxs] = Base::dim(i);
return {data_, shape, offset};
return {data_ + offset, Base::size() - offset, shape};
}
typedef Eigen::Matrix<Scalar, eigen_shape<0>(), eigen_shape<1>(), Eigen::RowMajor> EigenMatrix;
......@@ -301,8 +289,7 @@ public:
EigenMap matrix() const
{
static_assert(Shape::ndim == 2, "matrix must be two-dimensional");
return {(Scalar *)data_.data() + Base::offset(),
static_cast<Eigen::Index>(Base::dim(0)), static_cast<Eigen::Index>(Base::dim(1))};
return {data_, static_cast<Eigen::Index>(Base::dim(0)), static_cast<Eigen::Index>(Base::dim(1))};
}
operator EigenMap() const { return matrix(); }
......
......@@ -17,7 +17,7 @@ void dump(Array<Scalar,Shape> Q)
}
}
for (size_t i = 0; i < Q.data().size(); ++i) {
for (size_t i = 0; i < Q.size(); ++i) {
std::cout << Q.data()[i] << std::endl;
}
}
......@@ -25,7 +25,7 @@ void dump(Array<Scalar,Shape> Q)
int main()
{
std::vector<double> v(7*2*2*2);
Array<double,Shape<Dynamic,Dynamic,2,2> > Q0(v,{7,2,2,2});
Array<double,Shape<Dynamic,Dynamic,2,2> > Q0(v.data(), v.size(), {7,2,2,2});
auto Q = Q0.part(0u,1u);
S_2(Q);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment