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_parallel_for_each_H |
18 | #define __TBB_parallel_for_each_H |
19 | |
20 | #include "parallel_do.h" |
21 | #include "parallel_for.h" |
22 | |
23 | namespace tbb { |
24 | |
25 | //! @cond INTERNAL |
26 | namespace internal { |
27 | // The class calls user function in operator() |
28 | template <typename Function, typename Iterator> |
29 | class parallel_for_each_body_do : internal::no_assign { |
30 | const Function &my_func; |
31 | public: |
32 | parallel_for_each_body_do(const Function &_func) : my_func(_func) {} |
33 | |
34 | void operator()(typename std::iterator_traits<Iterator>::reference value) const { |
35 | my_func(value); |
36 | } |
37 | }; |
38 | |
39 | // The class calls user function in operator() |
40 | template <typename Function, typename Iterator> |
41 | class parallel_for_each_body_for : internal::no_assign { |
42 | const Function &my_func; |
43 | public: |
44 | parallel_for_each_body_for(const Function &_func) : my_func(_func) {} |
45 | |
46 | void operator()(tbb::blocked_range<Iterator> range) const { |
47 | #if __INTEL_COMPILER |
48 | #pragma ivdep |
49 | #endif |
50 | for(Iterator it = range.begin(), end = range.end(); it != end; ++it) { |
51 | my_func(*it); |
52 | } |
53 | } |
54 | }; |
55 | |
56 | template<typename Iterator, typename Function, typename Generic> |
57 | struct parallel_for_each_impl { |
58 | #if __TBB_TASK_GROUP_CONTEXT |
59 | static void doit(Iterator first, Iterator last, const Function& f, task_group_context &context) { |
60 | internal::parallel_for_each_body_do<Function, Iterator> body(f); |
61 | tbb::parallel_do(first, last, body, context); |
62 | } |
63 | #endif |
64 | static void doit(Iterator first, Iterator last, const Function& f) { |
65 | internal::parallel_for_each_body_do<Function, Iterator> body(f); |
66 | tbb::parallel_do(first, last, body); |
67 | } |
68 | }; |
69 | template<typename Iterator, typename Function> |
70 | struct parallel_for_each_impl<Iterator, Function, std::random_access_iterator_tag> { |
71 | #if __TBB_TASK_GROUP_CONTEXT |
72 | static void doit(Iterator first, Iterator last, const Function& f, task_group_context &context) { |
73 | internal::parallel_for_each_body_for<Function, Iterator> body(f); |
74 | tbb::parallel_for(tbb::blocked_range<Iterator>(first, last), body, context); |
75 | } |
76 | #endif |
77 | static void doit(Iterator first, Iterator last, const Function& f) { |
78 | internal::parallel_for_each_body_for<Function, Iterator> body(f); |
79 | tbb::parallel_for(tbb::blocked_range<Iterator>(first, last), body); |
80 | } |
81 | }; |
82 | } // namespace internal |
83 | //! @endcond |
84 | |
85 | /** \name parallel_for_each |
86 | **/ |
87 | //@{ |
88 | //! Calls function f for all items from [first, last) interval using user-supplied context |
89 | /** @ingroup algorithms */ |
90 | #if __TBB_TASK_GROUP_CONTEXT |
91 | template<typename Iterator, typename Function> |
92 | void parallel_for_each(Iterator first, Iterator last, const Function& f, task_group_context &context) { |
93 | internal::parallel_for_each_impl<Iterator, Function, typename std::iterator_traits<Iterator>::iterator_category>::doit(first, last, f, context); |
94 | } |
95 | |
96 | //! Calls function f for all items from rng using user-supplied context |
97 | /** @ingroup algorithms */ |
98 | template<typename Range, typename Function> |
99 | void parallel_for_each(Range& rng, const Function& f, task_group_context& context) { |
100 | parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); |
101 | } |
102 | |
103 | //! Calls function f for all items from const rng user-supplied context |
104 | /** @ingroup algorithms */ |
105 | template<typename Range, typename Function> |
106 | void parallel_for_each(const Range& rng, const Function& f, task_group_context& context) { |
107 | parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context); |
108 | } |
109 | #endif /* __TBB_TASK_GROUP_CONTEXT */ |
110 | |
111 | //! Uses default context |
112 | template<typename Iterator, typename Function> |
113 | void parallel_for_each(Iterator first, Iterator last, const Function& f) { |
114 | internal::parallel_for_each_impl<Iterator, Function, typename std::iterator_traits<Iterator>::iterator_category>::doit(first, last, f); |
115 | } |
116 | |
117 | //! Uses default context |
118 | template<typename Range, typename Function> |
119 | void parallel_for_each(Range& rng, const Function& f) { |
120 | parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); |
121 | } |
122 | |
123 | //! Uses default context |
124 | template<typename Range, typename Function> |
125 | void parallel_for_each(const Range& rng, const Function& f) { |
126 | parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f); |
127 | } |
128 | |
129 | //@} |
130 | |
131 | } // namespace |
132 | |
133 | #endif /* __TBB_parallel_for_each_H */ |
134 | |