HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
invoke.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * This file is part of the "https://github.com/blackmatov/invoke.hpp"
3  * For conditions of distribution and use, see copyright notice in LICENSE.md
4  * Copyright (C) 2018-2023, by Matvey Cherevko (blackmatov@gmail.com)
5  ******************************************************************************/
6 
7 #pragma once
8 
9 #include <tuple>
10 #include <utility>
11 #include <functional>
12 #include <type_traits>
13 
14 #define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...) \
15  noexcept(noexcept(__VA_ARGS__)) -> decltype (__VA_ARGS__) { return __VA_ARGS__; }
16 
17 #include "pxr/pxr.h"
18 
20 
21 //
22 // void_t
23 //
24 
25 namespace invoke_hpp
26 {
27  namespace impl
28  {
29  template < typename... Args >
30  struct make_void {
31  using type = void;
32  };
33  }
34 
35  template < typename... Args >
36  using void_t = typename impl::make_void<Args...>::type;
37 }
38 
39 //
40 // integer_sequence
41 //
42 
43 namespace invoke_hpp
44 {
45  template < typename T, T... Ints >
47  using value_type = T;
48  static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
49  };
50 
51  template < std::size_t... Ints >
52  using index_sequence = integer_sequence<std::size_t, Ints...>;
53 
54  namespace impl
55  {
56  template < typename T, std::size_t N, T... Ints >
58  : make_integer_sequence_impl<T, N - 1, N - 1, Ints...> {};
59 
60  template < typename T, T... Ints >
61  struct make_integer_sequence_impl<T, 0, Ints...>
62  : integer_sequence<T, Ints...> {};
63  }
64 
65  template < typename T, std::size_t N >
67 
68  template < std::size_t N >
70 
71  template < typename... Ts >
72  using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
73 }
74 
75 //
76 // is_reference_wrapper
77 //
78 
79 namespace invoke_hpp
80 {
81  namespace impl
82  {
83  template < typename T >
85  : std::false_type {};
86 
87  template < typename U >
88  struct is_reference_wrapper_impl<std::reference_wrapper<U>>
89  : std::true_type {};
90  }
91 
92  template < typename T >
94  : impl::is_reference_wrapper_impl<typename std::remove_cv<T>::type> {};
95 }
96 
97 //
98 // invoke
99 //
100 
101 namespace invoke_hpp
102 {
103  namespace impl
104  {
105  //
106  // invoke_member_object_impl
107  //
108 
109  template
110  <
111  typename Base, typename F, typename Derived,
113  >
114  constexpr auto invoke_member_object_impl(F Base::* f, Derived&& ref)
116  std::forward<Derived>(ref).*f)
117 
118  template
119  <
120  typename Base, typename F, typename RefWrap,
121  typename std::enable_if<is_reference_wrapper<typename std::decay<RefWrap>::type>::value, int>::type = 0
122  >
123  constexpr auto invoke_member_object_impl(F Base::* f, RefWrap&& ref)
125  ref.get().*f)
126 
127  template
128  <
129  typename Base, typename F, typename Pointer,
130  typename std::enable_if<
131  !std::is_base_of<Base, typename std::decay<Pointer>::type>::value &&
132  !is_reference_wrapper<typename std::decay<Pointer>::type>::value
133  , int>::type = 0
134  >
135  constexpr auto invoke_member_object_impl(F Base::* f, Pointer&& ptr)
137  (*std::forward<Pointer>(ptr)).*f)
138 
139  //
140  // invoke_member_function_impl
141  //
142 
143  template
144  <
145  typename Base, typename F, typename Derived, typename... Args,
146  typename std::enable_if<std::is_base_of<Base, typename std::decay<Derived>::type>::value, int>::type = 0
147  >
148  constexpr auto invoke_member_function_impl(F Base::* f, Derived&& ref, Args&&... args)
150  (std::forward<Derived>(ref).*f)(std::forward<Args>(args)...))
151 
152  template
153  <
154  typename Base, typename F, typename RefWrap, typename... Args,
155  typename std::enable_if<is_reference_wrapper<typename std::decay<RefWrap>::type>::value, int>::type = 0
156  >
157  constexpr auto invoke_member_function_impl(F Base::* f, RefWrap&& ref, Args&&... args)
159  (ref.get().*f)(std::forward<Args>(args)...))
160 
161  template
162  <
163  typename Base, typename F, typename Pointer, typename... Args,
164  typename std::enable_if<
165  !std::is_base_of<Base, typename std::decay<Pointer>::type>::value &&
166  !is_reference_wrapper<typename std::decay<Pointer>::type>::value
167  , int>::type = 0
168  >
169  constexpr auto invoke_member_function_impl(F Base::* f, Pointer&& ptr, Args&&... args)
171  ((*std::forward<Pointer>(ptr)).*f)(std::forward<Args>(args)...))
172  }
173 
174  template
175  <
176  typename F, typename... Args,
177  typename std::enable_if<!std::is_member_pointer<typename std::decay<F>::type>::value, int>::type = 0
178  >
179  constexpr auto invoke(F&& f, Args&&... args)
181  std::forward<F>(f)(std::forward<Args>(args)...))
182 
183  template
184  <
185  typename F, typename T,
186  typename std::enable_if<std::is_member_object_pointer<typename std::decay<F>::type>::value, int>::type = 0
187  >
188  constexpr auto invoke(F&& f, T&& t)
190  impl::invoke_member_object_impl(std::forward<F>(f), std::forward<T>(t)))
191 
192  template
193  <
194  typename F, typename... Args,
195  typename std::enable_if<std::is_member_function_pointer<typename std::decay<F>::type>::value, int>::type = 0
196  >
197  constexpr auto invoke(F&& f, Args&&... args)
199  impl::invoke_member_function_impl(std::forward<F>(f), std::forward<Args>(args)...))
200 }
201 
202 //
203 // invoke_result
204 //
205 
206 namespace invoke_hpp
207 {
208  namespace impl
209  {
211 
212  template < typename Void, typename F, typename... Args >
214 
215  template < typename F, typename... Args >
216  struct invoke_result_impl<void_t<invoke_result_impl_tag, decltype(invoke_hpp::invoke(std::declval<F>(), std::declval<Args>()...))>, F, Args...> {
217  using type = decltype(invoke_hpp::invoke(std::declval<F>(), std::declval<Args>()...));
218  };
219  }
220 
221  template < typename F, typename... Args >
223  : impl::invoke_result_impl<void, F, Args...> {};
224 
225  template < typename F, typename... Args >
226  using invoke_result_t = typename invoke_result<F, Args...>::type;
227 }
228 
229 //
230 // is_invocable
231 //
232 
233 namespace invoke_hpp
234 {
235  namespace impl
236  {
238 
239  template < typename Void, typename R, typename F, typename... Args >
241  : std::false_type {};
242 
243  template < typename R, typename F, typename... Args >
245  : std::conditional<
246  std::is_void<R>::value,
247  std::true_type,
248  std::is_convertible<invoke_result_t<F, Args...>, R>>::type {};
249  }
250 
251  template < typename R, typename F, typename... Args >
253  : impl::is_invocable_r_impl<void, R, F, Args...> {};
254 
255  template < typename F, typename... Args >
256  using is_invocable = is_invocable_r<void, F, Args...>;
257 }
258 
259 //
260 // apply
261 //
262 
263 namespace invoke_hpp
264 {
265  namespace impl
266  {
267  template < typename F, typename Tuple, std::size_t... I >
268  constexpr auto apply_impl(F&& f, Tuple&& args, index_sequence<I...>)
270  invoke_hpp::invoke(
271  std::forward<F>(f),
272  std::get<I>(std::forward<Tuple>(args))...))
273  }
274 
275  template < typename F, typename Tuple >
276  constexpr auto apply(F&& f, Tuple&& args)
278  impl::apply_impl(
279  std::forward<F>(f),
280  std::forward<Tuple>(args),
281  make_index_sequence<std::tuple_size<typename std::decay<Tuple>::type>::value>()))
282 }
283 
284 #undef INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN
285 
void
Definition: png.h:1083
static constexpr std::size_t size() noexcept
Definition: invoke.hpp:48
GLsizei const GLfloat * value
Definition: glcorearb.h:824
make_integer_sequence< std::size_t, N > make_index_sequence
Definition: invoke.hpp:69
GLfloat f
Definition: glcorearb.h:1926
auto get(const UT_JSONValue::map_traverser &m) -> decltype(m.key())
Definition: UT_JSONValue.h:972
#define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...)
Definition: invoke.hpp:14
GLint ref
Definition: glcorearb.h:124
GLdouble t
Definition: glad.h:2397
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
typename invoke_result< F, Args...>::type invoke_result_t
Definition: invoke.hpp:226
auto ptr(T p) -> const void *
Definition: format.h:2448
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GA_API const UT_StringHolder N
**If you just want to fire and args
Definition: thread.h:609
Definition: core.h:1131
type
Definition: core.h:1059
typename impl::make_void< Args...>::type void_t
Definition: invoke.hpp:36