tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

function_ref.h (6071B)


      1 // Copyright 2019 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: function_ref.h
     17 // -----------------------------------------------------------------------------
     18 //
     19 // This header file defines the `absl::FunctionRef` type for holding a
     20 // non-owning reference to an object of any invocable type. This function
     21 // reference is typically most useful as a type-erased argument type for
     22 // accepting function types that neither take ownership nor copy the type; using
     23 // the reference type in this case avoids a copy and an allocation. Best
     24 // practices of other non-owning reference-like objects (such as
     25 // `absl::string_view`) apply here.
     26 //
     27 //  An `absl::FunctionRef` is similar in usage to a `std::function` but has the
     28 //  following differences:
     29 //
     30 //  * It doesn't own the underlying object.
     31 //  * It doesn't have a null or empty state.
     32 //  * It never performs deep copies or allocations.
     33 //  * It's much faster and cheaper to construct.
     34 //  * It's trivially copyable and destructable.
     35 //
     36 // Generally, `absl::FunctionRef` should not be used as a return value, data
     37 // member, or to initialize a `std::function`. Such usages will often lead to
     38 // problematic lifetime issues. Once you convert something to an
     39 // `absl::FunctionRef` you cannot make a deep copy later.
     40 //
     41 // This class is suitable for use wherever a "const std::function<>&"
     42 // would be used without making a copy. ForEach functions and other versions of
     43 // the visitor pattern are a good example of when this class should be used.
     44 //
     45 // This class is trivial to copy and should be passed by value.
     46 #ifndef ABSL_FUNCTIONAL_FUNCTION_REF_H_
     47 #define ABSL_FUNCTIONAL_FUNCTION_REF_H_
     48 
     49 #include <cassert>
     50 #include <functional>
     51 #include <type_traits>
     52 
     53 #include "absl/base/attributes.h"
     54 #include "absl/functional/internal/function_ref.h"
     55 #include "absl/meta/type_traits.h"
     56 
     57 namespace absl {
     58 ABSL_NAMESPACE_BEGIN
     59 
     60 // FunctionRef
     61 //
     62 // Dummy class declaration to allow the partial specialization based on function
     63 // types below.
     64 template <typename T>
     65 class FunctionRef;
     66 
     67 // FunctionRef
     68 //
     69 // An `absl::FunctionRef` is a lightweight wrapper to any invocable object with
     70 // a compatible signature. Generally, an `absl::FunctionRef` should only be used
     71 // as an argument type and should be preferred as an argument over a const
     72 // reference to a `std::function`. `absl::FunctionRef` itself does not allocate,
     73 // although the wrapped invocable may.
     74 //
     75 // Example:
     76 //
     77 //   // The following function takes a function callback by const reference
     78 //   bool Visitor(const std::function<void(my_proto&,
     79 //                                         absl::string_view)>& callback);
     80 //
     81 //   // Assuming that the function is not stored or otherwise copied, it can be
     82 //   // replaced by an `absl::FunctionRef`:
     83 //   bool Visitor(absl::FunctionRef<void(my_proto&, absl::string_view)>
     84 //                  callback);
     85 //
     86 // Note: the assignment operator within an `absl::FunctionRef` is intentionally
     87 // deleted to prevent misuse; because the `absl::FunctionRef` does not own the
     88 // underlying type, assignment likely indicates misuse.
     89 template <typename R, typename... Args>
     90 class FunctionRef<R(Args...)> {
     91 private:
     92  // Used to disable constructors for objects that are not compatible with the
     93  // signature of this FunctionRef.
     94  template <typename F, typename FR = std::invoke_result_t<F, Args&&...>>
     95  using EnableIfCompatible =
     96      typename std::enable_if<std::is_void<R>::value ||
     97                              std::is_convertible<FR, R>::value>::type;
     98 
     99 public:
    100  // Constructs a FunctionRef from any invocable type.
    101  template <typename F, typename = EnableIfCompatible<const F&>>
    102  // NOLINTNEXTLINE(runtime/explicit)
    103  FunctionRef(const F& f ABSL_ATTRIBUTE_LIFETIME_BOUND)
    104      : invoker_(&absl::functional_internal::InvokeObject<F, R, Args...>) {
    105    absl::functional_internal::AssertNonNull(f);
    106    ptr_.obj = &f;
    107  }
    108 
    109  // Overload for function pointers. This eliminates a level of indirection that
    110  // would happen if the above overload was used (it lets us store the pointer
    111  // instead of a pointer to a pointer).
    112  //
    113  // This overload is also used for references to functions, since references to
    114  // functions can decay to function pointers implicitly.
    115  template <
    116      typename F, typename = EnableIfCompatible<F*>,
    117      absl::functional_internal::EnableIf<absl::is_function<F>::value> = 0>
    118  FunctionRef(F* f)  // NOLINT(runtime/explicit)
    119      : invoker_(&absl::functional_internal::InvokeFunction<F*, R, Args...>) {
    120    assert(f != nullptr);
    121    ptr_.fun = reinterpret_cast<decltype(ptr_.fun)>(f);
    122  }
    123 
    124  // To help prevent subtle lifetime bugs, FunctionRef is not assignable.
    125  // Typically, it should only be used as an argument type.
    126  FunctionRef& operator=(const FunctionRef& rhs) = delete;
    127  FunctionRef(const FunctionRef& rhs) = default;
    128 
    129  // Call the underlying object.
    130  R operator()(Args... args) const {
    131    return invoker_(ptr_, std::forward<Args>(args)...);
    132  }
    133 
    134 private:
    135  absl::functional_internal::VoidPtr ptr_;
    136  absl::functional_internal::Invoker<R, Args...> invoker_;
    137 };
    138 
    139 // Allow const qualified function signatures. Since FunctionRef requires
    140 // constness anyway we can just make this a no-op.
    141 template <typename R, typename... Args>
    142 class FunctionRef<R(Args...) const> : public FunctionRef<R(Args...)> {
    143 public:
    144  using FunctionRef<R(Args...)>::FunctionRef;
    145 };
    146 
    147 ABSL_NAMESPACE_END
    148 }  // namespace absl
    149 
    150 #endif  // ABSL_FUNCTIONAL_FUNCTION_REF_H_