Don't explicitly disable the C++1y-extensions warning in ForEach-inl and WhenN-inl
[folly.git] / folly / fibers / ForEach-inl.h
1 /*
2  * Copyright 2017 Facebook, Inc.
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 #include <folly/fibers/FiberManagerInternal.h>
17
18 namespace folly {
19 namespace fibers {
20
21 namespace {
22
23 template <class F, class G>
24 typename std::enable_if<
25     !std::is_same<typename std::result_of<F()>::type, void>::value,
26     void>::type inline callFuncs(F&& f, G&& g, size_t id) {
27   g(id, f());
28 }
29
30 template <class F, class G>
31 typename std::enable_if<
32     std::is_same<typename std::result_of<F()>::type, void>::value,
33     void>::type inline callFuncs(F&& f, G&& g, size_t id) {
34   f();
35   g(id);
36 }
37
38 } // anonymous namespace
39
40 template <class InputIterator, class F>
41 inline void forEach(InputIterator first, InputIterator last, F&& f) {
42   if (first == last) {
43     return;
44   }
45
46   typedef typename std::iterator_traits<InputIterator>::value_type FuncType;
47
48   size_t tasksTodo = 1;
49   std::exception_ptr e;
50   Baton baton;
51
52   auto taskFunc = [&tasksTodo, &e, &f, &baton](size_t id, FuncType&& func) {
53     return [
54       id,
55       &tasksTodo,
56       &e,
57       &f,
58       &baton,
59       func_ = std::forward<FuncType>(func)
60     ]() mutable {
61       try {
62         callFuncs(std::forward<FuncType>(func_), f, id);
63       } catch (...) {
64         e = std::current_exception();
65       }
66       if (--tasksTodo == 0) {
67         baton.post();
68       }
69     };
70   };
71
72   auto firstTask = first;
73   ++first;
74
75   for (size_t i = 1; first != last; ++i, ++first, ++tasksTodo) {
76     addTask(taskFunc(i, std::move(*first)));
77   }
78
79   taskFunc(0, std::move(*firstTask))();
80   baton.wait();
81
82   if (e != std::exception_ptr()) {
83     std::rethrow_exception(e);
84   }
85 }
86 }
87 } // folly::fibers