77 static constexpr decltype(
auto)
call(U&&...args);
91 constexpr decltype(
auto)
operator() (U&&...)
const;
182template<
class StaticCaller,
class Functor>
183class fallback_caller {
190 template<
class Dummy,
class...T>
191 constexpr auto forward(Dummy*, T&&...args)
const
192 ->
decltype(m_functor(std::forward<T>(args)...))
194 return m_functor(std::forward<T>(args)...);
197 template<
class Dummy,
class...T>
198 constexpr decltype(
auto) forward(Dummy, T&&...args)
const {
204 constexpr fallback_caller(
const Functor& f) : m_functor(f) {}
205 constexpr fallback_caller(Functor&& f) : m_functor(std::move(f)) {}
207 fallback_caller(fallback_caller&&) =
default;
208 fallback_caller(
const fallback_caller&) =
delete;
211 constexpr decltype(
auto)
call(T&&...args)
const {
212 if constexpr ( StaticCaller::template
is_matched_v<T...> ) {
213 return StaticCaller::call(std::forward<T>(args)...);
215 auto dummy = (
int*)
nullptr;
216 return forward(dummy, std::forward<T>(args)...);
221 constexpr decltype(
auto)
operator()(T&&...args)
const {
222 return call(std::forward<T>(args)...);
280#define UGMISC_NAMED_MEMBER_TYPE_TEST(TEMPLATENAME, ALIASNAME, HASMEMBERNAME, NAME) template<class TYPE, class DEFAULTTYPE = void> \
281 class TEMPLATENAME { \
282 template<class...> struct get_defined_type; \
284 template<class V, class T, class...Ts> struct get_defined_type<V, T, Ts...> { \
285 static constexpr bool has_member = get_defined_type<void, Ts...>::has_member; \
286 using type = typename get_defined_type<void, Ts...>::type; \
289 template<class T, class...Ts> struct get_defined_type<std::void_t<typename T::NAME>, T, Ts...> { \
290 static constexpr bool has_member = true; \
291 using type = typename T::NAME; \
294 template<class V> struct get_defined_type<V> { \
295 static constexpr bool has_member = false; \
296 using type = DEFAULTTYPE; \
299 using tlist = ::ugmisc::flatten_t<void, TYPE>; \
300 using dt = typename tlist::template apply<get_defined_type>; \
303 using type = typename dt::type; \
304 static constexpr bool has_member = dt::has_member; \
307 template<class T, class D=void> \
308 using ALIASNAME = typename TEMPLATENAME<T, D>::type; \
310 template<class...T> \
311 static constexpr bool HASMEMBERNAME = TEMPLATENAME<type_list<T...>>::has_member
343#define UGMISC_MEMBER_TYPE_TEST(NAME) \
344 UGMISC_NAMED_MEMBER_TYPE_TEST(member_type_test_##NAME, member_type_##NAME, has_member_type_##NAME, NAME)
387#define UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL(TEMPLATENAME, NAME) \
388 template<class...> class TEMPLATENAME; \
390 template<class FirstTry, class...Tries> \
391 struct TEMPLATENAME<FirstTry, Tries...> { \
392 template<class...> friend class TEMPLATENAME; \
395 template<class...T> struct Call : public TEMPLATENAME<Tries...>::template Call<T...> { \
398 template<class...T> struct Call<std::void_t<decltype(FirstTry::NAME(std::declval<T>()...))>, T...> { \
399 static constexpr bool is_matched = true; \
401 using matched_type = FirstTry; \
403 static constexpr decltype(auto) call(T...args) { \
404 return FirstTry::NAME(std::forward<T>(args)...); \
410 template<class...T> \
411 static constexpr decltype(auto) call(T&&...args) { \
412 return Call<void, T...>::call(std::forward<T>(args)...); \
415 template<class...T> \
416 decltype(auto) constexpr operator() (T&&...args) const { \
417 return TEMPLATENAME::call(std::forward<T>(args)...); \
422 member_::fallback_caller<TEMPLATENAME, std::remove_reference_t<F>> \
423 fallback(F&& functor) { \
424 return std::forward<F>(functor); \
427 template<class...T> \
428 using matched_type = typename Call<void, T...>::matched_type; \
430 template<class...T> \
431 static constexpr bool is_matched(T&&...) { return Call<void, T...>::is_matched; } \
433 template<class...T> \
434 static constexpr bool is_matched_v = Call<void, T...>::is_matched; \
436 template<class...T> \
437 static matched_type<T...> declval_matched(T&&...) noexcept; \
441 template<> class TEMPLATENAME<> { \
442 template<class...> friend class TEMPLATENAME; \
444 template<class...> struct Call { \
445 static constexpr bool is_matched = false; \
449 template<class...T> \
450 static constexpr bool is_matched(T&&...) { return false; } \
461#define UGMISC_MEMBER_STATIC_METHOD_CALL(NAME) \
462 UGMISC_NAMED_MEMBER_STATIC_METHOD_CALL(member_call_##NAME, NAME)
static constexpr decltype(auto) call(U &&...args)
static constexpr auto fallback(F &&functor)
??? matched_type
Definition member.hpp:132
static matched_type< U... > declval_matched(U &&...) noexcept
static constexpr bool is_matched(U &&...)
static constexpr bool is_matched_v
Definition member.hpp:139
Lists of types which may be used in some of the ugmisc templates where a single type would usually be...