OpenVDB 11.0.0
Loading...
Searching...
No Matches
Range.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3
4/*!
5 \file Range.h
6
7 \author Ken Museth
8
9 \date August 28, 2020
10
11 \brief Custom Range class that is compatible with the tbb::blocked_range classes
12*/
13
14#ifndef NANOVDB_RANGE_H_HAS_BEEN_INCLUDED
15#define NANOVDB_RANGE_H_HAS_BEEN_INCLUDED
16
17#include <cassert>
18
19#ifdef NANOVDB_USE_TBB
20#include <tbb/blocked_range.h>// for tbb::split
21#endif
22
23namespace nanovdb {
24
25class Split {};// Dummy class used by split constructors
26
27template <int, typename>
28class Range;
29
33
34// template specialization for Rank = 1
35template <typename T>
36class Range<1, T>
37{
38 T mBegin, mEnd;
39 size_t mGrainsize;
40 template<int, typename>
41 friend class Range;
42public:
43 using const_iterator = T;
44 using size_type = size_t;
45 Range(const Range&) = default;
46 Range(T begin, T end, size_type grainsize = size_type(1))
47 : mBegin(begin), mEnd(end), mGrainsize(grainsize)
48 {
49 assert(grainsize > size_type(0));
50 }
51 /// @brief Split constructor: r[a,b[ -> r[a,b/2[ & this[b/2,b[
52 Range(Range &r, Split) : mBegin(r.mBegin), mEnd(r.mEnd), mGrainsize(r.mGrainsize) {
53 assert(r.is_divisible());
54 r.mEnd = mBegin = this->middle();
55 }
56#ifdef NANOVDB_USE_TBB
57 Range(Range &r, tbb::split) : Range(r, Split()) {}
58#endif
59 bool operator==(const Range& rhs) const { return mBegin == rhs.mBegin && mEnd == rhs.mEnd && mGrainsize == rhs.mGrainsize; }
60 T middle() const {return mBegin + (mEnd - mBegin) / T(2);}
61 size_type size() const { assert(!this->empty()); return size_type(mEnd - mBegin); }
62 bool empty() const { return !(mBegin < mEnd); }
63 size_type grainsize() const {return mGrainsize;}
64 bool is_divisible() const {return mGrainsize < this->size();}
65 const_iterator begin() const { return mBegin; }
66 const_iterator end() const { return mEnd; }
67};// Range<1, T>
68
69// template specialization for Rank = 2
70template <typename T>
71class Range<2, T>
72{
73 Range<1, T> mRange[2];
74public:
76 Range(const Range<1, T> &rangeRow, const Range<1, T> &rangeCol) : mRange{ rangeRow, rangeCol } {}
77 Range(T beginRow, T endRow, size_type grainsizeRow, T beginCol, T endCol, size_type grainsizeCol)
78 : Range( Range<1,T>(beginRow, endRow, grainsizeRow), Range<1,T>(beginCol, endCol, grainsizeCol) )
79 {
80 }
81 Range(T beginRow, T endRow, T beginCol, T endCol) : Range(Range<1,T>(beginRow, endRow), Range<1,T>(beginCol, endCol) )
82 {
83 }
84 Range(Range &r, Split) : Range(r.mRange[0], r.mRange[1]) {
85 assert( r.is_divisible() );// at least one of the two dimensions must be divisible!
86 if( mRange[0].size()*double(mRange[1].grainsize()) < mRange[1].size()*double(mRange[0].grainsize()) ) {
87 r.mRange[1].mEnd = mRange[1].mBegin = mRange[1].middle();
88 } else {
89 r.mRange[0].mEnd = mRange[0].mBegin = mRange[0].middle();
90 }
91 }
92#ifdef NANOVDB_USE_TBB
93 Range(Range &r, tbb::split) : Range(r, Split()) {}
94#endif
95 bool operator==(const Range& rhs) const {return mRange[0] == rhs[0] && mRange[1] == rhs[1]; }
96 bool empty() const { return mRange[0].empty() || mRange[1].empty(); }
97 bool is_divisible() const {return mRange[0].is_divisible() || mRange[1].is_divisible();}
98 const Range<1, T>& operator[](int i) const { assert(i==0 || i==1); return mRange[i]; }
99};// Range<2, T>
100
101// template specialization for Rank = 3
102template <typename T>
103class Range<3, T>
104{
105 Range<1, T> mRange[3];
106public:
108 Range(const Range<1, T> &rangeX, const Range<1, T> &rangeY, const Range<1, T> &rangeZ) : mRange{ rangeX, rangeY, rangeZ } {}
109 Range(T beginX, T endX, size_type grainsizeX,
110 T beginY, T endY, size_type grainsizeY,
111 T beginZ, T endZ, size_type grainsizeZ)
112 : Range( Range<1,T>(beginX, endX, grainsizeX),
113 Range<1,T>(beginY, endY, grainsizeY),
114 Range<1,T>(beginZ, endZ, grainsizeZ) )
115 {
116 }
117 Range(T beginX, T endX, T beginY, T endY, T beginZ, T endZ)
118 : Range( Range<1,T>(beginX, endX), Range<1,T>(beginY, endY), Range<1,T>(beginZ, endZ) )
119 {
120 }
121 Range(Range &r, Split) : Range(r.mRange[0], r.mRange[1], r.mRange[2])
122 {
123 assert( r.is_divisible() );// at least one of the three dimensions must be divisible!
124 if ( mRange[2].size()*double(mRange[0].grainsize()) < mRange[0].size()*double(mRange[2].grainsize()) ) {
125 if ( mRange[0].size()*double(mRange[1].grainsize()) < mRange[1].size()*double(mRange[0].grainsize()) ) {
126 r.mRange[1].mEnd = mRange[1].mBegin = mRange[1].middle();
127 } else {
128 r.mRange[0].mEnd = mRange[0].mBegin = mRange[0].middle();
129 }
130 } else {
131 if ( mRange[2].size()*double(mRange[1].grainsize()) < mRange[1].size()*double(mRange[2].grainsize()) ) {
132 r.mRange[1].mEnd = mRange[1].mBegin = mRange[1].middle();
133 } else {
134 r.mRange[2].mEnd = mRange[2].mBegin = mRange[2].middle();
135 }
136 }
137 }
138#ifdef NANOVDB_USE_TBB
139 Range(Range &r, tbb::split) : Range(r, Split()) {}
140#endif
141 bool operator==(const Range& rhs) const {return mRange[0] == rhs[0] && mRange[1] == rhs[1] && mRange[2] == rhs[2]; }
142 bool empty() const { return mRange[0].empty() || mRange[1].empty() || mRange[2].empty(); }
143 bool is_divisible() const {return mRange[0].is_divisible() || mRange[1].is_divisible() || mRange[2].is_divisible();}
144 const Range<1, T>& operator[](int i) const { assert(i==0 || i==1 || i==2); return mRange[i]; }
145};// Range<3, T>
146
147}// namespace nanovdb
148
149#endif // NANOVDB_RANGE_H_HAS_BEEN_INCLUDED
Range(T begin, T end, size_type grainsize=size_type(1))
Definition Range.h:46
const_iterator begin() const
Definition Range.h:65
bool is_divisible() const
Definition Range.h:64
Range(const Range &)=default
size_type size() const
Definition Range.h:61
bool empty() const
Definition Range.h:62
size_t size_type
Definition Range.h:44
size_type grainsize() const
Definition Range.h:63
bool operator==(const Range &rhs) const
Definition Range.h:59
const_iterator end() const
Definition Range.h:66
T middle() const
Definition Range.h:60
Range(Range &r, Split)
Split constructor: r[a,b[ -> r[a,b/2[ & this[b/2,b[.
Definition Range.h:52
T const_iterator
Definition Range.h:43
const Range< 1, T > & operator[](int i) const
Definition Range.h:98
bool is_divisible() const
Definition Range.h:97
Range(const Range< 1, T > &rangeRow, const Range< 1, T > &rangeCol)
Definition Range.h:76
Range(T beginRow, T endRow, size_type grainsizeRow, T beginCol, T endCol, size_type grainsizeCol)
Definition Range.h:77
typename Range< 1, T >::size_type size_type
Definition Range.h:75
bool empty() const
Definition Range.h:96
Range(T beginRow, T endRow, T beginCol, T endCol)
Definition Range.h:81
bool operator==(const Range &rhs) const
Definition Range.h:95
Range(Range &r, Split)
Definition Range.h:84
Range(const Range< 1, T > &rangeX, const Range< 1, T > &rangeY, const Range< 1, T > &rangeZ)
Definition Range.h:108
const Range< 1, T > & operator[](int i) const
Definition Range.h:144
bool is_divisible() const
Definition Range.h:143
Range(T beginX, T endX, T beginY, T endY, T beginZ, T endZ)
Definition Range.h:117
typename Range< 1, T >::size_type size_type
Definition Range.h:107
Range(T beginX, T endX, size_type grainsizeX, T beginY, T endY, size_type grainsizeY, T beginZ, T endZ, size_type grainsizeZ)
Definition Range.h:109
bool empty() const
Definition Range.h:142
bool operator==(const Range &rhs) const
Definition Range.h:141
Range(Range &r, Split)
Definition Range.h:121
Definition Range.h:28
Definition Range.h:25
Definition NanoVDB.h:247