1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2022 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <type_traits> 20*38e8c45fSAndroid Build Coastguard Worker #include <variant> 21*38e8c45fSAndroid Build Coastguard Worker 22*38e8c45fSAndroid Build Coastguard Worker namespace android::ftl::details { 23*38e8c45fSAndroid Build Coastguard Worker 24*38e8c45fSAndroid Build Coastguard Worker template <typename... Ms> 25*38e8c45fSAndroid Build Coastguard Worker struct Matcher : Ms... { 26*38e8c45fSAndroid Build Coastguard Worker using Ms::operator()...; 27*38e8c45fSAndroid Build Coastguard Worker }; 28*38e8c45fSAndroid Build Coastguard Worker 29*38e8c45fSAndroid Build Coastguard Worker // Deduction guide. 30*38e8c45fSAndroid Build Coastguard Worker template <typename... Ms> 31*38e8c45fSAndroid Build Coastguard Worker Matcher(Ms...) -> Matcher<Ms...>; 32*38e8c45fSAndroid Build Coastguard Worker 33*38e8c45fSAndroid Build Coastguard Worker template <typename Matcher, typename... Ts> 34*38e8c45fSAndroid Build Coastguard Worker constexpr bool is_exhaustive_match_v = (std::is_invocable_v<Matcher, Ts> && ...); 35*38e8c45fSAndroid Build Coastguard Worker 36*38e8c45fSAndroid Build Coastguard Worker template <typename...> 37*38e8c45fSAndroid Build Coastguard Worker struct Match; 38*38e8c45fSAndroid Build Coastguard Worker 39*38e8c45fSAndroid Build Coastguard Worker template <typename T, typename U, typename... Ts> 40*38e8c45fSAndroid Build Coastguard Worker struct Match<T, U, Ts...> { 41*38e8c45fSAndroid Build Coastguard Worker template <typename Variant, typename Matcher> 42*38e8c45fSAndroid Build Coastguard Worker static decltype(auto) match(Variant& variant, const Matcher& matcher) { 43*38e8c45fSAndroid Build Coastguard Worker if (auto* const ptr = std::get_if<T>(&variant)) { 44*38e8c45fSAndroid Build Coastguard Worker return matcher(*ptr); 45*38e8c45fSAndroid Build Coastguard Worker } else { 46*38e8c45fSAndroid Build Coastguard Worker return Match<U, Ts...>::match(variant, matcher); 47*38e8c45fSAndroid Build Coastguard Worker } 48*38e8c45fSAndroid Build Coastguard Worker } 49*38e8c45fSAndroid Build Coastguard Worker }; 50*38e8c45fSAndroid Build Coastguard Worker 51*38e8c45fSAndroid Build Coastguard Worker template <typename T> 52*38e8c45fSAndroid Build Coastguard Worker struct Match<T> { 53*38e8c45fSAndroid Build Coastguard Worker template <typename Variant, typename Matcher> 54*38e8c45fSAndroid Build Coastguard Worker static decltype(auto) match(Variant& variant, const Matcher& matcher) { 55*38e8c45fSAndroid Build Coastguard Worker return matcher(std::get<T>(variant)); 56*38e8c45fSAndroid Build Coastguard Worker } 57*38e8c45fSAndroid Build Coastguard Worker }; 58*38e8c45fSAndroid Build Coastguard Worker 59*38e8c45fSAndroid Build Coastguard Worker } // namespace android::ftl::details 60