26#ifndef TGUI_SIGNAL_IMPL_HPP 
   27#define TGUI_SIGNAL_IMPL_HPP 
   29#include <TGUI/Signal.hpp> 
   35    namespace internal_signal
 
   37#if defined(__cpp_lib_void_t) && (__cpp_lib_void_t >= 201411L) 
   46        template <
typename...>
 
   50#if defined(__cpp_if_constexpr) && (__cpp_if_constexpr >= 201606L) 
   51        template <
typename Type>
 
   52        decltype(
auto) dereference(
const void* obj)
 
   54            if constexpr (std::is_same_v<Type, std::string>) 
 
   55                return static_cast<std::string
>(*
static_cast<const sf::String*
>(obj));
 
   56            else if constexpr (std::is_same_v<Type, sf::Vector2f>) 
 
   57                return static_cast<sf::Vector2f
>(*
static_cast<const Vector2f*
>(obj));
 
   58            else if constexpr (std::is_same_v<Type, sf::Color>) 
 
   59                return static_cast<sf::Color
>(*
static_cast<const Color*
>(obj));
 
   61                return *
static_cast<const std::decay_t<Type>*
>(obj);
 
   64        template <typename Type, typename std::enable_if<std::is_same<Type, std::string>::value>::type* = 
nullptr>
 
   65        decltype(
auto) dereference(
const void* obj)
 
   68            return static_cast<std::string
>(*
static_cast<const sf::String*
>(obj));
 
   71        template <typename Type, typename std::enable_if<std::is_same<Type, sf::Vector2f>::value>::type* = 
nullptr>
 
   72        decltype(
auto) dereference(
const void* obj)
 
   75            return static_cast<sf::Vector2f
>(*
static_cast<const Vector2f*
>(obj));
 
   78        template <typename Type, typename std::enable_if<std::is_same<Type, sf::Color>::value>::type* = 
nullptr>
 
   79        decltype(
auto) dereference(
const void* obj)
 
   82            return static_cast<sf::Color
>(*
static_cast<const Color*
>(obj));
 
   85        template <typename Type, typename std::enable_if<!std::is_same<Type, std::string>::value && !std::is_same<Type, sf::Vector2f>::value && !std::is_same<Type, sf::Color>::value>::type* = 
nullptr>
 
   86        decltype(
auto) dereference(
const void* obj)
 
   88            return *
static_cast<const typename std::decay<Type>::type*
>(obj);
 
   92#if !defined(__cpp_lib_invoke) || (__cpp_lib_invoke < 201411L) 
   95        template <
typename Func, 
typename... Args, 
typename std::enable_if<std::is_member_pointer<typename std::decay<Func>::type>::value>::type* = 
nullptr>
 
   96        void invokeFunc(Func&& func, Args&&... args)
 
   98            std::mem_fn(func)(std::forward<Args>(args)...);
 
  101        template <
typename Func, 
typename... Args, 
typename std::enable_if<!std::is_member_pointer<typename std::decay<Func>::type>::value>::type* = 
nullptr>
 
  102        void invokeFunc(Func&& func, Args&&... args)
 
  104            std::forward<Func>(func)(std::forward<Args>(args)...);
 
  109        template <
typename... Args>
 
  112        template <
typename Arg, 
typename... AllArgs, 
typename BoundArg, 
typename... BoundArgs>
 
  113        struct binder<TypeSet<Arg, AllArgs...>, TypeSet<BoundArg, BoundArgs...>>
 
  114            : binder<TypeSet<AllArgs...>, TypeSet<BoundArgs...>>
 
  118        template <
typename... UnboundArgs>
 
  119        struct binder<TypeSet<std::shared_ptr<Widget>, std::string, UnboundArgs...>, TypeSet<>>
 
  121            template <
typename Func, 
typename... BoundArgs>
 
  122            static decltype(
auto) bind(Signal& signal, Func&& func, BoundArgs&&... args)
 
  124                return bindImpl(std::index_sequence_for<UnboundArgs...>{}, signal, std::forward<Func>(func), std::forward<BoundArgs>(args)...);
 
  129            template <
typename Func, 
typename... BoundArgs, std::size_t... Indices>
 
  130            static decltype(
auto) bindImpl(std::index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
 
  132                const std::size_t offset = (
sizeof...(UnboundArgs) > 0) ? signal.validateTypes({
typeid(UnboundArgs)...}) : 0;
 
  133#if defined(__cpp_lib_invoke) && (__cpp_lib_invoke >= 201411L) 
  134                return [=,o=offset](
const std::shared_ptr<Widget>& widget, 
const std::string& signalName) {
 
  139                                internal_signal::dereference<UnboundArgs>(internal_signal::parameters[o + Indices])...);
 
  141                return [=,o=offset](
const std::shared_ptr<Widget>& widget, 
const std::string& signalName) {
 
  146                               internal_signal::dereference<UnboundArgs>(internal_signal::parameters[o + Indices])...);
 
  152        template <
typename... UnboundArgs>
 
  153        struct binder<TypeSet<UnboundArgs...>, TypeSet<>>
 
  155            template <
typename Func, 
typename... BoundArgs>
 
  156            static decltype(
auto) bind(Signal& signal, Func&& func, BoundArgs&&... args)
 
  158                return bindImpl(std::index_sequence_for<UnboundArgs...>{}, signal, std::forward<Func>(func), std::forward<BoundArgs>(args)...);
 
  163            template <
typename Func, 
typename... BoundArgs, std::size_t... Indices>
 
  164            static decltype(
auto) bindImpl(std::index_sequence<Indices...>, Signal& signal, Func&& func, BoundArgs&&... args)
 
  166                const std::size_t offset = (
sizeof...(UnboundArgs) > 0) ? signal.validateTypes({
typeid(UnboundArgs)...}) : 0;
 
  167#if defined(__cpp_lib_invoke) && (__cpp_lib_invoke >= 201411L) 
  171                               internal_signal::dereference<UnboundArgs>(internal_signal::parameters[o + Indices])...);
 
  176                               internal_signal::dereference<UnboundArgs>(internal_signal::parameters[o + Indices])...);
 
  183#if defined(__cpp_noexcept_function_type) && (__cpp_noexcept_function_type >= 201510L) 
  185        template <
typename Enable, 
typename Func, 
typename... BoundArgs>
 
  189        template <
typename... Args, 
typename... BoundArgs>
 
  190        struct func_traits<void, void(*)(Args...), BoundArgs...> : binder<TypeSet<std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  191        template <
typename... Args, 
typename... BoundArgs>
 
  192        struct func_traits<void, void(*)(Args...) noexcept, BoundArgs...> : binder<TypeSet<std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  195        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  196        struct func_traits<void, void(Class::*)(Args...), BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  197        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  198        struct func_traits<void, void(Class::*)(Args...) noexcept, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  199        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  200        struct func_traits<void, void(Class::*)(Args...) volatile, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  201        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  202        struct func_traits<void, void(Class::*)(Args...) volatile noexcept, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  203        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  204        struct func_traits<void, void(Class::*)(Args...) &, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  205        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  206        struct func_traits<void, void(Class::*)(Args...) & noexcept, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  207        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  208        struct func_traits<void, void(Class::*)(Args...) volatile &, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  209        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  210        struct func_traits<void, void(Class::*)(Args...) volatile & noexcept, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  211        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  212        struct func_traits<void, void(Class::*)(Args...) &&, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  213        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  214        struct func_traits<void, void(Class::*)(Args...) && noexcept, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  215        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  216        struct func_traits<void, void(Class::*)(Args...) volatile &&, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  217        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  218        struct func_traits<void, void(Class::*)(Args...) volatile && noexcept, BoundArgs...> : binder<TypeSet<Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  221        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  222        struct func_traits<void, void(Class::*)(Args...) const, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  223        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  224        struct func_traits<void, void(Class::*)(Args...) const noexcept, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  225        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  226        struct func_traits<void, void(Class::*)(Args...) volatile const, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  227        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  228        struct func_traits<void, void(Class::*)(Args...) volatile const noexcept, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  229        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  230        struct func_traits<void, void(Class::*)(Args...) const &, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  231        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  232        struct func_traits<void, void(Class::*)(Args...) const & noexcept, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  233        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  234        struct func_traits<void, void(Class::*)(Args...) volatile const &, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  235        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  236        struct func_traits<void, void(Class::*)(Args...) volatile const & noexcept, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  237        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  238        struct func_traits<void, void(Class::*)(Args...) const &&, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  239        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  240        struct func_traits<void, void(Class::*)(Args...) const && noexcept, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  241        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  242        struct func_traits<void, void(Class::*)(Args...) volatile const &&, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  243        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  244        struct func_traits<void, void(Class::*)(Args...) volatile const && noexcept, BoundArgs...> : binder<TypeSet<const Class*, std::decay_t<Args>...>, TypeSet<BoundArgs...>> {};
 
  247        template <
typename Func, 
typename... BoundArgs>
 
  248        struct func_traits<void_t<decltype(&Func::operator())>, Func, BoundArgs...> : 
public func_traits<
void, 
decltype(&Func::operator()), Func*, BoundArgs...> {};
 
  251        template <
typename Enable, 
typename Func, 
typename... BoundArgs>
 
  255        template <
typename Func, 
typename... BoundArgs>
 
  256        struct func_traits<void_t<decltype(&Func::operator())>, Func, BoundArgs...>
 
  257            : 
public func_traits<
void, 
decltype(&Func::operator()), Func*, BoundArgs...>
 
  262        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  263        struct func_traits<void, void(Class::*)(Args...), BoundArgs...>
 
  264            : binder<TypeSet<Class*, typename std::decay<Args>::type...>, TypeSet<BoundArgs...>>
 
  269        template <
typename Class, 
typename... Args, 
typename... BoundArgs>
 
  270        struct func_traits<void, void(Class::*)(Args...) const, BoundArgs...>
 
  271            : binder<TypeSet<const Class*, typename std::decay<Args>::type...>, TypeSet<BoundArgs...>>
 
  276        template <
typename... Args, 
typename... BoundArgs>
 
  277        struct func_traits<void, void(*)(Args...), BoundArgs...>
 
  278            : binder<TypeSet<typename std::decay<Args>::type...>, TypeSet<BoundArgs...>>
 
  286#if defined(__cpp_if_constexpr) && (__cpp_if_constexpr >= 201606L) 
  287    template <
typename Func, 
typename... BoundArgs>
 
  293        if constexpr (std::is_convertible_v<Func, std::function<void(
const BoundArgs&...)>>
 
  294                   && std::is_invocable_v<
decltype(&handler), BoundArgs...>
 
  295                   && !std::is_function_v<Func>)
 
  298            id = signal.connect([=, f=std::function<
void(
const BoundArgs&...)>(handler)]{ std::invoke(f, args...); });
 
  300        else if constexpr (std::is_convertible_v<Func, std::function<void(
const BoundArgs&...)>>)
 
  303            id = signal.connect([=]{ std::invoke(handler, args...); });
 
  305        else if constexpr (std::is_convertible_v<Func, std::function<void(
const BoundArgs&..., 
const std::shared_ptr<Widget>&, 
const std::string&)>>
 
  306                        && std::is_invocable_v<
decltype(&handler), BoundArgs..., 
const std::shared_ptr<Widget>&, 
const std::string&>
 
  307                        && !std::is_function_v<Func>)
 
  310            id = signal.connect([=, f=std::function<
void(
const BoundArgs&..., 
const std::shared_ptr<Widget>& w, 
const std::string& s)>(handler)](
const std::shared_ptr<Widget>& w, 
const std::string& s){ std::invoke(f, args..., w, s); });
 
  312        else if constexpr (std::is_convertible_v<Func, std::function<void(
const BoundArgs&..., 
const std::shared_ptr<Widget>&, 
const std::string&)>>)
 
  315            id = signal.connect([=](
const std::shared_ptr<Widget>& w, 
const std::string& s){ std::invoke(handler, args..., w, s); });
 
  320            using binder = internal_signal::func_traits<void, std::decay_t<Func>, BoundArgs...>;
 
  321            id = signal.connect(binder::bind(signal, std::forward<Func>(handler), args...));
 
  324        m_connectedSignals[id] = 
toLower(signalName);
 
  329    template <
typename Func, 
typename... Args, 
typename std::enable_if<std::is_convertible<Func, std::function<void(
const Args&...)>>::value>::type*>
 
  332        const unsigned int id = 
getSignal(
toLower(signalName)).
connect([f=std::function<
void(
const Args&...)>(handler),args...](){ f(args...); });
 
  333        m_connectedSignals[id] = 
toLower(signalName);
 
  337    template <
typename Func, 
typename... BoundArgs, 
typename std::enable_if<!std::is_convertible<Func, std::function<void(
const BoundArgs&...)>>::value 
 
  338                                                                         && std::is_convertible<Func, std::function<void(
const BoundArgs&..., std::shared_ptr<Widget>, 
const std::string&)>>::value>::type*>
 
  342                                    [f=std::function<
void(
const BoundArgs&..., 
const std::shared_ptr<Widget>&, 
const std::string&)>(handler), args...]
 
  343                                    (
const std::shared_ptr<Widget>& w, 
const std::string& s)
 
  344                                    { f(args..., w, s); }
 
  347        m_connectedSignals[id] = 
toLower(signalName);
 
  351    template <
typename Func, 
typename... BoundArgs, 
typename std::enable_if<!std::is_convertible<Func, std::function<void(
const BoundArgs&...)>>::value
 
  352                                                                         && !std::is_convertible<Func, std::function<void(
const BoundArgs&..., std::shared_ptr<Widget>, 
const std::string&)>>::value>::type*>
 
  356        using binder = internal_signal::func_traits<void, typename std::decay<Func>::type, BoundArgs...>;
 
  357        const unsigned int id = signal.
connect(binder::bind(signal, std::forward<Func>(handler), std::forward<BoundArgs>(args)...));
 
  358        m_connectedSignals[id] = 
toLower(signalName);
 
  365    template <
typename Func, 
typename... BoundArgs>
 
  368        unsigned int lastId = 0;
 
  369        for (
auto& signalName : signalNames)
 
  370            lastId = 
connect(std::move(signalName), handler, args...);
 
Signal to which the user can subscribe to get callbacks from.
Definition: Signal.hpp:231
 
unsigned int connect(const Delegate &handler)
Connects a signal handler that will be called when this signal is emitted.
 
Namespace that contains all TGUI functions and classes.
Definition: AbsoluteOrRelativeValue.hpp:37
 
TGUI_API std::string toLower(const std::string &str)
Converts a string to lowercase.