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