Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=pacman-g2.git;a=commitdiff;h=b4925c19f7df88ac296ff94e5cecf1cba8bea7fa
commit b4925c19f7df88ac296ff94e5cecf1cba8bea7fa Author: Michel Hermier <[email protected]> Date: Thu May 29 07:40:33 2014 +0200 libpacman: Move signal invocation part to FFunction. diff --git a/lib/libpacman/kernel/fsignal.h b/lib/libpacman/kernel/fsignal.h index 6c84a2d..02681a5 100644 --- a/lib/libpacman/kernel/fsignal.h +++ b/lib/libpacman/kernel/fsignal.h @@ -24,7 +24,6 @@ #include "util/falgorithms.h" #include "util/ffunctional.h" -#include <memory> // For std::unique_ptr #include <vector> // For std::vector #include "util.h" // for ASSERT @@ -42,16 +41,32 @@ template <typename R, typename... Args> class FSignalBase<R(Args...)> { protected: - std::vector<std::unique_ptr<flib::FCallable<R(Args...)>>> m_connections; - typedef typename std::vector<std::unique_ptr<flib::FCallable<R(Args...)>>>::value_type value_type; - typedef typename std::vector<std::unique_ptr<flib::FCallable<R(Args...)>>>::const_reference const_reference; + typedef std::vector<flib::FFunction<R(Args...)>> connections_container; + typedef typename connections_container::value_type value_type; + typedef typename connections_container::const_reference const_reference; - bool connect(FCallable<R(Args...)> *connection) + connections_container m_connections; + +public: + bool connect(const flib::FFunction<R(Args...)>& function) { - ASSERT(connection != nullptr, return false); - m_connections.push_back(value_type(connection)); + ASSERT(function, return false); + + m_connections.push_back(function); return true; } + + template <typename Pointer, typename MethodSignature> + bool connect(Pointer pointer, MethodSignature method) + { + return connect(flib::FFunction<R(Args...)>(pointer, method)); + } + + template <typename Pointer, typename MethodSignature, typename Receiver> + bool connect(Pointer *pointer, MethodSignature method, const Receiver *) + { + return connect(flib::FFunction<R(Args...)>(pointer, method, (const Receiver *)nullptr)); + } }; } @@ -61,156 +76,48 @@ class FSignal; template <typename R, typename... Args> class FSignal<R(Args...)> - : protected flib::detail::FSignalBase<R(Args...)> + : public flib::detail::FSignalBase<R(Args...)> { typedef flib::detail::FSignalBase<R(Args...)> super_type; typedef typename super_type::const_reference const_reference; - template <typename FunctionR, typename... FunctionArgs> - struct FFunctionConnection - : flib::FCallable<R(Args...)> - { - typedef FunctionR (*function_type)(FunctionArgs..., ...); - - function_type m_function; - - FFunctionConnection(FunctionR (*function)(FunctionArgs...)) - : m_function((function_type)function) - { } - - R operator () (Args... args) const - { - return m_function(args...); - } - }; - - template <typename Receiver, typename MethodR, typename... MethodArgs> - struct FMethodConnection - : flib::FCallable<R(Args...)> - { - typedef MethodR (Receiver::*method_type)(MethodArgs..., ...); - - Receiver *m_receiver; - method_type m_method; - - FMethodConnection(Receiver *receiver, MethodR (Receiver::*method)(MethodArgs...)) - : m_receiver(receiver), m_method((method_type)method) - { } - - R operator () (Args... args) const - { - return (m_receiver->*m_method)(args...); - } - }; - public: - template <typename FunctionR, typename... FunctionArgs> - bool connect(FunctionR (*function)(FunctionArgs...)) - { - ASSERT(function != nullptr, return false); - - return super_type::connect(new FFunctionConnection<FunctionR, FunctionArgs...>(function)); - } - - template <typename Receiver, typename MethodR, typename... MethodArgs> - bool connect(Receiver *receiver, MethodR (Receiver::*method)(MethodArgs...)) - { - ASSERT(receiver != nullptr, return false); - ASSERT(receiver != nullptr, return false); - - return super_type::connect(new FMethodConnection<Receiver, MethodR, MethodArgs...>(receiver, method)); - } - - template <typename Acc = flib::FAccumulator<void>> - Acc operator () (Args... args) const + template <typename Accumulator = flib::FAccumulator<void>> + Accumulator operator()(Args... args) const { - Acc accumulator = flib::fdefault_constructor<Acc>(); + Accumulator accumulator = flib::fdefault_constructor<Accumulator>(); - for(const_reference callable : super_type::m_connections) { - accumulator += (*callable)(args...); + for(const_reference connection : super_type::m_connections) { + accumulator += connection(args...); } return accumulator; } - template <typename Acc = flib::FAccumulator<void>> - inline Acc emit(Args... args) const + template <typename Accumulator = flib::FAccumulator<void>> + inline Accumulator emit(Args... args) const { - return operator () <Acc> (args...); + return operator()<Accumulator> (args...); } }; template <typename... Args> class FSignal<void(Args...)> - : protected flib::detail::FSignalBase<void(Args...)> + : public flib::detail::FSignalBase<void(Args...)> { typedef flib::detail::FSignalBase<void(Args...)> super_type; typedef typename super_type::const_reference const_reference; - template <typename FunctionR, typename... FunctionArgs> - struct FFunctionConnection - : flib::FCallable<void(Args...)> - { - typedef void (*function_type)(FunctionArgs..., ...); - - function_type m_function; - - FFunctionConnection(FunctionR (*function)(FunctionArgs...)) - : m_function((function_type)function) - { } - - void operator () (Args... args) const - { - m_function(args...); - } - }; - - template <typename Receiver, typename MethodR, typename... MethodArgs> - struct FMethodConnection - : flib::FCallable<void(Args...)> - { - typedef void (Receiver::*method_type)(MethodArgs..., ...); - - Receiver *m_receiver; - method_type m_method; - - FMethodConnection(Receiver *receiver, MethodR (Receiver::*method)(MethodArgs...)) - : m_receiver(receiver), m_method((method_type)method) - { } - - void operator () (Args... args) const - { - (m_receiver->*m_method)(args...); - } - }; - public: - template <typename FunctionR, typename... FunctionArgs> - bool connect(FunctionR (*function)(FunctionArgs...)) - { - ASSERT(function != nullptr, return false); - - return super_type::connect(new FFunctionConnection<FunctionR, FunctionArgs...>(function)); - } - - template <typename Receiver, typename MethodR, typename... MethodArgs> - bool connect(Receiver *receiver, MethodR (Receiver::*method)(MethodArgs...)) - { - ASSERT(receiver != nullptr, return false); - ASSERT(receiver != nullptr, return false); - - return super_type::connect(new FMethodConnection<Receiver, MethodR, MethodArgs...>(receiver, method)); - } - - void operator () (Args... args) const + void operator()(Args... args) const { - for(const_reference callable : super_type::m_connections) { - (*callable)(args...); + for(const_reference connection : super_type::m_connections) { + connection(args...); } } inline void emit(Args... args) const { - operator () (args...); + operator()(args...); } }; diff --git a/lib/libpacman/util/ffunctional.h b/lib/libpacman/util/ffunctional.h index 55ed8e4..ed1d190 100644 --- a/lib/libpacman/util/ffunctional.h +++ b/lib/libpacman/util/ffunctional.h @@ -22,6 +22,11 @@ #define FFUNCTIONAL_H #include <functional> +#include <memory> // For std::shared_ptr +#include <typeinfo> +#include <type_traits> + +#include "util.h" // For ASSERT namespace flib { @@ -37,7 +42,7 @@ struct FCallable<R(Args...)> virtual ~FCallable() { } - virtual R operator () (Args...) const = 0; + virtual R operator()(Args...) const = 0; }; template <typename R, typename... Args> @@ -48,7 +53,246 @@ struct FCallable<R(Args..., ...)> virtual ~FCallable() { } - virtual R operator () (Args..., ...) const = 0; + virtual R operator()(Args..., ...) const = 0; +}; + +namespace detail +{ + +template <typename> +struct FAbstractFunctionImpl; + +template <typename R, typename... Args> +struct FAbstractFunctionImpl<R(Args...)> + : flib::FCallable<void(R*, Args...)> +{ + virtual const std::type_info &target_type() const = 0; + virtual void *target() const = 0; + + virtual const std::type_info &target_method_type() const + { + return typeid(void); + } +}; + +template <typename, typename, typename> +struct FFunctionImpl; + +template <typename R, typename... Args, typename Target, typename FunctionR, typename... FunctionArgs> +struct FFunctionImpl<R(Args...), Target, FunctionR(FunctionArgs...)> + : flib::detail::FAbstractFunctionImpl<R(Args...)> +{ + Target m_target; + + FFunctionImpl(Target target) + : m_target(target) + { } + + const std::type_info &target_type() const + { + return typeid(Target); + } + + virtual void *target() const + { + return (void *)(uintptr_t)m_target; + } + + virtual void operator()(R *ret, Args... args) const + { + adapted(ret, args...); + } + + template <typename T = R> + inline void adapted(typename std::enable_if<!std::is_void<T>::value, FunctionR *>::type ret, FunctionArgs... args, ...) const + { + *ret = m_target(args...); + } + + template <typename T = R> + inline void adapted(typename std::enable_if<std::is_void<T>::value, void *>::type ret, FunctionArgs... args, ...) const + { + m_target(args...); + } +}; + +template <typename, typename, typename> +struct FAbstractMethodImpl; + +template <typename R, typename... Args, typename MethodSignature, typename Target> +struct FAbstractMethodImpl<R(Args...), MethodSignature, Target> + : FAbstractFunctionImpl<R(Args...)> +{ + MethodSignature m_method; + + FAbstractMethodImpl(MethodSignature method) + : m_method(method) + { } + + virtual const std::type_info &target_method_type() const + { + return typeid(MethodSignature); + } +}; + +template <typename, typename, typename, typename, typename> +struct FMethodImpl; + +template <typename R, typename... Args, typename MethodSignature, typename Target, typename Pointer, typename MethodR, typename... MethodArgs> +struct FMethodImpl<R(Args...), MethodSignature, Target, Pointer, MethodR(MethodArgs...)> + : flib::detail::FAbstractMethodImpl<R(Args...), MethodSignature, Target> +{ + typedef flib::detail::FAbstractMethodImpl<R(Args...), MethodSignature, Target> super_type; + + Pointer m_target; + + FMethodImpl(Pointer target, MethodSignature method) + : super_type(method) + , m_target(target) + { } + + const std::type_info &target_type() const + { + return typeid(Target); + } + + virtual void *target() const + { + return &(*m_target); + } + + virtual void operator()(R *ret, Args... args) const + { + adapted(ret, args...); + } + + template <typename T = R> + inline void adapted(typename std::enable_if<!std::is_void<T>::value, MethodR *>::type ret, MethodArgs... args, ...) const + { + *ret = (m_target->*(super_type::m_method))(args...); + } + + template <typename T = R> + inline void adapted(typename std::enable_if<std::is_void<T>::value, void *>::type ret, MethodArgs... args, ...) const + { + ((*m_target).*(super_type::m_method))(args...); + } +}; + +} + +template <typename> +class FFunction; + +template <typename R, typename... Args> +class FFunction<R(Args...)> +{ + typedef std::shared_ptr<flib::detail::FAbstractFunctionImpl<R(Args...)>> shared_ptr; + + shared_ptr d; + + template <typename Pointer, typename MethodSignature, typename Target, typename VirtualSignature> + void _connect(Pointer pointer, MethodSignature method) + { + ASSERT(pointer != nullptr, return;); + ASSERT(method != nullptr, return;); + + d = shared_ptr(new flib::detail::FMethodImpl<R(Args...), MethodSignature, Target, Pointer, VirtualSignature>(pointer, method)); + } + +public: + FFunction() + { } + + FFunction( std::nullptr_t ) + { } + + template <typename Target> + FFunction(Target *target) + : FFunction(target, &Target::operator()) + { } + + template <typename FunctionR, typename... FunctionArgs> + FFunction(FunctionR (*function)(FunctionArgs...)) + { + ASSERT(function != nullptr, return;); + + d = shared_ptr(new flib::detail::FFunctionImpl<R(Args...), FunctionR (*)(FunctionArgs...), FunctionR(FunctionArgs...)>(function)); + } + + template <typename Pointer, typename MethodR, typename MethodTarget, typename... MethodArgs> + FFunction(Pointer pointer, MethodR (MethodTarget::*method)(MethodArgs...)) + : FFunction(pointer, method, (MethodTarget *)nullptr) + { } + + template <typename Pointer, typename MethodR, typename MethodTarget, typename... MethodArgs, typename Target> + FFunction(Pointer pointer, MethodR (MethodTarget::*method)(MethodArgs...), Target *) + { + _connect<Pointer, MethodR (MethodTarget::*)(MethodArgs...), Target *, MethodR(MethodArgs...)>(pointer, method); + } + + template <typename Pointer, typename MethodR, typename MethodTarget, typename... MethodArgs> + FFunction(Pointer pointer, MethodR (MethodTarget::*method)(MethodArgs...) const) + : FFunction(pointer, method, (const MethodTarget *)nullptr) + { } + + template <typename Pointer, typename MethodR, typename MethodTarget, typename... MethodArgs, typename Target> + FFunction(Pointer pointer, MethodR (MethodTarget::*method)(MethodArgs...) const, const Target *) + { + _connect<Pointer, MethodR (MethodTarget::*)(MethodArgs...) const, const Target *, MethodR(MethodArgs...)>(pointer, method); + } + + template <typename T = R> + typename std::enable_if<!std::is_void<T>::value, T>::type operator()(Args... args) const + { + T ret; + d->operator()(&ret, args...); + return ret; + } + + template <typename T = R> + typename std::enable_if<std::is_void<T>::value, T>::type operator()(Args... args) const + { + d->operator()(nullptr, args...); + } + + inline operator bool() const + { + return (bool)d; + } + + inline void swap(flib::FFunction<R(Args...)> &other) + { + d.swap(other.d); + } + + inline const std::type_info &target_type() const + { + return d != nullptr ? d->target_type() : typeid(void); + } +#if 0 + template <typename T> + inline T *target() + { + T *ret = nullptr; + + if(d != nullptr) { + dynamic_cast<flib::detail::FAbstractFunctionImpl<R (Args...)> &>(*d); + } + return nullptr; + } + + template <typename T> + inline const T *target() const + { + return d != nullptr ? d->target() : nullptr; + } +#endif + template <typename T> + inline const std::type_info &target_method_type() const + { + return d != nullptr ? d->target_method_type() : typeid(void); + } }; } _______________________________________________ Frugalware-git mailing list [email protected] http://frugalware.org/mailman/listinfo/frugalware-git
