functionRef.h
1 //
2 // Copyright 2020 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_FUNCTION_REF_H
25 #define PXR_BASE_TF_FUNCTION_REF_H
26 
27 #include "pxr/pxr.h"
28 
29 #include <memory>
30 #include <type_traits>
31 #include <utility>
32 
33 PXR_NAMESPACE_OPEN_SCOPE
34 
35 template <class Sig>
37 
98 template <class Ret, class... Args>
99 class TfFunctionRef<Ret (Args...)>
100 {
101  // Type trait to detect when an argument is a potentially cv-qualified
102  // TfFunctionRef. This is used to disable the generic constructor and
103  // assignment operator so that TfFunctionRef arguments are copied rather
104  // than forming TfFunctionRefs pointing to TfFunctionRefs.
105  template <typename Fn>
106  using _IsFunctionRef = std::is_same<
107  std::remove_cv_t<std::remove_reference_t<Fn>>, TfFunctionRef>;
108 
109 public:
111  template <class Fn, class = std::enable_if_t<!_IsFunctionRef<Fn>::value>>
112  constexpr TfFunctionRef(Fn &fn) noexcept
113  : _fn(static_cast<void const *>(std::addressof(fn)))
114  , _invoke(_InvokeFn<Fn>) {}
115 
118  TfFunctionRef(TfFunctionRef const &rhs) noexcept = default;
119 
122  TfFunctionRef &
123  operator=(TfFunctionRef const &rhs) noexcept = default;
124 
126  template <class Fn>
127  std::enable_if_t<!_IsFunctionRef<Fn>::value,
128  TfFunctionRef &>
129  operator=(Fn &fn) noexcept {
130  *this = TfFunctionRef(fn);
131  return *this;
132  }
133 
136  void swap(TfFunctionRef &other) noexcept {
137  std::swap(_fn, other._fn);
138  std::swap(_invoke, other._invoke);
139  }
140 
142  inline Ret operator()(Args... args) const {
143  return _invoke(_fn, std::forward<Args>(args)...);
144  }
145 
146 private:
147  template <class Fn>
148  static Ret _InvokeFn(void const *fn, Args...args) {
149  using FnPtr = typename std::add_pointer<
150  typename std::add_const<Fn>::type>::type;
151  return (*static_cast<FnPtr>(fn))(std::forward<Args>(args)...);
152  }
153 
154  void const *_fn;
155  Ret (*_invoke)(void const *, Args...);
156 };
157 
159 template <class Sig>
160 inline void
162 {
163  lhs.swap(rhs);
164 }
165 
166 PXR_NAMESPACE_CLOSE_SCOPE
167 
168 #endif // PXR_BASE_TF_FUNCTION_REF_H
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:74
This class provides a non-owning reference to a type-erased callable object with a specified signatur...
Definition: functionRef.h:36
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.