HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
functionRef.h
Go to the documentation of this file.
1 //
2 // Copyright 2020 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_FUNCTION_REF_H
8 #define PXR_BASE_TF_FUNCTION_REF_H
9 
10 #include "pxr/pxr.h"
11 
12 #include <memory>
13 #include <type_traits>
14 #include <utility>
15 
17 
18 template <class Sig>
20 
21 /// \class TfFunctionRef
22 ///
23 /// This class provides a non-owning reference to a type-erased callable object
24 /// with a specified signature. This is useful in cases where you want to write
25 /// a function that takes a user-provided callback, and that callback is used
26 /// only in the duration of the function call, and you want to keep your
27 /// function's implementation out-of-line.
28 ///
29 /// For technical reasons, TfFunctionRef does not support function pointers;
30 /// only function objects. Internally TfFunctionRef stores a void pointer to
31 /// the function object it's referencing, but C++ does not allow function
32 /// pointers to be cast to void pointers. Supporting this case would increase
33 /// this class's size and add complexity to its implementation. Instead,
34 /// callers may wrap function pointers in lambdas to sidestep the issue.
35 ///
36 /// The advantage over std::function is that TfFunctionRef is lighter-weight.
37 /// Since it is non-owning, it guarantees no heap allocation; a possibility with
38 /// std::function. The cost to call a TfFunctionRef is an indirect function
39 /// call.
40 ///
41 /// For example:
42 ///
43 /// \code
44 ///
45 /// // widgetUtil.h ////////////////////////////////
46 ///
47 /// class WidgetUtil
48 /// {
49 /// template <class WidgetPredicate>
50 /// bool AnyWidgetsMatch(WidgetPredicate const &predicate) {
51 /// TfFunctionRef<bool (Widget const &)> predRef(predicate);
52 /// return _AnyWidgetsMatchImpl(predRef);
53 /// }
54 /// private:
55 /// bool _AnyWidgetsMatchImpl(
56 /// TfFunctionRef<bool (Widget const &)> const &pred);
57 /// };
58 ///
59 /// // widgetUtil.cpp //////////////////////////////
60 ///
61 /// #include "widgetUtil.h"
62 ///
63 /// bool WidgetUtil::_AnyWidgetsMatchImpl(
64 /// TfFunctionRef<bool (Widget const &)> const &pred)
65 /// {
66 /// for (Widget const &widget: GetAllTheWidgets()) {
67 /// if (pred(widget)) {
68 /// return true;
69 /// }
70 /// }
71 /// return false;
72 /// }
73 ///
74 /// \endcode
75 ///
76 /// Here the implementation of _AnyWidgetsMatchImpl is kept out-of-line, callers
77 /// can pass their own function objects for the predicate, there is no heap
78 /// allocation, and the cost to invoke the predicate in the implementation is
79 /// just the cost of calling a function pointer.
80 ///
81 template <class Ret, class... Args>
82 class TfFunctionRef<Ret (Args...)>
83 {
84  // Type trait to detect when an argument is a potentially cv-qualified
85  // TfFunctionRef. This is used to disable the generic constructor and
86  // assignment operator so that TfFunctionRef arguments are copied rather
87  // than forming TfFunctionRefs pointing to TfFunctionRefs.
88  template <typename Fn>
89  using _IsFunctionRef = std::is_same<
90  std::remove_cv_t<std::remove_reference_t<Fn>>, TfFunctionRef>;
91 
92 public:
93  /// Construct with an lvalue callable \p fn.
95  constexpr TfFunctionRef(Fn &fn) noexcept
96  : _fn(static_cast<void const *>(std::addressof(fn)))
97  , _invoke(_InvokeFn<Fn>) {}
98 
99  /// Copy construct from another TfFunctionRef. The constructed
100  /// TfFunctionRef refers to the same callable as \p rhs.
101  TfFunctionRef(TfFunctionRef const &rhs) noexcept = default;
102 
103  /// Assign from another TfFunctionRef. After assignment this object refers
104  /// to the same callable as \p rhs.
105  TfFunctionRef &
106  operator=(TfFunctionRef const &rhs) noexcept = default;
107 
108  /// Assign from an lvalue callable \p fn.
109  template <class Fn>
111  TfFunctionRef &>
112  operator=(Fn &fn) noexcept {
113  *this = TfFunctionRef(fn);
114  return *this;
115  }
116 
117  /// Swap this and \p other. After the swap, this refers to \p other's
118  /// previous callable, and \p other refers to this's previous callable.
119  void swap(TfFunctionRef &other) noexcept {
120  std::swap(_fn, other._fn);
121  std::swap(_invoke, other._invoke);
122  }
123 
124  /// Invoke the callable that this object refers to with \p args.
125  inline Ret operator()(Args... args) const {
126  return _invoke(_fn, std::forward<Args>(args)...);
127  }
128 
129 private:
130  template <class Fn>
131  static Ret _InvokeFn(void const *fn, Args...args) {
132  using FnPtr = typename std::add_pointer<
134  return (*static_cast<FnPtr>(fn))(std::forward<Args>(args)...);
135  }
136 
137  void const *_fn;
138  Ret (*_invoke)(void const *, Args...);
139 };
140 
141 /// Swap \p lhs and \p rhs. Equivalent to lhs.swap(rhs).
142 template <class Sig>
143 inline void
145 {
146  lhs.swap(rhs);
147 }
148 
150 
151 #endif // PXR_BASE_TF_FUNCTION_REF_H
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:57
type
Definition: core.h:556
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
Definition: UT_ArraySet.h:1699
GLsizei const GLfloat * value
Definition: glcorearb.h:824
std::enable_if_t<!_IsFunctionRef< Fn >::value, TfFunctionRef & > operator=(Fn &fn) noexcept
Assign from an lvalue callable fn.
Definition: functionRef.h:112
void swap(TfFunctionRef &other) noexcept
Definition: functionRef.h:119
constexpr TfFunctionRef(Fn &fn) noexcept
Construct with an lvalue callable fn.
Definition: functionRef.h:95
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
LeafData & operator=(const LeafData &)=delete
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
**If you just want to fire and args
Definition: thread.h:618
Ret operator()(Args...args) const
Invoke the callable that this object refers to with args.
Definition: functionRef.h:125