1*a65addddSAndroid Build Coastguard Worker /* 2*a65addddSAndroid Build Coastguard Worker * Copyright 2014 Google Inc. All rights reserved. 3*a65addddSAndroid Build Coastguard Worker * 4*a65addddSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*a65addddSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*a65addddSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*a65addddSAndroid Build Coastguard Worker * 8*a65addddSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*a65addddSAndroid Build Coastguard Worker * 10*a65addddSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*a65addddSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*a65addddSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*a65addddSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*a65addddSAndroid Build Coastguard Worker * limitations under the License. 15*a65addddSAndroid Build Coastguard Worker */ 16*a65addddSAndroid Build Coastguard Worker 17*a65addddSAndroid Build Coastguard Worker #ifndef FRUIT_META_METAPROGRAMMING_H 18*a65addddSAndroid Build Coastguard Worker #define FRUIT_META_METAPROGRAMMING_H 19*a65addddSAndroid Build Coastguard Worker 20*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/meta/basics.h> 21*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/meta/vector.h> 22*a65addddSAndroid Build Coastguard Worker 23*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/fruit_assert.h> 24*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/fruit_internal_forward_decls.h> 25*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/injection_errors.h> 26*a65addddSAndroid Build Coastguard Worker #include <fruit/impl/meta/errors.h> 27*a65addddSAndroid Build Coastguard Worker 28*a65addddSAndroid Build Coastguard Worker #include <memory> 29*a65addddSAndroid Build Coastguard Worker 30*a65addddSAndroid Build Coastguard Worker namespace fruit { 31*a65addddSAndroid Build Coastguard Worker namespace impl { 32*a65addddSAndroid Build Coastguard Worker namespace meta { 33*a65addddSAndroid Build Coastguard Worker 34*a65addddSAndroid Build Coastguard Worker struct IsConstructible { 35*a65addddSAndroid Build Coastguard Worker template <typename C, typename... Args> 36*a65addddSAndroid Build Coastguard Worker struct apply; 37*a65addddSAndroid Build Coastguard Worker 38*a65addddSAndroid Build Coastguard Worker template <typename C, typename... Args> 39*a65addddSAndroid Build Coastguard Worker struct apply<Type<C>, Type<Args>...> { 40*a65addddSAndroid Build Coastguard Worker using type = Bool<std::is_constructible<C, Args...>::value>; 41*a65addddSAndroid Build Coastguard Worker }; 42*a65addddSAndroid Build Coastguard Worker }; 43*a65addddSAndroid Build Coastguard Worker 44*a65addddSAndroid Build Coastguard Worker struct IsConstructibleWithVector { 45*a65addddSAndroid Build Coastguard Worker template <typename C, typename V> 46*a65addddSAndroid Build Coastguard Worker struct apply; 47*a65addddSAndroid Build Coastguard Worker 48*a65addddSAndroid Build Coastguard Worker template <typename C, typename... Types> 49*a65addddSAndroid Build Coastguard Worker struct apply<Type<C>, Vector<Type<Types>...>> { 50*a65addddSAndroid Build Coastguard Worker using type = Bool<std::is_constructible<C, Types...>::value>; 51*a65addddSAndroid Build Coastguard Worker }; 52*a65addddSAndroid Build Coastguard Worker }; 53*a65addddSAndroid Build Coastguard Worker 54*a65addddSAndroid Build Coastguard Worker struct AddPointer { 55*a65addddSAndroid Build Coastguard Worker template <typename T> 56*a65addddSAndroid Build Coastguard Worker struct apply; 57*a65addddSAndroid Build Coastguard Worker 58*a65addddSAndroid Build Coastguard Worker template <typename T> 59*a65addddSAndroid Build Coastguard Worker struct apply<Type<T>> { 60*a65addddSAndroid Build Coastguard Worker using type = Type<T*>; 61*a65addddSAndroid Build Coastguard Worker }; 62*a65addddSAndroid Build Coastguard Worker }; 63*a65addddSAndroid Build Coastguard Worker 64*a65addddSAndroid Build Coastguard Worker struct IsCallable { 65*a65addddSAndroid Build Coastguard Worker template <typename T> 66*a65addddSAndroid Build Coastguard Worker struct apply; 67*a65addddSAndroid Build Coastguard Worker 68*a65addddSAndroid Build Coastguard Worker template <typename C> 69*a65addddSAndroid Build Coastguard Worker struct apply<Type<C>> { 70*a65addddSAndroid Build Coastguard Worker template <typename C1> 71*a65addddSAndroid Build Coastguard Worker static Bool<true> test(decltype(&C1::operator())); 72*a65addddSAndroid Build Coastguard Worker 73*a65addddSAndroid Build Coastguard Worker template <typename> 74*a65addddSAndroid Build Coastguard Worker static Bool<false> test(...); 75*a65addddSAndroid Build Coastguard Worker 76*a65addddSAndroid Build Coastguard Worker using type = decltype(test<C>(nullptr)); 77*a65addddSAndroid Build Coastguard Worker }; 78*a65addddSAndroid Build Coastguard Worker }; 79*a65addddSAndroid Build Coastguard Worker 80*a65addddSAndroid Build Coastguard Worker struct GetCallOperatorSignature { 81*a65addddSAndroid Build Coastguard Worker template <typename T> 82*a65addddSAndroid Build Coastguard Worker struct apply; 83*a65addddSAndroid Build Coastguard Worker 84*a65addddSAndroid Build Coastguard Worker template <typename C> 85*a65addddSAndroid Build Coastguard Worker struct apply<Type<C>> { 86*a65addddSAndroid Build Coastguard Worker using type = Type<decltype(&C::operator())>; 87*a65addddSAndroid Build Coastguard Worker }; 88*a65addddSAndroid Build Coastguard Worker }; 89*a65addddSAndroid Build Coastguard Worker 90*a65addddSAndroid Build Coastguard Worker struct AddPointerToVector { 91*a65addddSAndroid Build Coastguard Worker template <typename V> 92*a65addddSAndroid Build Coastguard Worker struct apply; 93*a65addddSAndroid Build Coastguard Worker 94*a65addddSAndroid Build Coastguard Worker template <typename... Ts> 95*a65addddSAndroid Build Coastguard Worker struct apply<Vector<Type<Ts>...>> { 96*a65addddSAndroid Build Coastguard Worker using type = Vector<Type<Ts*>...>; 97*a65addddSAndroid Build Coastguard Worker }; 98*a65addddSAndroid Build Coastguard Worker }; 99*a65addddSAndroid Build Coastguard Worker 100*a65addddSAndroid Build Coastguard Worker struct GetNthTypeHelper { 101*a65addddSAndroid Build Coastguard Worker template <typename N, typename... Ts> 102*a65addddSAndroid Build Coastguard Worker struct apply; 103*a65addddSAndroid Build Coastguard Worker 104*a65addddSAndroid Build Coastguard Worker template <typename T, typename... Ts> 105*a65addddSAndroid Build Coastguard Worker struct apply<Int<0>, T, Ts...> { 106*a65addddSAndroid Build Coastguard Worker using type = T; 107*a65addddSAndroid Build Coastguard Worker }; 108*a65addddSAndroid Build Coastguard Worker 109*a65addddSAndroid Build Coastguard Worker template <int n, typename T, typename... Ts> 110*a65addddSAndroid Build Coastguard Worker struct apply<Int<n>, T, Ts...> { 111*a65addddSAndroid Build Coastguard Worker using type = GetNthTypeHelper(Int<n - 1>, Ts...); 112*a65addddSAndroid Build Coastguard Worker }; 113*a65addddSAndroid Build Coastguard Worker }; 114*a65addddSAndroid Build Coastguard Worker 115*a65addddSAndroid Build Coastguard Worker struct GetNthType { 116*a65addddSAndroid Build Coastguard Worker template <typename N, typename V> 117*a65addddSAndroid Build Coastguard Worker struct apply; 118*a65addddSAndroid Build Coastguard Worker 119*a65addddSAndroid Build Coastguard Worker template <typename N, typename... Ts> 120*a65addddSAndroid Build Coastguard Worker struct apply<N, Vector<Ts...>> { 121*a65addddSAndroid Build Coastguard Worker using type = GetNthTypeHelper(N, Ts...); 122*a65addddSAndroid Build Coastguard Worker }; 123*a65addddSAndroid Build Coastguard Worker }; 124*a65addddSAndroid Build Coastguard Worker 125*a65addddSAndroid Build Coastguard Worker struct FunctorResultHelper { 126*a65addddSAndroid Build Coastguard Worker template <typename MethodSignature> 127*a65addddSAndroid Build Coastguard Worker struct apply; 128*a65addddSAndroid Build Coastguard Worker 129*a65addddSAndroid Build Coastguard Worker template <typename Result, typename Functor, typename... Args> 130*a65addddSAndroid Build Coastguard Worker struct apply<Type<Result (Functor::*)(Args...)>> { 131*a65addddSAndroid Build Coastguard Worker using type = Type<Result>; 132*a65addddSAndroid Build Coastguard Worker }; 133*a65addddSAndroid Build Coastguard Worker }; 134*a65addddSAndroid Build Coastguard Worker 135*a65addddSAndroid Build Coastguard Worker struct FunctorResult { 136*a65addddSAndroid Build Coastguard Worker template <typename F> 137*a65addddSAndroid Build Coastguard Worker struct apply; 138*a65addddSAndroid Build Coastguard Worker 139*a65addddSAndroid Build Coastguard Worker template <typename F> 140*a65addddSAndroid Build Coastguard Worker struct apply<Type<F>> { 141*a65addddSAndroid Build Coastguard Worker using type = FunctorResultHelper(Type<decltype(&F::operator())>); 142*a65addddSAndroid Build Coastguard Worker }; 143*a65addddSAndroid Build Coastguard Worker }; 144*a65addddSAndroid Build Coastguard Worker 145*a65addddSAndroid Build Coastguard Worker struct FunctionSignatureHelper { 146*a65addddSAndroid Build Coastguard Worker template <typename LambdaMethod> 147*a65addddSAndroid Build Coastguard Worker struct apply; 148*a65addddSAndroid Build Coastguard Worker 149*a65addddSAndroid Build Coastguard Worker template <typename Result, typename LambdaObject, typename... Args> 150*a65addddSAndroid Build Coastguard Worker struct apply<Type<Result (LambdaObject::*)(Args...) const>> { 151*a65addddSAndroid Build Coastguard Worker using type = Type<Result(Args...)>; 152*a65addddSAndroid Build Coastguard Worker }; 153*a65addddSAndroid Build Coastguard Worker }; 154*a65addddSAndroid Build Coastguard Worker 155*a65addddSAndroid Build Coastguard Worker // Function is either a plain function type of the form T(*)(Args...) or a lambda. 156*a65addddSAndroid Build Coastguard Worker struct FunctionSignature { 157*a65addddSAndroid Build Coastguard Worker template <typename Function> 158*a65addddSAndroid Build Coastguard Worker struct apply; 159*a65addddSAndroid Build Coastguard Worker 160*a65addddSAndroid Build Coastguard Worker template <typename Function> 161*a65addddSAndroid Build Coastguard Worker struct apply<Type<Function>> { 162*a65addddSAndroid Build Coastguard Worker using CandidateSignature = FunctionSignatureHelper(GetCallOperatorSignature(Type<Function>)); 163*a65addddSAndroid Build Coastguard Worker using type = If(Not(IsCallable(Type<Function>)), ConstructError(NotALambdaErrorTag, Type<Function>), 164*a65addddSAndroid Build Coastguard Worker If(Not(IsConstructible(AddPointer(CandidateSignature), Type<Function>)), 165*a65addddSAndroid Build Coastguard Worker ConstructError(FunctorUsedAsProviderErrorTag, Type<Function>), CandidateSignature)); 166*a65addddSAndroid Build Coastguard Worker }; 167*a65addddSAndroid Build Coastguard Worker 168*a65addddSAndroid Build Coastguard Worker template <typename Result, typename... Args> 169*a65addddSAndroid Build Coastguard Worker struct apply<Type<Result(Args...)>> { 170*a65addddSAndroid Build Coastguard Worker using type = Type<Result(Args...)>; 171*a65addddSAndroid Build Coastguard Worker }; 172*a65addddSAndroid Build Coastguard Worker 173*a65addddSAndroid Build Coastguard Worker template <typename Result, typename... Args> 174*a65addddSAndroid Build Coastguard Worker struct apply<Type<Result (*)(Args...)>> { 175*a65addddSAndroid Build Coastguard Worker using type = Type<Result(Args...)>; 176*a65addddSAndroid Build Coastguard Worker }; 177*a65addddSAndroid Build Coastguard Worker }; 178*a65addddSAndroid Build Coastguard Worker 179*a65addddSAndroid Build Coastguard Worker } // namespace meta 180*a65addddSAndroid Build Coastguard Worker } // namespace impl 181*a65addddSAndroid Build Coastguard Worker } // namespace fruit 182*a65addddSAndroid Build Coastguard Worker 183*a65addddSAndroid Build Coastguard Worker #endif // FRUIT_META_METAPROGRAMMING_H 184