1 // Copyright 2023 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // ----------------------------------------------------------------------------- 16 // File: overload.h 17 // ----------------------------------------------------------------------------- 18 // 19 // `absl::Overload` is a functor that provides overloads based on the functors 20 // with which it is created. This can, for example, be used to locally define an 21 // anonymous visitor type for `std::visit` inside a function using lambdas. 22 // 23 // Before using this function, consider whether named function overloads would 24 // be a better design. 25 // 26 // Example: 27 // 28 // std::variant<std::string, int32_t, int64_t> v(int32_t{1}); 29 // const size_t result = 30 // std::visit(absl::Overload{ 31 // [](const std::string& s) { return s.size(); }, 32 // [](const auto& s) { return sizeof(s); }, 33 // }, 34 // v); 35 // assert(result == 4); 36 // 37 38 #ifndef ABSL_FUNCTIONAL_OVERLOAD_H_ 39 #define ABSL_FUNCTIONAL_OVERLOAD_H_ 40 41 #include "absl/base/config.h" 42 #include "absl/meta/type_traits.h" 43 44 namespace absl { 45 ABSL_NAMESPACE_BEGIN 46 47 template <typename... T> 48 struct Overload final : T... { 49 using T::operator()...; 50 51 // For historical reasons we want to support use that looks like a function 52 // call: 53 // 54 // absl::Overload(lambda_1, lambda_2) 55 // 56 // This works automatically in C++20 because we have support for parenthesized 57 // aggregate initialization. Before then we must provide a constructor that 58 // makes this work. 59 // 60 constexpr explicit Overload(T... ts) : T(std::move(ts))... {} 61 }; 62 63 // Before C++20, which added support for CTAD for aggregate types, we must also 64 // teach the compiler how to deduce the template arguments for Overload. 65 // 66 template <typename... T> 67 Overload(T...) -> Overload<T...>; 68 69 ABSL_NAMESPACE_END 70 } // namespace absl 71 72 #endif // ABSL_FUNCTIONAL_OVERLOAD_H_ 73