diff options
author | 2016-11-05 20:26:04 +0100 | |
---|---|---|
committer | 2016-11-05 20:26:04 +0100 | |
commit | dedf3c9b9d78decb2647b710454305e324f6d380 (patch) | |
tree | fadf7ceb82a6c62fbe65b34f6ddcf71269b72fdb | |
parent | f05e7ffad0fce71293f65d142b7c13084ad48215 (diff) |
Delegate support for lambdas and std::functions in general, also supporting const members now [Miodrag Milanovic]
-rw-r--r-- | src/emu/devdelegate.cpp | 2 | ||||
-rw-r--r-- | src/emu/devdelegate.h | 18 | ||||
-rw-r--r-- | src/lib/util/delegate.h | 115 | ||||
-rw-r--r-- | src/mame/drivers/statriv2.cpp | 32 |
4 files changed, 106 insertions, 61 deletions
diff --git a/src/emu/devdelegate.cpp b/src/emu/devdelegate.cpp index 8917d5dfc3f..380f01180e2 100644 --- a/src/emu/devdelegate.cpp +++ b/src/emu/devdelegate.cpp @@ -17,7 +17,7 @@ // fatal error if not found //------------------------------------------------- -delegate_late_bind &device_delegate_helper::bound_object(device_t &search_root) +delegate_late_bind &device_delegate_helper::bound_object(device_t &search_root) const { device_t *device = search_root.subdevice(m_device_name); if (device == nullptr) diff --git a/src/emu/devdelegate.h b/src/emu/devdelegate.h index 58974c4f5b3..147550791b0 100644 --- a/src/emu/devdelegate.h +++ b/src/emu/devdelegate.h @@ -30,7 +30,7 @@ protected: device_delegate_helper(const char *devname) : m_device_name(devname) { } // internal helpers - delegate_late_bind &bound_object(device_t &search_root); + delegate_late_bind &bound_object(device_t &search_root) const; static const char *safe_tag(device_t *object); // internal state @@ -54,20 +54,24 @@ public: device_delegate(const basetype &src) : basetype(src), device_delegate_helper(src.m_device_name) { } device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), device_delegate_helper(src.m_device_name) { } template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { } #ifdef USE_STATIC_DELEGATE template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { } template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { } #endif + device_delegate(std::function<_Signature> funcptr) : basetype(funcptr), device_delegate_helper(nullptr) { } device_delegate &operator=(const thistype &src) { *static_cast<basetype *>(this) = src; m_device_name = src.m_device_name; return *this; } // provide additional constructors that take a device name string - template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, (_FunctionClass *)nullptr), device_delegate_helper(devname) { } - template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)nullptr), device_delegate_helper(devname) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { } #ifdef USE_STATIC_DELEGATE - template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)nullptr), device_delegate_helper(devname) { } - template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, const char *devname, _FunctionClass *object) : basetype(funcptr, name, (_FunctionClass *)nullptr), device_delegate_helper(devname) { } - device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)nullptr), device_delegate_helper(nullptr) { } - device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, (device_t *)nullptr), device_delegate_helper(nullptr) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { } + template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { } + device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { } + device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { } #endif // and constructors that provide a search root diff --git a/src/lib/util/delegate.h b/src/lib/util/delegate.h index 1d849b508f2..9e37d6e78bf 100644 --- a/src/lib/util/delegate.h +++ b/src/lib/util/delegate.h @@ -79,11 +79,11 @@ #define __DELEGATE_H__ // standard C++ includes -#include <exception> +#include <cstring> #include <typeinfo> #include <utility> -#include <cstring> -#include <cstdint> +#include <functional> + //************************************************************************** // MACROS @@ -134,7 +134,7 @@ //************************************************************************** // generic function type -typedef void (*delegate_generic_function)(); +using delegate_generic_function = void(*)(); // ======================> generic_class @@ -180,9 +180,10 @@ public: template<typename _ClassType, typename _ReturnType, typename... Params> struct delegate_traits { - typedef _ReturnType (*static_func_type)(_ClassType *, Params...); - typedef _ReturnType (*static_ref_func_type)(_ClassType &, Params...); - typedef _ReturnType (_ClassType::*member_func_type)(Params...); + using static_func_type = _ReturnType(*)(_ClassType *, Params...); + using static_ref_func_type = _ReturnType(*)(_ClassType &, Params...); + using member_func_type = _ReturnType(_ClassType::*)(Params...); + using const_member_func_type = _ReturnType(_ClassType::*)(Params...) const; }; @@ -247,7 +248,7 @@ private: static _ReturnType method_stub(delegate_generic_class *object, Params ... args) { delegate_mfp *_this = reinterpret_cast<delegate_mfp *>(object); - typedef _ReturnType (_FunctionClass::*mfptype)(Params...); + using mfptype = _ReturnType(_FunctionClass::*)(Params...); mfptype &mfp = *reinterpret_cast<mfptype *>(&_this->m_rawdata); return (reinterpret_cast<_FunctionClass *>(_this->m_realobject)->*mfp)(std::forward<Params>(args)...); } @@ -256,7 +257,7 @@ private: // helper to convert a function of a given type to a generic function, forcing template // instantiation to match the source type template <typename _SourceType> - delegate_generic_function make_generic(_SourceType funcptr) + static delegate_generic_function make_generic(_SourceType funcptr) { return reinterpret_cast<delegate_generic_function>(funcptr); } @@ -310,7 +311,7 @@ public: bool isnull() const { return (m_function == 0 && m_this_delta==0); } // getters - delegate_generic_class *real_object(delegate_generic_class *original) const { return original; } + static delegate_generic_class *real_object(delegate_generic_class *original) { return original; } // binding helper template<typename _FunctionType> @@ -341,11 +342,15 @@ class delegate_mfp public: // default constructor delegate_mfp() - : m_function(0) { } + : m_function(0), m_this_delta(0), m_dummy1(0), m_dummy2(0), m_size(0) + { + } // copy constructor delegate_mfp(const delegate_mfp &src) - : m_function(src.m_function) { } + : m_function(src.m_function), m_this_delta(0), m_dummy1(0), m_dummy2(0), m_size(0) + { + } // construct from any member function pointer template<typename _MemberFunctionType, class _MemberFunctionClass, typename _ReturnType, typename _StaticFunctionType> @@ -361,7 +366,7 @@ public: bool isnull() const { return (m_function == 0); } // getters - delegate_generic_class *real_object(delegate_generic_class *original) const { return original; } + static delegate_generic_class *real_object(delegate_generic_class *original) { return original; } // binding helper template<typename _FunctionType> @@ -407,19 +412,22 @@ public: template<class _FunctionClass> struct traits { - typedef typename delegate_traits<_FunctionClass, _ReturnType, Params...>::member_func_type member_func_type; - typedef typename delegate_traits<_FunctionClass, _ReturnType, Params...>::static_func_type static_func_type; - typedef typename delegate_traits<_FunctionClass, _ReturnType, Params...>::static_ref_func_type static_ref_func_type; + using member_func_type = typename delegate_traits<_FunctionClass, _ReturnType, Params...>::member_func_type; + using const_member_func_type = typename delegate_traits<_FunctionClass, _ReturnType, Params...>::const_member_func_type; + using static_func_type = typename delegate_traits<_FunctionClass, _ReturnType, Params...>::static_func_type; + using static_ref_func_type = typename delegate_traits<_FunctionClass, _ReturnType, Params...>::static_ref_func_type; }; - typedef typename traits<delegate_generic_class>::static_func_type generic_static_func; - typedef MEMBER_ABI generic_static_func generic_member_func; + using functional_type = std::function<_ReturnType(Params...)>; + using generic_static_func = typename traits<delegate_generic_class>::static_func_type; + using generic_member_func = MEMBER_ABI generic_static_func; // generic constructor delegate_base() : m_function(nullptr), m_object(nullptr), m_name(nullptr), m_latebinder(nullptr), - m_raw_function(nullptr) { } + m_raw_function(nullptr), + m_std_func(nullptr){ } // copy constructor delegate_base(const delegate_base &src) @@ -428,7 +436,8 @@ public: m_name(src.m_name), m_latebinder(src.m_latebinder), m_raw_function(src.m_raw_function), - m_raw_mfp(src.m_raw_mfp) + m_raw_mfp(src.m_raw_mfp), + m_std_func(src.m_std_func) { bind(src.object()); } @@ -440,7 +449,8 @@ public: m_name(src.m_name), m_latebinder(src.m_latebinder), m_raw_function(src.m_raw_function), - m_raw_mfp(src.m_raw_mfp) + m_raw_mfp(src.m_raw_mfp), + m_std_func(src.m_std_func) { late_bind(object); } @@ -453,7 +463,21 @@ public: m_name(name), m_latebinder(&late_bind_helper<_FunctionClass>), m_raw_function(nullptr), - m_raw_mfp(funcptr, object, (_ReturnType *)nullptr, static_cast<generic_static_func>(nullptr)) + m_raw_mfp(funcptr, object, static_cast<_ReturnType *>(nullptr), static_cast<generic_static_func>(nullptr)), + m_std_func(nullptr) + { + bind(reinterpret_cast<delegate_generic_class *>(object)); + } + + template<class _FunctionClass> + delegate_base(typename traits<_FunctionClass>::const_member_func_type funcptr, const char *name, _FunctionClass *object) + : m_function(nullptr), + m_object(nullptr), + m_name(name), + m_latebinder(&late_bind_helper<_FunctionClass>), + m_raw_function(nullptr), + m_raw_mfp(funcptr, object, static_cast<_ReturnType *>(nullptr), static_cast<generic_static_func>(nullptr)), + m_std_func(nullptr) { bind(reinterpret_cast<delegate_generic_class *>(object)); } @@ -465,7 +489,8 @@ public: m_object(nullptr), m_name(name), m_latebinder(&late_bind_helper<_FunctionClass>), - m_raw_function(reinterpret_cast<generic_static_func>(funcptr)) + m_raw_function(reinterpret_cast<generic_static_func>(funcptr)), + m_std_func(nullptr) { bind(reinterpret_cast<delegate_generic_class *>(object)); } @@ -477,11 +502,24 @@ public: m_object(nullptr), m_name(name), m_latebinder(&late_bind_helper<_FunctionClass>), - m_raw_function(reinterpret_cast<generic_static_func>(funcptr)) + m_raw_function(reinterpret_cast<generic_static_func>(funcptr)), + m_std_func(nullptr) { bind(reinterpret_cast<delegate_generic_class *>(object)); } + // construct from static reference function with object reference + delegate_base(functional_type funcptr, const char *name) + : m_function(nullptr), + m_object(nullptr), + m_name(name), + m_latebinder(nullptr), + m_raw_function(nullptr), + m_std_func(funcptr) + { + + } + // copy operator delegate_base &operator=(const delegate_base &src) { @@ -493,6 +531,8 @@ public: m_latebinder = src.m_latebinder; m_raw_function = src.m_raw_function; m_raw_mfp = src.m_raw_mfp; + m_std_func = src.m_std_func; + bind(src.object()); } return *this; @@ -501,24 +541,26 @@ public: // comparison helper bool operator==(const delegate_base &rhs) const { - return (m_raw_function == rhs.m_raw_function && object() == rhs.object() && m_raw_mfp == rhs.m_raw_mfp); + return (m_raw_function == rhs.m_raw_function && object() == rhs.object() && m_raw_mfp == rhs.m_raw_mfp && m_std_func.target_type().name() == rhs.m_std_func.target_type().name()); } -#define DELEGATE_CALL(x) \ - if (is_mfp() && (HAS_DIFFERENT_ABI)) \ - return (*reinterpret_cast<generic_member_func>(m_function)) x; \ - else \ - return (*m_function) x; // call the function - _ReturnType operator()(Params... args) const { DELEGATE_CALL((m_object, std::forward<Params>(args)...)); } + _ReturnType operator()(Params... args) const { + if (is_mfp() && (HAS_DIFFERENT_ABI)) + return (*reinterpret_cast<generic_member_func>(m_function)) (m_object, std::forward<Params>(args)...); + else if (m_std_func) + return m_std_func(std::forward<Params>(args)...); + else + return (*m_function) (m_object, std::forward<Params>(args)...); + } // getters - bool has_object() const { return (object() != nullptr); } + bool has_object() const { return (object() != nullptr) || (m_std_func); } const char *name() const { return m_name; } // helpers - bool isnull() const { return (m_raw_function == nullptr && m_raw_mfp.isnull()); } + bool isnull() const { return (m_raw_function == nullptr && m_raw_mfp.isnull() && !m_std_func); } bool is_mfp() const { return !m_raw_mfp.isnull(); } // late binding @@ -529,7 +571,7 @@ protected: delegate_generic_class *object() const { return is_mfp() ? m_raw_mfp.real_object(m_object) : m_object; } // late binding function - typedef delegate_generic_class *(*late_bind_func)(delegate_late_bind &object); + using late_bind_func = delegate_generic_class*(*)(delegate_late_bind &object); // late binding helper template<class _FunctionClass> @@ -559,6 +601,7 @@ protected: late_bind_func m_latebinder; // late binding helper generic_static_func m_raw_function; // raw static function pointer delegate_mfp m_raw_mfp; // raw member function pointer + functional_type m_std_func; // std::function pointer }; @@ -574,7 +617,7 @@ class delegate; template<typename _ReturnType, typename... Params> class delegate<_ReturnType (Params...)> : public delegate_base<_ReturnType, Params...> { - typedef delegate_base<_ReturnType, Params...> basetype; + using basetype = delegate_base<_ReturnType, Params...>; public: // create a standard set of constructors @@ -582,6 +625,8 @@ public: delegate(const basetype &src) : basetype(src) { } delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object) { } template<class _FunctionClass> delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } + template<class _FunctionClass> delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } + delegate(std::function<_ReturnType(Params...)> funcptr) : basetype(funcptr, "") { } #ifdef USE_STATIC_DELEGATE template<class _FunctionClass> delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } template<class _FunctionClass> delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object) { } diff --git a/src/mame/drivers/statriv2.cpp b/src/mame/drivers/statriv2.cpp index de2d3c1bad2..e82db5281c5 100644 --- a/src/mame/drivers/statriv2.cpp +++ b/src/mame/drivers/statriv2.cpp @@ -105,8 +105,6 @@ public: uint8_t m_last_coin; DECLARE_WRITE8_MEMBER(statriv2_videoram_w); DECLARE_READ8_MEMBER(question_data_r); - DECLARE_READ8_MEMBER(laserdisc_io_r); - DECLARE_WRITE8_MEMBER(laserdisc_io_w); DECLARE_CUSTOM_INPUT_MEMBER(latched_coin_r); DECLARE_WRITE8_MEMBER(ppi_portc_hi_w); DECLARE_DRIVER_INIT(addr_xlh); @@ -1141,25 +1139,23 @@ DRIVER_INIT_MEMBER(statriv2_state,addr_lmhe) DRIVER_INIT_CALL(addr_lmh); } - -READ8_MEMBER(statriv2_state::laserdisc_io_r) -{ - uint8_t result = 0x00; - if (offset == 1) - result = 0x18; - osd_printf_debug("%s:ld read ($%02X) = %02X\n", machine().describe_context(), 0x28 + offset, result); - return result; -} - -WRITE8_MEMBER(statriv2_state::laserdisc_io_w) -{ - osd_printf_debug("%s:ld write ($%02X) = %02X\n", machine().describe_context(), 0x28 + offset, data); -} - DRIVER_INIT_MEMBER(statriv2_state,laserdisc) { address_space &iospace = m_maincpu->space(AS_IO); - iospace.install_readwrite_handler(0x28, 0x2b, read8_delegate(FUNC(statriv2_state::laserdisc_io_r), this), write8_delegate(FUNC(statriv2_state::laserdisc_io_w), this)); + iospace.install_readwrite_handler(0x28, 0x2b, + read8_delegate([this](address_space &space, offs_t offset, uint8_t mem_mask) -> uint8_t + { + uint8_t result = 0x00; + if (offset == 1) + result = 0x18; + osd_printf_debug("%s:ld read ($%02X) = %02X\n", machine().describe_context(), 0x28 + offset, result); + return result; + }), + write8_delegate([this](address_space &space, offs_t offset, uint8_t data, uint8_t mem_mask) + { + osd_printf_debug("%s:ld write ($%02X) = %02X\n", machine().describe_context(), 0x28 + offset, data); + }) + ); } |