summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pstate.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/pstate.h')
-rw-r--r--src/lib/netlist/plib/pstate.h173
1 files changed, 129 insertions, 44 deletions
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index ac75ca6b69e..72473590b9b 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -1,14 +1,13 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
-/*
- * pstate.h
- *
- */
#ifndef PSTATE_H_
#define PSTATE_H_
-#include "palloc.h"
+///
+/// \file pstate.h
+///
+
#include "pstring.h"
#include "ptypes.h"
@@ -28,16 +27,22 @@ public:
struct datatype_t
{
datatype_t(std::size_t bsize, bool bintegral, bool bfloat)
- : size(bsize), is_integral(bintegral), is_float(bfloat), is_custom(false)
+ : m_size(bsize), m_is_integral(bintegral), m_is_float(bfloat), m_is_custom(false)
{}
explicit datatype_t(bool bcustom)
- : size(0), is_integral(false), is_float(false), is_custom(bcustom)
+ : m_size(0), m_is_integral(false), m_is_float(false), m_is_custom(bcustom)
{}
- const std::size_t size;
- const bool is_integral;
- const bool is_float;
- const bool is_custom;
+ std::size_t size() const noexcept { return m_size; }
+ bool is_integral() const noexcept { return m_is_integral; }
+ bool is_float() const noexcept { return m_is_float; }
+ bool is_custom() const noexcept { return m_is_custom; }
+
+ private:
+ std::size_t m_size;
+ bool m_is_integral;
+ bool m_is_float;
+ bool m_is_custom;
};
template<typename T>
@@ -45,10 +50,10 @@ public:
{
return datatype_t(sizeof(T),
plib::is_integral<T>::value || std::is_enum<T>::value,
- std::is_floating_point<T>::value);
+ plib::is_floating_point<T>::value);
}
- class callback_t
+ struct callback_t
{
public:
using list_t = std::vector<callback_t *>;
@@ -58,85 +63,165 @@ public:
virtual void on_post_load(state_manager_t &manager) = 0;
protected:
callback_t() = default;
- ~callback_t() = default;
- COPYASSIGNMOVE(callback_t, default)
+ virtual ~callback_t() = default;
+ PCOPYASSIGNMOVE(callback_t, default)
};
struct entry_t
{
- using list_t = std::vector<plib::unique_ptr<entry_t>>;
+ using list_t = std::vector<entry_t>;
- entry_t(const pstring &stname, const datatype_t &dt, const void *owner,
+ entry_t(const pstring &item_name, const datatype_t &dt, const void *owner,
const std::size_t count, void *ptr)
- : m_name(stname), m_dt(dt), m_owner(owner), m_callback(nullptr), m_count(count), m_ptr(ptr) { }
+ : m_name(item_name), m_dt(dt), m_owner(owner), m_callback(nullptr), m_count(count), m_ptr(ptr) { }
- entry_t(const pstring &stname, const void *owner, callback_t *callback)
- : m_name(stname), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { }
+ entry_t(const pstring &item_name, const void *owner, callback_t *callback)
+ : m_name(item_name), m_dt(datatype_t(true)), m_owner(owner), m_callback(callback), m_count(0), m_ptr(nullptr) { }
+ pstring name() const noexcept { return m_name; }
+ datatype_t dt() const noexcept { return m_dt; }
+ const void * owner() const noexcept { return m_owner; }
+ callback_t * callback() const noexcept { return m_callback; }
+ std::size_t count() const noexcept { return m_count; }
+ void * ptr() const noexcept { return m_ptr; }
+
+ private:
pstring m_name;
- const datatype_t m_dt;
+ datatype_t m_dt;
const void * m_owner;
callback_t * m_callback;
- const std::size_t m_count;
+ std::size_t m_count;
void * m_ptr;
};
state_manager_t() = default;
+ struct saver_t
+ {
+ saver_t(state_manager_t &sm, const void *owner, const pstring &member_name)
+ : m_sm(sm)
+ , m_owner(owner)
+ , m_member_name(member_name)
+ { }
+
+ template <typename XS>
+ void save_item(XS &some_state, const pstring &item_name)
+ {
+ m_sm.save_item(m_owner, some_state, m_member_name + "." + item_name);
+ }
+
+ state_manager_t &m_sm;
+ const void * m_owner;
+ const pstring m_member_name;
+ };
+
template<typename C>
- void save_item(const void *owner, C &state, const pstring &stname)
+ void save_item(const void *owner, C &state, const pstring &item_name)
{
- save_state_ptr( owner, stname, dtype<C>(), 1, &state);
+ save_item_dispatch(owner, state, item_name);
}
template<typename C, std::size_t N>
- void save_item(const void *owner, C (&state)[N], const pstring &stname) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
+ void save_item(const void *owner, C (&state)[N], const pstring &item_name) // NOLINT(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
{
- save_state_ptr(owner, stname, dtype<C>(), N, &(state[0]));
+ save_state_ptr(owner, item_name, dtype<C>(), N, &(state[0]));
}
template<typename C>
- void save_item(const void *owner, C *state, const pstring &stname, const std::size_t count)
+ void save_item(const void *owner, C *state, const pstring &item_name, const std::size_t count)
{
- save_state_ptr(owner, stname, dtype<C>(), count, state);
+ save_state_ptr(owner, item_name, dtype<C>(), count, state);
}
- template<typename C>
- void save_item(const void *owner, std::vector<C> &v, const pstring &stname)
+ template<typename C, typename A>
+ void save_item(const void *owner, std::vector<C, A> &v, const pstring &item_name)
{
- save_state_ptr(owner, stname, dtype<C>(), v.size(), v.data());
+ save_state_ptr(owner, item_name, dtype<C>(), v.size(), v.data());
}
template<typename C, std::size_t N>
- void save_item(const void *owner, std::array<C, N> &a, const pstring &stname)
+ void save_item(const void *owner, std::array<C, N> &a, const pstring &item_name)
+ {
+ save_state_ptr(owner, item_name, dtype<C>(), N, a.data());
+ }
+
+ void save_state_ptr(const void *owner, const pstring &item_name, const datatype_t &dt, const std::size_t count, void *ptr)
+ {
+ m_save.emplace_back(item_name, dt, owner, count, ptr);
+ }
+
+ void pre_save()
+ {
+ for (auto & s : m_custom)
+ s.callback()->on_pre_save(*this);
+ }
+
+ void post_load()
{
- save_state_ptr(owner, stname, dtype<C>(), N, a.data());
+ for (auto & s : m_custom)
+ s.callback()->on_post_load(*this);
}
- void pre_save();
- void post_load();
- void remove_save_items(const void *owner);
+ void remove_save_items(const void *owner)
+ {
+ auto i = m_save.end();
+ while (i != m_save.begin())
+ {
+ i--;
+ if (i->owner() == owner)
+ i = m_save.erase(i);
+ }
+ i = m_custom.end();
+ while (i > m_custom.begin())
+ {
+ i--;
+ if (i->owner() == owner)
+ i = m_custom.erase(i);
+ }
+ }
- const std::vector<const entry_t *> save_list() const
+ std::vector<const entry_t *> save_list() const
{
std::vector<const entry_t *> ret;
- for (auto &i : m_save)
- ret.push_back(i.get());
+ for (const auto &i : m_save)
+ ret.push_back(&i);
return ret;
}
- void save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr);
-
protected:
private:
+
+ template<typename C>
+ std::enable_if_t<plib::is_integral<C>::value || std::is_enum<C>::value
+ || plib::is_floating_point<C>::value>
+ save_item_dispatch(const void *owner, C &state, const pstring &item_name)
+ {
+ save_state_ptr( owner, item_name, dtype<C>(), 1, &state);
+ }
+
+ template<typename C>
+ std::enable_if_t<!(plib::is_integral<C>::value || std::is_enum<C>::value
+ || plib::is_floating_point<C>::value)>
+ save_item_dispatch(const void *owner, C &state, const pstring &item_name)
+ {
+ saver_t sav(*this, owner, item_name);
+ state.save_state(sav);
+ }
+
entry_t::list_t m_save;
entry_t::list_t m_custom;
};
-template<> void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &stname);
+template<>
+inline void state_manager_t::save_item(const void *owner, callback_t &state, const pstring &item_name)
+{
+ m_custom.emplace_back(item_name, owner, &state);
+ state.register_state(*this, item_name);
+}
+
} // namespace plib
-#endif /* PSTATE_H_ */
+#endif // PSTATE_H_