Gaia-ECS v1.0.0
A simple and powerful entity component system
Loading...
Searching...
No Matches
func.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <type_traits>
5
6namespace gaia {
8 namespace detail {
9 // template <class T>
10 // struct is_reference_wrapper: std::false_type {};
11 // template <class U>
12 // struct is_reference_wrapper<std::reference_wrapper<U>>: std::true_type {};
13 template <class C, class Pointed, class Object, class... Args>
14 constexpr decltype(auto) invoke_memptr(Pointed C::* member, Object&& object, Args&&... args) {
15 using object_t = std::decay_t<Object>;
16 constexpr bool is_member_function = std::is_function_v<Pointed>;
17 // constexpr bool is_wrapped = is_reference_wrapper<object_t>::value;
18 constexpr bool is_derived_object = std::is_same_v<C, object_t> || std::is_base_of_v<C, object_t>;
19
20 if constexpr (is_member_function) {
21 if constexpr (is_derived_object)
22 return (GAIA_FWD(object).*member)(GAIA_FWD(args)...);
23 // else if constexpr (is_wrapped)
24 // return (object.get().*member)(GAIA_FWD(args)...);
25 else
26 return ((*GAIA_FWD(object)).*member)(GAIA_FWD(args)...);
27 } else {
28 static_assert(std::is_object_v<Pointed> && sizeof...(args) == 0);
29 if constexpr (is_derived_object)
30 return GAIA_FWD(object).*member;
31 // else if constexpr (is_wrapped)
32 // return object.get().*member;
33 else
34 return (*GAIA_FWD(object)).*member;
35 }
36 }
37 } // namespace detail
39
52 template <class F, class... Args>
53 constexpr decltype(auto) invoke(F&& f, Args&&... args) noexcept(std::is_nothrow_invocable_v<F, Args...>) {
54 if constexpr (std::is_member_pointer_v<std::decay_t<F>>)
55 return detail::invoke_memptr(f, GAIA_FWD(args)...);
56 else
57 return GAIA_FWD(f)(GAIA_FWD(args)...);
58 }
59} // namespace gaia