Blender  V2.93
BLI_function_ref.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #pragma once
18 
19 #include <optional>
20 #include <type_traits>
21 #include <utility>
22 
23 #include "BLI_utildefines.h"
24 
83 namespace blender {
84 
85 template<typename Function> class FunctionRef;
86 
87 template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> {
88  private:
92  Ret (*callback_)(intptr_t callable, Params... params) = nullptr;
93 
103  intptr_t callable_;
104 
105  template<typename Callable> static Ret callback_fn(intptr_t callable, Params... params)
106  {
107  return (*reinterpret_cast<Callable *>(callable))(std::forward<Params>(params)...);
108  }
109 
110  public:
111  FunctionRef() = default;
112 
123  template<typename Callable,
124  std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Callable>>,
125  FunctionRef>> * = nullptr>
126  FunctionRef(Callable &&callable)
127  : callback_(callback_fn<typename std::remove_reference_t<Callable>>),
128  callable_(reinterpret_cast<intptr_t>(&callable))
129  {
130  }
131 
137  Ret operator()(Params... params) const
138  {
139  BLI_assert(callback_ != nullptr);
140  return callback_(callable_, std::forward<Params>(params)...);
141  }
142 
143  using OptionalReturnValue = std::conditional_t<std::is_void_v<Ret>, void, std::optional<Ret>>;
144 
151  {
152  if constexpr (std::is_void_v<Ret>) {
153  if (callback_ == nullptr) {
154  return;
155  }
156  callback_(callable_, std::forward<Params>(params)...);
157  }
158  else {
159  if (callback_ == nullptr) {
160  return {};
161  }
162  return callback_(callable_, std::forward<Params>(params)...);
163  }
164  }
165 
170  operator bool() const
171  {
172  /* Just checking `callback_` is enough to determine if the `FunctionRef` is in a state that it
173  * can be called in. */
174  return callback_ != nullptr;
175  }
176 };
177 
178 } // namespace blender
#define BLI_assert(a)
Definition: BLI_assert.h:58
std::conditional_t< std::is_void_v< Ret >, void, std::optional< Ret > > OptionalReturnValue
OptionalReturnValue call_safe(Params... params) const
Ret operator()(Params... params) const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
_W64 int intptr_t
Definition: stdint.h:121