Go to the documentation of this file.
26 #ifndef TILEDARRAY_BLOCK_RANGE_H__INCLUDED
27 #define TILEDARRAY_BLOCK_RANGE_H__INCLUDED
45 template <
typename Index1,
typename Index2,
46 typename = std::enable_if_t<detail::is_integral_range_v<Index1> &&
47 detail::is_integral_range_v<Index2>>>
48 void init(
const Range& range,
const Index1& lower_bound,
49 const Index2& upper_bound) {
60 const auto* MADNESS_RESTRICT
const range_stride = range.
stride_data();
67 auto lower_it = std::begin(lower_bound);
68 auto upper_it = std::begin(upper_bound);
69 auto lower_end = std::end(lower_bound);
70 auto upper_end = std::end(upper_bound);
71 for (
int d = 0; lower_it != lower_end && upper_it != upper_end;
72 ++lower_it, ++upper_it, ++d) {
74 const auto lower_bound_d = *lower_it;
75 const auto upper_bound_d = *upper_it;
78 lower[d] = lower_bound_d;
79 upper[d] = upper_bound_d;
84 extent[d] = upper[d] - lower[d];
86 static_cast<index1_type>(upper_bound_d - lower_bound_d));
91 for (
int d =
int(rank_) - 1; d >= 0; --d) {
92 const auto range_stride_d = range_stride[d];
93 stride[d] = range_stride_d;
94 block_offset_ += lower[d] * range_stride_d;
99 template <
typename PairRange,
100 typename = std::enable_if_t<detail::is_gpair_range_v<PairRange>>>
101 void init(
const Range& range,
const PairRange& bounds) {
108 rank_ = range.
rank();
112 const auto* MADNESS_RESTRICT
const range_stride = range.
stride_data();
120 for (
auto&& bound_d : bounds) {
122 const auto lower_bound_d =
detail::at(bound_d, 0);
123 const auto upper_bound_d =
detail::at(bound_d, 1);
125 lower[d] = lower_bound_d;
126 upper[d] = upper_bound_d;
131 extent[d] = upper[d] - lower[d];
133 static_cast<index1_type>(upper_bound_d - lower_bound_d));
139 for (
int d =
int(rank_) - 1; d >= 0; --d) {
140 const auto range_stride_d = range_stride[d];
141 stride[d] = range_stride_d;
142 block_offset_ += lower[d] * range_stride_d;
178 template <
typename Index1,
typename Index2,
179 typename = std::enable_if_t<detail::is_integral_range_v<Index1> &&
180 detail::is_integral_range_v<Index2>>>
182 const Index2& upper_bound)
184 init(range, lower_bound, upper_bound);
205 template <
typename Index1,
typename Index2,
206 typename = std::enable_if_t<std::is_integral_v<Index1> &&
207 std::is_integral_v<Index2>>>
209 const std::initializer_list<Index1>& lower_bound,
210 const std::initializer_list<Index2>& upper_bound)
212 init(range, lower_bound, upper_bound);
246 template <
typename PairRange,
247 typename = std::enable_if_t<detail::is_gpair_range_v<PairRange>>>
264 template <
typename GPair>
266 std::enable_if_t<detail::is_gpair_v<GPair>>* =
nullptr)
269 if constexpr (detail::is_contiguous_range_v<GPair>) {
270 for (
auto&& bound_d : bounds) {
275 init<std::initializer_list<GPair>>(range, bounds);
290 template <
typename Index,
291 typename = std::enable_if_t<std::is_integral_v<Index>>>
293 const std::initializer_list<std::initializer_list<Index>>& bounds)
296 for (
auto&& bound_d : bounds) {
300 init<std::initializer_list<std::initializer_list<Index>>>(range, bounds);
310 template <
typename Index,
typename std::enable_if_t<
311 detail::is_integral_range_v<Index>>* =
nullptr>
316 template <
typename... Index,
317 typename std::enable_if<(
sizeof...(Index) > 1ul)>::type* =
nullptr>
336 const auto* MADNESS_RESTRICT
const size =
extent_data();
340 for (
int i =
int(rank_) - 1; i >= 0; --i) {
341 const auto size_i = size[i];
342 const auto stride_i =
stride[i];
345 result += (
index % size_i) * stride_i;
349 return result + block_offset_ - offset_;
353 template <
typename Index>
364 template <
typename Index>
366 TA_EXCEPTION(
"BlockRange::inplace_shift() is not supported");
374 template <
typename Index>
382 std::swap(block_offset_, other.block_offset_);
386 template <
typename Archive>
402 static_cast<const Range&
>(r2));
434 return r1.block_offset_ == r2.block_offset_ &&
435 static_cast<const Range&
>(r1) ==
static_cast<const Range&
>(r2);
447 #endif // TILEDARRAY_BLOCK_RANGE_H__INCLUDED
index1_type * upbound_data_nc()
distance_type offset_
Ordinal index offset correction.
ordinal_type volume_
Total number of elements.
void serialize(const Archive &ar) const
Serialization Block range.
BlockRange(BlockRange &&)=default
void swap(Bitset< B > &b0, Bitset< B > &b1)
bool operator==(const BlockRange &r1, const BlockRange &r2)
BlockRange equality comparison.
ordinal_type ordinal(ordinal_type index) const
calculate the coordinate index of the ordinal index, index.
TA_1INDEX_TYPE index1_type
BlockRange & operator=(BlockRange &&)=default
Range that references a subblock of another range.
ordinal_type ordinal(const ordinal_type index) const
calculate the ordinal index of i
index1_type * stride_data_nc()
#define TA_ASSERT(EXPR,...)
index_view_type lobound() const
Range lower bound accessor.
distance_type offset() const
Range offset.
index_view_type extent() const
Range extent accessor.
friend bool operator==(const BlockRange &r1, const BlockRange &r2)
BlockRange equality comparison.
bool includes(const Index &index) const
Check the coordinate to make sure it is within the range.
index1_type * extent_data_nc()
void serialize(Archive &ar)
ordinal_type ordinal(const Index &index) const
calculate the ordinal index of i
void init_datavec(unsigned int rank)
BlockRange(const Range &range, const Index1 &lower_bound, const Index2 &upper_bound)
Construct a BlockRange defined by lower and upper bounds.
bool is_contiguous(const BlockRange &range)
BlockRange(const Range &range, const std::initializer_list< Index1 > &lower_bound, const std::initializer_list< Index2 > &upper_bound)
Construct a BlockRange defined by lower and upper bounds.
bool is_congruent(const BlockRange &r1, const BlockRange &r2)
Test that two BlockRange objects are congruent.
BlockRange(const Range &range, const PairRange &bounds)
Construct Range defined by a range of {lower,upper} bound pairs.
index_view_type stride() const
Range stride accessor.
container::svector< index1_type, 4 *TA_MAX_SOO_RANK_METADATA > datavec_
Range_ shift(const Index &)
Shift the lower and upper bound of this range.
const index1_type * stride_data() const
Range stride data accessor.
BlockRange & operator=(const BlockRange &)=default
BlockRange & resize(const Index &, const Index &)
Resize of block range is not supported.
BlockRange(const BlockRange &)=default
BlockRange(const Range &range, const std::initializer_list< GPair > &bounds, std::enable_if_t< detail::is_gpair_v< GPair >> *=nullptr)
Construct range defined by an initializer_list of std::initializer_list{lower,upper} bounds.
ordinal_type ordinal(const Index &... index) const
BlockRange(const Range &range, const std::initializer_list< std::initializer_list< Index >> &bounds)
Construct range defined by an initializer_list of std::initializer_list{lower,upper} bounds.
void swap(BlockRange &other)
unsigned int rank_
The rank (or number of dimensions) in the range.
decltype(auto) at(GeneralizedPair &&v, std::size_t idx)
at(pair, i) extracts i-th element from gpair
index_view_type upbound() const
Range upper bound accessor.
std::size_t ordinal_type
Ordinal type, to conform to TWG spec.
const index1_type * extent_data() const
Range extent data accessor.
index_type index
Coordinate index type (deprecated)
Range_ & inplace_shift(const Index &)
Shift the lower and upper bound of this range.
unsigned int rank() const
Rank accessor.
index1_type * lobound_data_nc()
A (hyperrectangular) interval on , space of integer -indices.