mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
Netlist refactoring:
- Refactored netlist pmf code. - Small optimization for diode calculations. - Minor refactoring across the board. (nw)
This commit is contained in:
parent
093bda0193
commit
25152bd69a
@ -23,6 +23,7 @@ generic_diode::generic_diode(device_t &dev, pstring name)
|
||||
, m_Id(dev, name + ".m_Id", 0.0)
|
||||
, m_G(dev, name + ".m_G", 1e-15)
|
||||
, m_Vt(0.0)
|
||||
, m_Vmin(0.0)
|
||||
, m_Is(0.0)
|
||||
, m_n(0.0)
|
||||
, m_gmin(1e-15)
|
||||
@ -40,6 +41,7 @@ void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double g
|
||||
m_gmin = gmin;
|
||||
|
||||
m_Vt = 0.0258 * m_n;
|
||||
m_Vmin = -5.0 * m_Vt;
|
||||
|
||||
m_Vcrit = m_Vt * std::log(m_Vt / m_Is / csqrt2);
|
||||
m_VtInv = 1.0 / m_Vt;
|
||||
@ -47,8 +49,7 @@ void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double g
|
||||
|
||||
void generic_diode::update_diode(const nl_double nVd)
|
||||
{
|
||||
#if 1
|
||||
if (nVd < NL_FCONST(-5.0) * m_Vt)
|
||||
if (nVd < m_Vmin)
|
||||
{
|
||||
m_Vd = nVd;
|
||||
m_G = m_gmin;
|
||||
@ -58,29 +59,19 @@ void generic_diode::update_diode(const nl_double nVd)
|
||||
{
|
||||
m_Vd = nVd;
|
||||
//m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
|
||||
const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
|
||||
m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
|
||||
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
|
||||
//const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv);
|
||||
const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv);
|
||||
m_Id = IseVDVt - m_Is;
|
||||
m_G = IseVDVt * m_VtInv + m_gmin;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
const nl_double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(-0.99));
|
||||
const double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(-0.99));
|
||||
m_Vd = m_Vd + std::log1p(a) * m_Vt;
|
||||
#else
|
||||
m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
|
||||
#endif
|
||||
const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
|
||||
m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
|
||||
|
||||
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
|
||||
const double IseVDVt = m_Is * std::exp(m_Vd * m_VtInv);
|
||||
m_Id = IseVDVt - m_Is;
|
||||
m_G = IseVDVt * m_VtInv + m_gmin;
|
||||
}
|
||||
#else
|
||||
m_Vd = m_Vd + 20.0 * m_Vt * std::tanh((nVd - m_Vd) / 20.0 / m_Vt);
|
||||
const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
|
||||
m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
|
||||
m_G = m_Is * m_VtInv * eVDVt + m_gmin;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
@ -338,29 +338,30 @@ class generic_diode
|
||||
public:
|
||||
generic_diode(device_t &dev, pstring name);
|
||||
|
||||
void update_diode(const nl_double nVd);
|
||||
void update_diode(const double nVd);
|
||||
|
||||
void set_param(const nl_double Is, const nl_double n, nl_double gmin);
|
||||
void set_param(const double Is, const double n, double gmin);
|
||||
|
||||
inline nl_double I() const { return m_Id; }
|
||||
inline nl_double G() const { return m_G; }
|
||||
inline nl_double Ieq() const { return (m_Id - m_Vd * m_G); }
|
||||
inline nl_double Vd() const { return m_Vd; }
|
||||
inline double I() const { return m_Id; }
|
||||
inline double G() const { return m_G; }
|
||||
inline double Ieq() const { return (m_Id - m_Vd * m_G); }
|
||||
inline double Vd() const { return m_Vd; }
|
||||
|
||||
/* owning object must save those ... */
|
||||
|
||||
private:
|
||||
state_var<nl_double> m_Vd;
|
||||
state_var<nl_double> m_Id;
|
||||
state_var<nl_double> m_G;
|
||||
state_var<double> m_Vd;
|
||||
state_var<double> m_Id;
|
||||
state_var<double> m_G;
|
||||
|
||||
nl_double m_Vt;
|
||||
nl_double m_Is;
|
||||
nl_double m_n;
|
||||
nl_double m_gmin;
|
||||
double m_Vt;
|
||||
double m_Vmin;
|
||||
double m_Is;
|
||||
double m_n;
|
||||
double m_gmin;
|
||||
|
||||
nl_double m_VtInv;
|
||||
nl_double m_Vcrit;
|
||||
double m_VtInv;
|
||||
double m_Vcrit;
|
||||
};
|
||||
|
||||
/*! Class representing the diode model paramers.
|
||||
|
@ -578,7 +578,7 @@ core_device_t::core_device_t(netlist_t &owner, const pstring &name)
|
||||
, logic_family_t()
|
||||
, netlist_ref(owner)
|
||||
, m_hint_deactivate(false)
|
||||
#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
|
||||
#if (!NL_USE_PMF_VIRTUAL)
|
||||
, m_static_update()
|
||||
#endif
|
||||
{
|
||||
@ -591,7 +591,7 @@ core_device_t::core_device_t(core_device_t &owner, const pstring &name)
|
||||
, logic_family_t()
|
||||
, netlist_ref(owner.netlist())
|
||||
, m_hint_deactivate(false)
|
||||
#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
|
||||
#if (!NL_USE_PMF_VIRTUAL)
|
||||
, m_static_update()
|
||||
#endif
|
||||
{
|
||||
@ -607,14 +607,8 @@ core_device_t::~core_device_t()
|
||||
|
||||
void core_device_t::set_delegate_pointer()
|
||||
{
|
||||
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
||||
void (core_device_t::* pFunc)() = &core_device_t::update;
|
||||
m_static_update = pFunc;
|
||||
#elif (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV)
|
||||
void (core_device_t::* pFunc)() = &core_device_t::update;
|
||||
m_static_update = reinterpret_cast<net_update_delegate>((this->*pFunc));
|
||||
#elif (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL)
|
||||
m_static_update = plib::mfp::get_mfp<net_update_delegate>(&core_device_t::update, this);
|
||||
#if (!NL_USE_PMF_VIRTUAL)
|
||||
m_static_update.set_base(&core_device_t::update, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1082,12 +1082,10 @@ namespace netlist
|
||||
|
||||
void do_update() NL_NOEXCEPT
|
||||
{
|
||||
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
||||
(this->*m_static_update)();
|
||||
#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
|
||||
m_static_update(this);
|
||||
#if (NL_USE_PMF_VIRTUAL)
|
||||
update();
|
||||
#else
|
||||
update();
|
||||
m_static_update.call(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1104,14 +1102,9 @@ namespace netlist
|
||||
|
||||
private:
|
||||
bool m_hint_deactivate;
|
||||
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF)
|
||||
typedef void (core_device_t::*net_update_delegate)();
|
||||
#elif ((NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV) || (NL_PMF_TYPE == NL_PMF_TYPE_INTERNAL))
|
||||
using net_update_delegate = MEMBER_ABI void (*)(core_device_t *);
|
||||
#endif
|
||||
|
||||
#if (NL_PMF_TYPE > NL_PMF_TYPE_VIRTUAL)
|
||||
net_update_delegate m_static_update;
|
||||
#if (!NL_USE_PMF_VIRTUAL)
|
||||
plib::pmfp_base<void> m_static_update;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1277,11 +1270,11 @@ namespace netlist
|
||||
|
||||
template<typename O, typename C> void save(O &owner, C &state, const pstring &stname)
|
||||
{
|
||||
this->state().save_item(static_cast<void *>(&owner), state, pstring::from_utf8(owner.name()) + pstring(".") + stname);
|
||||
this->state().save_item(static_cast<void *>(&owner), state, from_utf8(owner.name()) + pstring(".") + stname);
|
||||
}
|
||||
template<typename O, typename C> void save(O &owner, C *state, const pstring &stname, const std::size_t count)
|
||||
{
|
||||
this->state().save_state_ptr(static_cast<void *>(&owner), pstring::from_utf8(owner.name()) + pstring(".") + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
|
||||
this->state().save_state_ptr(static_cast<void *>(&owner), from_utf8(owner.name()) + pstring(".") + stname, plib::state_manager_t::datatype_f<C>::f(), count, state);
|
||||
}
|
||||
|
||||
void rebuild_lists(); /* must be called after post_load ! */
|
||||
@ -1299,6 +1292,10 @@ namespace netlist
|
||||
|
||||
private:
|
||||
|
||||
/* helper for save above */
|
||||
static pstring from_utf8(const char *c) { return pstring(c, pstring::UTF8); }
|
||||
static pstring from_utf8(const pstring &c) { return c; }
|
||||
|
||||
core_device_t *pget_single_device(const pstring classname, bool (*cc)(core_device_t *));
|
||||
|
||||
/* mostly rw */
|
||||
|
@ -18,59 +18,6 @@
|
||||
// SETUP
|
||||
//============================================================
|
||||
|
||||
/*
|
||||
* The following options determine how object::update is called.
|
||||
* NL_PMF_TYPE_VIRTUAL
|
||||
* Use stock virtual call
|
||||
*
|
||||
* NL_PMF_TYPE_GNUC_PMF
|
||||
* Use standard pointer to member function syntax
|
||||
*
|
||||
* NL_PMF_TYPE_GNUC_PMF_CONV
|
||||
* Use gnu extension and convert the pmf to a function pointer.
|
||||
* This is not standard compliant and needs
|
||||
* -Wno-pmf-conversions to compile.
|
||||
*
|
||||
* NL_PMF_TYPE_INTERNAL
|
||||
* Use the same approach as MAME for deriving the function pointer.
|
||||
* This is compiler-dependant as well
|
||||
*
|
||||
* Benchmarks for ./nltool -c run -f src/mame/drivers/nl_pong.c -t 10 -n pong_fast
|
||||
*
|
||||
* NL_PMF_TYPE_INTERNAL: 215%
|
||||
* NL_PMF_TYPE_GNUC_PMF: 163%
|
||||
* NL_PMF_TYPE_GNUC_PMF_CONV: 215%
|
||||
* NL_PMF_TYPE_VIRTUAL: 213%
|
||||
*
|
||||
* The whole exercise was done to avoid virtual calls. In prior versions of
|
||||
* netlist, the INTERNAL and GNUC_PMF_CONV approach provided significant improvement.
|
||||
* Since than, was removed from functions declared as virtual.
|
||||
* This may explain that the recent benchmarks show no difference at all.
|
||||
*
|
||||
* Disappointing is the GNUC_PMF performance.
|
||||
*/
|
||||
|
||||
// This will be autodetected
|
||||
// #define NL_PMF_TYPE 0
|
||||
|
||||
#define NL_PMF_TYPE_VIRTUAL 0
|
||||
#define NL_PMF_TYPE_GNUC_PMF 1
|
||||
#define NL_PMF_TYPE_GNUC_PMF_CONV 2
|
||||
#define NL_PMF_TYPE_INTERNAL 3
|
||||
|
||||
#ifndef NL_PMF_TYPE
|
||||
#if PHAS_PMF_INTERNAL
|
||||
#define NL_PMF_TYPE NL_PMF_TYPE_INTERNAL
|
||||
#else
|
||||
#define NL_PMF_TYPE NL_PMF_TYPE_VIRTUAL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (NL_PMF_TYPE == NL_PMF_TYPE_GNUC_PMF_CONV)
|
||||
#pragma GCC diagnostic ignored "-Wpmf-conversions"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
//============================================================
|
||||
// GENERAL
|
||||
@ -156,6 +103,20 @@ using nperfcount_t = plib::chrono::counter<false>;
|
||||
#define NL_FCONST(x) x
|
||||
using nl_double = double;
|
||||
|
||||
/* The following option determines how object::update is called.
|
||||
* If set to 1, a virtual call is used. If it is left undefined, the best
|
||||
* approach will be automatically selected.
|
||||
*/
|
||||
|
||||
//#define NL_USE_PMF_VIRTUAL 1
|
||||
|
||||
#ifndef NL_USE_PMF_VIRTUAL
|
||||
#if PPMF_TYPE == PPMF_TYPE_PMF
|
||||
#define NL_USE_PMF_VIRTUAL 1
|
||||
#else
|
||||
#define NL_USE_PMF_VIRTUAL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// WARNINGS
|
||||
|
@ -63,6 +63,42 @@ typedef __int128_t INT128;
|
||||
// cut down delegate implementation
|
||||
//============================================================
|
||||
|
||||
/*
|
||||
*
|
||||
* NL_PMF_TYPE_GNUC_PMF
|
||||
* Use standard pointer to member function syntax C++11
|
||||
*
|
||||
* NL_PMF_TYPE_GNUC_PMF_CONV
|
||||
* Use gnu extension and convert the pmf to a function pointer.
|
||||
* This is not standard compliant and needs
|
||||
* -Wno-pmf-conversions to compile.
|
||||
*
|
||||
* NL_PMF_TYPE_INTERNAL
|
||||
* Use the same approach as MAME for deriving the function pointer.
|
||||
* This is compiler-dependent as well
|
||||
*
|
||||
* Benchmarks for ./nltool -c run -f src/mame/machine/nl_pong.cpp -t 10 -n pong_fast
|
||||
*
|
||||
* NL_PMF_TYPE_INTERNAL: 215% 215%
|
||||
* NL_PMF_TYPE_GNUC_PMF: 163% 196%
|
||||
* NL_PMF_TYPE_GNUC_PMF_CONV: 215% 215%
|
||||
* NL_PMF_TYPE_VIRTUAL: 213% 209%
|
||||
*
|
||||
* The whole exercise was done to avoid virtual calls. In prior versions of
|
||||
* netlist, the INTERNAL and GNUC_PMF_CONV approach provided significant improvement.
|
||||
* Since than, "hot" was removed from functions declared as virtual.
|
||||
* This may explain that the recent benchmarks show no difference at all.
|
||||
*
|
||||
*/
|
||||
|
||||
// This will be autodetected
|
||||
// #define PPMF_TYPE 1
|
||||
|
||||
#define PPMF_TYPE_PMF 0
|
||||
#define PPMF_TYPE_GNUC_PMF_CONV 1
|
||||
#define PPMF_TYPE_INTERNAL 2
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* does not work in versions over 4.7.x of 32bit MINGW */
|
||||
#if defined(__MINGW32__) && !defined(__x86_64) && defined(__i386__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
|
||||
@ -87,6 +123,18 @@ typedef __int128_t INT128;
|
||||
#define MEMBER_ABI
|
||||
#endif
|
||||
|
||||
#ifndef PPMF_TYPE
|
||||
#if PHAS_PMF_INTERNAL
|
||||
#define PPMF_TYPE PPMF_TYPE_INTERNAL
|
||||
#else
|
||||
#define PPMF_TYPE PPMF_TYPE_PMF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (PPMF_TYPE == PPMF_TYPE_GNUC_PMF_CONV)
|
||||
#pragma GCC diagnostic ignored "-Wpmf-conversions"
|
||||
#endif
|
||||
|
||||
namespace plib {
|
||||
/*
|
||||
* The following class was derived from the MAME delegate.h code.
|
||||
@ -108,18 +156,13 @@ namespace plib {
|
||||
*reinterpret_cast<MemberFunctionType *>(this) = mftp;
|
||||
}
|
||||
|
||||
// binding helper
|
||||
template<typename FunctionType, typename ObjectType>
|
||||
FunctionType update_after_bind(ObjectType *object)
|
||||
{
|
||||
return reinterpret_cast<FunctionType>(
|
||||
convert_to_generic(reinterpret_cast<generic_class *>(object)));
|
||||
}
|
||||
template<typename FunctionType, typename MemberFunctionType, typename ObjectType>
|
||||
static FunctionType get_mfp(MemberFunctionType mftp, ObjectType *object)
|
||||
{
|
||||
mfp mfpo(mftp);
|
||||
return mfpo.update_after_bind<FunctionType>(object);
|
||||
//return mfpo.update_after_bind<FunctionType>(object);
|
||||
return reinterpret_cast<FunctionType>(
|
||||
mfpo.convert_to_generic(reinterpret_cast<generic_class *>(object)));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -144,9 +187,89 @@ namespace plib {
|
||||
// if odd, it's the byte offset into the vtable
|
||||
int m_this_delta; // delta to apply to the 'this' pointer
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if (PPMF_TYPE == PPMF_TYPE_PMF)
|
||||
template<typename R, typename... Targs>
|
||||
class pmfp_base
|
||||
{
|
||||
public:
|
||||
class generic_class;
|
||||
using generic_function = R (generic_class::*)(Targs...);
|
||||
pmfp_base() : m_func(nullptr) {}
|
||||
|
||||
template<typename MemberFunctionType, typename O>
|
||||
void set_base(MemberFunctionType mftp, O *object)
|
||||
{
|
||||
using function_ptr = R (O::*)(Targs...);
|
||||
function_ptr t = mftp;
|
||||
m_func = reinterpret_cast<generic_function>(t);
|
||||
}
|
||||
template<typename O>
|
||||
inline R call(O *obj, Targs... args) const
|
||||
{
|
||||
using function_ptr = R (O::*)(Targs...);
|
||||
function_ptr t = reinterpret_cast<function_ptr>(m_func);
|
||||
return (obj->*t)(std::forward<Targs>(args)...);
|
||||
}
|
||||
private:
|
||||
generic_function m_func;
|
||||
};
|
||||
|
||||
#elif ((PPMF_TYPE == PPMF_TYPE_GNUC_PMF_CONV) || (PPMF_TYPE == PPMF_TYPE_INTERNAL))
|
||||
template<typename R, typename... Targs>
|
||||
class pmfp_base
|
||||
{
|
||||
public:
|
||||
using generic_function = void (*)();
|
||||
|
||||
pmfp_base() : m_func(nullptr) {}
|
||||
|
||||
template<typename MemberFunctionType, typename O>
|
||||
void set_base(MemberFunctionType mftp, O *object)
|
||||
{
|
||||
#if (PPMF_TYPE == PPMF_TYPE_INTERNAL)
|
||||
using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args);
|
||||
m_func = reinterpret_cast<generic_function>(plib::mfp::get_mfp<function_ptr>(mftp, object));
|
||||
#elif (PPMF_TYPE == PPMF_TYPE_GNUC_PMF_CONV)
|
||||
R (O::* pFunc)(Targs...) = mftp;
|
||||
m_func = reinterpret_cast<generic_function>((object->*pFunc));
|
||||
#endif
|
||||
}
|
||||
template<typename O>
|
||||
inline R call(O *obj, Targs... args) const
|
||||
{
|
||||
using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args);
|
||||
return (*reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...);
|
||||
}
|
||||
private:
|
||||
generic_function m_func;
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename R, typename... Targs>
|
||||
class pmfp : public pmfp_base<R, Targs...>
|
||||
{
|
||||
public:
|
||||
class generic_class;
|
||||
pmfp() : pmfp_base<R, Targs...>(), m_obj(nullptr) {}
|
||||
|
||||
template<typename MemberFunctionType, typename O>
|
||||
void set(MemberFunctionType mftp, O *object)
|
||||
{
|
||||
this->set_base(mftp, object);
|
||||
m_obj = reinterpret_cast<generic_class *>(object);
|
||||
}
|
||||
|
||||
inline R operator()(Targs... args) const
|
||||
{
|
||||
return this->call(m_obj, std::forward<Targs>(args)...);
|
||||
}
|
||||
private:
|
||||
generic_class *m_obj;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* PCONFIG_H_ */
|
||||
|
@ -81,7 +81,7 @@ void pfunction::compile_postfix(const std::vector<pstring> &inputs,
|
||||
throw plib::pexception(plib::pfmt("nld_function: stack count different to one on <{2}>")(expr));
|
||||
}
|
||||
|
||||
int get_prio(pstring v)
|
||||
static int get_prio(pstring v)
|
||||
{
|
||||
if (v == "(" or v == ")")
|
||||
return 1;
|
||||
|
@ -371,7 +371,7 @@ void pstringbuffer::pcat(const pstring &s)
|
||||
* This improves startup performance by 30%.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
|
||||
static std::stack<pstr_t *> *stk = nullptr;
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
struct pstr_t
|
||||
{
|
||||
pstr_t(const int alen) { init(alen); }
|
||||
pstr_t(const std::size_t alen) { init(alen); }
|
||||
void init(const std::size_t alen)
|
||||
{
|
||||
m_ref_count = 1;
|
||||
@ -169,13 +169,6 @@ public:
|
||||
|
||||
const pstring_t ucase() const;
|
||||
|
||||
// FIXME: do something with encoding
|
||||
// FIXME: belongs into derived class
|
||||
// This is only used in state saving to support "owners" whose name() function
|
||||
// returns char*.
|
||||
static pstring_t from_utf8(const mem_t *c) { return pstring_t(c, UTF8); }
|
||||
static pstring_t from_utf8(const pstring_t &c) { return c; }
|
||||
|
||||
static void resetmem();
|
||||
|
||||
protected:
|
||||
|
@ -502,12 +502,30 @@ static const pstring pmf_verbose[] =
|
||||
};
|
||||
#endif
|
||||
|
||||
struct tt
|
||||
{
|
||||
void test(int a) {printf ("test :%d\n", a);}
|
||||
int test1() { return 1;}
|
||||
};
|
||||
|
||||
plib::pmfp<void, int> atest;
|
||||
plib::pmfp<int> atest1;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
tool_options_t opts;
|
||||
int ret;
|
||||
|
||||
tt x;
|
||||
|
||||
atest.set(&tt::test, &x);
|
||||
atest1.set(&tt::test1, &x);
|
||||
|
||||
atest(1);
|
||||
int a = atest1();
|
||||
|
||||
printf("%d\n", a);
|
||||
//return 1 ;
|
||||
/* make SIGFPE actually deliver signals on supoorted platforms */
|
||||
plib::fpsignalenabler::global_enable(true);
|
||||
plib::fpsignalenabler sigen(plib::FP_ALL & ~plib::FP_INEXACT & ~plib::FP_UNDERFLOW);
|
||||
|
Loading…
Reference in New Issue
Block a user