Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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