/* * Copyright 2022 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 #include namespace android::ftl { // Concise alternative to std::visit that compiles to branches rather than a dispatch table. For // std::variant where N is small, this is slightly faster since the branches can be // inlined unlike the function pointers. // // using namespace std::chrono; // std::variant duration = 119min; // // // Mutable match. // ftl::match(duration, [](auto& d) { ++d; }); // // // Immutable match. Exhaustive due to minutes being convertible to seconds. // assert("2 hours"s == // ftl::match(duration, // [](const seconds& s) { // const auto h = duration_cast(s); // return std::to_string(h.count()) + " hours"s; // }, // [](const hours& h) { return std::to_string(h.count() / 24) + " days"s; })); // template decltype(auto) match(std::variant& variant, Ms&&... matchers) { const auto matcher = details::Matcher{std::forward(matchers)...}; static_assert(details::is_exhaustive_match_v, "Non-exhaustive match"); return details::Match::match(variant, matcher); } template decltype(auto) match(const std::variant& variant, Ms&&... matchers) { const auto matcher = details::Matcher{std::forward(matchers)...}; static_assert(details::is_exhaustive_match_v, "Non-exhaustive match"); return details::Match::match(variant, matcher); } } // namespace android::ftl