1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_FUNCTIONAL_OVERLOADED_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_FUNCTIONAL_OVERLOADED_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker namespace base { 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker // absl::visit() needs to be called with a functor object, such as 11*6777b538SAndroid Build Coastguard Worker // 12*6777b538SAndroid Build Coastguard Worker // struct Visitor { 13*6777b538SAndroid Build Coastguard Worker // std::string operator()(const PackageA& source) { 14*6777b538SAndroid Build Coastguard Worker // return "PackageA"; 15*6777b538SAndroid Build Coastguard Worker // } 16*6777b538SAndroid Build Coastguard Worker // 17*6777b538SAndroid Build Coastguard Worker // std::string operator()(const PackageB& source) { 18*6777b538SAndroid Build Coastguard Worker // return "PackageB"; 19*6777b538SAndroid Build Coastguard Worker // } 20*6777b538SAndroid Build Coastguard Worker // }; 21*6777b538SAndroid Build Coastguard Worker // 22*6777b538SAndroid Build Coastguard Worker // absl::variant<PackageA, PackageB> var = PackageA(); 23*6777b538SAndroid Build Coastguard Worker // return absl::visit(Visitor(), var); 24*6777b538SAndroid Build Coastguard Worker // 25*6777b538SAndroid Build Coastguard Worker // `Overloaded` enables the above code to be written as: 26*6777b538SAndroid Build Coastguard Worker // 27*6777b538SAndroid Build Coastguard Worker // absl::visit( 28*6777b538SAndroid Build Coastguard Worker // Overloaded{ 29*6777b538SAndroid Build Coastguard Worker // [](const PackageA& pack) { return "PackageA"; }, 30*6777b538SAndroid Build Coastguard Worker // [](const PackageB& pack) { return "PackageB"; }, 31*6777b538SAndroid Build Coastguard Worker // }, var); 32*6777b538SAndroid Build Coastguard Worker // 33*6777b538SAndroid Build Coastguard Worker // Note: Overloads must be implemented for all the variant options. Otherwise, 34*6777b538SAndroid Build Coastguard Worker // there will be a compilation error. 35*6777b538SAndroid Build Coastguard Worker // 36*6777b538SAndroid Build Coastguard Worker // This struct inherits operator() method from all its base classes. 37*6777b538SAndroid Build Coastguard Worker // Introduces operator() method from all its base classes into its definition. 38*6777b538SAndroid Build Coastguard Worker template <typename... Callables> 39*6777b538SAndroid Build Coastguard Worker struct Overloaded : Callables... { 40*6777b538SAndroid Build Coastguard Worker using Callables::operator()...; 41*6777b538SAndroid Build Coastguard Worker }; 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker // Uses template argument deduction so that the `Overloaded` struct can be used 44*6777b538SAndroid Build Coastguard Worker // without specifying its template argument. This allows anonymous lambdas 45*6777b538SAndroid Build Coastguard Worker // passed into the `Overloaded` constructor. 46*6777b538SAndroid Build Coastguard Worker template <typename... Callables> 47*6777b538SAndroid Build Coastguard Worker Overloaded(Callables...) -> Overloaded<Callables...>; 48*6777b538SAndroid Build Coastguard Worker 49*6777b538SAndroid Build Coastguard Worker } // namespace base 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker #endif // BASE_FUNCTIONAL_OVERLOADED_H_ 52