STLFunctionalExtras.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/ADT/STLFunctionalExtras.h - Extras for <functional> -*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file contains some extension to <functional>.
  15. //
  16. // No library is required when using these functions.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_ADT_STLFUNCTIONALEXTRAS_H
  20. #define LLVM_ADT_STLFUNCTIONALEXTRAS_H
  21. #include "llvm/ADT/STLForwardCompat.h"
  22. #include <type_traits>
  23. #include <utility>
  24. #include <cstdint>
  25. namespace llvm {
  26. //===----------------------------------------------------------------------===//
  27. // Extra additions to <functional>
  28. //===----------------------------------------------------------------------===//
  29. /// An efficient, type-erasing, non-owning reference to a callable. This is
  30. /// intended for use as the type of a function parameter that is not used
  31. /// after the function in question returns.
  32. ///
  33. /// This class does not own the callable, so it is not in general safe to store
  34. /// a function_ref.
  35. template<typename Fn> class function_ref;
  36. template<typename Ret, typename ...Params>
  37. class function_ref<Ret(Params...)> {
  38. Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
  39. intptr_t callable;
  40. template<typename Callable>
  41. static Ret callback_fn(intptr_t callable, Params ...params) {
  42. return (*reinterpret_cast<Callable*>(callable))(
  43. std::forward<Params>(params)...);
  44. }
  45. public:
  46. function_ref() = default;
  47. function_ref(std::nullptr_t) {}
  48. template <typename Callable>
  49. function_ref(
  50. Callable &&callable,
  51. // This is not the copy-constructor.
  52. std::enable_if_t<!std::is_same<remove_cvref_t<Callable>,
  53. function_ref>::value> * = nullptr,
  54. // Functor must be callable and return a suitable type.
  55. std::enable_if_t<std::is_void<Ret>::value ||
  56. std::is_convertible<decltype(std::declval<Callable>()(
  57. std::declval<Params>()...)),
  58. Ret>::value> * = nullptr)
  59. : callback(callback_fn<typename std::remove_reference<Callable>::type>),
  60. callable(reinterpret_cast<intptr_t>(&callable)) {}
  61. Ret operator()(Params ...params) const {
  62. return callback(callable, std::forward<Params>(params)...);
  63. }
  64. explicit operator bool() const { return callback; }
  65. };
  66. } // end namespace llvm
  67. #endif // LLVM_ADT_STLFUNCTIONALEXTRAS_H
  68. #ifdef __GNUC__
  69. #pragma GCC diagnostic pop
  70. #endif