293 lines
9.9 KiB
C++
293 lines
9.9 KiB
C++
#ifndef AHFINDERDIRECT__ARRAY_HH
|
|
#define AHFINDERDIRECT__ARRAY_HH
|
|
|
|
namespace AHFinderDirect
|
|
{
|
|
namespace jtutil
|
|
{
|
|
|
|
//******************************************************************************
|
|
|
|
template <typename T>
|
|
class array1d
|
|
{
|
|
public:
|
|
int min_i() const { return min_i_; }
|
|
int max_i() const { return max_i_; }
|
|
int N_i() const { return jtutil::how_many_in_range(min_i_, max_i_); }
|
|
bool is_valid_i(int i) const { return (i >= min_i_) && (i <= max_i_); }
|
|
|
|
int subscript_unchecked(int i) const
|
|
{
|
|
return offset_ + stride_i_ * i;
|
|
}
|
|
int subscript(int i) const
|
|
{
|
|
assert(is_valid_i(i));
|
|
const int posn = subscript_unchecked(i);
|
|
assert(posn >= 0);
|
|
assert(posn <= max_subscript_);
|
|
return posn;
|
|
}
|
|
int subscript_offset() const { return offset_; }
|
|
int subscript_stride_i() const { return stride_i_; }
|
|
|
|
// normal-use access functions
|
|
// ... rvalue
|
|
const T &operator()(int i) const { return array_[subscript(i)]; }
|
|
// ... lvalue
|
|
T &operator()(int i) { return array_[subscript(i)]; }
|
|
|
|
// get access to internal 0-origin 1D storage array
|
|
// (low-level, dangerous, use with caution!)
|
|
// ... semantics of N_array() may not be what you want
|
|
// if strides specify noncontiguous storage
|
|
int N_array() const { return max_subscript_ + stride_i_; }
|
|
const T *data_array() const { return const_cast<const T *>(array_); }
|
|
T *data_array() { return array_; }
|
|
|
|
// constructor, destructor
|
|
// ... constructor initializes all array elements to T(0.0)
|
|
// ... omitted strides default to C storage order
|
|
array1d(int min_i_in, int max_i_in,
|
|
T *array_in = NULL, // caller-provided storage array
|
|
// if non-NULL
|
|
int stride_i_in = 0);
|
|
~array1d();
|
|
|
|
private:
|
|
// we forbid copying and passing by value
|
|
// by declaring the copy constructor and assignment operator
|
|
// private, but never defining them
|
|
array1d(const array1d<T> &rhs);
|
|
array1d<T> &operator=(const array1d<T> &rhs);
|
|
|
|
private:
|
|
// n.b. we declare the array pointer first in the class
|
|
// ==> it's probably at 0 offset
|
|
// ==> we may get slightly faster array access
|
|
T *array_; // --> new-allocated 1D storage array
|
|
|
|
// subscripting info
|
|
// n.b. put this next in class so it should be in the same
|
|
// cpu cache line as array_ ==> faster array access
|
|
int offset_, stride_i_;
|
|
|
|
// min/max array bounds
|
|
const int min_i_, max_i_;
|
|
int max_subscript_;
|
|
|
|
// n.b. put this at end of class since performance doesn't matter
|
|
bool we_own_array_; // true ==> array_ --> new[] array which we own
|
|
// false ==> array_ --> client-owned storage
|
|
};
|
|
|
|
//******************************************************************************
|
|
|
|
template <typename T>
|
|
class array2d
|
|
{
|
|
public:
|
|
// array info
|
|
int min_i() const { return min_i_; }
|
|
int max_i() const { return max_i_; }
|
|
int min_j() const { return min_j_; }
|
|
int max_j() const { return max_j_; }
|
|
int N_i() const { return jtutil::how_many_in_range(min_i_, max_i_); }
|
|
int N_j() const { return jtutil::how_many_in_range(min_j_, max_j_); }
|
|
bool is_valid_i(int i) const { return (i >= min_i_) && (i <= max_i_); }
|
|
bool is_valid_j(int j) const { return (j >= min_j_) && (j <= max_j_); }
|
|
bool is_valid_ij(int i, int j) const
|
|
{
|
|
return is_valid_i(i) && is_valid_j(j);
|
|
}
|
|
|
|
int subscript_unchecked(int i, int j) const
|
|
{
|
|
return offset_ + stride_i_ * i + stride_j_ * j;
|
|
}
|
|
int subscript(int i, int j) const
|
|
{
|
|
// n.b. we want each assert() here to be on a separate
|
|
// source line, so an assert() failure message can
|
|
// pinpoint *which* index is bad
|
|
assert(is_valid_i(i));
|
|
assert(is_valid_j(j));
|
|
const int posn = subscript_unchecked(i, j);
|
|
assert(posn >= 0);
|
|
assert(posn <= max_subscript_);
|
|
return posn;
|
|
}
|
|
int subscript_offset() const { return offset_; }
|
|
int subscript_stride_i() const { return stride_i_; }
|
|
int subscript_stride_j() const { return stride_j_; }
|
|
|
|
// normal-use access functions
|
|
// ... rvalue
|
|
const T &operator()(int i, int j) const
|
|
{
|
|
return array_[subscript(i, j)];
|
|
}
|
|
// ... lvalue
|
|
T &operator()(int i, int j)
|
|
{
|
|
return array_[subscript(i, j)];
|
|
}
|
|
|
|
// get access to internal 0-origin 1D storage array
|
|
// (low-level, dangerous, use with caution!)
|
|
// ... semantics of N_array() may not be what you want
|
|
// if strides specify noncontiguous storage
|
|
int N_array() const { return max_subscript_ + stride_j_; }
|
|
const T *data_array() const { return const_cast<const T *>(array_); }
|
|
T *data_array() { return array_; }
|
|
|
|
// constructor, destructor
|
|
// ... constructor initializes all array elements to T(0.0)
|
|
// ... omitted strides default to C storage order
|
|
array2d(int min_i_in, int max_i_in,
|
|
int min_j_in, int max_j_in,
|
|
T *array_in = NULL, // caller-provided storage array
|
|
// if non-NULL
|
|
int stride_i_in = 0, int stride_j_in = 0);
|
|
~array2d();
|
|
|
|
private:
|
|
// we forbid copying and passing by value
|
|
// by declaring the copy constructor and assignment operator
|
|
// private, but never defining them
|
|
array2d(const array2d<T> &rhs);
|
|
array2d<T> &operator=(const array2d<T> &rhs);
|
|
|
|
private:
|
|
// n.b. we declare the array pointer first in the class
|
|
// ==> it's probably at 0 offset
|
|
// ==> we may get slightly faster array access
|
|
T *array_; // --> new-allocated 1D storage array
|
|
|
|
// subscripting info
|
|
// n.b. put this next in class so it should be in the same
|
|
// cpu cache line as array_ ==> faster array access
|
|
int offset_, stride_i_, stride_j_;
|
|
|
|
// min/max array bounds
|
|
const int min_i_, max_i_;
|
|
const int min_j_, max_j_;
|
|
int max_subscript_;
|
|
|
|
// n.b. put this at end of class since performance doesn't matter
|
|
bool we_own_array_; // true ==> array_ --> new[] array which we own
|
|
// false ==> array_ --> client-owned storage
|
|
};
|
|
|
|
//******************************************************************************
|
|
|
|
template <typename T>
|
|
class array3d
|
|
{
|
|
public:
|
|
// array info
|
|
int min_i() const { return min_i_; }
|
|
int max_i() const { return max_i_; }
|
|
int min_j() const { return min_j_; }
|
|
int max_j() const { return max_j_; }
|
|
int min_k() const { return min_k_; }
|
|
int max_k() const { return max_k_; }
|
|
int N_i() const { return jtutil::how_many_in_range(min_i_, max_i_); }
|
|
int N_j() const { return jtutil::how_many_in_range(min_j_, max_j_); }
|
|
int N_k() const { return jtutil::how_many_in_range(min_k_, max_k_); }
|
|
bool is_valid_i(int i) const { return (i >= min_i_) && (i <= max_i_); }
|
|
bool is_valid_j(int j) const { return (j >= min_j_) && (j <= max_j_); }
|
|
bool is_valid_k(int k) const { return (k >= min_k_) && (k <= max_k_); }
|
|
bool is_valid_ijk(int i, int j, int k) const
|
|
{
|
|
return is_valid_i(i) && is_valid_j(j) && is_valid_k(k);
|
|
}
|
|
|
|
int subscript_unchecked(int i, int j, int k) const
|
|
{
|
|
return offset_ + stride_i_ * i + stride_j_ * j + stride_k_ * k;
|
|
}
|
|
int subscript(int i, int j, int k) const
|
|
{
|
|
// n.b. we want each assert() here to be on a separate
|
|
// source line, so an assert() failure message can
|
|
// pinpoint *which* index is bad
|
|
assert(is_valid_i(i));
|
|
assert(is_valid_j(j));
|
|
assert(is_valid_k(k));
|
|
const int posn = subscript_unchecked(i, j, k);
|
|
assert(posn >= 0);
|
|
assert(posn <= max_subscript_);
|
|
return posn;
|
|
}
|
|
int subscript_offset() const { return offset_; }
|
|
int subscript_stride_i() const { return stride_i_; }
|
|
int subscript_stride_j() const { return stride_j_; }
|
|
int subscript_stride_k() const { return stride_k_; }
|
|
|
|
// normal-use access functions
|
|
// ... rvalue
|
|
const T &operator()(int i, int j, int k) const
|
|
{
|
|
return array_[subscript(i, j, k)];
|
|
}
|
|
// ... lvalue
|
|
T &operator()(int i, int j, int k)
|
|
{
|
|
return array_[subscript(i, j, k)];
|
|
}
|
|
|
|
// get access to internal 0-origin 1D storage array
|
|
// (low-level, dangerous, use with caution!)
|
|
// ... semantics of N_array() may not be what you want
|
|
// if strides specify noncontiguous storage
|
|
int N_array() const { return max_subscript_ + stride_k_; }
|
|
const T *data_array() const { return const_cast<const T *>(array_); }
|
|
T *data_array() { return array_; }
|
|
|
|
// constructor, destructor
|
|
// ... constructor initializes all array elements to T(0.0)
|
|
// ... omitted strides default to C storage order
|
|
array3d(int min_i_in, int max_i_in,
|
|
int min_j_in, int max_j_in,
|
|
int min_k_in, int max_k_in,
|
|
T *array_in = NULL, // caller-provided storage array
|
|
// if non-NULL
|
|
int stride_i_in = 0, int stride_j_in = 0, int stride_k_in = 0);
|
|
~array3d();
|
|
|
|
private:
|
|
// we forbid copying and passing by value
|
|
// by declaring the copy constructor and assignment operator
|
|
// private, but never defining them
|
|
array3d(const array3d<T> &rhs);
|
|
array3d<T> &operator=(const array3d<T> &rhs);
|
|
|
|
private:
|
|
// n.b. we declare the array pointer first in the class
|
|
// ==> it's probably at 0 offset
|
|
// ==> we may get slightly faster array access
|
|
T *array_; // --> new-allocated 1D storage array
|
|
|
|
// subscripting info
|
|
// n.b. put this next in class so it should be in the same
|
|
// cpu cache line as array_ ==> faster array access
|
|
int offset_, stride_i_, stride_j_, stride_k_;
|
|
|
|
// min/max array bounds
|
|
const int min_i_, max_i_;
|
|
const int min_j_, max_j_;
|
|
const int min_k_, max_k_;
|
|
int max_subscript_;
|
|
|
|
// n.b. put this at end of class since performance doesn't matter
|
|
bool we_own_array_; // true ==> array_ --> new[] array which we own
|
|
// false ==> array_ --> client-owned storage
|
|
};
|
|
|
|
} // namespace jtutil
|
|
} // namespace AHFinderDirect
|
|
|
|
#endif /* AHFINDERDIRECT__ARRAY_HH */
|