1/*
2 Copyright (c) 2005-2019 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#ifndef __TBB_blocked_range3d_H
18#define __TBB_blocked_range3d_H
19
20#include "tbb_stddef.h"
21#include "blocked_range.h"
22
23namespace tbb {
24
25//! A 3-dimensional range that models the Range concept.
26/** @ingroup algorithms */
27template<typename PageValue, typename RowValue=PageValue, typename ColValue=RowValue>
28class blocked_range3d {
29public:
30 //! Type for size of an iteration range
31 typedef blocked_range<PageValue> page_range_type;
32 typedef blocked_range<RowValue> row_range_type;
33 typedef blocked_range<ColValue> col_range_type;
34
35private:
36 page_range_type my_pages;
37 row_range_type my_rows;
38 col_range_type my_cols;
39
40public:
41
42 blocked_range3d( PageValue page_begin, PageValue page_end,
43 RowValue row_begin, RowValue row_end,
44 ColValue col_begin, ColValue col_end ) :
45 my_pages(page_begin,page_end),
46 my_rows(row_begin,row_end),
47 my_cols(col_begin,col_end)
48 {}
49
50 blocked_range3d( PageValue page_begin, PageValue page_end, typename page_range_type::size_type page_grainsize,
51 RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize,
52 ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) :
53 my_pages(page_begin,page_end,page_grainsize),
54 my_rows(row_begin,row_end,row_grainsize),
55 my_cols(col_begin,col_end,col_grainsize)
56 {}
57
58 //! True if range is empty
59 bool empty() const {
60 // Range is empty if at least one dimension is empty.
61 return my_pages.empty() || my_rows.empty() || my_cols.empty();
62 }
63
64 //! True if range is divisible into two pieces.
65 bool is_divisible() const {
66 return my_pages.is_divisible() || my_rows.is_divisible() || my_cols.is_divisible();
67 }
68
69 blocked_range3d( blocked_range3d& r, split ) :
70 my_pages(r.my_pages),
71 my_rows(r.my_rows),
72 my_cols(r.my_cols)
73 {
74 split split_obj;
75 do_split(r, split_obj);
76 }
77
78#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
79 //! Static field to support proportional split
80 static const bool is_splittable_in_proportion = true;
81
82 blocked_range3d( blocked_range3d& r, proportional_split& proportion ) :
83 my_pages(r.my_pages),
84 my_rows(r.my_rows),
85 my_cols(r.my_cols)
86 {
87 do_split(r, proportion);
88 }
89#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
90
91 //! The pages of the iteration space
92 const page_range_type& pages() const {return my_pages;}
93
94 //! The rows of the iteration space
95 const row_range_type& rows() const {return my_rows;}
96
97 //! The columns of the iteration space
98 const col_range_type& cols() const {return my_cols;}
99
100private:
101
102 template <typename Split>
103 void do_split( blocked_range3d& r, Split& split_obj)
104 {
105 if ( my_pages.size()*double(my_rows.grainsize()) < my_rows.size()*double(my_pages.grainsize()) ) {
106 if ( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) {
107 my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj);
108 } else {
109 my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj);
110 }
111 } else {
112 if ( my_pages.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_pages.grainsize()) ) {
113 my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj);
114 } else {
115 my_pages.my_begin = page_range_type::do_split(r.my_pages, split_obj);
116 }
117 }
118 }
119};
120
121} // namespace tbb
122
123#endif /* __TBB_blocked_range3d_H */
124