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 public:
103  template <class Fn>
104  constexpr TfFunctionRef(Fn &fn) noexcept
105  : _fn(static_cast<void const *>(std::addressof(fn)))
106  , _invoke(_InvokeFn<Fn>) {}
107 
110  TfFunctionRef(TfFunctionRef const &rhs) noexcept = default;
111 
114  TfFunctionRef &
115  operator=(TfFunctionRef const &rhs) noexcept = default;
116 
118  template <class Fn>
119  TfFunctionRef &
120  operator=(Fn &fn) noexcept {
121  *this = TfFunctionRef(fn);
122  return *this;
123  }
124 
127  void swap(TfFunctionRef &other) noexcept {
128  std::swap(_fn, other._fn);
129  std::swap(_invoke, other._invoke);
130  }
131 
133  inline Ret operator()(Args... args) const {
134  return _invoke(_fn, std::forward<Args>(args)...);
135  }
136 
137 private:
138  template <class Fn>
139  static Ret _InvokeFn(void const *fn, Args...args) {
140  using FnPtr = typename std::add_pointer<
141  typename std::add_const<Fn>::type>::type;
142  return (*static_cast<FnPtr>(fn))(std::forward<Args>(args)...);
143  }
144 
145  void const *_fn;
146  Ret (*_invoke)(void const *, Args...);
147 };
148 
150 template <class Sig>
151 inline void
153 {
154  lhs.swap(rhs);
155 }
156 
157 PXR_NAMESPACE_CLOSE_SCOPE
158 
159 #endif // PXR_BASE_TF_FUNCTION_REF_H
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:61
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.