/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include namespace cuttlefish { /** * This is a template helper to add bindings for a set of implementation * classes that may each be part of multiple multibindings. To be more specific, * for these example classes: * * class ImplementationA : public IntX, IntY {}; * class ImplementationB : public IntY, IntZ {}; * * can be installed with * * using Deps = fruit::Required<...>; * using Bases = Multibindings::Bases; * return fruit::createComponent() * .install(Bases::Impls); * * Note that not all implementations have to implement all interfaces. Invalid * combinations are filtered out at compile-time through SFINAE. */ template struct Multibindings { /* SFINAE logic for an individual interface binding. The class does implement * the interface, so add a multibinding. */ template ::value, bool> = true> static fruit::Component OneBaseOneImpl() { return fruit::createComponent().addMultibinding(); } /* SFINAE logic for an individual interface binding. The class does not * implement the interface, so do not add a multibinding. */ template ::value, bool> = true> static fruit::Component OneBaseOneImpl() { return fruit::createComponent(); } template struct OneBase { template static fruit::Component Impls() { return fruit::createComponent().installComponentFunctions( fruit::componentFunction(OneBaseOneImpl)...); } }; template struct Bases { template static fruit::Component Impls() { return fruit::createComponent().installComponentFunctions( fruit::componentFunction( OneBase::template Impls)...); } }; }; } // namespace cuttlefish