• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google Inc. All rights reserved.
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 FRUIT_META_FOLD_H
18 #define FRUIT_META_FOLD_H
19 
20 #include <functional>
21 
22 namespace fruit {
23 namespace impl {
24 namespace meta {
25 
26 struct Fold {
27   template <typename F, typename InitialValue, typename... Types>
28   struct apply;
29 
30   template <typename F, typename InitialValue>
31   struct apply<F, InitialValue> {
32     using type = InitialValue;
33   };
34 
35   template <typename F, typename InitialValue, typename T0>
36   struct apply<F, InitialValue, T0> {
37     using type = typename F::template apply<InitialValue, T0>::type;
38   };
39 
40   template <typename F, typename InitialValue, typename T0, typename T1>
41   struct apply<F, InitialValue, T0, T1> {
42     using type =
43         typename F::template apply<typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type;
44   };
45 
46   template <typename F, typename InitialValue, typename T0, typename T1, typename T2>
47   struct apply<F, InitialValue, T0, T1, T2> {
48     using type = typename F::template apply<
49         typename DoEval<typename F::template apply<
50             typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
51         T2>::type;
52   };
53 
54   template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3>
55   struct apply<F, InitialValue, T0, T1, T2, T3> {
56     using type = typename F::template apply<
57         typename DoEval<typename F::template apply<
58             typename DoEval<typename F::template apply<
59                 typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
60             T2>::type>::type,
61         T3>::type;
62   };
63 
64   template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4>
65   struct apply<F, InitialValue, T0, T1, T2, T3, T4> {
66     using type = typename F::template apply<
67         typename DoEval<typename F::template apply<
68             typename DoEval<typename F::template apply<
69                 typename DoEval<typename F::template apply<
70                     typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
71                 T2>::type>::type,
72             T3>::type>::type,
73         T4>::type;
74   };
75 
76   template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4,
77             typename... Types>
78   struct apply<F, InitialValue, T0, T1, T2, T3, T4, Types...> {
79     using type = Fold(
80         F, typename F::template apply<
81                typename DoEval<typename F::template apply<
82                    typename DoEval<typename F::template apply<
83                        typename DoEval<typename F::template apply<
84                            typename DoEval<typename F::template apply<InitialValue, T0>::type>::type, T1>::type>::type,
85                        T2>::type>::type,
86                    T3>::type>::type,
87                T4>::type,
88         Types...);
89   };
90 
91   // Optimized specialization, processing 10 values at a time.
92   template <typename F, typename InitialValue, typename T0, typename T1, typename T2, typename T3, typename T4,
93             typename T5, typename T6, typename T7, typename T8, typename T9, typename... Types>
94   struct apply<F, InitialValue, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Types...> {
95     using type = Fold(
96         F,
97         typename F::template apply<
98             typename DoEval<typename F::template apply<
99                 typename DoEval<typename F::template apply<
100                     typename DoEval<typename F::template apply<
101                         typename DoEval<typename F::template apply<
102                             typename DoEval<typename F::template apply<
103                                 typename DoEval<typename F::template apply<
104                                     typename DoEval<typename F::template apply<
105                                         typename DoEval<typename F::template apply<
106                                             typename DoEval<typename F::template apply<InitialValue, T0>::type>::type,
107                                             T1>::type>::type,
108                                         T2>::type>::type,
109                                     T3>::type>::type,
110                                 T4>::type>::type,
111                             T5>::type>::type,
112                         T6>::type>::type,
113                     T7>::type>::type,
114                 T8>::type>::type,
115             T9>::type,
116         Types...);
117   };
118 };
119 
120 } // namespace meta
121 } // namespace impl
122 } // namespace fruit
123 
124 #endif // FRUIT_META_FOLD_H
125