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