summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-11-05 20:26:04 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2016-11-05 20:26:04 +0100
commitdedf3c9b9d78decb2647b710454305e324f6d380 (patch)
treefadf7ceb82a6c62fbe65b34f6ddcf71269b72fdb
parentf05e7ffad0fce71293f65d142b7c13084ad48215 (diff)
Delegate support for lambdas and std::functions in general, also supporting const members now [Miodrag Milanovic]
-rw-r--r--src/emu/devdelegate.cpp2
-rw-r--r--src/emu/devdelegate.h18
-rw-r--r--src/lib/util/delegate.h115
-rw-r--r--src/mame/drivers/statriv2.cpp32
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);
+ })
+ );
}