summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Couriersud <couriersud@users.noreply.github.com>2014-01-02 14:40:36 +0000
committer Couriersud <couriersud@users.noreply.github.com>2014-01-02 14:40:36 +0000
commit838276728a99327d99e45768bac9cc659160d7b1 (patch)
tree1865bc684a201354e8842f9da2a847b5395bfc89 /src
parente778a278d7c08399a6232ce5625aad463645f0bf (diff)
Netlist:
- fixed 7474 save state - remove a printf - simplified netlist_list_t - increased reschedule count to 15 - diodes are dog-slow - made reschedule count a solver parameter - simplified solver code - solver time now also resets
Diffstat (limited to 'src')
-rw-r--r--src/emu/machine/netlist.c2
-rw-r--r--src/emu/netlist/devices/nld_7474.c15
-rw-r--r--src/emu/netlist/devices/nld_solver.c253
-rw-r--r--src/emu/netlist/devices/nld_solver.h17
-rw-r--r--src/emu/netlist/devices/nld_twoterm.c6
-rw-r--r--src/emu/netlist/nl_base.c6
-rw-r--r--src/emu/netlist/nl_base.h6
-rw-r--r--src/emu/netlist/nl_lists.h51
8 files changed, 174 insertions, 182 deletions
diff --git a/src/emu/machine/netlist.c b/src/emu/machine/netlist.c
index 9ddef77cc29..dd2377e03e8 100644
--- a/src/emu/machine/netlist.c
+++ b/src/emu/machine/netlist.c
@@ -178,7 +178,7 @@ void netlist_mame_device_t::device_start()
{
LOG_DEV_CALLS(("device_start %s\n", tag()));
- printf("clock is %d\n", clock());
+ //printf("clock is %d\n", clock());
m_netlist = global_alloc_clear(netlist_mame_t(*this));
m_setup = global_alloc_clear(netlist_setup_t(*m_netlist));
diff --git a/src/emu/netlist/devices/nld_7474.c b/src/emu/netlist/devices/nld_7474.c
index ef23fe819c5..90d11c3e284 100644
--- a/src/emu/netlist/devices/nld_7474.c
+++ b/src/emu/netlist/devices/nld_7474.c
@@ -47,13 +47,13 @@ NETLIB_START(7474)
{
register_sub(sub, "sub");
- register_subalias("CLK", sub.m_clk);
- register_input("D", m_D);
- register_input("CLRQ", m_clrQ);
- register_input("PREQ", m_preQ);
+ register_subalias("CLK", sub.m_clk);
+ register_input("D", m_D);
+ register_input("CLRQ", m_clrQ);
+ register_input("PREQ", m_preQ);
- register_subalias("Q", sub.m_Q);
- register_subalias("QQ", sub.m_QQ);
+ register_subalias("Q", sub.m_Q);
+ register_subalias("QQ", sub.m_QQ);
}
@@ -64,6 +64,9 @@ NETLIB_START(7474sub)
register_output("Q", m_Q);
register_output("QQ", m_QQ);
+ m_nextD = 0;
m_Q.initial(1);
m_QQ.initial(0);
+
+ save(NAME(m_nextD));
}
diff --git a/src/emu/netlist/devices/nld_solver.c b/src/emu/netlist/devices/nld_solver.c
index 99f6a1d33c4..9055d5f1781 100644
--- a/src/emu/netlist/devices/nld_solver.c
+++ b/src/emu/netlist/devices/nld_solver.c
@@ -47,8 +47,8 @@ ATTR_COLD void netlist_matrix_solver_t::setup(netlist_net_t::list_t &nets, NETLI
NL_VERBOSE_OUT(("Added terminal\n"));
break;
case netlist_terminal_t::INPUT:
- if (!m_inps.contains(&p->netdev()))
- m_inps.add(&p->netdev());
+ if (!m_inps.contains(p))
+ m_inps.add(p);
NL_VERBOSE_OUT(("Added input\n"));
break;
default:
@@ -68,103 +68,85 @@ ATTR_HOT inline void netlist_matrix_solver_t::step(const netlist_time delta)
ATTR_HOT inline void netlist_matrix_solver_t::update_inputs()
{
- for (dev_list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ for (netlist_core_terminal_t::list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
{
- p->object()->update_dev();
+ if (p->object()->net().m_last.Analog != p->object()->net().m_cur.Analog)
+ {
+ p->object()->netdev().update_dev();
+ }
}
+ for (netlist_core_terminal_t::list_t::entry_t *p = m_inps.first(); p != NULL; p = m_inps.next(p))
+ {
+ p->object()->net().m_last.Analog = p->object()->net().m_cur.Analog;
+ }
+
}
ATTR_HOT inline bool netlist_matrix_solver_t::solve()
{
- bool resched = false;
-
- /* update all non-linear devices */
- for (dev_list_t::entry_t *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
- switch (p->object()->family())
- {
- case netlist_device_t::DIODE:
- static_cast<NETLIB_NAME(D) *>(p->object())->update_terminals();
- break;
- default:
- p->object()->update_terminals();
- break;
- }
+ bool resched;
+ // FIXME: There may be situations where we *could* need more than one iteration for dynamic elements
+
+ int resched_cnt = (is_dynamic() ? /* 0 */ 1 : 1);
+ ATTR_UNUSED netlist_net_t *last_resched_net = NULL;
+
+ do {
+ resched = false;
+ /* update all non-linear devices */
+ for (dev_list_t::entry_t *p = m_dynamic.first(); p != NULL; p = m_dynamic.next(p))
+ switch (p->object()->family())
+ {
+ case netlist_device_t::DIODE:
+ static_cast<NETLIB_NAME(D) *>(p->object())->update_terminals();
+ break;
+ default:
+ p->object()->update_terminals();
+ break;
+ }
+
+ for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
+ {
+ netlist_net_t *net = pn->object();
+ const netlist_net_t::terminal_list_t &terms = net->m_terms;
+
+ double gtot = 0;
+ double gabs = 0;
+ double iIdr = 0;
+ double new_val;
+
+ for (int i = 0; i < terms.count(); i++)
+ {
+ gtot += terms[i]->m_gt;
+ gabs += fabs(terms[i]->m_go);
+ iIdr += terms[i]->m_Idr + terms[i]->m_go * terms[i]->m_otherterm->net().Q_Analog();
+ }
+
+ gabs *= m_convergence_factor;
+ if (gabs > gtot)
+ new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
+ else
+ new_val = iIdr / gtot;
+
+ if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
+ {
+ resched = true;
+ last_resched_net = net;
+ }
+
+ net->m_cur.Analog = net->m_new.Analog = new_val;
+
+ NL_VERBOSE_OUT(("Info: %d\n", pn->object()->m_num_cons));
+ //NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
+ }
+ resched_cnt++;
+ } while ((resched && (resched_cnt < m_resched_loops)) || (resched_cnt <= 1));
+
+ if (!resched)
+ update_inputs();
+ //if (resched)
+ //printf("Resched on net %s first term %s\n", last_resched_net->name().cstr(), last_resched_net->m_terms[0]->name().cstr());
- for (netlist_net_t::list_t::entry_t *pn = m_nets.first(); pn != NULL; pn = m_nets.next(pn))
- {
- netlist_net_t *net = pn->object();
-
- double gtot = 0;
- double gabs = 0;
- double iIdr = 0;
- const netlist_net_t::terminal_list_t &terms = net->m_terms;
-#if 1
- switch (terms.count())
- {
- case 1:
- {
- const netlist_terminal_t *pt = terms.first()->object();
- gtot = pt->m_gt;
- gabs = fabs(pt->m_go);
- iIdr = pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
- }
- break;
- case 2:
- {
- const netlist_terminal_t *pt1 = terms[0];
- const netlist_terminal_t *pt2 = terms[1];
- gtot = pt1->m_gt + pt2->m_gt;
- gabs = fabs(pt1->m_go) + fabs(pt2->m_go);
- iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
- + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog();
- }
- break;
- case 3:
- {
- const netlist_terminal_t *pt1 = terms[0];
- const netlist_terminal_t *pt2 = terms[1];
- const netlist_terminal_t *pt3 = terms[2];
- gtot = pt1->m_gt + pt2->m_gt + pt3->m_gt;
- gabs = fabs(pt1->m_go) + fabs(pt2->m_go) + fabs(pt3->m_go);
- iIdr = pt1->m_Idr + pt1->m_go * pt1->m_otherterm->net().Q_Analog()
- + pt2->m_Idr + pt2->m_go * pt2->m_otherterm->net().Q_Analog()
- + pt3->m_Idr + pt3->m_go * pt3->m_otherterm->net().Q_Analog();
- }
- break;
- default:
- for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
- {
- netlist_terminal_t *pt = e->object();
- gtot += pt->m_gt;
- gabs += fabs(pt->m_go);
- iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
- }
- break;
- }
-#else
- for (netlist_net_t::terminal_list_t::entry_t *e = terms.first(); e != NULL; e = terms.next(e))
- {
- netlist_terminal_t *pt = e->object();
- gtot += pt->m_gt;
- gabs += fabs(pt->m_go);
- iIdr += pt->m_Idr + pt->m_go * pt->m_otherterm->net().Q_Analog();
- }
-#endif
- double new_val;
- gabs *= m_convergence_factor;
- if (gabs > gtot)
- new_val = (net->m_cur.Analog * gabs + iIdr) / (gtot + gabs);
- else
- new_val = iIdr / gtot;
-
- if (fabs(new_val - net->m_cur.Analog) > m_accuracy)
- resched = true;
- net->m_cur.Analog = net->m_new.Analog = new_val;
-
- NL_VERBOSE_OUT(("Info: %d\n", pn->object()->m_num_cons));
- //NL_VERBOSE_OUT(("New: %lld %f %f\n", netlist().time().as_raw(), netlist().time().as_double(), new_val));
- }
return resched;
}
@@ -174,7 +156,7 @@ ATTR_HOT inline bool netlist_matrix_solver_t::solve()
typedef netlist_net_t::list_t *net_groups_t;
-static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
+ATTR_COLD static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t *net)
{
if (net->isRailNet())
return true;
@@ -186,7 +168,7 @@ static bool already_processed(net_groups_t groups, int &cur_group, netlist_net_t
return false;
}
-static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
+ATTR_COLD static void process_net(net_groups_t groups, int &cur_group, netlist_net_t *net)
{
/* add the net */
if (net->m_head == NULL)
@@ -219,6 +201,7 @@ NETLIB_START(solver)
register_param("ACCURACY", m_accuracy, 1e-3);
register_param("CONVERG", m_convergence, 0.3);
+ register_param("RESCHED_LOOPS", m_resched_loops, 15);
// internal staff
@@ -251,44 +234,8 @@ NETLIB_NAME(solver)::~NETLIB_NAME(solver)()
}
-NETLIB_FUNC_VOID(solver, post_start, ())
-{
- netlist_net_t::list_t groups[100];
- int cur_group = -1;
-
- SOLVER_VERBOSE_OUT(("Scanning net groups ...\n"));
- // determine net groups
- for (netlist_net_t::list_t::entry_t *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn))
- {
- if (!already_processed(groups, cur_group, pn->object()))
- {
- cur_group++;
- process_net(groups, cur_group, pn->object());
- }
- }
-
- // setup the solvers
- SOLVER_VERBOSE_OUT(("Found %d net groups in %d nets\n", cur_group + 1, m_nets.count()));
- for (int i = 0; i <= cur_group; i++)
- {
- netlist_matrix_solver_t *ms = new netlist_matrix_solver_t();
- ms->m_accuracy = m_accuracy.Value();
- ms->m_convergence_factor = m_convergence.Value();
- ms->setup(groups[i], *this);
- m_mat_solvers.add(ms);
- SOLVER_VERBOSE_OUT(("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr()));
- SOLVER_VERBOSE_OUT((" has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic"));
- }
-
-}
-
NETLIB_UPDATE(solver)
{
- //m_Q.setToNoCheck(!m_Q.new_Q(), m_inc );
- //OUTLOGIC(m_Q, !m_Q.net().new_Q(), m_inc );
-
- bool resched = false;
- int resched_cnt = 0;
netlist_time now = netlist().time();
netlist_time delta = now - m_last_step;
@@ -305,30 +252,50 @@ NETLIB_UPDATE(solver)
bool global_resched = false;
for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
{
- resched_cnt = (e->object()->is_dynamic() ? 0 : 1);
- do {
- resched = e->object()->solve();
- resched_cnt++;
- } while ((resched && (resched_cnt < 5)) || (resched_cnt <= 1));
- global_resched = global_resched || resched;
+ global_resched = global_resched || e->object()->solve();
}
- //if (global_resched)
- // printf("rescheduled\n");
if (global_resched)
{
schedule();
}
else
{
- /* update all inputs connected */
- for (netlist_matrix_solver_t::list_t::entry_t *e = m_mat_solvers.first(); e != NULL; e = m_mat_solvers.next(e))
- {
- e->object()->update_inputs();
- }
-
/* step circuit */
if (!m_Q_step.net().is_queued())
m_Q_step.net().push_to_queue(m_inc);
}
}
+
+ATTR_COLD void NETLIB_NAME(solver)::post_start()
+{
+ netlist_net_t::list_t groups[100];
+ int cur_group = -1;
+
+ SOLVER_VERBOSE_OUT(("Scanning net groups ...\n"));
+ // determine net groups
+ for (netlist_net_t::list_t::entry_t *pn = netlist().m_nets.first(); pn != NULL; pn = netlist().m_nets.next(pn))
+ {
+ if (!already_processed(groups, cur_group, pn->object()))
+ {
+ cur_group++;
+ process_net(groups, cur_group, pn->object());
+ }
+ }
+
+ // setup the solvers
+ SOLVER_VERBOSE_OUT(("Found %d net groups in %d nets\n", cur_group + 1, netlist().m_nets.count()));
+ for (int i = 0; i <= cur_group; i++)
+ {
+ netlist_matrix_solver_t *ms = new netlist_matrix_solver_t();
+ ms->m_accuracy = m_accuracy.Value();
+ ms->m_convergence_factor = m_convergence.Value();
+ ms->m_resched_loops = m_resched_loops.Value();
+ ms->setup(groups[i], *this);
+ m_mat_solvers.add(ms);
+ SOLVER_VERBOSE_OUT(("%d ==> %d nets %s\n", i, groups[i].count(), groups[i].first()->object()->m_head->name().cstr()));
+ SOLVER_VERBOSE_OUT((" has %s elements\n", ms->is_dynamic() ? "dynamic" : "no dynamic"));
+ SOLVER_VERBOSE_OUT((" has %s elements\n", ms->is_timestep() ? "timestep" : "no timestep"));
+ }
+
+}
diff --git a/src/emu/netlist/devices/nld_solver.h b/src/emu/netlist/devices/nld_solver.h
index 0f9d0f54c28..c937e42386b 100644
--- a/src/emu/netlist/devices/nld_solver.h
+++ b/src/emu/netlist/devices/nld_solver.h
@@ -36,16 +36,18 @@ public:
ATTR_HOT void update_inputs();
ATTR_HOT inline bool is_dynamic() { return m_dynamic.count() > 0; }
+ ATTR_HOT inline bool is_timestep() { return m_steps.count() > 0; }
- inline const NETLIB_NAME(solver) &owner() const;
+ ATTR_HOT inline const NETLIB_NAME(solver) &owner() const;
double m_accuracy;
double m_convergence_factor;
+ int m_resched_loops;
private:
netlist_net_t::list_t m_nets;
dev_list_t m_dynamic;
- dev_list_t m_inps;
+ netlist_core_terminal_t::list_t m_inps;
dev_list_t m_steps;
NETLIB_NAME(solver) *m_owner;
@@ -64,6 +66,7 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
netlist_param_double_t m_sync_delay;
netlist_param_double_t m_accuracy;
netlist_param_double_t m_convergence;
+ netlist_param_int_t m_resched_loops;
netlist_time m_inc;
netlist_time m_last_step;
@@ -72,21 +75,25 @@ NETLIB_DEVICE_WITH_PARAMS(solver,
netlist_matrix_solver_t::list_t m_mat_solvers;
public:
- ~NETLIB_NAME(solver)();
+ ATTR_COLD ~NETLIB_NAME(solver)();
ATTR_HOT inline void schedule();
ATTR_COLD void post_start();
+ ATTR_COLD void reset()
+ {
+ m_last_step = netlist_time::zero;
+ }
);
-inline void NETLIB_NAME(solver)::schedule()
+ATTR_HOT inline void NETLIB_NAME(solver)::schedule()
{
// FIXME: time should be parameter;
if (!m_Q_sync.net().is_queued())
m_Q_sync.net().push_to_queue(m_nt_sync_delay);
}
-inline const NETLIB_NAME(solver) &netlist_matrix_solver_t::owner() const
+ATTR_HOT inline const NETLIB_NAME(solver) &netlist_matrix_solver_t::owner() const
{
return *m_owner;
}
diff --git a/src/emu/netlist/devices/nld_twoterm.c b/src/emu/netlist/devices/nld_twoterm.c
index ba647e35420..cbd4e3b8cf8 100644
--- a/src/emu/netlist/devices/nld_twoterm.c
+++ b/src/emu/netlist/devices/nld_twoterm.c
@@ -207,6 +207,12 @@ NETLIB_START(QBJT_switch<_type>)
setup().connect(m_RB.m_N, m_EV);
save(NAME(m_state_on));
+
+ m_RB.set(NETLIST_GMIN, 0.0, 0.0);
+ m_RC.set(NETLIST_GMIN, 0.0, 0.0);
+
+ m_state_on = 0;
+
}
NETLIB_UPDATE(Q)
diff --git a/src/emu/netlist/nl_base.c b/src/emu/netlist/nl_base.c
index 7704fc6fdec..eb86f8b93ea 100644
--- a/src/emu/netlist/nl_base.c
+++ b/src/emu/netlist/nl_base.c
@@ -5,6 +5,7 @@
#include "nl_base.h"
#include "devices/nld_system.h"
+#include "devices/nld_solver.h"
#include "pstring.h"
#include "nl_util.h"
@@ -170,6 +171,8 @@ ATTR_COLD void netlist_base_t::reset()
m_queue.clear();
if (m_mainclock != NULL)
m_mainclock->m_Q.net().set_time(netlist_time::zero);
+ if (m_solver != NULL)
+ m_solver->reset();
// FIXME: some const devices rely on this
/* make sure params are set now .. */
@@ -429,6 +432,9 @@ ATTR_COLD netlist_net_t::netlist_net_t(const type_t atype, const family_t afamil
, m_in_queue(2)
, m_railterminal(NULL)
{
+ m_last.Analog = -123456789.0; // set to something we will never hit.
+ m_new.Analog = 0.0;
+ m_cur.Analog = 0.0;
};
ATTR_COLD void netlist_net_t::init_object(netlist_base_t &nl, const pstring &aname)
diff --git a/src/emu/netlist/nl_base.h b/src/emu/netlist/nl_base.h
index b0c9d238f96..92087f91bff 100644
--- a/src/emu/netlist/nl_base.h
+++ b/src/emu/netlist/nl_base.h
@@ -332,6 +332,8 @@ class netlist_core_terminal_t : public netlist_owned_object_t
NETLIST_PREVENT_COPYING(netlist_core_terminal_t)
public:
+ typedef netlist_list_t<netlist_core_terminal_t *> list_t;
+
/* needed here ... */
enum state_e {
@@ -1093,8 +1095,8 @@ protected:
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1));
else if (m_I.Q_Analog() < m_I.m_low_thresh_V)
OUTLOGIC(m_Q, 0, NLTIME_FROM_NS(1));
- else
- OUTLOGIC(m_Q, m_Q.net().last_Q(), NLTIME_FROM_NS(1));
+ //else
+ // OUTLOGIC(m_Q, m_Q.net().last_Q(), NLTIME_FROM_NS(1));
}
};
diff --git a/src/emu/netlist/nl_lists.h b/src/emu/netlist/nl_lists.h
index f38def1aa14..8f303d26140 100644
--- a/src/emu/netlist/nl_lists.h
+++ b/src/emu/netlist/nl_lists.h
@@ -20,10 +20,13 @@ struct netlist_list_t
{
public:
- struct entry_t {
+ struct entry_t
+ {
+ friend class netlist_list_t;
+ public:
// keep compatibility with tagmap
- _ListClass object() { return m_obj; }
-
+ ATTR_HOT inline _ListClass object() { return m_obj; }
+ private:
_ListClass m_obj;
};
@@ -31,16 +34,14 @@ public:
{
m_num_elements = numElements;
m_list = new entry_t[m_num_elements];
- m_ptr = m_list;
- m_ptr--;
+ m_count = 0;
}
ATTR_COLD netlist_list_t(const netlist_list_t &rhs)
{
m_num_elements = rhs.capacity();
m_list = new entry_t[m_num_elements];
- m_ptr = m_list;
- m_ptr--;
+ m_count = 0;
for (int i=0; i<rhs.count(); i++)
{
this->add(rhs[i]);
@@ -64,10 +65,10 @@ public:
ATTR_HOT inline void add(const _ListClass elem)
{
- if (m_ptr-m_list >= m_num_elements - 1)
+ if (m_count >= m_num_elements)
resize(m_num_elements * 2);
- (++m_ptr)->m_obj = elem;
+ m_list[m_count++].m_obj = elem;
}
ATTR_HOT inline void resize(const int new_size)
@@ -76,26 +77,26 @@ public:
entry_t *m_new = new entry_t[new_size];
entry_t *pd = m_new;
- for (entry_t *ps = m_list; ps <= m_ptr; ps++, pd++)
+ for (entry_t *ps = m_list; ps < m_list + cnt; ps++, pd++)
*pd = *ps;
delete[] m_list;
m_list = m_new;
- m_ptr = m_list + cnt - 1;
+ m_count = cnt;
m_num_elements = new_size;
}
ATTR_HOT inline void remove(const _ListClass elem)
{
- for (entry_t *i = m_list; i <= m_ptr; i++)
+ for (int i =0; i < m_count; i++)
{
- if (i->object() == elem)
+ if (m_list[i].object() == elem)
{
- while (i < m_ptr)
+ m_count --;
+ while (i < m_count)
{
- *i = *(i+1);
+ m_list[i] = m_list[i+1];
i++;
}
- m_ptr--;
return;
}
}
@@ -103,7 +104,7 @@ public:
ATTR_HOT inline bool contains(const _ListClass elem) const
{
- for (entry_t *i = m_list; i <= m_ptr; i++)
+ for (entry_t *i = m_list; i < m_list + m_count; i++)
{
if (i->object() == elem)
return true;
@@ -111,17 +112,17 @@ public:
return false;
}
- ATTR_HOT inline entry_t *first() const { return (m_ptr >= m_list ? &m_list[0] : NULL ); }
- ATTR_HOT inline entry_t *next(entry_t *lc) const { return (lc < last() ? lc + 1 : NULL ); }
- ATTR_HOT inline entry_t *last() const { return m_ptr; }
- ATTR_HOT inline int count() const { return m_ptr - m_list + 1; }
- ATTR_HOT inline bool empty() const { return (m_ptr < m_list); }
- ATTR_HOT inline void reset() { m_ptr = m_list - 1; }
+ ATTR_HOT inline entry_t *first() const { return ((m_count > 0) ? &m_list[0] : NULL ); }
+ ATTR_HOT inline entry_t *next(entry_t *lc) const { return ((lc < last()) ? lc + 1 : NULL ); }
+ ATTR_HOT inline entry_t *last() const { return &m_list[m_count -1]; }
+ ATTR_HOT inline int count() const { return m_count; }
+ ATTR_HOT inline bool empty() const { return (m_count == 0); }
+ ATTR_HOT inline void reset() { m_count = 0; }
ATTR_HOT inline int capacity() const { return m_num_elements; }
ATTR_COLD void reset_and_free()
{
- for (entry_t *i = m_list; i <= m_ptr; i++)
+ for (entry_t *i = m_list; i < m_list + m_count; i++)
{
delete i->object();
}
@@ -132,7 +133,7 @@ public:
ATTR_HOT inline const _ListClass& operator[](const int & index) const { return m_list[index].m_obj; }
private:
- entry_t * m_ptr;
+ int m_count;
entry_t * m_list;
int m_num_elements;
//_ListClass m_list[_NumElements];