1#ifndef LIBSBX_SIGNAL_FUNCTION_TRAITS_HPP_
2#define LIBSBX_SIGNAL_FUNCTION_TRAITS_HPP_
8#include <libsbx/memory/observer_ptr.hpp>
10namespace sbx::signals {
14struct a {
virtual ~a() =
default;
void f();
virtual void g();
static void h(); };
15struct b {
virtual ~b() =
default;
void f();
virtual void g(); };
16struct c :
a,
b {
void f();
void g()
override; };
17struct d :
virtual a {
void g()
override; };
38 std::ranges::fill(_data,
'\n');
41 template<
typename Type>
42 void store(
const Type& value) {
43 const auto* ptr =
reinterpret_cast<const std::uint8_t*
>(std::addressof(value));
45 std::memcpy(_data, ptr,
sizeof(Type));
48 template<
typename Type>
50 if (
sizeof(Type) != _size) {
54 return reinterpret_cast<const Type*
>(_data);
64template<
typename,
typename =
void>
67template<
typename Type>
68struct has_call_operator<Type, std::void_t<decltype(&std::remove_reference_t<Type>::operator())>> : std::true_type {};
70template<
typename Type>
73template<
typename Type,
typename =
void>
75 static constexpr auto is_disconnectable_v =
false;
76 static constexpr auto must_check_object_v =
true;
82 static auto eq(
const Type& ,
const function_ptr& ) ->
bool {
87template<
typename Type>
89 static constexpr bool is_disconnectable_v =
true;
90 static constexpr bool must_check_object_v =
false;
92 static auto ptr(Type& value,
function_ptr& ptr) ->
void {
93 ptr.store(std::addressof(value));
96 static auto eq(Type& value,
const function_ptr& ptr) ->
bool {
97 const auto* result = ptr.as<
const Type*>();
99 return result && *result == std::addressof(value);
103template<
typename Type>
105 static constexpr bool is_disconnectable_v =
true;
106 static constexpr bool must_check_object_v =
false;
117template<
typename Type>
118struct function_traits<Type, std::enable_if_t<std::is_member_function_pointer_v<Type>>> {
119 static constexpr bool is_disconnectable_v =
false;
120 static constexpr bool must_check_object_v =
true;
122 static auto ptr(Type value,
function_ptr& ptr) ->
void {
126 static auto eq(Type value,
const function_ptr& ptr) ->
bool {
127 const auto* result = ptr.as<
const Type>();
129 return result && *result == value;
133template<
typename Type>
135 using call_type =
decltype(&std::remove_reference_t<Type>::operator());
140 static auto ptr(
const Type& ,
function_ptr& ptr) ->
void {
144 static auto eq(
const Type& ,
const function_ptr& ptr) ->
bool {
149template<
typename Type>
150auto get_function_ptr(
const Type& value) ->
function_ptr {
153 function_traits<std::decay_t<Type>>::ptr(value, ptr);
158template<
typename Type>
159auto eq_function_ptr(
const Type& value,
const function_ptr& ptr) ->
bool {
160 return function_traits<std::decay_t<Type>>::eq(value, ptr);
A non-owning pointer that can be used to observe the value of a pointer.
Definition: observer_ptr.hpp:27
Definition: function_traits.hpp:32
Definition: function_traits.hpp:14
Definition: function_traits.hpp:15
Definition: function_traits.hpp:16
Definition: function_traits.hpp:17
Definition: function_traits.hpp:74
Definition: function_traits.hpp:65
Definition: function_traits.hpp:19