2#ifndef LIBSBX_SIGNAL_FUNCTION_TRAITS_HPP_
3#define LIBSBX_SIGNAL_FUNCTION_TRAITS_HPP_
9#include <libsbx/memory/observer_ptr.hpp>
11namespace sbx::signals {
15struct a {
virtual ~a() =
default;
void f();
virtual void g();
static void h(); };
16struct b {
virtual ~b() =
default;
void f();
virtual void g(); };
17struct c :
a,
b {
void f();
void g()
override; };
18struct d :
virtual a {
void g()
override; };
39 std::ranges::fill(_data,
'\n');
42 template<
typename Type>
43 void store(
const Type& value) {
44 const auto* ptr =
reinterpret_cast<const std::uint8_t*
>(std::addressof(value));
46 std::memcpy(_data, ptr,
sizeof(Type));
49 template<
typename Type>
51 if (
sizeof(Type) != _size) {
55 return reinterpret_cast<const Type*
>(_data);
65template<
typename,
typename =
void>
68template<
typename Type>
69struct has_call_operator<Type, std::void_t<decltype(&std::remove_reference_t<Type>::operator())>> : std::true_type {};
71template<
typename Type>
74template<
typename Type,
typename =
void>
76 static constexpr auto is_disconnectable_v =
false;
77 static constexpr auto must_check_object_v =
true;
83 static auto eq(
const Type& ,
const function_ptr& ) ->
bool {
88template<
typename Type>
90 static constexpr bool is_disconnectable_v =
true;
91 static constexpr bool must_check_object_v =
false;
93 static auto ptr(Type& value,
function_ptr& ptr) ->
void {
94 ptr.store(std::addressof(value));
97 static auto eq(Type& value,
const function_ptr& ptr) ->
bool {
98 const auto* result = ptr.as<
const Type*>();
100 return result && *result == std::addressof(value);
104template<
typename Type>
106 static constexpr bool is_disconnectable_v =
true;
107 static constexpr bool must_check_object_v =
false;
118template<
typename Type>
119struct function_traits<Type, std::enable_if_t<std::is_member_function_pointer_v<Type>>> {
120 static constexpr bool is_disconnectable_v =
false;
121 static constexpr bool must_check_object_v =
true;
123 static auto ptr(Type value,
function_ptr& ptr) ->
void {
127 static auto eq(Type value,
const function_ptr& ptr) ->
bool {
128 const auto* result = ptr.as<
const Type>();
130 return result && *result == value;
134template<
typename Type>
136 using call_type =
decltype(&std::remove_reference_t<Type>::operator());
141 static auto ptr(
const Type& ,
function_ptr& ptr) ->
void {
145 static auto eq(
const Type& ,
const function_ptr& ptr) ->
bool {
150template<
typename Type>
151auto get_function_ptr(
const Type& value) ->
function_ptr {
154 function_traits<std::decay_t<Type>>::ptr(value, ptr);
159template<
typename Type>
160auto eq_function_ptr(
const Type& value,
const function_ptr& ptr) ->
bool {
161 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:28
Definition: function_traits.hpp:33
Definition: function_traits.hpp:15
Definition: function_traits.hpp:16
Definition: function_traits.hpp:17
Definition: function_traits.hpp:18
Definition: function_traits.hpp:75
Definition: function_traits.hpp:66
Definition: function_traits.hpp:20