Advertisement
qdmitry

for_each_impl

Feb 26th, 2021
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.20 KB | None | 0 0
  1. #include <algorithm>
  2. #include <execution>
  3. #include <iostream>
  4. #include <string>
  5. #include <string_view>
  6. #include <vector>
  7. #include <future>
  8. #include <iterator>
  9.  
  10. using namespace std;
  11.  
  12. vector<int> makeBuckets(int max, int numberOfBuckets) {
  13.     int e = max / numberOfBuckets;
  14.     vector<int> b(numberOfBuckets, e);
  15.     fill(b.begin(), b.begin() + (max % numberOfBuckets), e + 1);
  16.     return b;
  17. }
  18.  
  19. template <typename ForwardRange, typename Function>
  20. void ForEachImpl(ForwardRange& range, Function function) {
  21.     static constexpr int PART_COUNT = 4;
  22.     const auto part_length = range.size() / PART_COUNT;
  23.     auto part_begin = range.begin();
  24.     auto part_end = next(part_begin, part_length);
  25.  
  26.     vector<future<void>> futures;
  27.     for (
  28.         int i = 0;
  29.         i < PART_COUNT;
  30.         ++i,
  31.             part_begin = part_end,
  32.             part_end = (i == PART_COUNT - 1
  33.                         ? range.end()
  34.                         : next(part_begin, part_length))
  35.     ) {
  36.         futures.push_back(async([function, part_begin, part_end] { for_each(part_begin, part_end, function); }));
  37.     }
  38. }
  39.  
  40.  
  41. template <typename ExecutionPolicy, typename ForwardRange, typename Function>
  42. void ForEach(ExecutionPolicy&&, ForwardRange& range, Function function)
  43. {
  44.     using category = typename std::iterator_traits<typename ForwardRange::iterator>::iterator_category;
  45.     if constexpr ((false == std::is_same_v<category, std::random_access_iterator_tag>) && (is_same_v<decay_t<ExecutionPolicy>, execution::parallel_policy>)) {
  46.         ForEachImpl(range, function);
  47.     } else {
  48.         for_each(range.begin(), range.end(), function);
  49.     }
  50. }
  51.  
  52. template <typename ForwardRange, typename Function>
  53. void ForEach(ForwardRange& range, Function function) {
  54.     ForEach(execution::seq, range, function);
  55. }
  56.  
  57.  
  58. int main() {
  59.     // для итераторов с произвольным доступом тоже должно работать
  60.     vector<string> strings = {"cat", "dog", "code"};
  61.  
  62.     ForEach(strings, [](string& s) { reverse(s.begin(), s.end()); });
  63.  
  64.     for (string_view s : strings) {
  65.         cout << s << " ";
  66.     }
  67.     cout << endl;
  68.    
  69.     // вывод: tac god edoc
  70.  
  71.     return 0;
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement