overload.h 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. // Note: absl::Overload requires C++17.
  27. //
  28. // Example:
  29. //
  30. // std::variant<std::string, int32_t, int64_t> v(int32_t{1});
  31. // const size_t result =
  32. // std::visit(absl::Overload{
  33. // [](const std::string& s) { return s.size(); },
  34. // [](const auto& s) { return sizeof(s); },
  35. // },
  36. // v);
  37. // assert(result == 4);
  38. //
  39. #ifndef ABSL_FUNCTIONAL_OVERLOAD_H_
  40. #define ABSL_FUNCTIONAL_OVERLOAD_H_
  41. #include "absl/base/config.h"
  42. #include "absl/meta/type_traits.h"
  43. namespace absl {
  44. ABSL_NAMESPACE_BEGIN
  45. #if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
  46. ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
  47. template <typename... T>
  48. struct Overload final : T... {
  49. using T::operator()...;
  50. // For historical reasons we want to support use that looks like a function
  51. // call:
  52. //
  53. // absl::Overload(lambda_1, lambda_2)
  54. //
  55. // This works automatically in C++20 because we have support for parenthesized
  56. // aggregate initialization. Before then we must provide a constructor that
  57. // makes this work.
  58. //
  59. constexpr explicit Overload(T... ts) : T(std::move(ts))... {}
  60. };
  61. // Before C++20, which added support for CTAD for aggregate types, we must also
  62. // teach the compiler how to deduce the template arguments for Overload.
  63. //
  64. template <typename... T>
  65. Overload(T...) -> Overload<T...>;
  66. #else
  67. namespace functional_internal {
  68. template <typename T>
  69. constexpr bool kDependentFalse = false;
  70. }
  71. template <typename Dependent = int, typename... T>
  72. auto Overload(T&&...) {
  73. static_assert(functional_internal::kDependentFalse<Dependent>,
  74. "Overload is only usable with C++17 or above.");
  75. }
  76. #endif
  77. ABSL_NAMESPACE_END
  78. } // namespace absl
  79. #endif // ABSL_FUNCTIONAL_OVERLOAD_H_